2004-02-25 Roland McGrath <roland@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 468151f6af8dbe69a78e13f3df1ce2118e9c2876..46c3cf4ed7e28df2c43dde5c75ed72b7dc18ff92 100644 (file)
@@ -1,5 +1,6 @@
 /* DWARF 2 debugging format support for GDB.
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -30,7 +31,6 @@
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
-#include "symfile.h"
 #include "objfiles.h"
 #include "elf/dwarf2.h"
 #include "buildsym.h"
 #include "objfiles.h"
 #include "elf/dwarf2.h"
 #include "buildsym.h"
@@ -128,18 +128,6 @@ _STATEMENT_PROLOGUE;
 
 /* offsets and sizes of debugging sections */
 
 
 /* offsets and sizes of debugging sections */
 
-static file_ptr dwarf_info_offset;
-static file_ptr dwarf_abbrev_offset;
-static file_ptr dwarf_line_offset;
-static file_ptr dwarf_pubnames_offset;
-static file_ptr dwarf_aranges_offset;
-static file_ptr dwarf_loc_offset;
-static file_ptr dwarf_macinfo_offset;
-static file_ptr dwarf_str_offset;
-static file_ptr dwarf_ranges_offset;
-file_ptr dwarf_frame_offset;
-file_ptr dwarf_eh_frame_offset;
-
 static unsigned int dwarf_info_size;
 static unsigned int dwarf_abbrev_size;
 static unsigned int dwarf_line_size;
 static unsigned int dwarf_info_size;
 static unsigned int dwarf_abbrev_size;
 static unsigned int dwarf_line_size;
@@ -230,6 +218,48 @@ struct comp_unit_head
     int base_known;
   };
 
     int base_known;
   };
 
+/* Internal state when decoding a particular compilation unit.  */
+struct dwarf2_cu
+{
+  /* The objfile containing this compilation unit.  */
+  struct objfile *objfile;
+
+  /* The header of the compilation unit.
+
+     FIXME drow/2003-11-10: Some of the things from the comp_unit_head
+     should be moved to the dwarf2_cu structure; for instance the abbrevs
+     hash table.  */
+  struct comp_unit_head header;
+
+  struct function_range *first_fn, *last_fn, *cached_fn;
+
+  /* The language we are debugging.  */
+  enum language language;
+  const struct language_defn *language_defn;
+
+  /* The generic symbol table building routines have separate lists for
+     file scope symbols and all all other scopes (local scopes).  So
+     we need to select the right one to pass to add_symbol_to_list().
+     We do it by keeping a pointer to the correct list in list_in_scope.
+
+     FIXME: The original dwarf code just treated the file scope as the
+     first local scope, and all other local scopes as nested local
+     scopes, and worked fine.  Check to see if we really need to
+     distinguish these in buildsym.c.  */
+  struct pending **list_in_scope;
+
+  /* Maintain an array of referenced fundamental types for the current
+     compilation unit being read.  For DWARF version 1, we have to construct
+     the fundamental types on the fly, since no information about the
+     fundamental types is supplied.  Each such fundamental type is created by
+     calling a language dependent routine to create the type, and then a
+     pointer to that type is then placed in the array at the index specified
+     by it's FT_<TYPENAME> value.  The array has a fixed size set by the
+     FT_NUM_MEMBERS compile time constant, which is the number of predefined
+     fundamental types gdb knows how to construct.  */
+  struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+};
+
 /* The line number information for a compilation unit (found in the
    .debug_line section) begins with a "statement program header",
    which contains the following information.  */
 /* The line number information for a compilation unit (found in the
    .debug_line section) begins with a "statement program header",
    which contains the following information.  */
@@ -315,13 +345,21 @@ struct attr_abbrev
 struct die_info
   {
     enum dwarf_tag tag;                /* Tag indicating type of die */
 struct die_info
   {
     enum dwarf_tag tag;                /* Tag indicating type of die */
-    unsigned short has_children;       /* Does the die have children */
     unsigned int abbrev;       /* Abbrev number */
     unsigned int offset;       /* Offset in .debug_info section */
     unsigned int num_attrs;    /* Number of attributes */
     struct attribute *attrs;   /* An array of attributes */
     struct die_info *next_ref; /* Next die in ref hash table */
     unsigned int abbrev;       /* Abbrev number */
     unsigned int offset;       /* Offset in .debug_info section */
     unsigned int num_attrs;    /* Number of attributes */
     struct attribute *attrs;   /* An array of attributes */
     struct die_info *next_ref; /* Next die in ref hash table */
-    struct die_info *next;     /* Next die in linked list */
+
+    /* The dies in a compilation unit form an n-ary tree.  PARENT
+       points to this die's parent; CHILD points to the first child of
+       this node; and all the children of a given node are chained
+       together via their SIBLING fields, terminated by a die whose
+       tag is zero.  */
+    struct die_info *child;    /* Its first child, if any.  */
+    struct die_info *sibling;  /* Its next sibling, if any.  */
+    struct die_info *parent;   /* Its parent, if any.  */
+
     struct type *type;         /* Cached type information */
   };
 
     struct type *type;         /* Cached type information */
   };
 
@@ -349,8 +387,6 @@ struct function_range
   struct function_range *next;
 };
 
   struct function_range *next;
 };
 
-static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
-
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
@@ -380,19 +416,11 @@ static struct die_info *die_ref_table[REF_HASH_SIZE];
 /* Obstack for allocating temporary storage used during symbol reading.  */
 static struct obstack dwarf2_tmp_obstack;
 
 /* Obstack for allocating temporary storage used during symbol reading.  */
 static struct obstack dwarf2_tmp_obstack;
 
-/* Offset to the first byte of the current compilation unit header,
-   for resolving relative reference dies. */
-static unsigned int cu_header_offset;
-
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
 #endif
 
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
 #endif
 
-/* The language we are debugging.  */
-static enum language cu_language;
-static const struct language_defn *cu_language_defn;
-
 /* Actually data from the sections.  */
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
 /* Actually data from the sections.  */
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
@@ -405,57 +433,19 @@ static char *dwarf_loc_buffer;
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
-/* The generic symbol table building routines have separate lists for
-   file scope symbols and all all other scopes (local scopes).  So
-   we need to select the right one to pass to add_symbol_to_list().
-   We do it by keeping a pointer to the correct list in list_in_scope.
-
-   FIXME:  The original dwarf code just treated the file scope as the first
-   local scope, and all other local scopes as nested local scopes, and worked
-   fine.  Check to see if we really need to distinguish these
-   in buildsym.c.  */
-static struct pending **list_in_scope = &file_symbols;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
    by decode_locdesc.  */
 
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
    by decode_locdesc.  */
 
-static int optimized_out;      /* No ops in location in expression,
-                                  so object was optimized out.  */
 static int isreg;              /* Object lives in register.
                                   decode_locdesc's return value is
                                   the register number.  */
 static int isreg;              /* Object lives in register.
                                   decode_locdesc's return value is
                                   the register number.  */
-static int offreg;             /* Object's address is the sum of the
-                                  register specified by basereg, plus
-                                  the offset returned.  */
-static int basereg;            /* See `offreg'.  */
-static int isderef;            /* Value described by flags above is
-                                  the address of a pointer to the object.  */
-static int islocal;            /* Variable is at the returned offset
-                                  from the frame start, but there's
-                                  no identified frame pointer for
-                                  this function, so we can't say
-                                  which register it's relative to;
-                                  use LOC_LOCAL.  */
-
-/* DW_AT_frame_base values for the current function.
-   frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
-   contains the register number for the frame register.
-   frame_base_offset is the offset from the frame register to the
-   virtual stack frame. */
-static int frame_base_reg;
-static CORE_ADDR frame_base_offset;
-
-/* This value is added to each symbol value.  FIXME:  Generalize to
-   the section_offsets structure used by dbxread (once this is done,
-   pass the appropriate section number to end_symtab).  */
-static CORE_ADDR baseaddr;     /* Add to each symbol value */
 
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.
    The complete dwarf information for an objfile is kept in the
 
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.
    The complete dwarf information for an objfile is kept in the
-   psymbol_obstack, so that absolute die references can be handled.
+   objfile_obstack, so that absolute die references can be handled.
    Most of the information in this structure is related to an entire
    object file and could be passed via the sym_private field of the objfile.
    It is however conceivable that dwarf2 might not be the only type
    Most of the information in this structure is related to an entire
    object file and could be passed via the sym_private field of the objfile.
    It is however conceivable that dwarf2 might not be the only type
@@ -536,17 +526,6 @@ struct dwarf2_pinfo
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
-/* Maintain an array of referenced fundamental types for the current
-   compilation unit being read.  For DWARF version 1, we have to construct
-   the fundamental types on the fly, since no information about the
-   fundamental types is supplied.  Each such fundamental type is created by
-   calling a language dependent routine to create the type, and then a
-   pointer to that type is then placed in the array at the index specified
-   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
-   FT_NUM_MEMBERS compile time constant, which is the number of predefined
-   fundamental types gdb knows how to construct.  */
-static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
-
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
@@ -602,13 +581,6 @@ struct field_info
 
 /* Various complaints about symbol reading that don't abort the process */
 
 
 /* Various complaints about symbol reading that don't abort the process */
 
-static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
-            arg1);
-}
-
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
@@ -622,13 +594,6 @@ dwarf2_complex_location_expr_complaint (void)
   complaint (&symfile_complaints, "location expression too complex");
 }
 
   complaint (&symfile_complaints, "location expression too complex");
 }
 
-static void
-dwarf2_unsupported_at_frame_base_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints,
-            "unsupported DW_AT_frame_base for function '%s'", arg1);
-}
-
 static void
 dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
 static void
 dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
@@ -670,59 +635,60 @@ static void dwarf2_build_psymtabs_easy (struct objfile *, int);
 
 static void dwarf2_build_psymtabs_hard (struct objfile *, int);
 
 
 static void dwarf2_build_psymtabs_hard (struct objfile *, int);
 
-static char *scan_partial_symbols (char *, struct objfile *,
-                                  CORE_ADDR *, CORE_ADDR *,
-                                  const struct comp_unit_head *,
+static char *scan_partial_symbols (char *, CORE_ADDR *, CORE_ADDR *,
+                                  struct dwarf2_cu *,
                                   const char *namespace);
 
                                   const char *namespace);
 
-static void add_partial_symbol (struct partial_die_info *, struct objfile *,
-                               const struct comp_unit_head *,
+static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
                                const char *namespace);
 
                                const char *namespace);
 
+static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace);
+
 static char *add_partial_namespace (struct partial_die_info *pdi,
                                    char *info_ptr,
 static char *add_partial_namespace (struct partial_die_info *pdi,
                                    char *info_ptr,
-                                   struct objfile *objfile,
                                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
                                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                                   const struct comp_unit_head *cu_header,
+                                   struct dwarf2_cu *cu,
+                                   const char *namespace);
+
+static char *add_partial_structure (struct partial_die_info *struct_pdi,
+                                   char *info_ptr,
+                                   struct dwarf2_cu *cu,
                                    const char *namespace);
 
 static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
                                      char *info_ptr,
                                    const char *namespace);
 
 static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
                                      char *info_ptr,
-                                     struct objfile *objfile,
-                                     const struct comp_unit_head *cu_header,
+                                     struct dwarf2_cu *cu,
                                      const char *namespace);
 
 static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
                                 char *info_ptr,
                                 bfd *abfd,
                                      const char *namespace);
 
 static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
                                 char *info_ptr,
                                 bfd *abfd,
-                                const struct comp_unit_head *cu_header);
+                                struct dwarf2_cu *cu);
 
 static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
 
 static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int,
-                          asection *);
+char *dwarf2_read_section (struct objfile *, asection *);
 
 
-static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header);
+static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
 
 static void dwarf2_empty_abbrev_table (void *);
 
 static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
 
 static void dwarf2_empty_abbrev_table (void *);
 
 static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
-                                         const struct comp_unit_head *cu_header);
+                                                struct dwarf2_cu *);
 
 static char *read_partial_die (struct partial_die_info *,
 
 static char *read_partial_die (struct partial_die_info *,
-                              bfd *, char *,
-                              const struct comp_unit_head *);
+                              bfd *, char *, struct dwarf2_cu *);
 
 static char *read_full_die (struct die_info **, bfd *, char *,
 
 static char *read_full_die (struct die_info **, bfd *, char *,
-                           const struct comp_unit_head *);
+                           struct dwarf2_cu *, int *);
 
 static char *read_attribute (struct attribute *, struct attr_abbrev *,
 
 static char *read_attribute (struct attribute *, struct attr_abbrev *,
-                            bfd *, char *, const struct comp_unit_head *);
+                            bfd *, char *, struct dwarf2_cu *);
 
 static char *read_attribute_value (struct attribute *, unsigned,
 
 static char *read_attribute_value (struct attribute *, unsigned,
-                            bfd *, char *, const struct comp_unit_head *);
+                            bfd *, char *, struct dwarf2_cu *);
 
 static unsigned int read_1_byte (bfd *, char *);
 
 
 static unsigned int read_1_byte (bfd *, char *);
 
@@ -734,7 +700,7 @@ static unsigned int read_4_bytes (bfd *, char *);
 
 static unsigned long read_8_bytes (bfd *, char *);
 
 
 static unsigned long read_8_bytes (bfd *, char *);
 
-static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *,
+static CORE_ADDR read_address (bfd *, char *ptr, struct dwarf2_cu *,
                               int *bytes_read);
 
 static LONGEST read_initial_length (bfd *, char *,
                               int *bytes_read);
 
 static LONGEST read_initial_length (bfd *, char *,
@@ -754,137 +720,146 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
 
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
 
-static void set_cu_language (unsigned int);
+static void set_cu_language (unsigned int, struct dwarf2_cu *);
 
 
-static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
+                                     struct dwarf2_cu *);
 
 
-static int die_is_declaration (struct die_info *);
+static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
+
+static struct die_info *die_specification (struct die_info *die,
+                                          struct dwarf2_cu *);
 
 static void free_line_header (struct line_header *lh);
 
 static struct line_header *(dwarf_decode_line_header
                             (unsigned int offset,
 
 static void free_line_header (struct line_header *lh);
 
 static struct line_header *(dwarf_decode_line_header
                             (unsigned int offset,
-                             bfd *abfd,
-                             const struct comp_unit_head *cu_header));
+                             bfd *abfd, struct dwarf2_cu *cu));
 
 static void dwarf_decode_lines (struct line_header *, char *, bfd *,
 
 static void dwarf_decode_lines (struct line_header *, char *, bfd *,
-                               const struct comp_unit_head *);
+                               struct dwarf2_cu *);
 
 static void dwarf2_start_subfile (char *, char *);
 
 static struct symbol *new_symbol (struct die_info *, struct type *,
 
 static void dwarf2_start_subfile (char *, char *);
 
 static struct symbol *new_symbol (struct die_info *, struct type *,
-                                 struct objfile *, const struct comp_unit_head *);
+                                 struct dwarf2_cu *);
 
 static void dwarf2_const_value (struct attribute *, struct symbol *,
 
 static void dwarf2_const_value (struct attribute *, struct symbol *,
-                               struct objfile *, const struct comp_unit_head *);
+                               struct dwarf2_cu *);
 
 static void dwarf2_const_value_data (struct attribute *attr,
                                     struct symbol *sym,
                                     int bits);
 
 
 static void dwarf2_const_value_data (struct attribute *attr,
                                     struct symbol *sym,
                                     int bits);
 
-static struct type *die_type (struct die_info *, struct objfile *,
-                             const struct comp_unit_head *);
+static struct type *die_type (struct die_info *, struct dwarf2_cu *);
 
 
-static struct type *die_containing_type (struct die_info *, struct objfile *,
-                                        const struct comp_unit_head *);
+static struct type *die_containing_type (struct die_info *,
+                                        struct dwarf2_cu *);
 
 #if 0
 static struct type *type_at_offset (unsigned int, struct objfile *);
 #endif
 
 
 #if 0
 static struct type *type_at_offset (unsigned int, struct objfile *);
 #endif
 
-static struct type *tag_type_to_type (struct die_info *, struct objfile *,
-                                     const struct comp_unit_head *);
+static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
+
+static void read_type_die (struct die_info *, struct dwarf2_cu *);
+
+static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
+
+static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *);
 
 
-static void read_type_die (struct die_info *, struct objfile *,
-                          const struct comp_unit_head *);
+static char *typename_concat (const char *prefix, const char *suffix);
 
 
-static void read_typedef (struct die_info *, struct objfile *,
-                         const struct comp_unit_head *);
+static char *class_name (struct die_info *die, struct dwarf2_cu *);
 
 
-static void read_base_type (struct die_info *, struct objfile *);
+static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_file_scope (struct die_info *, struct objfile *,
-                            const struct comp_unit_head *);
+static void read_base_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_func_scope (struct die_info *, struct objfile *,
-                            const struct comp_unit_head *);
+static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu);
 
 
-static void read_lexical_block_scope (struct die_info *, struct objfile *,
-                                     const struct comp_unit_head *);
+static void read_file_scope (struct die_info *, struct dwarf2_cu *);
+
+static void read_func_scope (struct die_info *, struct dwarf2_cu *);
+
+static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 
 static int dwarf2_get_pc_bounds (struct die_info *,
 
 static int dwarf2_get_pc_bounds (struct die_info *,
-                                CORE_ADDR *, CORE_ADDR *, struct objfile *,
-                                const struct comp_unit_head *);
+                                CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
+
+static void get_scope_pc_bounds (struct die_info *,
+                                CORE_ADDR *, CORE_ADDR *,
+                                struct dwarf2_cu *);
 
 static void dwarf2_add_field (struct field_info *, struct die_info *,
 
 static void dwarf2_add_field (struct field_info *, struct die_info *,
-                             struct objfile *, const struct comp_unit_head *);
+                             struct dwarf2_cu *);
 
 static void dwarf2_attach_fields_to_type (struct field_info *,
 
 static void dwarf2_attach_fields_to_type (struct field_info *,
-                                         struct type *, struct objfile *);
+                                         struct type *, struct dwarf2_cu *);
 
 static void dwarf2_add_member_fn (struct field_info *,
                                  struct die_info *, struct type *,
 
 static void dwarf2_add_member_fn (struct field_info *,
                                  struct die_info *, struct type *,
-                                 struct objfile *objfile,
-                                 const struct comp_unit_head *);
+                                 struct dwarf2_cu *);
 
 static void dwarf2_attach_fn_fields_to_type (struct field_info *,
 
 static void dwarf2_attach_fn_fields_to_type (struct field_info *,
-                                            struct type *, struct objfile *);
+                                            struct type *, struct dwarf2_cu *);
+
+static void read_structure_scope (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_structure_scope (struct die_info *, struct objfile *,
-                                 const struct comp_unit_head *);
+static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_common_block (struct die_info *, struct objfile *,
-                              const struct comp_unit_head *);
+static void read_namespace (struct die_info *die, struct dwarf2_cu *);
 
 
-static void read_namespace (struct die_info *die, struct objfile *objfile,
-                           const struct comp_unit_head *cu_header);
+static const char *namespace_name (struct die_info *die,
+                                  int *is_anonymous, struct dwarf2_cu *);
 
 
-static void read_enumeration (struct die_info *, struct objfile *,
-                             const struct comp_unit_head *);
+static void read_enumeration (struct die_info *, struct dwarf2_cu *);
 
 
-static struct type *dwarf_base_type (int, int, struct objfile *);
+static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
 
 
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
-                                const struct comp_unit_head *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
 
 
-static void read_array_type (struct die_info *, struct objfile *,
-                            const struct comp_unit_head *);
+static void read_array_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_tag_pointer_type (struct die_info *, struct objfile *,
-                                  const struct comp_unit_head *);
+static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *,
-                                        const struct comp_unit_head *);
+static void read_tag_ptr_to_member_type (struct die_info *,
+                                        struct dwarf2_cu *);
 
 
-static void read_tag_reference_type (struct die_info *, struct objfile *,
-                                    const struct comp_unit_head *);
+static void read_tag_reference_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_tag_const_type (struct die_info *, struct objfile *,
-                                const struct comp_unit_head *);
+static void read_tag_const_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_tag_volatile_type (struct die_info *, struct objfile *,
-                                   const struct comp_unit_head *);
+static void read_tag_volatile_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_tag_string_type (struct die_info *, struct objfile *);
+static void read_tag_string_type (struct die_info *, struct dwarf2_cu *);
 
 
-static void read_subroutine_type (struct die_info *, struct objfile *,
-                                 const struct comp_unit_head *);
+static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);
 
 
-static struct die_info *read_comp_unit (char *, bfd *,
-                                        const struct comp_unit_head *);
+static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);
+
+static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd,
+                                              struct dwarf2_cu *,
+                                              char **new_info_ptr,
+                                              struct die_info *parent);
+
+static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd,
+                                              struct dwarf2_cu *,
+                                              char **new_info_ptr,
+                                              struct die_info *parent);
 
 static void free_die_list (struct die_info *);
 
 static struct cleanup *make_cleanup_free_die_list (struct die_info *);
 
 
 static void free_die_list (struct die_info *);
 
 static struct cleanup *make_cleanup_free_die_list (struct die_info *);
 
-static void process_die (struct die_info *, struct objfile *,
-                        const struct comp_unit_head *);
+static void process_die (struct die_info *, struct dwarf2_cu *);
 
 
-static char *dwarf2_linkage_name (struct die_info *);
+static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 
 
-static char *dwarf2_name (struct die_info *die);
+static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
 
-static struct die_info *dwarf2_extension (struct die_info *die);
+static struct die_info *dwarf2_extension (struct die_info *die,
+                                         struct dwarf2_cu *);
 
 static char *dwarf_tag_name (unsigned int);
 
 
 static char *dwarf_tag_name (unsigned int);
 
@@ -914,11 +889,15 @@ static void store_in_ref_table (unsigned int, struct die_info *);
 
 static void dwarf2_empty_hash_tables (void);
 
 
 static void dwarf2_empty_hash_tables (void);
 
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
+                                              struct dwarf2_cu *);
+
+static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
 static struct die_info *follow_die_ref (unsigned int);
 
 
 static struct die_info *follow_die_ref (unsigned int);
 
-static struct type *dwarf2_fundamental_type (struct objfile *, int);
+static struct type *dwarf2_fundamental_type (struct objfile *, int,
+                                            struct dwarf2_cu *);
 
 /* memory allocation interface */
 
 
 /* memory allocation interface */
 
@@ -930,20 +909,19 @@ static struct abbrev_info *dwarf_alloc_abbrev (void);
 
 static struct die_info *dwarf_alloc_die (void);
 
 
 static struct die_info *dwarf_alloc_die (void);
 
-static void initialize_cu_func_list (void);
+static void initialize_cu_func_list (struct dwarf2_cu *);
 
 
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
+                                struct dwarf2_cu *);
 
 static void dwarf_decode_macros (struct line_header *, unsigned int,
 
 static void dwarf_decode_macros (struct line_header *, unsigned int,
-                                 char *, bfd *, const struct comp_unit_head *,
-                                 struct objfile *);
+                                 char *, bfd *, struct dwarf2_cu *);
 
 static int attr_form_is_block (struct attribute *);
 
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 
 static int attr_form_is_block (struct attribute *);
 
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
-                            const struct comp_unit_head *,
-                            struct objfile *objfile);
+                            struct dwarf2_cu *cu);
 
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
@@ -951,25 +929,18 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 int
 dwarf2_has_info (bfd *abfd)
 {
 int
 dwarf2_has_info (bfd *abfd)
 {
-  dwarf_info_offset = 0;
-  dwarf_abbrev_offset = 0;
-  dwarf_line_offset = 0;
-  dwarf_str_offset = 0;
-  dwarf_macinfo_offset = 0;
-  dwarf_frame_offset = 0;
-  dwarf_eh_frame_offset = 0;
-  dwarf_ranges_offset = 0;
-  dwarf_loc_offset = 0;
+  dwarf_info_section = 0;
+  dwarf_abbrev_section = 0;
+  dwarf_line_section = 0;
+  dwarf_str_section = 0;
+  dwarf_macinfo_section = 0;
+  dwarf_frame_section = 0;
+  dwarf_eh_frame_section = 0;
+  dwarf_ranges_section = 0;
+  dwarf_loc_section = 0;
   
   bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
   
   bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
-  if (dwarf_info_offset && dwarf_abbrev_offset)
-    {
-      return 1;
-    }
-  else
-    {
-      return 0;
-    }
+  return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
 }
 
 /* This function is mapped across the sections and remembers the
 }
 
 /* This function is mapped across the sections and remembers the
@@ -979,73 +950,62 @@ dwarf2_has_info (bfd *abfd)
 static void
 dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
 {
 static void
 dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
 {
-  if (STREQ (sectp->name, INFO_SECTION))
+  if (strcmp (sectp->name, INFO_SECTION) == 0)
     {
     {
-      dwarf_info_offset = sectp->filepos;
       dwarf_info_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_info_section = sectp;
     }
       dwarf_info_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_info_section = sectp;
     }
-  else if (STREQ (sectp->name, ABBREV_SECTION))
+  else if (strcmp (sectp->name, ABBREV_SECTION) == 0)
     {
     {
-      dwarf_abbrev_offset = sectp->filepos;
       dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_abbrev_section = sectp;
     }
       dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_abbrev_section = sectp;
     }
-  else if (STREQ (sectp->name, LINE_SECTION))
+  else if (strcmp (sectp->name, LINE_SECTION) == 0)
     {
     {
-      dwarf_line_offset = sectp->filepos;
       dwarf_line_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_line_section = sectp;
     }
       dwarf_line_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_line_section = sectp;
     }
-  else if (STREQ (sectp->name, PUBNAMES_SECTION))
+  else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0)
     {
     {
-      dwarf_pubnames_offset = sectp->filepos;
       dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_pubnames_section = sectp;
     }
       dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_pubnames_section = sectp;
     }
-  else if (STREQ (sectp->name, ARANGES_SECTION))
+  else if (strcmp (sectp->name, ARANGES_SECTION) == 0)
     {
     {
-      dwarf_aranges_offset = sectp->filepos;
       dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_aranges_section = sectp;
     }
       dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_aranges_section = sectp;
     }
-  else if (STREQ (sectp->name, LOC_SECTION))
+  else if (strcmp (sectp->name, LOC_SECTION) == 0)
     {
     {
-      dwarf_loc_offset = sectp->filepos;
       dwarf_loc_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_loc_section = sectp;
     }
       dwarf_loc_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_loc_section = sectp;
     }
-  else if (STREQ (sectp->name, MACINFO_SECTION))
+  else if (strcmp (sectp->name, MACINFO_SECTION) == 0)
     {
     {
-      dwarf_macinfo_offset = sectp->filepos;
       dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_macinfo_section = sectp;
     }
       dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_macinfo_section = sectp;
     }
-  else if (STREQ (sectp->name, STR_SECTION))
+  else if (strcmp (sectp->name, STR_SECTION) == 0)
     {
     {
-      dwarf_str_offset = sectp->filepos;
       dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_str_section = sectp;
     }
       dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_str_section = sectp;
     }
-  else if (STREQ (sectp->name, FRAME_SECTION))
+  else if (strcmp (sectp->name, FRAME_SECTION) == 0)
     {
     {
-      dwarf_frame_offset = sectp->filepos;
       dwarf_frame_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_frame_section = sectp;
     }
       dwarf_frame_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_frame_section = sectp;
     }
-  else if (STREQ (sectp->name, EH_FRAME_SECTION))
+  else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0)
     {
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
         {
     {
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
         {
-          dwarf_eh_frame_offset = sectp->filepos;
           dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
           dwarf_eh_frame_section = sectp;
         }
     }
           dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
           dwarf_eh_frame_section = sectp;
         }
     }
-  else if (STREQ (sectp->name, RANGES_SECTION))
+  else if (strcmp (sectp->name, RANGES_SECTION) == 0)
     {
     {
-      dwarf_ranges_offset = sectp->filepos;
       dwarf_ranges_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_ranges_section = sectp;
     }
       dwarf_ranges_size = bfd_get_section_size_before_reloc (sectp);
       dwarf_ranges_section = sectp;
     }
@@ -1059,52 +1019,32 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
 
   /* We definitely need the .debug_info and .debug_abbrev sections */
 
 
   /* We definitely need the .debug_info and .debug_abbrev sections */
 
-  dwarf_info_buffer = dwarf2_read_section (objfile,
-                                          dwarf_info_offset,
-                                          dwarf_info_size,
-                                          dwarf_info_section);
-  dwarf_abbrev_buffer = dwarf2_read_section (objfile,
-                                            dwarf_abbrev_offset,
-                                            dwarf_abbrev_size,
-                                            dwarf_abbrev_section);
-
-  if (dwarf_line_offset)
-    dwarf_line_buffer = dwarf2_read_section (objfile,
-                                            dwarf_line_offset,
-                                            dwarf_line_size,
-                                            dwarf_line_section);
+  dwarf_info_buffer = dwarf2_read_section (objfile, dwarf_info_section);
+  dwarf_abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section);
+
+  if (dwarf_line_section)
+    dwarf_line_buffer = dwarf2_read_section (objfile, dwarf_line_section);
   else
     dwarf_line_buffer = NULL;
 
   else
     dwarf_line_buffer = NULL;
 
-  if (dwarf_str_offset)
-    dwarf_str_buffer = dwarf2_read_section (objfile,
-                                           dwarf_str_offset,
-                                           dwarf_str_size,
-                                           dwarf_str_section);
+  if (dwarf_str_section)
+    dwarf_str_buffer = dwarf2_read_section (objfile, dwarf_str_section);
   else
     dwarf_str_buffer = NULL;
 
   else
     dwarf_str_buffer = NULL;
 
-  if (dwarf_macinfo_offset)
+  if (dwarf_macinfo_section)
     dwarf_macinfo_buffer = dwarf2_read_section (objfile,
     dwarf_macinfo_buffer = dwarf2_read_section (objfile,
-                                                dwarf_macinfo_offset,
-                                                dwarf_macinfo_size,
                                                dwarf_macinfo_section);
   else
     dwarf_macinfo_buffer = NULL;
 
                                                dwarf_macinfo_section);
   else
     dwarf_macinfo_buffer = NULL;
 
-  if (dwarf_ranges_offset)
-    dwarf_ranges_buffer = dwarf2_read_section (objfile,
-                                              dwarf_ranges_offset,
-                                              dwarf_ranges_size,
-                                              dwarf_ranges_section);
+  if (dwarf_ranges_section)
+    dwarf_ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section);
   else
     dwarf_ranges_buffer = NULL;
 
   else
     dwarf_ranges_buffer = NULL;
 
-  if (dwarf_loc_offset)
-    dwarf_loc_buffer = dwarf2_read_section (objfile,
-                                           dwarf_loc_offset,
-                                           dwarf_loc_size,
-                                           dwarf_loc_section);
+  if (dwarf_loc_section)
+    dwarf_loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section);
   else
     dwarf_loc_buffer = NULL;
 
   else
     dwarf_loc_buffer = NULL;
 
@@ -1145,8 +1085,6 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
   unsigned int entry_length, version, info_offset, info_size;
 
   pubnames_buffer = dwarf2_read_section (objfile,
   unsigned int entry_length, version, info_offset, info_size;
 
   pubnames_buffer = dwarf2_read_section (objfile,
-                                        dwarf_pubnames_offset,
-                                        dwarf_pubnames_size,
                                         dwarf_pubnames_section);
   pubnames_ptr = pubnames_buffer;
   while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
                                         dwarf_pubnames_section);
   pubnames_ptr = pubnames_buffer;
   while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size)
@@ -1166,8 +1104,6 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
     }
 
   aranges_buffer = dwarf2_read_section (objfile,
     }
 
   aranges_buffer = dwarf2_read_section (objfile,
-                                       dwarf_aranges_offset,
-                                       dwarf_aranges_size,
                                        dwarf_aranges_section);
 
 }
                                        dwarf_aranges_section);
 
 }
@@ -1214,7 +1150,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
-  CORE_ADDR lowpc, highpc;
+  CORE_ADDR lowpc, highpc, baseaddr;
 
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
 
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
@@ -1265,47 +1201,51 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
      left at all should be sufficient.  */
   while (info_ptr < dwarf_info_buffer + dwarf_info_size)
     {
      left at all should be sufficient.  */
   while (info_ptr < dwarf_info_buffer + dwarf_info_size)
     {
-      struct comp_unit_head cu_header;
+      struct dwarf2_cu cu;
       beg_of_comp_unit = info_ptr;
       beg_of_comp_unit = info_ptr;
-      info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
 
 
-      if (cu_header.version != 2)
+      cu.objfile = objfile;
+      info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
+
+      if (cu.header.version != 2)
        {
        {
-         error ("Dwarf Error: wrong version in compilation unit header (is %d, should be %d) [in module %s]", cu_header.version, 2, bfd_get_filename (abfd));
+         error ("Dwarf Error: wrong version in compilation unit header (is %d, should be %d) [in module %s]", cu.header.version, 2, bfd_get_filename (abfd));
          return;
        }
          return;
        }
-      if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+      if (cu.header.abbrev_offset >= dwarf_abbrev_size)
        {
          error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6) [in module %s]",
        {
          error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6) [in module %s]",
-                (long) cu_header.abbrev_offset,
+                (long) cu.header.abbrev_offset,
                 (long) (beg_of_comp_unit - dwarf_info_buffer),
                 bfd_get_filename (abfd));
          return;
        }
                 (long) (beg_of_comp_unit - dwarf_info_buffer),
                 bfd_get_filename (abfd));
          return;
        }
-      if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size
+      if (beg_of_comp_unit + cu.header.length + cu.header.initial_length_size
          > dwarf_info_buffer + dwarf_info_size)
        {
          error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0) [in module %s]",
          > dwarf_info_buffer + dwarf_info_size)
        {
          error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0) [in module %s]",
-                (long) cu_header.length,
+                (long) cu.header.length,
                 (long) (beg_of_comp_unit - dwarf_info_buffer),
                 bfd_get_filename (abfd));
          return;
        }
       /* Complete the cu_header */
                 (long) (beg_of_comp_unit - dwarf_info_buffer),
                 bfd_get_filename (abfd));
          return;
        }
       /* Complete the cu_header */
-      cu_header.offset = beg_of_comp_unit - dwarf_info_buffer;
-      cu_header.first_die_ptr = info_ptr;
-      cu_header.cu_head_ptr = beg_of_comp_unit;
+      cu.header.offset = beg_of_comp_unit - dwarf_info_buffer;
+      cu.header.first_die_ptr = info_ptr;
+      cu.header.cu_head_ptr = beg_of_comp_unit;
+
+      cu.list_in_scope = &file_symbols;
 
       /* Read the abbrevs for this compilation unit into a table */
 
       /* Read the abbrevs for this compilation unit into a table */
-      dwarf2_read_abbrevs (abfd, &cu_header);
-      make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs);
+      dwarf2_read_abbrevs (abfd, &cu);
+      make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
 
       /* Read the compilation unit die */
       info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
 
       /* Read the compilation unit die */
       info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
-                                  &cu_header);
+                                  &cu);
 
       /* Set the language we're debugging */
 
       /* Set the language we're debugging */
-      set_cu_language (comp_unit_die.language);
+      set_cu_language (comp_unit_die.language, &cu);
 
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
 
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
@@ -1315,8 +1255,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
-       obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
-      cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+       obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
       DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
       DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
       DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
       DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
@@ -1344,8 +1283,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          lowpc = ((CORE_ADDR) -1);
          highpc = ((CORE_ADDR) 0);
 
          lowpc = ((CORE_ADDR) -1);
          highpc = ((CORE_ADDR) 0);
 
-         info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
-                                          &cu_header, NULL);
+         info_ptr = scan_partial_symbols (info_ptr, &lowpc, &highpc,
+                                          &cu, NULL);
 
          /* If we didn't find a lowpc, set it to highpc to avoid
             complaints from `maint check'.  */
 
          /* If we didn't find a lowpc, set it to highpc to avoid
             complaints from `maint check'.  */
@@ -1374,8 +1313,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          also happen.) This happens in VxWorks.  */
       free_named_symtabs (pst->filename);
 
          also happen.) This happens in VxWorks.  */
       free_named_symtabs (pst->filename);
 
-      info_ptr = beg_of_comp_unit + cu_header.length 
-                                  + cu_header.initial_length_size;
+      info_ptr = beg_of_comp_unit + cu.header.length 
+                                  + cu.header.initial_length_size;
     }
   do_cleanups (back_to);
 }
     }
   do_cleanups (back_to);
 }
@@ -1388,11 +1327,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
    previously encountered a DW_TAG_namespace.  */
 
 static char *
    previously encountered a DW_TAG_namespace.  */
 
 static char *
-scan_partial_symbols (char *info_ptr, struct objfile *objfile,
-                     CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                     const struct comp_unit_head *cu_header,
+scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
+                     CORE_ADDR *highpc, struct dwarf2_cu *cu,
                      const char *namespace)
 {
                      const char *namespace)
 {
+  struct objfile *objfile = cu->objfile;
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
 
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
 
@@ -1406,7 +1345,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
         inside the loop.  */
       int info_ptr_updated = 0;
 
         inside the loop.  */
       int info_ptr_updated = 0;
 
-      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
 
       /* Anonymous namespaces have no name but have interesting
         children, so we need to look at them.  Ditto for anonymous
 
       /* Anonymous namespaces have no name but have interesting
         children, so we need to look at them.  Ditto for anonymous
@@ -1430,33 +1369,40 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
                    }
                  if (!pdi.is_declaration)
                    {
                    }
                  if (!pdi.is_declaration)
                    {
-                     add_partial_symbol (&pdi, objfile, cu_header, namespace);
+                     add_partial_symbol (&pdi, cu, namespace);
                    }
                }
              break;
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
                    }
                }
              break;
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
+             if (!pdi.is_declaration)
+               {
+                 add_partial_symbol (&pdi, cu, namespace);
+               }
+             break;
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
              if (!pdi.is_declaration)
                {
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
              if (!pdi.is_declaration)
                {
-                 add_partial_symbol (&pdi, objfile, cu_header, namespace);
+                 info_ptr = add_partial_structure (&pdi, info_ptr, cu,
+                                                   namespace);
+                 info_ptr_updated = 1;
                }
              break;
            case DW_TAG_enumeration_type:
              if (!pdi.is_declaration)
                {
                }
              break;
            case DW_TAG_enumeration_type:
              if (!pdi.is_declaration)
                {
-                 info_ptr = add_partial_enumeration (&pdi, info_ptr,
-                                                     objfile, cu_header,
+                 info_ptr = add_partial_enumeration (&pdi, info_ptr, cu,
                                                      namespace);
                  info_ptr_updated = 1;
                }
              break;
            case DW_TAG_base_type:
                                                      namespace);
                  info_ptr_updated = 1;
                }
              break;
            case DW_TAG_base_type:
+            case DW_TAG_subrange_type:
              /* File scope base type definitions are added to the partial
                 symbol table.  */
              /* File scope base type definitions are added to the partial
                 symbol table.  */
-             add_partial_symbol (&pdi, objfile, cu_header, namespace);
+             add_partial_symbol (&pdi, cu, namespace);
              break;
            case DW_TAG_namespace:
              /* We've hit a DW_TAG_namespace entry, so we know this
              break;
            case DW_TAG_namespace:
              /* We've hit a DW_TAG_namespace entry, so we know this
@@ -1464,9 +1410,8 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
                 generates them; update NAMESPACE to reflect that.  */
              if (namespace == NULL)
                namespace = "";
                 generates them; update NAMESPACE to reflect that.  */
              if (namespace == NULL)
                namespace = "";
-             info_ptr = add_partial_namespace (&pdi, info_ptr, objfile,
-                                               lowpc, highpc, cu_header,
-                                               namespace);
+             info_ptr = add_partial_namespace (&pdi, info_ptr, lowpc, highpc,
+                                               cu, namespace);
              info_ptr_updated = 1;
              break;
            default:
              info_ptr_updated = 1;
              break;
            default:
@@ -1486,42 +1431,57 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
         this seems like the easiest way to handle the issue.  */
 
       if (!info_ptr_updated)
         this seems like the easiest way to handle the issue.  */
 
       if (!info_ptr_updated)
-         info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header);
+       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
     }
 
   return info_ptr;
 }
 
 static void
     }
 
   return info_ptr;
 }
 
 static void
-add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
-                   const struct comp_unit_head *cu_header,
-                   const char *namespace)
+add_partial_symbol (struct partial_die_info *pdi,
+                   struct dwarf2_cu *cu, const char *namespace)
 {
 {
+  struct objfile *objfile = cu->objfile;
   CORE_ADDR addr = 0;
   CORE_ADDR addr = 0;
+  char *actual_name = pdi->name;
   const struct partial_symbol *psym = NULL;
   const struct partial_symbol *psym = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* If we're not in the global namespace and if the namespace name
+     isn't encoded in a mangled actual_name, add it.  */
+  
+  if (pdi_needs_namespace (pdi->tag, namespace))
+    {
+      actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
+      strcpy (actual_name, namespace);
+      strcat (actual_name, "::");
+      strcat (actual_name, pdi->name);
+    }
 
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
 
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
             mst_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       else
        {
        }
       else
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_file_text, objfile); */
             mst_file_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_variable:
        }
       break;
     case DW_TAG_variable:
@@ -1541,35 +1501,36 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
             table building.  */
 
          if (pdi->locdesc)
             table building.  */
 
          if (pdi->locdesc)
-           addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+           addr = decode_locdesc (pdi->locdesc, cu);
          if (pdi->locdesc || pdi->has_type)
          if (pdi->locdesc || pdi->has_type)
-           psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+           psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                        VAR_DOMAIN, LOC_STATIC,
                                        &objfile->global_psymbols,
                                        0, addr + baseaddr,
                                        VAR_DOMAIN, LOC_STATIC,
                                        &objfile->global_psymbols,
                                        0, addr + baseaddr,
-                                       cu_language, objfile);
+                                       cu->language, objfile);
        }
       else
        {
          /* Static Variable. Skip symbols without location descriptors.  */
          if (pdi->locdesc == NULL)
            return;
        }
       else
        {
          /* Static Variable. Skip symbols without location descriptors.  */
          if (pdi->locdesc == NULL)
            return;
-         addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
-         /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+         addr = decode_locdesc (pdi->locdesc, cu);
+         /*prim_record_minimal_symbol (actual_name, addr + baseaddr,
             mst_file_data, objfile); */
             mst_file_data, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+    case DW_TAG_subrange_type:
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
@@ -1577,27 +1538,33 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
+      /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+        static vs. global.  */
       if (pdi->has_children == 0)
        return;
       if (pdi->has_children == 0)
        return;
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
                           STRUCT_DOMAIN, LOC_TYPEDEF,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
 
 
-      if (cu_language == language_cplus)
+      if (cu->language == language_cplus)
        {
          /* For C++, these implicitly act as typedefs as well. */
        {
          /* For C++, these implicitly act as typedefs as well. */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         add_psymbol_to_list (actual_name, strlen (actual_name),
                               VAR_DOMAIN, LOC_TYPEDEF,
                               VAR_DOMAIN, LOC_TYPEDEF,
-                              &objfile->static_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+                              &objfile->global_psymbols,
+                              0, (CORE_ADDR) 0, cu->language, objfile);
        }
       break;
     case DW_TAG_enumerator:
        }
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_CONST,
                           VAR_DOMAIN, LOC_CONST,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     default:
       break;
       break;
     default:
       break;
@@ -1609,7 +1576,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
      (otherwise we'll have psym == NULL), and if we actually had a
      mangled name to begin with.  */
 
      (otherwise we'll have psym == NULL), and if we actually had a
      mangled name to begin with.  */
 
-  if (cu_language == language_cplus
+  if (cu->language == language_cplus
       && namespace == NULL
       && psym != NULL
       && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
       && namespace == NULL
       && psym != NULL
       && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
@@ -1617,22 +1584,45 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
                                         objfile);
 }
 
                                         objfile);
 }
 
+/* Determine whether a die of type TAG living in the C++ namespace
+   NAMESPACE needs to have the name of the namespace prepended to the
+   name listed in the die.  */
+
+static int
+pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
+{
+  if (namespace == NULL || namespace[0] == '\0')
+    return 0;
+
+  switch (tag)
+    {
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
 
 static char *
 add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
 
 static char *
 add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
-                      struct objfile *objfile,
                       CORE_ADDR *lowpc, CORE_ADDR *highpc,
                       CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                      const struct comp_unit_head *cu_header,
-                      const char *namespace)
+                      struct dwarf2_cu *cu, const char *namespace)
 {
 {
-  /* Calculate the full name of the namespace that we just entered.  */
-
+  struct objfile *objfile = cu->objfile;
   const char *new_name = pdi->name;
   char *full_name;
 
   const char *new_name = pdi->name;
   char *full_name;
 
+  /* Calculate the full name of the namespace that we just entered.  */
+
   if (new_name == NULL)
     new_name = "(anonymous namespace)";
   full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
   if (new_name == NULL)
     new_name = "(anonymous namespace)";
   full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
@@ -1641,48 +1631,118 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
-  /* FIXME: carlton/2003-06-27: Once we build qualified names for more
-     symbols than just namespaces, we should replace this by a call to
-     add_partial_symbol.  */
+  /* FIXME: carlton/2003-10-07: We can't just replace this by a call
+     to add_partial_symbol, because we don't have a way to pass in the
+     full name to that function; that might be a flaw in
+     add_partial_symbol's interface.  */
 
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
 
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
-                      0, 0, cu_language, objfile);
+                      0, 0, cu->language, objfile);
 
   /* Now scan partial symbols in that namespace.  */
 
   if (pdi->has_children)
 
   /* Now scan partial symbols in that namespace.  */
 
   if (pdi->has_children)
-    info_ptr = scan_partial_symbols (info_ptr, objfile,
-                                    lowpc, highpc,
-                                    cu_header, full_name);
+    info_ptr = scan_partial_symbols (info_ptr, lowpc, highpc, cu, full_name);
 
   return info_ptr;
 }
 
 
   return info_ptr;
 }
 
+/* Read a partial die corresponding to a class or structure.  */
+
+static char *
+add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
+                      struct dwarf2_cu *cu,
+                      const char *namespace)
+{
+  bfd *abfd = cu->objfile->obfd;
+  char *actual_class_name = NULL;
+
+  if (cu->language == language_cplus
+      && (namespace == NULL || namespace[0] == '\0')
+      && struct_pdi->name != NULL
+      && struct_pdi->has_children)
+    {
+      /* See if we can figure out if the class lives in a namespace
+        (or is nested within another class.)  We do this by looking
+        for a member function; its demangled name will contain
+        namespace info, if there is any.  */
+
+      /* NOTE: carlton/2003-10-07: Getting the info this way changes
+        what template types look like, because the demangler
+        frequently doesn't give the same name as the debug info.  We
+        could fix this by only using the demangled name to get the
+        prefix (but see comment in read_structure_scope).  */
+
+      /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have
+        the appropriate debug information, so it would be nice to be
+        able to avoid this hack.  But NAMESPACE may not be the
+        namespace where this class was defined: NAMESPACE reflects
+        where STRUCT_PDI occurs in the tree of dies, but because of
+        DW_AT_specification, that may not actually tell us where the
+        class is defined.  (See the comment in read_func_scope for an
+        example of how this could occur.)
+
+         Unfortunately, our current partial symtab data structures are
+         completely unable to deal with DW_AT_specification.  So, for
+         now, the best thing to do is to get nesting information from
+         places other than the tree structure of dies if there's any
+         chance that a DW_AT_specification is involved. :-( */
+
+      char *next_child = info_ptr;
+
+      while (1)
+       {
+         struct partial_die_info child_pdi;
+
+         next_child = read_partial_die (&child_pdi, abfd, next_child,
+                                        cu);
+         if (!child_pdi.tag)
+           break;
+         if (child_pdi.tag == DW_TAG_subprogram)
+           {
+             actual_class_name = class_name_from_physname (child_pdi.name);
+             if (actual_class_name != NULL)
+               struct_pdi->name = actual_class_name;
+             break;
+           }
+         else
+           {
+             next_child = locate_pdi_sibling (&child_pdi, next_child,
+                                              abfd, cu);
+           }
+       }
+    }
+
+  add_partial_symbol (struct_pdi, cu, namespace);
+  xfree (actual_class_name);
+
+  return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
+}
+
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
 add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
 add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
-                        struct objfile *objfile,
-                        const struct comp_unit_head *cu_header,
-                        const char *namespace)
+                        struct dwarf2_cu *cu, const char *namespace)
 {
 {
+  struct objfile *objfile = cu->objfile;
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
 
   if (enum_pdi->name != NULL)
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
 
   if (enum_pdi->name != NULL)
-    add_partial_symbol (enum_pdi, objfile, cu_header, namespace);
+    add_partial_symbol (enum_pdi, cu, namespace);
   
   while (1)
     {
   
   while (1)
     {
-      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
       if (pdi.tag == 0)
        break;
       if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL)
        complaint (&symfile_complaints, "malformed enumerator DIE ignored");
       else
       if (pdi.tag == 0)
        break;
       if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL)
        complaint (&symfile_complaints, "malformed enumerator DIE ignored");
       else
-       add_partial_symbol (&pdi, objfile, cu_header, namespace);
+       add_partial_symbol (&pdi, cu, namespace);
     }
 
   return info_ptr;
     }
 
   return info_ptr;
@@ -1693,7 +1753,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
 
 static char *
 locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
 
 static char *
 locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
-                   bfd *abfd, const struct comp_unit_head *cu_header)
+                   bfd *abfd, struct dwarf2_cu *cu)
 {
   /* Do we know the sibling already?  */
   
 {
   /* Do we know the sibling already?  */
   
@@ -1713,12 +1773,12 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
     {
       struct partial_die_info pdi;
       
     {
       struct partial_die_info pdi;
       
-      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
 
       if (pdi.tag == 0)
        return info_ptr;
       else
 
       if (pdi.tag == 0)
        return info_ptr;
       else
-       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header);
+       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
     }
 }
 
     }
 }
 
@@ -1756,7 +1816,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
   struct objfile *objfile = pst->objfile;
   bfd *abfd = objfile->obfd;
 {
   struct objfile *objfile = pst->objfile;
   bfd *abfd = objfile->obfd;
-  struct comp_unit_head cu_header;
+  struct dwarf2_cu cu;
   struct die_info *dies;
   unsigned long offset;
   CORE_ADDR lowpc, highpc;
   struct die_info *dies;
   unsigned long offset;
   CORE_ADDR lowpc, highpc;
@@ -1765,6 +1825,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   struct symtab *symtab;
   struct cleanup *back_to;
   struct attribute *attr;
   struct symtab *symtab;
   struct cleanup *back_to;
   struct attribute *attr;
+  CORE_ADDR baseaddr;
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
@@ -1781,9 +1842,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
-  baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
-  cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
   info_ptr = dwarf_info_buffer + offset;
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* We're in the global namespace.  */
+  processing_current_prefix = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -1791,14 +1854,20 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   buildsym_init ();
   make_cleanup (really_free_pendings, NULL);
 
   buildsym_init ();
   make_cleanup (really_free_pendings, NULL);
 
+  cu.objfile = objfile;
+
   /* read in the comp_unit header  */
   /* read in the comp_unit header  */
-  info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
+  info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
 
   /* Read the abbrevs for this compilation unit  */
 
   /* Read the abbrevs for this compilation unit  */
-  dwarf2_read_abbrevs (abfd, &cu_header);
-  make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs);
+  dwarf2_read_abbrevs (abfd, &cu);
+  make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
 
 
-  dies = read_comp_unit (info_ptr, abfd, &cu_header);
+  cu.header.offset = offset;
+
+  cu.list_in_scope = &file_symbols;
+
+  dies = read_comp_unit (info_ptr, abfd, &cu);
 
   make_cleanup_free_die_list (dies);
 
 
   make_cleanup_free_die_list (dies);
 
@@ -1808,62 +1877,42 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      DW_AT_entry_pc.  It's been removed, but GCC still uses this for
      compilation units with discontinuous ranges.  */
 
      DW_AT_entry_pc.  It's been removed, but GCC still uses this for
      compilation units with discontinuous ranges.  */
 
-  cu_header.base_known = 0;
-  cu_header.base_address = 0;
+  cu.header.base_known = 0;
+  cu.header.base_address = 0;
 
 
-  attr = dwarf_attr (dies, DW_AT_entry_pc);
+  attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
   if (attr)
     {
   if (attr)
     {
-      cu_header.base_address = DW_ADDR (attr);
-      cu_header.base_known = 1;
+      cu.header.base_address = DW_ADDR (attr);
+      cu.header.base_known = 1;
     }
   else
     {
     }
   else
     {
-      attr = dwarf_attr (dies, DW_AT_low_pc);
+      attr = dwarf2_attr (dies, DW_AT_low_pc, &cu);
       if (attr)
        {
       if (attr)
        {
-         cu_header.base_address = DW_ADDR (attr);
-         cu_header.base_known = 1;
+         cu.header.base_address = DW_ADDR (attr);
+         cu.header.base_known = 1;
        }
     }
 
   /* Do line number decoding in read_file_scope () */
        }
     }
 
   /* Do line number decoding in read_file_scope () */
-  process_die (dies, objfile, &cu_header);
+  process_die (dies, &cu);
 
 
-  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header))
-    {
-      /* Some compilers don't define a DW_AT_high_pc attribute for
-         the compilation unit.   If the DW_AT_high_pc is missing,
-         synthesize it, by scanning the DIE's below the compilation unit.  */
-      highpc = 0;
-      if (dies->has_children)
-       {
-         child_die = dies->next;
-         while (child_die && child_die->tag)
-           {
-             if (child_die->tag == DW_TAG_subprogram)
-               {
-                 CORE_ADDR low, high;
+  /* Some compilers don't define a DW_AT_high_pc attribute for the
+     compilation unit.  If the DW_AT_high_pc is missing, synthesize
+     it, by scanning the DIE's below the compilation unit.  */
+  get_scope_pc_bounds (dies, &lowpc, &highpc, &cu);
 
 
-                 if (dwarf2_get_pc_bounds (child_die, &low, &high,
-                                           objfile, &cu_header))
-                   {
-                     highpc = max (highpc, high);
-                   }
-               }
-             child_die = sibling_die (child_die);
-           }
-       }
-    }
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
   /* Set symtab language to language from DW_AT_language.
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
   /* Set symtab language to language from DW_AT_language.
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
-      && !(cu_language == language_c && symtab->language != language_c))
+      && !(cu.language == language_c && symtab->language != language_c))
     {
     {
-      symtab->language = cu_language;
+      symtab->language = cu.language;
     }
   pst->symtab = symtab;
   pst->readin = 1;
     }
   pst->symtab = symtab;
   pst->readin = 1;
@@ -1874,19 +1923,18 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 /* Process a die and its children.  */
 
 static void
 /* Process a die and its children.  */
 
 static void
-process_die (struct die_info *die, struct objfile *objfile,
-            const struct comp_unit_head *cu_header)
+process_die (struct die_info *die, struct dwarf2_cu *cu)
 {
   switch (die->tag)
     {
     case DW_TAG_padding:
       break;
     case DW_TAG_compile_unit:
 {
   switch (die->tag)
     {
     case DW_TAG_padding:
       break;
     case DW_TAG_compile_unit:
-      read_file_scope (die, objfile, cu_header);
+      read_file_scope (die, cu);
       break;
     case DW_TAG_subprogram:
       break;
     case DW_TAG_subprogram:
-      read_subroutine_type (die, objfile, cu_header);
-      read_func_scope (die, objfile, cu_header);
+      read_subroutine_type (die, cu);
+      read_func_scope (die, cu);
       break;
     case DW_TAG_inlined_subroutine:
       /* FIXME:  These are ignored for now.
       break;
     case DW_TAG_inlined_subroutine:
       /* FIXME:  These are ignored for now.
@@ -1896,54 +1944,58 @@ process_die (struct die_info *die, struct objfile *objfile,
     case DW_TAG_lexical_block:
     case DW_TAG_try_block:
     case DW_TAG_catch_block:
     case DW_TAG_lexical_block:
     case DW_TAG_try_block:
     case DW_TAG_catch_block:
-      read_lexical_block_scope (die, objfile, cu_header);
+      read_lexical_block_scope (die, cu);
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_scope (die, objfile, cu_header);
+      read_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration (die, objfile, cu_header);
+      read_enumeration (die, cu);
       break;
     case DW_TAG_subroutine_type:
       break;
     case DW_TAG_subroutine_type:
-      read_subroutine_type (die, objfile, cu_header);
+      read_subroutine_type (die, cu);
       break;
     case DW_TAG_array_type:
       break;
     case DW_TAG_array_type:
-      read_array_type (die, objfile, cu_header);
+      read_array_type (die, cu);
       break;
     case DW_TAG_pointer_type:
       break;
     case DW_TAG_pointer_type:
-      read_tag_pointer_type (die, objfile, cu_header);
+      read_tag_pointer_type (die, cu);
       break;
     case DW_TAG_ptr_to_member_type:
       break;
     case DW_TAG_ptr_to_member_type:
-      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
       break;
     case DW_TAG_reference_type:
-      read_tag_reference_type (die, objfile, cu_header);
+      read_tag_reference_type (die, cu);
       break;
     case DW_TAG_string_type:
       break;
     case DW_TAG_string_type:
-      read_tag_string_type (die, objfile);
+      read_tag_string_type (die, cu);
       break;
     case DW_TAG_base_type:
       break;
     case DW_TAG_base_type:
-      read_base_type (die, objfile);
-      if (dwarf_attr (die, DW_AT_name))
+      read_base_type (die, cu);
+      if (dwarf2_attr (die, DW_AT_name, cu))
        {
          /* Add a typedef symbol for the base type definition.  */
        {
          /* Add a typedef symbol for the base type definition.  */
-         new_symbol (die, die->type, objfile, cu_header);
+         new_symbol (die, die->type, cu);
        }
       break;
        }
       break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
+      if (dwarf2_attr (die, DW_AT_name, cu))
+       {
+         /* Add a typedef symbol for the base type definition.  */
+         new_symbol (die, die->type, cu);
+       }
+      break;
     case DW_TAG_common_block:
     case DW_TAG_common_block:
-      read_common_block (die, objfile, cu_header);
+      read_common_block (die, cu);
       break;
     case DW_TAG_common_inclusion:
       break;
     case DW_TAG_namespace:
       break;
     case DW_TAG_common_inclusion:
       break;
     case DW_TAG_namespace:
-      if (!processing_has_namespace_info)
-       {
-         processing_has_namespace_info = 1;
-         processing_current_namespace = "";
-       }
-      read_namespace (die, objfile, cu_header);
+      processing_has_namespace_info = 1;
+      read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
@@ -1953,29 +2005,26 @@ process_die (struct die_info *die, struct objfile *objfile,
         shouldn't in the C++ case, but conceivably could in the
         Fortran case, so we'll have to replace this gdb_assert if
         Fortran compilers start generating that info.  */
         shouldn't in the C++ case, but conceivably could in the
         Fortran case, so we'll have to replace this gdb_assert if
         Fortran compilers start generating that info.  */
-      if (!processing_has_namespace_info)
-       {
-         processing_has_namespace_info = 1;
-         processing_current_namespace = "";
-       }
-      gdb_assert (!die->has_children);
+      processing_has_namespace_info = 1;
+      gdb_assert (die->child == NULL);
       break;
     default:
       break;
     default:
-      new_symbol (die, NULL, objfile, cu_header);
+      new_symbol (die, NULL, cu);
       break;
     }
 }
 
 static void
       break;
     }
 }
 
 static void
-initialize_cu_func_list (void)
+initialize_cu_func_list (struct dwarf2_cu *cu)
 {
 {
-  cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+  cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
 }
 
 static void
 }
 
 static void
-read_file_scope (struct die_info *die, struct objfile *objfile,
-                const struct comp_unit_head *cu_header)
+read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
@@ -1985,29 +2034,11 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
   struct line_header *line_header = 0;
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
   struct line_header *line_header = 0;
+  CORE_ADDR baseaddr;
+  
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
 
-  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
-    {
-      if (die->has_children)
-       {
-         child_die = die->next;
-         while (child_die && child_die->tag)
-           {
-             if (child_die->tag == DW_TAG_subprogram)
-               {
-                 CORE_ADDR low, high;
-
-                 if (dwarf2_get_pc_bounds (child_die, &low, &high,
-                                           objfile, cu_header))
-                   {
-                     lowpc = min (lowpc, low);
-                     highpc = max (highpc, high);
-                   }
-               }
-             child_die = sibling_die (child_die);
-           }
-       }
-    }
+  get_scope_pc_bounds (die, &lowpc, &highpc, cu);
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
@@ -2016,12 +2047,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   lowpc += baseaddr;
   highpc += baseaddr;
 
   lowpc += baseaddr;
   highpc += baseaddr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr)
     {
       name = DW_STRING (attr);
     }
   if (attr)
     {
       name = DW_STRING (attr);
     }
-  attr = dwarf_attr (die, DW_AT_comp_dir);
+  attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
   if (attr)
     {
       comp_dir = DW_STRING (attr);
   if (attr)
     {
       comp_dir = DW_STRING (attr);
@@ -2043,10 +2074,10 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
       objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
       objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
-  attr = dwarf_attr (die, DW_AT_language);
+  attr = dwarf2_attr (die, DW_AT_language, cu);
   if (attr)
     {
   if (attr)
     {
-      set_cu_language (DW_UNSND (attr));
+      set_cu_language (DW_UNSND (attr), cu);
     }
 
   /* We assume that we're processing GCC output. */
     }
 
   /* We assume that we're processing GCC output. */
@@ -2061,36 +2092,35 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
 
   /* The compilation unit may be in a different language or objfile,
      zero out all remembered fundamental types.  */
 
   /* The compilation unit may be in a different language or objfile,
      zero out all remembered fundamental types.  */
-  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+  memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
-  initialize_cu_func_list ();
+  initialize_cu_func_list (cu);
 
   /* Process all dies in compilation unit.  */
 
   /* Process all dies in compilation unit.  */
-  if (die->has_children)
+  if (die->child != NULL)
     {
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
 
   /* Decode line number information if present.  */
          child_die = sibling_die (child_die);
        }
     }
 
   /* Decode line number information if present.  */
-  attr = dwarf_attr (die, DW_AT_stmt_list);
+  attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
   if (attr)
     {
       unsigned int line_offset = DW_UNSND (attr);
   if (attr)
     {
       unsigned int line_offset = DW_UNSND (attr);
-      line_header = dwarf_decode_line_header (line_offset,
-                                              abfd, cu_header);
+      line_header = dwarf_decode_line_header (line_offset, abfd, cu);
       if (line_header)
         {
           make_cleanup ((make_cleanup_ftype *) free_line_header,
                         (void *) line_header);
       if (line_header)
         {
           make_cleanup ((make_cleanup_ftype *) free_line_header,
                         (void *) line_header);
-          dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
+          dwarf_decode_lines (line_header, comp_dir, abfd, cu);
         }
     }
 
         }
     }
 
@@ -2098,18 +2128,19 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
      refers to information in the line number info statement program
      header, so we can only read it if we've read the header
      successfully.  */
      refers to information in the line number info statement program
      header, so we can only read it if we've read the header
      successfully.  */
-  attr = dwarf_attr (die, DW_AT_macro_info);
+  attr = dwarf2_attr (die, DW_AT_macro_info, cu);
   if (attr && line_header)
     {
       unsigned int macro_offset = DW_UNSND (attr);
       dwarf_decode_macros (line_header, macro_offset,
   if (attr && line_header)
     {
       unsigned int macro_offset = DW_UNSND (attr);
       dwarf_decode_macros (line_header, macro_offset,
-                           comp_dir, abfd, cu_header, objfile);
+                           comp_dir, abfd, cu);
     }
   do_cleanups (back_to);
 }
 
 static void
     }
   do_cleanups (back_to);
 }
 
 static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
+                    struct dwarf2_cu *cu)
 {
   struct function_range *thisfn;
 
 {
   struct function_range *thisfn;
 
@@ -2121,37 +2152,76 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
   thisfn->seen_line = 0;
   thisfn->next = NULL;
 
   thisfn->seen_line = 0;
   thisfn->next = NULL;
 
-  if (cu_last_fn == NULL)
-      cu_first_fn = thisfn;
+  if (cu->last_fn == NULL)
+      cu->first_fn = thisfn;
   else
   else
-      cu_last_fn->next = thisfn;
+      cu->last_fn->next = thisfn;
 
 
-  cu_last_fn = thisfn;
+  cu->last_fn = thisfn;
 }
 
 static void
 }
 
 static void
-read_func_scope (struct die_info *die, struct objfile *objfile,
-                const struct comp_unit_head *cu_header)
+read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct context_stack *new;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
   struct die_info *child_die;
   struct attribute *attr;
   char *name;
   struct context_stack *new;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
   struct die_info *child_die;
   struct attribute *attr;
   char *name;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
 
-  name = dwarf2_linkage_name (die);
+  name = dwarf2_linkage_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
-  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
+  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
 
     return;
 
+  if (cu->language == language_cplus)
+    {
+      struct die_info *spec_die = die_specification (die, cu);
+
+      /* NOTE: carlton/2004-01-23: We have to be careful in the
+         presence of DW_AT_specification.  For example, with GCC 3.4,
+         given the code
+
+           namespace N {
+             void foo() {
+               // Definition of N::foo.
+             }
+           }
+
+         then we'll have a tree of DIEs like this:
+
+         1: DW_TAG_compile_unit
+           2: DW_TAG_namespace        // N
+             3: DW_TAG_subprogram     // declaration of N::foo
+           4: DW_TAG_subprogram       // definition of N::foo
+                DW_AT_specification   // refers to die #3
+
+         Thus, when processing die #4, we have to pretend that we're
+         in the context of its DW_AT_specification, namely the contex
+         of die #3.  */
+       
+      if (spec_die != NULL)
+       {
+         char *specification_prefix = determine_prefix (spec_die, cu);
+         processing_current_prefix = specification_prefix;
+         back_to = make_cleanup (xfree, specification_prefix);
+       }
+    }
+
   lowpc += baseaddr;
   highpc += baseaddr;
 
   /* Record the function range for dwarf_decode_lines.  */
   lowpc += baseaddr;
   highpc += baseaddr;
 
   /* Record the function range for dwarf_decode_lines.  */
-  add_to_cu_func_list (name, lowpc, highpc);
+  add_to_cu_func_list (name, lowpc, highpc, cu);
 
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
 
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
@@ -2160,61 +2230,32 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
       objfile->ei.entry_func_highpc = highpc;
     }
 
       objfile->ei.entry_func_highpc = highpc;
     }
 
-  /* Decode DW_AT_frame_base location descriptor if present, keep result
-     for DW_OP_fbreg operands in decode_locdesc.  */
-  frame_base_reg = -1;
-  frame_base_offset = 0;
-  attr = dwarf_attr (die, DW_AT_frame_base);
-  if (attr)
-    {
-      CORE_ADDR addr;
-
-      /* Support the .debug_loc offsets */
-      if (attr_form_is_block (attr))
-        {
-          addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
-        }
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
-        {
-         dwarf2_complex_location_expr_complaint ();
-          addr = 0;
-        }
-      else
-        {
-         dwarf2_invalid_attrib_class_complaint ("DW_AT_frame_base", name);
-          addr = 0;
-        }
-    
-      if (isderef)
-       dwarf2_unsupported_at_frame_base_complaint (name);
-      else if (isreg)
-       frame_base_reg = addr;
-      else if (offreg)
-       {
-         frame_base_reg = basereg;
-         frame_base_offset = addr;
-       }
-      else
-       dwarf2_unsupported_at_frame_base_complaint (name);
-    }
-
   new = push_context (0, lowpc);
   new = push_context (0, lowpc);
-  new->name = new_symbol (die, die->type, objfile, cu_header);
+  new->name = new_symbol (die, die->type, cu);
 
 
-  /* If there was a location expression for DW_AT_frame_base above,
-     record it.  We still need to decode it above because not all
-     symbols use location expressions exclusively.  */
+  /* If there is a location expression for DW_AT_frame_base, record
+     it.  */
+  attr = dwarf2_attr (die, DW_AT_frame_base, cu);
   if (attr)
   if (attr)
-    dwarf2_symbol_mark_computed (attr, new->name, cu_header, objfile);
-
-  list_in_scope = &local_symbols;
-
-  if (die->has_children)
-    {
-      child_die = die->next;
+    /* FIXME: cagney/2004-01-26: The DW_AT_frame_base's location
+       expression is being recorded directly in the function's symbol
+       and not in a separate frame-base object.  I guess this hack is
+       to avoid adding some sort of frame-base adjunct/annex to the
+       function's symbol :-(.  The problem with doing this is that it
+       results in a function symbol with a location expression that
+       has nothing to do with the location of the function, ouch!  The
+       relationship should be: a function's symbol has-a frame base; a
+       frame-base has-a location expression.  */
+    dwarf2_symbol_mark_computed (attr, new->name, cu);
+
+  cu->list_in_scope = &local_symbols;
+
+  if (die->child != NULL)
+    {
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
          child_die = sibling_die (child_die);
        }
     }
@@ -2234,37 +2275,44 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
   /* If we've finished processing a top-level function, subsequent
      symbols go in the file symbol list.  */
   if (outermost_context_p ())
   /* If we've finished processing a top-level function, subsequent
      symbols go in the file symbol list.  */
   if (outermost_context_p ())
-    list_in_scope = &file_symbols;
+    cu->list_in_scope = &file_symbols;
+
+  processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Process all the DIES contained within a lexical block scope.  Start
    a new scope, process the dies, and then close the scope.  */
 
 static void
 }
 
 /* Process all the DIES contained within a lexical block scope.  Start
    a new scope, process the dies, and then close the scope.  */
 
 static void
-read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
-                         const struct comp_unit_head *cu_header)
+read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct context_stack *new;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
   struct context_stack *new;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   /* Ignore blocks with missing or invalid low and high pc attributes.  */
   /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
      as multiple lexical blocks?  Handling children in a sane way would
      be nasty.  Might be easier to properly extend generic blocks to 
      describe ranges.  */
 
   /* Ignore blocks with missing or invalid low and high pc attributes.  */
   /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
      as multiple lexical blocks?  Handling children in a sane way would
      be nasty.  Might be easier to properly extend generic blocks to 
      describe ranges.  */
-  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
   lowpc += baseaddr;
   highpc += baseaddr;
 
   push_context (0, lowpc);
     return;
   lowpc += baseaddr;
   highpc += baseaddr;
 
   push_context (0, lowpc);
-  if (die->has_children)
+  if (die->child != NULL)
     {
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
          child_die = sibling_die (child_die);
        }
     }
@@ -2283,20 +2331,21 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
    discontinuous, i.e. derived from DW_AT_ranges information.  */
 static int
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
    discontinuous, i.e. derived from DW_AT_ranges information.  */
 static int
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
-                     CORE_ADDR *highpc, struct objfile *objfile,
-                     const struct comp_unit_head *cu_header)
+                     CORE_ADDR *highpc, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
   struct attribute *attr;
   bfd *obfd = objfile->obfd;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
   int ret = 0;
 
   struct attribute *attr;
   bfd *obfd = objfile->obfd;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
   int ret = 0;
 
-  attr = dwarf_attr (die, DW_AT_high_pc);
+  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
   if (attr)
     {
       high = DW_ADDR (attr);
   if (attr)
     {
       high = DW_ADDR (attr);
-      attr = dwarf_attr (die, DW_AT_low_pc);
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr)
        low = DW_ADDR (attr);
       else
       if (attr)
        low = DW_ADDR (attr);
       else
@@ -2308,7 +2357,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
     }
   else
     {
     }
   else
     {
-      attr = dwarf_attr (die, DW_AT_ranges);
+      attr = dwarf2_attr (die, DW_AT_ranges, cu);
       if (attr != NULL)
        {
          unsigned int addr_size = cu_header->addr_size;
       if (attr != NULL)
        {
          unsigned int addr_size = cu_header->addr_size;
@@ -2320,7 +2369,6 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
          CORE_ADDR base;
          int found_base;
          int dummy;
          CORE_ADDR base;
          int found_base;
          int dummy;
-         unsigned int i;
          char *buffer;
          CORE_ADDR marker;
          int low_set;
          char *buffer;
          CORE_ADDR marker;
          int low_set;
@@ -2338,13 +2386,12 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
          buffer = dwarf_ranges_buffer + offset;
 
          /* Read in the largest possible address.  */
          buffer = dwarf_ranges_buffer + offset;
 
          /* Read in the largest possible address.  */
-         marker = read_address (obfd, buffer, cu_header, &dummy);
+         marker = read_address (obfd, buffer, cu, &dummy);
          if ((marker & mask) == mask)
            {
              /* If we found the largest possible address, then
                 read the base address.  */
          if ((marker & mask) == mask)
            {
              /* If we found the largest possible address, then
                 read the base address.  */
-             base = read_address (obfd, buffer + addr_size,
-                                  cu_header, &dummy);
+             base = read_address (obfd, buffer + addr_size, cu, &dummy);
              buffer += 2 * addr_size;
              offset += 2 * addr_size;
              found_base = 1;
              buffer += 2 * addr_size;
              offset += 2 * addr_size;
              found_base = 1;
@@ -2356,10 +2403,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
            {
              CORE_ADDR range_beginning, range_end;
 
            {
              CORE_ADDR range_beginning, range_end;
 
-             range_beginning = read_address (obfd, buffer,
-                                             cu_header, &dummy);
+             range_beginning = read_address (obfd, buffer, cu, &dummy);
              buffer += addr_size;
              buffer += addr_size;
-             range_end = read_address (obfd, buffer, cu_header, &dummy);
+             range_end = read_address (obfd, buffer, cu, &dummy);
              buffer += addr_size;
              offset += 2 * addr_size;
 
              buffer += addr_size;
              offset += 2 * addr_size;
 
@@ -2375,8 +2421,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                {
                  /* If we found the largest possible address, then
                     read the base address.  */
                {
                  /* If we found the largest possible address, then
                     read the base address.  */
-                 base = read_address (obfd, buffer + addr_size,
-                                      cu_header, &dummy);
+                 base = read_address (obfd, buffer + addr_size, cu, &dummy);
                  found_base = 1;
                  continue;
                }
                  found_base = 1;
                  continue;
                }
@@ -2440,13 +2485,75 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   return ret;
 }
 
   return ret;
 }
 
+/* Get the low and high pc's represented by the scope DIE, and store
+   them in *LOWPC and *HIGHPC.  If the correct values can't be
+   determined, set *LOWPC to -1 and *HIGHPC to 0.  */
+
+static void
+get_scope_pc_bounds (struct die_info *die,
+                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                    struct dwarf2_cu *cu)
+{
+  CORE_ADDR best_low = (CORE_ADDR) -1;
+  CORE_ADDR best_high = (CORE_ADDR) 0;
+  CORE_ADDR current_low, current_high;
+
+  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu))
+    {
+      best_low = current_low;
+      best_high = current_high;
+    }
+  else
+    {
+      struct die_info *child = die->child;
+
+      while (child && child->tag)
+       {
+         switch (child->tag) {
+         case DW_TAG_subprogram:
+           if (dwarf2_get_pc_bounds (child, &current_low, &current_high, cu))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         case DW_TAG_namespace:
+           /* FIXME: carlton/2004-01-16: Should we do this for
+              DW_TAG_class_type/DW_TAG_structure_type, too?  I think
+              that current GCC's always emit the DIEs corresponding
+              to definitions of methods of classes as children of a
+              DW_TAG_compile_unit or DW_TAG_namespace (as opposed to
+              the DIEs giving the declarations, which could be
+              anywhere).  But I don't see any reason why the
+              standards says that they have to be there.  */
+           get_scope_pc_bounds (child, &current_low, &current_high, cu);
+
+           if (current_low != ((CORE_ADDR) -1))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         default:
+           /* Ignore. */
+           break;
+         }
+
+         child = sibling_die (child);
+       }
+    }
+
+  *lowpc = best_low;
+  *highpc = best_high;
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
 dwarf2_add_field (struct field_info *fip, struct die_info *die,
 /* Add an aggregate field to the field list.  */
 
 static void
 dwarf2_add_field (struct field_info *fip, struct die_info *die,
-                 struct objfile *objfile,
-                 const struct comp_unit_head *cu_header)
-{
+                 struct dwarf2_cu *cu)
+{ 
+  struct objfile *objfile = cu->objfile;
   struct nextfield *new_field;
   struct attribute *attr;
   struct field *fp;
   struct nextfield *new_field;
   struct attribute *attr;
   struct field *fp;
@@ -2469,28 +2576,28 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     new_field->accessibility = DW_ACCESS_private;
   new_field->virtuality = DW_VIRTUALITY_none;
 
     new_field->accessibility = DW_ACCESS_private;
   new_field->virtuality = DW_VIRTUALITY_none;
 
-  attr = dwarf_attr (die, DW_AT_accessibility);
+  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr)
     new_field->accessibility = DW_UNSND (attr);
   if (new_field->accessibility != DW_ACCESS_public)
     fip->non_public_fields = 1;
   if (attr)
     new_field->accessibility = DW_UNSND (attr);
   if (new_field->accessibility != DW_ACCESS_public)
     fip->non_public_fields = 1;
-  attr = dwarf_attr (die, DW_AT_virtuality);
+  attr = dwarf2_attr (die, DW_AT_virtuality, cu);
   if (attr)
     new_field->virtuality = DW_UNSND (attr);
 
   fp = &new_field->field;
 
   if (attr)
     new_field->virtuality = DW_UNSND (attr);
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die))
+  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
       /* Data member other than a C++ static data member.  */
       
       /* Get type of field.  */
     {
       /* Data member other than a C++ static data member.  */
       
       /* Get type of field.  */
-      fp->type = die_type (die, objfile, cu_header);
+      fp->type = die_type (die, cu);
 
       FIELD_STATIC_KIND (*fp) = 0;
 
       /* Get bit size of field (zero if none).  */
 
       FIELD_STATIC_KIND (*fp) = 0;
 
       /* Get bit size of field (zero if none).  */
-      attr = dwarf_attr (die, DW_AT_bit_size);
+      attr = dwarf2_attr (die, DW_AT_bit_size, cu);
       if (attr)
        {
          FIELD_BITSIZE (*fp) = DW_UNSND (attr);
       if (attr)
        {
          FIELD_BITSIZE (*fp) = DW_UNSND (attr);
@@ -2501,15 +2608,15 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
        }
 
       /* Get bit offset of field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        {
          FIELD_BITPOS (*fp) =
       if (attr)
        {
          FIELD_BITPOS (*fp) =
-           decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte;
+           decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
        }
       else
        FIELD_BITPOS (*fp) = 0;
        }
       else
        FIELD_BITPOS (*fp) = 0;
-      attr = dwarf_attr (die, DW_AT_bit_offset);
+      attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
          if (BITS_BIG_ENDIAN)
       if (attr)
        {
          if (BITS_BIG_ENDIAN)
@@ -2532,7 +2639,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
              int anonymous_size;
              int bit_offset = DW_UNSND (attr);
 
              int anonymous_size;
              int bit_offset = DW_UNSND (attr);
 
-             attr = dwarf_attr (die, DW_AT_byte_size);
+             attr = dwarf2_attr (die, DW_AT_byte_size, cu);
              if (attr)
                {
                  /* The size of the anonymous object containing
              if (attr)
                {
                  /* The size of the anonymous object containing
@@ -2554,15 +2661,15 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get name of field.  */
        }
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       fp->name = obsavestring (fieldname, strlen (fieldname),
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       fp->name = obsavestring (fieldname, strlen (fieldname),
-                              &objfile->type_obstack);
+                              &objfile->objfile_obstack);
 
       /* Change accessibility for artificial fields (e.g. virtual table
          pointer or virtual base class pointer) to private.  */
 
       /* Change accessibility for artificial fields (e.g. virtual table
          pointer or virtual base class pointer) to private.  */
-      if (dwarf_attr (die, DW_AT_artificial))
+      if (dwarf2_attr (die, DW_AT_artificial, cu))
        {
          new_field->accessibility = DW_ACCESS_private;
          fip->non_public_fields = 1;
        {
          new_field->accessibility = DW_ACCESS_private;
          fip->non_public_fields = 1;
@@ -2580,31 +2687,31 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       char *physname;
 
       /* Get name of field.  */
       char *physname;
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       else
        return;
 
       /* Get physical name.  */
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       else
        return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die);
+      physname = dwarf2_linkage_name (die, cu);
 
       SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
 
       SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
-                                            &objfile->type_obstack));
-      FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+                                            &objfile->objfile_obstack));
+      FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
       FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
-                                      &objfile->type_obstack);
+                                      &objfile->objfile_obstack);
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
       if (attr)
-       FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
+       FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
                              * bits_per_byte);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_STATIC_KIND (*fp) = 0;
                              * bits_per_byte);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_STATIC_KIND (*fp) = 0;
-      FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+      FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
       fip->nbaseclasses++;
     }
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
       fip->nbaseclasses++;
     }
@@ -2614,7 +2721,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
 static void
 dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
 
 static void
 dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
-                             struct objfile *objfile)
+                             struct dwarf2_cu *cu)
 {
   int nfields = fip->nfields;
 
 {
   int nfields = fip->nfields;
 
@@ -2701,9 +2808,9 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
 
 static void
 dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
 static void
 dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
-                     struct type *type, struct objfile *objfile,
-                     const struct comp_unit_head *cu_header)
+                     struct type *type, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct attribute *attr;
   struct fnfieldlist *flp;
   int i;
   struct attribute *attr;
   struct fnfieldlist *flp;
   int i;
@@ -2713,19 +2820,19 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   struct nextfnfield *new_fnfield;
 
   /* Get name of member function.  */
   struct nextfnfield *new_fnfield;
 
   /* Get name of member function.  */
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     fieldname = DW_STRING (attr);
   else
     return;
 
   /* Get the mangled name.  */
   if (attr && DW_STRING (attr))
     fieldname = DW_STRING (attr);
   else
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die);
+  physname = dwarf2_linkage_name (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
     {
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
     {
-      if (STREQ (fip->fnfieldlists[i].name, fieldname))
+      if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0)
        break;
     }
 
        break;
     }
 
@@ -2762,11 +2869,10 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
   fnp->physname = obsavestring (physname, strlen (physname),
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
   fnp->physname = obsavestring (physname, strlen (physname),
-                               &objfile->type_obstack);
+                               &objfile->objfile_obstack);
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
-      struct type *return_type = TYPE_TARGET_TYPE (die->type);
       int nparams = TYPE_NFIELDS (die->type);
 
       /* TYPE is the domain of this method, and DIE->TYPE is the type
       int nparams = TYPE_NFIELDS (die->type);
 
       /* TYPE is the domain of this method, and DIE->TYPE is the type
@@ -2791,14 +2897,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
-  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
-    fnp->fcontext = die_containing_type (die, objfile, cu_header);
+  if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
+    fnp->fcontext = die_containing_type (die, cu);
 
   /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
      and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
 
   /* Get accessibility.  */
 
   /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
      and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
 
   /* Get accessibility.  */
-  attr = dwarf_attr (die, DW_AT_accessibility);
+  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr)
     {
       switch (DW_UNSND (attr))
   if (attr)
     {
       switch (DW_UNSND (attr))
@@ -2813,18 +2919,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
 
   /* Check for artificial methods.  */
     }
 
   /* Check for artificial methods.  */
-  attr = dwarf_attr (die, DW_AT_artificial);
+  attr = dwarf2_attr (die, DW_AT_artificial, cu);
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
   /* Get index in virtual function table if it is a virtual member function.  */
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
   /* Get index in virtual function table if it is a virtual member function.  */
-  attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+  attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
         {
   if (attr)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
         {
-          fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
+          fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
         }
       else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
         {
         }
       else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
         {
@@ -2842,7 +2948,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
 static void
 dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
 
 static void
 dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
-                                struct objfile *objfile)
+                                struct dwarf2_cu *cu)
 {
   struct fnfieldlist *flp;
   int total_length = 0;
 {
   struct fnfieldlist *flp;
   int total_length = 0;
@@ -2889,21 +2995,60 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
    suppresses creating a symbol table entry itself).  */
 
 static void
    suppresses creating a symbol table entry itself).  */
 
 static void
-read_structure_scope (struct die_info *die, struct objfile *objfile,
-                     const struct comp_unit_head *cu_header)
+read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
   struct type *type;
   struct attribute *attr;
+  const char *name = NULL;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  /* This says whether or not we want to try to update the structure's
+     name to include enclosing namespace/class information, if
+     any.  */
+  int need_to_update_name = 0;
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      name = DW_STRING (attr);
+
+      if (cu->language == language_cplus)
+       {
+         struct die_info *spec_die = die_specification (die, cu);
+
+         if (spec_die != NULL)
+           {
+             char *specification_prefix = determine_prefix (spec_die, cu);
+             processing_current_prefix = specification_prefix;
+             back_to = make_cleanup (xfree, specification_prefix);
+           }
+       }
+
+      if (processing_has_namespace_info)
+       {
+         /* FIXME: carlton/2003-11-10: This variable exists only for
+            const-correctness reasons.  When I tried to change
+            TYPE_TAG_NAME to be a const char *, I ran into a cascade
+            of changes which would have forced decode_line_1 to take
+            a const char **.  */
+         char *new_prefix = obconcat (&objfile->objfile_obstack,
+                                      processing_current_prefix,
+                                      processing_current_prefix[0] == '\0'
+                                      ? "" : "::",
+                                      name);
+         TYPE_TAG_NAME (type) = new_prefix;
+         processing_current_prefix = new_prefix;
+       }
+      else
+       {
+         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+                                              &objfile->objfile_obstack);
+         need_to_update_name = (cu->language == language_cplus);
+       }
     }
 
   if (die->tag == DW_TAG_structure_type)
     }
 
   if (die->tag == DW_TAG_structure_type)
@@ -2921,7 +3066,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
       TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
       TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -2936,7 +3081,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
      type within the structure itself. */
   die->type = type;
 
      type within the structure itself. */
   die->type = type;
 
-  if (die->has_children && ! die_is_declaration (die))
+  if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
       struct die_info *child_die;
     {
       struct field_info fi;
       struct die_info *child_die;
@@ -2944,7 +3089,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
 
       memset (&fi, 0, sizeof (struct field_info));
 
 
       memset (&fi, 0, sizeof (struct field_info));
 
-      child_die = die->next;
+      child_die = die->child;
 
       while (child_die && child_die->tag)
        {
 
       while (child_die && child_die->tag)
        {
@@ -2956,40 +3101,75 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
                 all versions of G++ as of this writing (so through at
                 least 3.2.1) incorrectly generate DW_TAG_variable
                 tags for them instead.  */
                 all versions of G++ as of this writing (so through at
                 least 3.2.1) incorrectly generate DW_TAG_variable
                 tags for them instead.  */
-             dwarf2_add_field (&fi, child_die, objfile, cu_header);
+             dwarf2_add_field (&fi, child_die, cu);
            }
          else if (child_die->tag == DW_TAG_subprogram)
            {
              /* C++ member function. */
            }
          else if (child_die->tag == DW_TAG_subprogram)
            {
              /* C++ member function. */
-             process_die (child_die, objfile, cu_header);
-             dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header);
+             process_die (child_die, cu);
+             dwarf2_add_member_fn (&fi, child_die, type, cu);
+             if (need_to_update_name)
+               {
+                 /* The demangled names of member functions contain
+                    information about enclosing namespaces/classes,
+                    if any.  */
+
+                 /* FIXME: carlton/2003-11-10: The excessive
+                    demangling here is a bit wasteful, as is the
+                    memory usage for names.  */
+
+                 /* NOTE: carlton/2003-11-10: As commented in
+                    add_partial_structure, the demangler sometimes
+                    prints the type info in a different form from the
+                    debug info.  We could solve this by using the
+                    demangled name to get the prefix; if doing so,
+                    however, we'd need to be careful when reading a
+                    class that's nested inside a template class.
+                    That would also cause problems when trying to
+                    determine RTTI information, since we use the
+                    demangler to determine the appropriate class
+                    name.  */
+                 char *actual_class_name
+                   = class_name_from_physname (dwarf2_linkage_name
+                                               (child_die, cu));
+                 if (actual_class_name != NULL
+                     && strcmp (actual_class_name, name) != 0)
+                   {
+                     TYPE_TAG_NAME (type)
+                       = obsavestring (actual_class_name,
+                                       strlen (actual_class_name),
+                                       &objfile->objfile_obstack);
+                   }
+                 xfree (actual_class_name);
+                 need_to_update_name = 0;
+               }
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
              /* C++ base class field.  */
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
              /* C++ base class field.  */
-             dwarf2_add_field (&fi, child_die, objfile, cu_header);
+             dwarf2_add_field (&fi, child_die, cu);
            }
          else
            {
            }
          else
            {
-             process_die (child_die, objfile, cu_header);
+             process_die (child_die, cu);
            }
          child_die = sibling_die (child_die);
        }
 
       /* Attach fields and member functions to the type.  */
       if (fi.nfields)
            }
          child_die = sibling_die (child_die);
        }
 
       /* Attach fields and member functions to the type.  */
       if (fi.nfields)
-       dwarf2_attach_fields_to_type (&fi, type, objfile);
+       dwarf2_attach_fields_to_type (&fi, type, cu);
       if (fi.nfnfields)
        {
       if (fi.nfnfields)
        {
-         dwarf2_attach_fn_fields_to_type (&fi, type, objfile);
+         dwarf2_attach_fn_fields_to_type (&fi, type, cu);
 
          /* Get the type which refers to the base class (possibly this
             class itself) which contains the vtable pointer for the current
             class from the DW_AT_containing_type attribute.  */
 
 
          /* Get the type which refers to the base class (possibly this
             class itself) which contains the vtable pointer for the current
             class from the DW_AT_containing_type attribute.  */
 
-         if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+         if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
            {
            {
-             struct type *t = die_containing_type (die, objfile, cu_header);
+             struct type *t = die_containing_type (die, cu);
 
              TYPE_VPTR_BASETYPE (type) = t;
              if (type == t)
 
              TYPE_VPTR_BASETYPE (type) = t;
              if (type == t)
@@ -3005,7 +3185,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
                    {
                      char *fieldname = TYPE_FIELD_NAME (t, i);
 
                    {
                      char *fieldname = TYPE_FIELD_NAME (t, i);
 
-                     if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+                     if ((strncmp (fieldname, vptr_name,
+                                    strlen (vptr_name) - 1)
+                           == 0)
                          && is_cplus_marker (fieldname[strlen (vptr_name)]))
                        {
                          TYPE_VPTR_FIELDNO (type) = i;
                          && is_cplus_marker (fieldname[strlen (vptr_name)]))
                        {
                          TYPE_VPTR_FIELDNO (type) = i;
@@ -3027,7 +3209,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
            }
        }
 
            }
        }
 
-      new_symbol (die, type, objfile, cu_header);
+      new_symbol (die, type, cu);
 
       do_cleanups (back_to);
     }
 
       do_cleanups (back_to);
     }
@@ -3036,6 +3218,10 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
+
+  processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -3048,9 +3234,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
    NOTE: We reverse the order of the element list.  */
 
 static void
    NOTE: We reverse the order of the element list.  */
 
 static void
-read_enumeration (struct die_info *die, struct objfile *objfile,
-                 const struct comp_unit_head *cu_header)
+read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct die_info *child_die;
   struct type *type;
   struct field *fields;
   struct die_info *child_die;
   struct type *type;
   struct field *fields;
@@ -3062,15 +3248,27 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      const char *name = DW_STRING (attr);
+
+      if (processing_has_namespace_info)
+       {
+         TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
+                                          processing_current_prefix,
+                                          processing_current_prefix[0] == '\0'
+                                          ? "" : "::",
+                                          name);
+       }
+      else
+       {
+         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+                                              &objfile->objfile_obstack);
+       }
     }
 
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3082,21 +3280,21 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
 
   num_fields = 0;
   fields = NULL;
 
   num_fields = 0;
   fields = NULL;
-  if (die->has_children)
+  if (die->child != NULL)
     {
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
          if (child_die->tag != DW_TAG_enumerator)
            {
       while (child_die && child_die->tag)
        {
          if (child_die->tag != DW_TAG_enumerator)
            {
-             process_die (child_die, objfile, cu_header);
+             process_die (child_die, cu);
            }
          else
            {
            }
          else
            {
-             attr = dwarf_attr (child_die, DW_AT_name);
+             attr = dwarf2_attr (child_die, DW_AT_name, cu);
              if (attr)
                {
              if (attr)
                {
-                 sym = new_symbol (child_die, type, objfile, cu_header);
+                 sym = new_symbol (child_die, type, cu);
                  if (SYMBOL_VALUE (sym) < 0)
                    unsigned_enum = 0;
 
                  if (SYMBOL_VALUE (sym) < 0)
                    unsigned_enum = 0;
 
@@ -3134,7 +3332,7 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
        TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
     }
   die->type = type;
        TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
     }
   die->type = type;
-  new_symbol (die, type, objfile, cu_header);
+  new_symbol (die, type, cu);
 }
 
 /* Extract all information from a DW_TAG_array_type DIE and put it in
 }
 
 /* Extract all information from a DW_TAG_array_type DIE and put it in
@@ -3142,9 +3340,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
    arrays.  */
 
 static void
    arrays.  */
 
 static void
-read_array_type (struct die_info *die, struct objfile *objfile,
-                const struct comp_unit_head *cu_header)
+read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct die_info *child_die;
   struct type *type = NULL;
   struct type *element_type, *range_type, *index_type;
   struct die_info *child_die;
   struct type *type = NULL;
   struct type *element_type, *range_type, *index_type;
@@ -3159,110 +3357,40 @@ read_array_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
       return;
     }
 
-  element_type = die_type (die, objfile, cu_header);
+  element_type = die_type (die, cu);
 
   /* Irix 6.2 native cc creates array types without children for
      arrays with unspecified length.  */
 
   /* Irix 6.2 native cc creates array types without children for
      arrays with unspecified length.  */
-  if (die->has_children == 0)
+  if (die->child == NULL)
     {
     {
-      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
       range_type = create_range_type (NULL, index_type, 0, -1);
       die->type = create_array_type (NULL, element_type, range_type);
       return;
     }
 
   back_to = make_cleanup (null_cleanup, NULL);
       range_type = create_range_type (NULL, index_type, 0, -1);
       die->type = create_array_type (NULL, element_type, range_type);
       return;
     }
 
   back_to = make_cleanup (null_cleanup, NULL);
-  child_die = die->next;
+  child_die = die->child;
   while (child_die && child_die->tag)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
   while (child_die && child_die->tag)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
-         unsigned int low, high;
-
-         /* Default bounds to an array with unspecified length.  */
-         low = 0;
-         high = -1;
-         if (cu_language == language_fortran)
-           {
-             /* FORTRAN implies a lower bound of 1, if not given.  */
-             low = 1;
-           }
+          read_subrange_type (child_die, cu);
 
 
-         index_type = die_type (child_die, objfile, cu_header);
-         attr = dwarf_attr (child_die, DW_AT_lower_bound);
-         if (attr)
-           {
-             if (attr->form == DW_FORM_sdata)
-               {
-                 low = DW_SND (attr);
-               }
-             else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4
-                      || attr->form == DW_FORM_data8)
-               {
-                 low = DW_UNSND (attr);
-               }
-             else
-               {
-                 dwarf2_non_const_array_bound_ignored_complaint
-                   (dwarf_form_name (attr->form));
-#ifdef FORTRAN_HACK
-                 die->type = lookup_pointer_type (element_type);
-                 return;
-#else
-                 low = 0;
-#endif
-               }
-           }
-         attr = dwarf_attr (child_die, DW_AT_upper_bound);
-         if (attr)
-           {
-             if (attr->form == DW_FORM_sdata)
-               {
-                 high = DW_SND (attr);
-               }
-             else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4
-                      || attr->form == DW_FORM_data8)
-               {
-                 high = DW_UNSND (attr);
-               }
-             else if (attr->form == DW_FORM_block1)
-               {
-                 /* GCC encodes arrays with unspecified or dynamic length
-                    with a DW_FORM_block1 attribute.
-                    FIXME: GDB does not yet know how to handle dynamic
-                    arrays properly, treat them as arrays with unspecified
-                    length for now.  */
-                 high = -1;
-               }
-             else
-               {
-                 dwarf2_non_const_array_bound_ignored_complaint
-                   (dwarf_form_name (attr->form));
-#ifdef FORTRAN_HACK
-                 die->type = lookup_pointer_type (element_type);
-                 return;
-#else
-                 high = 1;
-#endif
-               }
-           }
-
-         /* Create a range type and save it for array type creation.  */
-         if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
-           {
-             range_types = (struct type **)
-               xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
-                         * sizeof (struct type *));
-             if (ndim == 0)
-               make_cleanup (free_current_contents, &range_types);
-           }
-         range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+          if (child_die->type != NULL)
+            {
+             /* The range type was succesfully read. Save it for
+                 the array type creation.  */
+              if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+                {
+                  range_types = (struct type **)
+                    xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                              * sizeof (struct type *));
+                  if (ndim == 0)
+                    make_cleanup (free_current_contents, &range_types);
+               }
+             range_types[ndim++] = child_die->type;
+            }
        }
       child_die = sibling_die (child_die);
     }
        }
       child_die = sibling_die (child_die);
     }
@@ -3279,7 +3407,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
      custom vendor extension.  The main difference between a regular
      array and the vector variant is that vectors are passed by value
      to functions.  */
      custom vendor extension.  The main difference between a regular
      array and the vector variant is that vectors are passed by value
      to functions.  */
-  attr = dwarf_attr (die, DW_AT_GNU_vector);
+  attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
   if (attr)
     TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
 
   if (attr)
     TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
 
@@ -3292,21 +3420,20 @@ read_array_type (struct die_info *die, struct objfile *objfile,
 /* First cut: install each common block member as a global variable.  */
 
 static void
 /* First cut: install each common block member as a global variable.  */
 
 static void
-read_common_block (struct die_info *die, struct objfile *objfile,
-                  const struct comp_unit_head *cu_header)
+read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct die_info *child_die;
   struct attribute *attr;
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
 
 {
   struct die_info *child_die;
   struct attribute *attr;
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
 
-  attr = dwarf_attr (die, DW_AT_location);
+  attr = dwarf2_attr (die, DW_AT_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
         {
   if (attr)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
         {
-          base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+          base = decode_locdesc (DW_BLOCK (attr), cu);
         }
       else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
         {
         }
       else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
         {
@@ -3318,17 +3445,17 @@ read_common_block (struct die_info *die, struct objfile *objfile,
                                                 "common block member");
         }
     }
                                                 "common block member");
         }
     }
-  if (die->has_children)
+  if (die->child != NULL)
     {
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
       while (child_die && child_die->tag)
        {
-         sym = new_symbol (child_die, NULL, objfile, cu_header);
-         attr = dwarf_attr (child_die, DW_AT_data_member_location);
+         sym = new_symbol (child_die, NULL, cu);
+         attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) =
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) =
-               base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
+               base + decode_locdesc (DW_BLOCK (attr), cu);
              add_symbol_to_list (sym, &global_symbols);
            }
          child_die = sibling_die (child_die);
              add_symbol_to_list (sym, &global_symbols);
            }
          child_die = sibling_die (child_die);
@@ -3338,95 +3465,110 @@ read_common_block (struct die_info *die, struct objfile *objfile,
 
 /* Read a C++ namespace.  */
 
 
 /* Read a C++ namespace.  */
 
-static void
-read_namespace (struct die_info *die, struct objfile *objfile,
-               const struct comp_unit_head *cu_header)
-{
-  const char *previous_namespace = processing_current_namespace;
-  const char *name = NULL;
-  int is_anonymous;
-  struct die_info *current_die;
-
-  /* Loop through the extensions until we find a name.  */
-
-  for (current_die = die;
-       current_die != NULL;
-       current_die = dwarf2_extension (die))
-    {
-      name = dwarf2_name (current_die);
-      if (name != NULL)
-       break;
-    }
-
-  /* Is it an anonymous namespace?  */
+static void
+read_namespace (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  const char *previous_prefix = processing_current_prefix;
+  const char *name;
+  int is_anonymous;
+  struct die_info *current_die;
 
 
-  is_anonymous = (name == NULL);
-  if (is_anonymous)
-    name = "(anonymous namespace)";
+  name = namespace_name (die, &is_anonymous, cu);
 
   /* Now build the name of the current namespace.  */
 
 
   /* Now build the name of the current namespace.  */
 
-  if (previous_namespace[0] == '\0')
+  if (previous_prefix[0] == '\0')
     {
     {
-      processing_current_namespace = name;
+      processing_current_prefix = name;
     }
   else
     {
     }
   else
     {
-      /* We need temp_name around because processing_current_namespace
+      /* We need temp_name around because processing_current_prefix
         is a const char *.  */
         is a const char *.  */
-      char *temp_name = alloca (strlen (previous_namespace)
+      char *temp_name = alloca (strlen (previous_prefix)
                                + 2 + strlen(name) + 1);
                                + 2 + strlen(name) + 1);
-      strcpy (temp_name, previous_namespace);
+      strcpy (temp_name, previous_prefix);
       strcat (temp_name, "::");
       strcat (temp_name, name);
 
       strcat (temp_name, "::");
       strcat (temp_name, name);
 
-      processing_current_namespace = temp_name;
+      processing_current_prefix = temp_name;
     }
 
   /* Add a symbol associated to this if we haven't seen the namespace
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
     }
 
   /* Add a symbol associated to this if we haven't seen the namespace
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
-  if (dwarf2_extension (die) == NULL)
+  if (dwarf2_extension (die, cu) == NULL)
     {
       struct type *type;
 
       /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
         this cast will hopefully become unnecessary.  */
       type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
     {
       struct type *type;
 
       /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
         this cast will hopefully become unnecessary.  */
       type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
-                       (char *) processing_current_namespace,
+                       (char *) processing_current_prefix,
                        objfile);
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
                        objfile);
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
-      new_symbol (die, type, objfile, cu_header);
+      new_symbol (die, type, cu);
 
       if (is_anonymous)
 
       if (is_anonymous)
-       cp_add_using_directive (processing_current_namespace,
-                               strlen (previous_namespace),
-                               strlen (processing_current_namespace));
+       cp_add_using_directive (processing_current_prefix,
+                               strlen (previous_prefix),
+                               strlen (processing_current_prefix));
     }
 
     }
 
-  if (die->has_children)
+  if (die->child != NULL)
     {
     {
-      struct die_info *child_die = die->next;
+      struct die_info *child_die = die->child;
       
       while (child_die && child_die->tag)
        {
       
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
 
          child_die = sibling_die (child_die);
        }
     }
 
-  processing_current_namespace = previous_namespace;
+  processing_current_prefix = previous_prefix;
+}
+
+/* Return the name of the namespace represented by DIE.  Set
+   *IS_ANONYMOUS to tell whether or not the namespace is an anonymous
+   namespace.  */
+
+static const char *
+namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
+{
+  struct die_info *current_die;
+  const char *name = NULL;
+
+  /* Loop through the extensions until we find a name.  */
+
+  for (current_die = die;
+       current_die != NULL;
+       current_die = dwarf2_extension (die, cu))
+    {
+      name = dwarf2_name (current_die, cu);
+      if (name != NULL)
+       break;
+    }
+
+  /* Is it an anonymous namespace?  */
+
+  *is_anonymous = (name == NULL);
+  if (*is_anonymous)
+    name = "(anonymous namespace)";
+
+  return name;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
    the user defined type vector.  */
 
 static void
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
    the user defined type vector.  */
 
 static void
-read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
-                      const struct comp_unit_head *cu_header)
+read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
   struct attribute *attr_address_class;
   struct type *type;
   struct attribute *attr_byte_size;
   struct attribute *attr_address_class;
@@ -3437,15 +3579,15 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
       return;
     }
 
-  type = lookup_pointer_type (die_type (die, objfile, cu_header));
+  type = lookup_pointer_type (die_type (die, cu));
 
 
-  attr_byte_size = dwarf_attr (die, DW_AT_byte_size);
+  attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr_byte_size)
     byte_size = DW_UNSND (attr_byte_size);
   else
     byte_size = cu_header->addr_size;
 
   if (attr_byte_size)
     byte_size = DW_UNSND (attr_byte_size);
   else
     byte_size = cu_header->addr_size;
 
-  attr_address_class = dwarf_attr (die, DW_AT_address_class);
+  attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu);
   if (attr_address_class)
     addr_class = DW_UNSND (attr_address_class);
   else
   if (attr_address_class)
     addr_class = DW_UNSND (attr_address_class);
   else
@@ -3481,9 +3623,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
    the user defined type vector.  */
 
 static void
    the user defined type vector.  */
 
 static void
-read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
-                            const struct comp_unit_head *cu_header)
+read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct type *type;
   struct type *to_type;
   struct type *domain;
   struct type *type;
   struct type *to_type;
   struct type *domain;
@@ -3494,8 +3636,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
     }
 
   type = alloc_type (objfile);
     }
 
   type = alloc_type (objfile);
-  to_type = die_type (die, objfile, cu_header);
-  domain = die_containing_type (die, objfile, cu_header);
+  to_type = die_type (die, cu);
+  domain = die_containing_type (die, cu);
   smash_to_member_type (type, domain, to_type);
 
   die->type = type;
   smash_to_member_type (type, domain, to_type);
 
   die->type = type;
@@ -3505,9 +3647,9 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
    the user defined type vector.  */
 
 static void
    the user defined type vector.  */
 
 static void
-read_tag_reference_type (struct die_info *die, struct objfile *objfile,
-                        const struct comp_unit_head *cu_header)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr;
 
   struct type *type;
   struct attribute *attr;
 
@@ -3516,8 +3658,8 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
       return;
     }
 
-  type = lookup_reference_type (die_type (die, objfile, cu_header));
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  type = lookup_reference_type (die_type (die, cu));
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3530,8 +3672,7 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile,
 }
 
 static void
 }
 
 static void
-read_tag_const_type (struct die_info *die, struct objfile *objfile,
-                    const struct comp_unit_head *cu_header)
+read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *base_type;
 
 {
   struct type *base_type;
 
@@ -3540,13 +3681,12 @@ read_tag_const_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
       return;
     }
 
-  base_type = die_type (die, objfile, cu_header);
+  base_type = die_type (die, cu);
   die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
 }
 
 static void
   die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
 }
 
 static void
-read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
-                       const struct comp_unit_head *cu_header)
+read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *base_type;
 
 {
   struct type *base_type;
 
@@ -3555,7 +3695,7 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
       return;
     }
 
-  base_type = die_type (die, objfile, cu_header);
+  base_type = die_type (die, cu);
   die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
 }
 
   die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
 }
 
@@ -3565,8 +3705,9 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
    attribute to reference it.  */
 
 static void
    attribute to reference it.  */
 
 static void
-read_tag_string_type (struct die_info *die, struct objfile *objfile)
+read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
   unsigned int length;
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
   unsigned int length;
@@ -3576,7 +3717,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
       return;
     }
 
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_string_length);
+  attr = dwarf2_attr (die, DW_AT_string_length, cu);
   if (attr)
     {
       length = DW_UNSND (attr);
   if (attr)
     {
       length = DW_UNSND (attr);
@@ -3584,7 +3725,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
   else
     {
       /* check for the DW_AT_byte_size attribute */
   else
     {
       /* check for the DW_AT_byte_size attribute */
-      attr = dwarf_attr (die, DW_AT_byte_size);
+      attr = dwarf2_attr (die, DW_AT_byte_size, cu);
       if (attr)
         {
           length = DW_UNSND (attr);
       if (attr)
         {
           length = DW_UNSND (attr);
@@ -3594,9 +3735,9 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
           length = 1;
         }
     }
           length = 1;
         }
     }
-  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
   range_type = create_range_type (NULL, index_type, 1, length);
   range_type = create_range_type (NULL, index_type, 1, length);
-  if (cu_language == language_fortran)
+  if (cu->language == language_fortran)
     {
       /* Need to create a unique string type for bounds
          information */
     {
       /* Need to create a unique string type for bounds
          information */
@@ -3604,7 +3745,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
     }
   else
     {
     }
   else
     {
-      char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+      char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
       type = create_string_type (char_type, range_type);
     }
   die->type = type;
       type = create_string_type (char_type, range_type);
     }
   die->type = type;
@@ -3622,8 +3763,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
  */
 
 static void
  */
 
 static void
-read_subroutine_type (struct die_info *die, struct objfile *objfile,
-                     const struct comp_unit_head *cu_header)
+read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;           /* Type that this function returns */
   struct type *ftype;          /* Function that returns above type */
 {
   struct type *type;           /* Type that this function returns */
   struct type *ftype;          /* Function that returns above type */
@@ -3634,16 +3774,16 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
     {
       return;
     }
     {
       return;
     }
-  type = die_type (die, objfile, cu_header);
+  type = die_type (die, cu);
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
-  attr = dwarf_attr (die, DW_AT_prototyped);
+  attr = dwarf2_attr (die, DW_AT_prototyped, cu);
   if ((attr && (DW_UNSND (attr) != 0))
   if ((attr && (DW_UNSND (attr) != 0))
-      || cu_language == language_cplus)
+      || cu->language == language_cplus)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
-  if (die->has_children)
+  if (die->child != NULL)
     {
       struct die_info *child_die;
       int nparams = 0;
     {
       struct die_info *child_die;
       int nparams = 0;
@@ -3652,7 +3792,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
       /* Count the number of parameters.
          FIXME: GDB currently ignores vararg functions, but knows about
          vararg member functions.  */
       /* Count the number of parameters.
          FIXME: GDB currently ignores vararg functions, but knows about
          vararg member functions.  */
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
@@ -3667,7 +3807,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
       TYPE_FIELDS (ftype) = (struct field *)
        TYPE_ALLOC (ftype, nparams * sizeof (struct field));
 
       TYPE_FIELDS (ftype) = (struct field *)
        TYPE_ALLOC (ftype, nparams * sizeof (struct field));
 
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
@@ -3677,13 +3817,12 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
                 parameter for non-static member functions (which is the
                 this pointer) as artificial. We pass this information
                 to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
                 parameter for non-static member functions (which is the
                 this pointer) as artificial. We pass this information
                 to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
-             attr = dwarf_attr (child_die, DW_AT_artificial);
+             attr = dwarf2_attr (child_die, DW_AT_artificial, cu);
              if (attr)
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
              else
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
              if (attr)
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
              else
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
-             TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile,
-                                                          cu_header);
+             TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, cu);
              iparams++;
            }
          child_die = sibling_die (child_die);
              iparams++;
            }
          child_die = sibling_die (child_die);
@@ -3694,21 +3833,21 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
 }
 
 static void
 }
 
 static void
-read_typedef (struct die_info *die, struct objfile *objfile,
-             const struct comp_unit_head *cu_header)
+read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct attribute *attr;
   char *name = NULL;
 
   if (!die->type)
     {
   struct attribute *attr;
   char *name = NULL;
 
   if (!die->type)
     {
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        {
          name = DW_STRING (attr);
        }
       die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
       if (attr && DW_STRING (attr))
        {
          name = DW_STRING (attr);
        }
       die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
-      TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header);
+      TYPE_TARGET_TYPE (die->type) = die_type (die, cu);
     }
 }
 
     }
 }
 
@@ -3716,8 +3855,9 @@ read_typedef (struct die_info *die, struct objfile *objfile,
    it in the TYPE field of the die.  */
 
 static void
    it in the TYPE field of the die.  */
 
 static void
-read_base_type (struct die_info *die, struct objfile *objfile)
+read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, size = 0;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, size = 0;
@@ -3728,17 +3868,17 @@ read_base_type (struct die_info *die, struct objfile *objfile)
       return;
     }
 
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_encoding);
+  attr = dwarf2_attr (die, DW_AT_encoding, cu);
   if (attr)
     {
       encoding = DW_UNSND (attr);
     }
   if (attr)
     {
       encoding = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       size = DW_UNSND (attr);
     }
   if (attr)
     {
       size = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
@@ -3775,73 +3915,187 @@ read_base_type (struct die_info *die, struct objfile *objfile)
        }
       type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
       if (encoding == DW_ATE_address)
        }
       type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
       if (encoding == DW_ATE_address)
-       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID,
+                                                          cu);
       else if (encoding == DW_ATE_complex_float)
        {
          if (size == 32)
            TYPE_TARGET_TYPE (type)
       else if (encoding == DW_ATE_complex_float)
        {
          if (size == 32)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
          else if (size == 16)
            TYPE_TARGET_TYPE (type)
          else if (size == 16)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
          else if (size == 8)
            TYPE_TARGET_TYPE (type)
          else if (size == 8)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
     }
   else
     {
        }
     }
   else
     {
-      type = dwarf_base_type (encoding, size, objfile);
+      type = dwarf_base_type (encoding, size, cu);
     }
   die->type = type;
 }
 
     }
   die->type = type;
 }
 
+/* Read the given DW_AT_subrange DIE.  */
+
+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *base_type;
+  struct type *range_type;
+  struct attribute *attr;
+  int low = 0;
+  int high = -1;
+  
+  /* If we have already decoded this die, then nothing more to do.  */
+  if (die->type)
+    return;
+
+  base_type = die_type (die, cu);
+  if (base_type == NULL)
+    {
+      complaint (&symfile_complaints,
+                "DW_AT_type missing from DW_TAG_subrange_type");
+      return;
+    }
+
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+    base_type = alloc_type (NULL);
+
+  if (cu->language == language_fortran)
+    { 
+      /* FORTRAN implies a lower bound of 1, if not given.  */
+      low = 1;
+    }
+
+  attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
+  if (attr)
+    low = dwarf2_get_attr_constant_value (attr, 0);
+
+  attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+  if (attr)
+    {       
+      if (attr->form == DW_FORM_block1)
+        {
+          /* GCC encodes arrays with unspecified or dynamic length
+             with a DW_FORM_block1 attribute.
+             FIXME: GDB does not yet know how to handle dynamic
+             arrays properly, treat them as arrays with unspecified
+             length for now.
+
+             FIXME: jimb/2003-09-22: GDB does not really know
+             how to handle arrays of unspecified length
+             either; we just represent them as zero-length
+             arrays.  Choose an appropriate upper bound given
+             the lower bound we've computed above.  */
+          high = low - 1;
+        }
+      else
+        high = dwarf2_get_attr_constant_value (attr, 1);
+    }
+
+  range_type = create_range_type (NULL, base_type, low, high);
+
+  attr = dwarf2_attr (die, DW_AT_name, cu);
+  if (attr && DW_STRING (attr))
+    TYPE_NAME (range_type) = DW_STRING (attr);
+  
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+  if (attr)
+    TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+  die->type = range_type;
+}
+  
+
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
-read_comp_unit (char *info_ptr, bfd *abfd,
-               const struct comp_unit_head *cu_header)
+read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
 {
 {
-  struct die_info *first_die, *last_die, *die;
-  char *cur_ptr;
-  int nesting_level;
-
   /* Reset die reference table; we are
      building new ones now.  */
   dwarf2_empty_hash_tables ();
 
   /* Reset die reference table; we are
      building new ones now.  */
   dwarf2_empty_hash_tables ();
 
+  return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
+}
+
+/* Read a single die and all its descendents.  Set the die's sibling
+   field to NULL; set other fields in the die correctly, and set all
+   of the descendents' fields correctly.  Set *NEW_INFO_PTR to the
+   location of the info_ptr after reading all of those dies.  PARENT
+   is the parent of the die in question.  */
+
+static struct die_info *
+read_die_and_children (char *info_ptr, bfd *abfd,
+                      struct dwarf2_cu *cu,
+                      char **new_info_ptr,
+                      struct die_info *parent)
+{
+  struct die_info *die;
+  char *cur_ptr;
+  int has_children;
+
+  cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children);
+  store_in_ref_table (die->offset, die);
+
+  if (has_children)
+    {
+      die->child = read_die_and_siblings (cur_ptr, abfd, cu,
+                                         new_info_ptr, die);
+    }
+  else
+    {
+      die->child = NULL;
+      *new_info_ptr = cur_ptr;
+    }
+
+  die->sibling = NULL;
+  die->parent = parent;
+  return die;
+}
+
+/* Read a die, all of its descendents, and all of its siblings; set
+   all of the fields of all of the dies correctly.  Arguments are as
+   in read_die_and_children.  */
+
+static struct die_info *
+read_die_and_siblings (char *info_ptr, bfd *abfd,
+                      struct dwarf2_cu *cu,
+                      char **new_info_ptr,
+                      struct die_info *parent)
+{
+  struct die_info *first_die, *last_sibling;
+  char *cur_ptr;
+
   cur_ptr = info_ptr;
   cur_ptr = info_ptr;
-  nesting_level = 0;
-  first_die = last_die = NULL;
-  do
+  first_die = last_sibling = NULL;
+
+  while (1)
     {
     {
-      cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header);
-      if (die->has_children)
+      struct die_info *die
+       = read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent);
+
+      if (!first_die)
        {
        {
-         nesting_level++;
+         first_die = die;
        }
        }
-      if (die->tag == 0)
+      else
        {
        {
-         nesting_level--;
+         last_sibling->sibling = die;
        }
 
        }
 
-      die->next = NULL;
-
-      /* Enter die in reference hash table */
-      store_in_ref_table (die->offset, die);
-
-      if (!first_die)
+      if (die->tag == 0)
        {
        {
-         first_die = last_die = die;
+         *new_info_ptr = cur_ptr;
+         return first_die;
        }
       else
        {
        }
       else
        {
-         last_die->next = die;
-         last_die = die;
+         last_sibling = die;
        }
     }
        }
     }
-  while (nesting_level > 0);
-  return first_die;
 }
 
 /* Free a linked list of dies.  */
 }
 
 /* Free a linked list of dies.  */
@@ -3854,7 +4108,9 @@ free_die_list (struct die_info *dies)
   die = dies;
   while (die)
     {
   die = dies;
   while (die)
     {
-      next = die->next;
+      if (die->child != NULL)
+       free_die_list (die->child);
+      next = die->sibling;
       xfree (die->attrs);
       xfree (die);
       die = next;
       xfree (die->attrs);
       xfree (die);
       die = next;
@@ -3875,31 +4131,29 @@ make_cleanup_free_die_list (struct die_info *dies)
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
-   object file specified by OBJFILE into the psymbol_obstack and return it.  */
+   object file specified by OBJFILE into the objfile_obstack and return it.  */
 
 char *
 
 char *
-dwarf2_read_section (struct objfile *objfile, file_ptr offset,
-                    unsigned int size, asection *sectp)
+dwarf2_read_section (struct objfile *objfile, asection *sectp)
 {
   bfd *abfd = objfile->obfd;
   char *buf, *retbuf;
 {
   bfd *abfd = objfile->obfd;
   char *buf, *retbuf;
+  bfd_size_type size = bfd_get_section_size_before_reloc (sectp);
 
   if (size == 0)
     return NULL;
 
 
   if (size == 0)
     return NULL;
 
-  buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+  buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
   retbuf
     = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
     return retbuf;
 
   retbuf
     = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
     return retbuf;
 
-  if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
-      (bfd_bread (buf, size, abfd) != size))
-    {
-      buf = NULL;
-      error ("Dwarf Error: Can't read DWARF data from '%s'",
-            bfd_get_filename (abfd));
-    }
+  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+      || bfd_bread (buf, size, abfd) != size)
+    error ("Dwarf Error: Can't read DWARF data from '%s'",
+          bfd_get_filename (abfd));
+
   return buf;
 }
 
   return buf;
 }
 
@@ -3909,8 +4163,9 @@ dwarf2_read_section (struct objfile *objfile, file_ptr offset,
    in a hash table.  */
 
 static void
    in a hash table.  */
 
 static void
-dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header)
+dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   char *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   char *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
@@ -3974,7 +4229,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header)
        break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
        break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
-      if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL)
+      if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
        break;
     }
 }
        break;
     }
 }
@@ -4008,8 +4263,9 @@ dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
 /* Lookup an abbrev_info structure in the abbrev hash table.  */
 
 static struct abbrev_info *
 /* Lookup an abbrev_info structure in the abbrev hash table.  */
 
 static struct abbrev_info *
-dwarf2_lookup_abbrev (unsigned int number, const struct comp_unit_head *cu_header)
+dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   unsigned int hash_number;
   struct abbrev_info *abbrev;
 
   unsigned int hash_number;
   struct abbrev_info *abbrev;
 
@@ -4030,7 +4286,7 @@ dwarf2_lookup_abbrev (unsigned int number, const struct comp_unit_head *cu_heade
 
 static char *
 read_partial_die (struct partial_die_info *part_die, bfd *abfd,
 
 static char *
 read_partial_die (struct partial_die_info *part_die, bfd *abfd,
-                 char *info_ptr, const struct comp_unit_head *cu_header)
+                 char *info_ptr, struct dwarf2_cu *cu)
 {
   unsigned int abbrev_number, bytes_read, i;
   struct abbrev_info *abbrev;
 {
   unsigned int abbrev_number, bytes_read, i;
   struct abbrev_info *abbrev;
@@ -4046,7 +4302,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
   if (!abbrev_number)
     return info_ptr;
 
   if (!abbrev_number)
     return info_ptr;
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
+  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
       error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
   if (!abbrev)
     {
       error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
@@ -4059,8 +4315,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
-      info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd,
-                                info_ptr, cu_header);
+      info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu);
 
       /* Store the data if it is of an attribute we want to keep in a
          partial symbol table.  */
 
       /* Store the data if it is of an attribute we want to keep in a
          partial symbol table.  */
@@ -4123,7 +4378,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
            complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
          else
            part_die->sibling =
            complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
          else
            part_die->sibling =
-             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
          break;
        default:
          break;
          break;
        default:
          break;
@@ -4137,10 +4392,10 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
     {
       struct partial_die_info spec_die;
       char *spec_ptr;
     {
       struct partial_die_info spec_die;
       char *spec_ptr;
-      int dummy;
 
 
-      spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
-      read_partial_die (&spec_die, abfd, spec_ptr, cu_header);
+      spec_ptr = dwarf_info_buffer
+       + dwarf2_get_ref_die_offset (&spec_attr, cu);
+      read_partial_die (&spec_die, abfd, spec_ptr, cu);
       if (spec_die.name)
        {
          part_die->name = spec_die.name;
       if (spec_die.name)
        {
          part_die->name = spec_die.name;
@@ -4167,12 +4422,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
   return info_ptr;
 }
 
   return info_ptr;
 }
 
-/* Read the die from the .debug_info section buffer.  And set diep to
-   point to a newly allocated die with its information.  */
+/* Read the die from the .debug_info section buffer.  Set DIEP to
+   point to a newly allocated die with its information, except for its
+   child, sibling, and parent fields.  Set HAS_CHILDREN to tell
+   whether the die has children or not.  */
 
 static char *
 read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
 
 static char *
 read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
-              const struct comp_unit_head *cu_header)
+              struct dwarf2_cu *cu, int *has_children)
 {
   unsigned int abbrev_number, bytes_read, i, offset;
   struct abbrev_info *abbrev;
 {
   unsigned int abbrev_number, bytes_read, i, offset;
   struct abbrev_info *abbrev;
@@ -4188,19 +4445,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
       die->abbrev = abbrev_number;
       die->type = NULL;
       *diep = die;
       die->abbrev = abbrev_number;
       die->type = NULL;
       *diep = die;
+      *has_children = 0;
       return info_ptr;
     }
 
       return info_ptr;
     }
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
+  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
   if (!abbrev)
     {
-      error ("Dwarf Error: could not find abbrev number %d [in module %s]", abbrev_number, 
-                     bfd_get_filename (abfd));
+      error ("Dwarf Error: could not find abbrev number %d [in module %s]",
+            abbrev_number, 
+            bfd_get_filename (abfd));
     }
   die = dwarf_alloc_die ();
   die->offset = offset;
   die->tag = abbrev->tag;
     }
   die = dwarf_alloc_die ();
   die->offset = offset;
   die->tag = abbrev->tag;
-  die->has_children = abbrev->has_children;
   die->abbrev = abbrev_number;
   die->type = NULL;
 
   die->abbrev = abbrev_number;
   die->type = NULL;
 
@@ -4211,10 +4469,11 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
       info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
       info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
-                                abfd, info_ptr, cu_header);
+                                abfd, info_ptr, cu);
     }
 
   *diep = die;
     }
 
   *diep = die;
+  *has_children = abbrev->has_children;
   return info_ptr;
 }
 
   return info_ptr;
 }
 
@@ -4222,9 +4481,10 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
 
 static char *
 read_attribute_value (struct attribute *attr, unsigned form,
 
 static char *
 read_attribute_value (struct attribute *attr, unsigned form,
-               bfd *abfd, char *info_ptr,
-               const struct comp_unit_head *cu_header)
+                     bfd *abfd, char *info_ptr,
+                     struct dwarf2_cu *cu)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   unsigned int bytes_read;
   struct dwarf_block *blk;
 
   unsigned int bytes_read;
   struct dwarf_block *blk;
 
@@ -4233,7 +4493,7 @@ read_attribute_value (struct attribute *attr, unsigned form,
     {
     case DW_FORM_addr:
     case DW_FORM_ref_addr:
     {
     case DW_FORM_addr:
     case DW_FORM_ref_addr:
-      DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read);
+      DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
       info_ptr += bytes_read;
       break;
     case DW_FORM_block2:
       info_ptr += bytes_read;
       break;
     case DW_FORM_block2:
@@ -4328,7 +4588,7 @@ read_attribute_value (struct attribute *attr, unsigned form,
     case DW_FORM_indirect:
       form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
     case DW_FORM_indirect:
       form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
-      info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header);
+      info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu);
       break;
     default:
       error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
       break;
     default:
       error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
@@ -4342,11 +4602,10 @@ read_attribute_value (struct attribute *attr, unsigned form,
 
 static char *
 read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
 
 static char *
 read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
-               bfd *abfd, char *info_ptr,
-               const struct comp_unit_head *cu_header)
+               bfd *abfd, char *info_ptr, struct dwarf2_cu *cu)
 {
   attr->name = abbrev->name;
 {
   attr->name = abbrev->name;
-  return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header);
+  return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu);
 }
 
 /* read dwarf information from a buffer */
 }
 
 /* read dwarf information from a buffer */
@@ -4394,9 +4653,9 @@ read_8_bytes (bfd *abfd, char *buf)
 }
 
 static CORE_ADDR
 }
 
 static CORE_ADDR
-read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
-             int *bytes_read)
+read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
 {
 {
+  struct comp_unit_head *cu_header = &cu->header;
   CORE_ADDR retval = 0;
 
   if (cu_header->signed_addr_p)
   CORE_ADDR retval = 0;
 
   if (cu_header->signed_addr_p)
@@ -4669,27 +4928,27 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
 }
 
 static void
 }
 
 static void
-set_cu_language (unsigned int lang)
+set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
 {
   switch (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
 {
   switch (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
-      cu_language = language_c;
+      cu->language = language_c;
       break;
     case DW_LANG_C_plus_plus:
       break;
     case DW_LANG_C_plus_plus:
-      cu_language = language_cplus;
+      cu->language = language_cplus;
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
-      cu_language = language_fortran;
+      cu->language = language_fortran;
       break;
     case DW_LANG_Mips_Assembler:
       break;
     case DW_LANG_Mips_Assembler:
-      cu_language = language_asm;
+      cu->language = language_asm;
       break;
     case DW_LANG_Java:
       break;
     case DW_LANG_Java:
-      cu_language = language_java;
+      cu->language = language_java;
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
@@ -4698,16 +4957,16 @@ set_cu_language (unsigned int lang)
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
-      cu_language = language_minimal;
+      cu->language = language_minimal;
       break;
     }
       break;
     }
-  cu_language_defn = language_def (cu_language);
+  cu->language_defn = language_def (cu->language);
 }
 
 /* Return the named attribute or NULL if not there.  */
 
 static struct attribute *
 }
 
 /* Return the named attribute or NULL if not there.  */
 
 static struct attribute *
-dwarf_attr (struct die_info *die, unsigned int name)
+dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
 {
   unsigned int i;
   struct attribute *spec = NULL;
 {
   unsigned int i;
   struct attribute *spec = NULL;
@@ -4725,22 +4984,35 @@ dwarf_attr (struct die_info *die, unsigned int name)
   if (spec)
     {
       struct die_info *ref_die =
   if (spec)
     {
       struct die_info *ref_die =
-      follow_die_ref (dwarf2_get_ref_die_offset (spec));
+      follow_die_ref (dwarf2_get_ref_die_offset (spec, cu));
 
       if (ref_die)
 
       if (ref_die)
-       return dwarf_attr (ref_die, name);
+       return dwarf2_attr (ref_die, name, cu);
     }
 
   return NULL;
 }
 
 static int
     }
 
   return NULL;
 }
 
 static int
-die_is_declaration (struct die_info *die)
+die_is_declaration (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
-  return (dwarf_attr (die, DW_AT_declaration)
-         && ! dwarf_attr (die, DW_AT_specification));
+  return (dwarf2_attr (die, DW_AT_declaration, cu)
+         && ! dwarf2_attr (die, DW_AT_specification, cu));
 }
 
 }
 
+/* Return the die giving the specification for DIE, if there is
+   one.  */
+
+static struct die_info *
+die_specification (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
+
+  if (spec_attr == NULL)
+    return NULL;
+  else
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
+}
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
@@ -4828,7 +5100,7 @@ add_file_name (struct line_header *lh,
    freed.  */
 static struct line_header *
 dwarf_decode_line_header (unsigned int offset, bfd *abfd,
    freed.  */
 static struct line_header *
 dwarf_decode_line_header (unsigned int offset, bfd *abfd,
-                          const struct comp_unit_head *cu_header)
+                         struct dwarf2_cu *cu)
 {
   struct cleanup *back_to;
   struct line_header *lh;
 {
   struct cleanup *back_to;
   struct line_header *lh;
@@ -4869,7 +5141,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
   lh->statement_program_end = line_ptr + lh->total_length;
   lh->version = read_2_bytes (abfd, line_ptr);
   line_ptr += 2;
   lh->statement_program_end = line_ptr + lh->total_length;
   lh->version = read_2_bytes (abfd, line_ptr);
   line_ptr += 2;
-  lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
+  lh->header_length = read_offset (abfd, line_ptr, &cu->header, &bytes_read);
   line_ptr += bytes_read;
   lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
   line_ptr += bytes_read;
   lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
@@ -4933,26 +5205,26 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
    addresses passed to record_line.  */
 
 static CORE_ADDR
    addresses passed to record_line.  */
 
 static CORE_ADDR
-check_cu_functions (CORE_ADDR address)
+check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
 {
   struct function_range *fn;
 
   /* Find the function_range containing address.  */
 {
   struct function_range *fn;
 
   /* Find the function_range containing address.  */
-  if (!cu_first_fn)
+  if (!cu->first_fn)
     return address;
 
     return address;
 
-  if (!cu_cached_fn)
-    cu_cached_fn = cu_first_fn;
+  if (!cu->cached_fn)
+    cu->cached_fn = cu->first_fn;
 
 
-  fn = cu_cached_fn;
+  fn = cu->cached_fn;
   while (fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
       fn = fn->next;
 
   while (fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
       fn = fn->next;
 
-  fn = cu_first_fn;
-  while (fn && fn != cu_cached_fn)
+  fn = cu->first_fn;
+  while (fn && fn != cu->cached_fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
@@ -4977,13 +5249,16 @@ check_cu_functions (CORE_ADDR address)
 
 static void
 dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
 
 static void
 dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
-                   const struct comp_unit_head *cu_header)
+                   struct dwarf2_cu *cu)
 {
   char *line_ptr;
   char *line_end;
 {
   char *line_ptr;
   char *line_end;
-  unsigned int i, bytes_read;
-  char *cur_dir;
+  unsigned int bytes_read;
   unsigned char op_code, extended_op, adj_opcode;
   unsigned char op_code, extended_op, adj_opcode;
+  CORE_ADDR baseaddr;
+  struct objfile *objfile = cu->objfile;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
 
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
@@ -5029,7 +5304,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
              record_line (current_subfile, line, 
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 1;
            }
          else switch (op_code)
              basic_block = 1;
            }
          else switch (op_code)
@@ -5045,7 +5320,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                  record_line (current_subfile, 0, address);
                  break;
                case DW_LNE_set_address:
                  record_line (current_subfile, 0, address);
                  break;
                case DW_LNE_set_address:
-                 address = read_address (abfd, line_ptr, cu_header, &bytes_read);
+                 address = read_address (abfd, line_ptr, cu, &bytes_read);
                  line_ptr += bytes_read;
                  address += baseaddr;
                  break;
                  line_ptr += bytes_read;
                  address += baseaddr;
                  break;
@@ -5076,7 +5351,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              break;
            case DW_LNS_copy:
              record_line (current_subfile, line, 
              break;
            case DW_LNS_copy:
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -5189,9 +5464,11 @@ dwarf2_start_subfile (char *filename, char *dirname)
 
 static void
 var_decode_location (struct attribute *attr, struct symbol *sym,
 
 static void
 var_decode_location (struct attribute *attr, struct symbol *sym,
-                    struct objfile *objfile,
-                    const struct comp_unit_head *cu_header)
+                    struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
+
   /* NOTE drow/2003-01-30: There used to be a comment and some special
      code here to turn a symbol with DW_AT_external and a
      SYMBOL_VALUE_ADDRESS of 0 into a LOC_UNRESOLVED symbol.  This was
   /* NOTE drow/2003-01-30: There used to be a comment and some special
      code here to turn a symbol with DW_AT_external and a
      SYMBOL_VALUE_ADDRESS of 0 into a LOC_UNRESOLVED symbol.  This was
@@ -5222,8 +5499,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
       int dummy;
 
       SYMBOL_VALUE_ADDRESS (sym) =
       int dummy;
 
       SYMBOL_VALUE_ADDRESS (sym) =
-       read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu_header,
-                     &dummy);
+       read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
       fixup_symbol_section (sym, objfile);
       SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
                                              SYMBOL_SECTION (sym));
       fixup_symbol_section (sym, objfile);
       SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
                                              SYMBOL_SECTION (sym));
@@ -5238,7 +5514,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
      not be worthwhile.  I'm assuming that it isn't unless performance
      or memory numbers show me otherwise.  */
 
      not be worthwhile.  I'm assuming that it isn't unless performance
      or memory numbers show me otherwise.  */
 
-  dwarf2_symbol_mark_computed (attr, sym, cu_header, objfile);
+  dwarf2_symbol_mark_computed (attr, sym, cu);
   SYMBOL_CLASS (sym) = LOC_COMPUTED;
 }
 
   SYMBOL_CLASS (sym) = LOC_COMPUTED;
 }
 
@@ -5249,29 +5525,31 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
    used the passed type.  */
 
 static struct symbol *
    used the passed type.  */
 
 static struct symbol *
-new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
-           const struct comp_unit_head *cu_header)
+new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
   struct symbol *sym = NULL;
   char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
   struct symbol *sym = NULL;
   char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
-  CORE_ADDR addr = 0;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   if (die->tag != DW_TAG_namespace)
 
   if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die);
+    name = dwarf2_linkage_name (die, cu);
   else
     name = TYPE_NAME (type);
 
   if (name)
     {
   else
     name = TYPE_NAME (type);
 
   if (name)
     {
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+      sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
-      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_LANGUAGE (sym) = cu->language;
       SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
       SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
@@ -5281,8 +5559,8 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
       if (type != NULL)
        SYMBOL_TYPE (sym) = type;
       else
       if (type != NULL)
        SYMBOL_TYPE (sym) = type;
       else
-       SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
-      attr = dwarf_attr (die, DW_AT_decl_line);
+       SYMBOL_TYPE (sym) = die_type (die, cu);
+      attr = dwarf2_attr (die, DW_AT_decl_line, cu);
       if (attr)
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
       if (attr)
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
@@ -5290,7 +5568,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
       switch (die->tag)
        {
        case DW_TAG_label:
       switch (die->tag)
        {
        case DW_TAG_label:
-         attr = dwarf_attr (die, DW_AT_low_pc);
+         attr = dwarf2_attr (die, DW_AT_low_pc, cu);
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
@@ -5301,14 +5579,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
-         attr2 = dwarf_attr (die, DW_AT_external);
+         attr2 = dwarf2_attr (die, DW_AT_external, cu);
          if (attr2 && (DW_UNSND (attr2) != 0))
            {
              add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
          if (attr2 && (DW_UNSND (attr2) != 0))
            {
              add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
-             add_symbol_to_list (sym, list_in_scope);
+             add_symbol_to_list (sym, cu->list_in_scope);
            }
          break;
        case DW_TAG_variable:
            }
          break;
        case DW_TAG_variable:
@@ -5320,26 +5598,26 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                                           TARGET_INT_BIT / HOST_CHAR_BIT, 0,
                                           "<variable, no debug info>",
                                           objfile);
                                           TARGET_INT_BIT / HOST_CHAR_BIT, 0,
                                           "<variable, no debug info>",
                                           objfile);
-         attr = dwarf_attr (die, DW_AT_const_value);
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
-             attr2 = dwarf_attr (die, DW_AT_external);
+             dwarf2_const_value (attr, sym, cu);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
              break;
            }
              break;
            }
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
          if (attr)
            {
-             var_decode_location (attr, sym, objfile, cu_header);
-             attr2 = dwarf_attr (die, DW_AT_external);
+             var_decode_location (attr, sym, cu);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
            }
          else
            {
            }
          else
            {
@@ -5349,9 +5627,9 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                 The address of the variable will then be determined from
                 the minimal symbol table whenever the variable is
                 referenced.  */
                 The address of the variable will then be determined from
                 the minimal symbol table whenever the variable is
                 referenced.  */
-             attr2 = dwarf_attr (die, DW_AT_external);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0)
              if (attr2 && (DW_UNSND (attr2) != 0)
-                 && dwarf_attr (die, DW_AT_type) != NULL)
+                 && dwarf2_attr (die, DW_AT_type, cu) != NULL)
                {
                  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                  add_symbol_to_list (sym, &global_symbols);
                {
                  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                  add_symbol_to_list (sym, &global_symbols);
@@ -5359,20 +5637,20 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
            }
          break;
        case DW_TAG_formal_parameter:
            }
          break;
        case DW_TAG_formal_parameter:
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
          if (attr)
            {
-             var_decode_location (attr, sym, objfile, cu_header);
+             var_decode_location (attr, sym, cu);
              /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary?  */
              if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
                SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
            }
              /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary?  */
              if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
                SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
            }
-         attr = dwarf_attr (die, DW_AT_const_value);
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
+             dwarf2_const_value (attr, sym, cu);
            }
            }
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_unspecified_parameters:
          /* From varargs functions; gdb doesn't seem to have any
          break;
        case DW_TAG_unspecified_parameters:
          /* From varargs functions; gdb doesn't seem to have any
@@ -5385,39 +5663,109 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
 
 
-         /* The semantics of C++ state that "struct foo { ... }" also
-            defines a typedef for "foo". Synthesize a typedef symbol so
-            that "ptype foo" works as expected.  */
-         if (cu_language == language_cplus)
+         /* Make sure that the symbol includes appropriate enclosing
+            classes/namespaces in its name.  These are calculated in
+            read_structure_scope, and the correct name is saved in
+            the type.  */
+
+         if (cu->language == language_cplus)
            {
            {
-             struct symbol *typedef_sym = (struct symbol *)
-             obstack_alloc (&objfile->symbol_obstack,
-                            sizeof (struct symbol));
-             *typedef_sym = *sym;
-             SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
-             if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-               TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 obsavestring (DEPRECATED_SYMBOL_NAME (sym),
-                               strlen (DEPRECATED_SYMBOL_NAME (sym)),
-                               &objfile->type_obstack);
-             add_symbol_to_list (typedef_sym, list_in_scope);
+             struct type *type = SYMBOL_TYPE (sym);
+             
+             if (TYPE_TAG_NAME (type) != NULL)
+               {
+                 /* FIXME: carlton/2003-11-10: Should this use
+                    SYMBOL_SET_NAMES instead?  (The same problem also
+                    arises a further down in the function.)  */
+                 SYMBOL_LINKAGE_NAME (sym)
+                   = obsavestring (TYPE_TAG_NAME (type),
+                                   strlen (TYPE_TAG_NAME (type)),
+                                   &objfile->objfile_obstack);
+               }
            }
            }
+
+         {
+           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+              really ever be static objects: otherwise, if you try
+              to, say, break of a class's method and you're in a file
+              which doesn't mention that class, it won't work unless
+              the check for all static symbols in lookup_symbol_aux
+              saves you.  See the OtherFileClass tests in
+              gdb.c++/namespace.exp.  */
+
+           struct pending **list_to_add;
+
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
+         
+           add_symbol_to_list (sym, list_to_add);
+
+           /* The semantics of C++ state that "struct foo { ... }" also
+              defines a typedef for "foo". Synthesize a typedef symbol so
+              that "ptype foo" works as expected.  */
+           if (cu->language == language_cplus)
+             {
+               struct symbol *typedef_sym = (struct symbol *)
+                 obstack_alloc (&objfile->objfile_obstack,
+                                sizeof (struct symbol));
+               *typedef_sym = *sym;
+               SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+               if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+                 TYPE_NAME (SYMBOL_TYPE (sym)) =
+                   obsavestring (SYMBOL_NATURAL_NAME (sym),
+                                 strlen (SYMBOL_NATURAL_NAME (sym)),
+                                 &objfile->objfile_obstack);
+               add_symbol_to_list (typedef_sym, list_to_add);
+             }
+         }
          break;
        case DW_TAG_typedef:
          break;
        case DW_TAG_typedef:
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         add_symbol_to_list (sym, cu->list_in_scope);
+         break;
        case DW_TAG_base_type:
        case DW_TAG_base_type:
+        case DW_TAG_subrange_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_enumerator:
          break;
        case DW_TAG_enumerator:
-         attr = dwarf_attr (die, DW_AT_const_value);
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
+             dwarf2_const_value (attr, sym, cu);
            }
            }
-         add_symbol_to_list (sym, list_in_scope);
+         {
+           /* NOTE: carlton/2003-11-10: See comment above in the
+              DW_TAG_class_type, etc. block.  */
+
+           struct pending **list_to_add;
+
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
+         
+           add_symbol_to_list (sym, list_to_add);
+         }
          break;
        case DW_TAG_namespace:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          break;
        case DW_TAG_namespace:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -5440,9 +5788,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
 
 static void
 dwarf2_const_value (struct attribute *attr, struct symbol *sym,
 
 static void
 dwarf2_const_value (struct attribute *attr, struct symbol *sym,
-                   struct objfile *objfile,
-                   const struct comp_unit_head *cu_header)
+                   struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
   struct dwarf_block *blk;
 
   switch (attr->form)
   struct dwarf_block *blk;
 
   switch (attr->form)
@@ -5454,7 +5803,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+       obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size);
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
       store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
       store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
@@ -5472,7 +5821,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, blk->size);
+       obstack_alloc (&objfile->objfile_obstack, blk->size);
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
@@ -5541,37 +5890,36 @@ dwarf2_const_value_data (struct attribute *attr,
 /* Return the type of the die in question using its DW_AT_type attribute.  */
 
 static struct type *
 /* Return the type of the die in question using its DW_AT_type attribute.  */
 
 static struct type *
-die_type (struct die_info *die, struct objfile *objfile,
-         const struct comp_unit_head *cu_header)
+die_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;
   struct attribute *type_attr;
   struct die_info *type_die;
   unsigned int ref;
 
 {
   struct type *type;
   struct attribute *type_attr;
   struct die_info *type_die;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_type);
+  type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
-      return dwarf2_fundamental_type (objfile, FT_VOID);
+      return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
     }
   else
     {
     }
   else
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
-                         ref, objfile->name);
+                         ref, cu->objfile->name);
          return NULL;
        }
     }
          return NULL;
        }
     }
-  type = tag_type_to_type (type_die, objfile, cu_header);
+  type = tag_type_to_type (type_die, cu);
   if (!type)
     {
       dump_die (type_die);
       error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]",
   if (!type)
     {
       dump_die (type_die);
       error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]",
-                     objfile->name);
+                     cu->objfile->name);
     }
   return type;
 }
     }
   return type;
 }
@@ -5580,40 +5928,39 @@ die_type (struct die_info *die, struct objfile *objfile,
    DW_AT_containing_type attribute.  */
 
 static struct type *
    DW_AT_containing_type attribute.  */
 
 static struct type *
-die_containing_type (struct die_info *die, struct objfile *objfile,
-                    const struct comp_unit_head *cu_header)
+die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type = NULL;
   struct attribute *type_attr;
   struct die_info *type_die = NULL;
   unsigned int ref;
 
 {
   struct type *type = NULL;
   struct attribute *type_attr;
   struct die_info *type_die = NULL;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_containing_type);
+  type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (type_attr)
     {
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
-                         objfile->name);
+                         cu->objfile->name);
          return NULL;
        }
          return NULL;
        }
-      type = tag_type_to_type (type_die, objfile, cu_header);
+      type = tag_type_to_type (type_die, cu);
     }
   if (!type)
     {
       if (type_die)
        dump_die (type_die);
       error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]", 
     }
   if (!type)
     {
       if (type_die)
        dump_die (type_die);
       error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]", 
-                     objfile->name);
+                     cu->objfile->name);
     }
   return type;
 }
 
 #if 0
 static struct type *
     }
   return type;
 }
 
 #if 0
 static struct type *
-type_at_offset (unsigned int offset, struct objfile *objfile)
+type_at_offset (unsigned int offset, struct dwarf2_cu *cu)
 {
   struct die_info *die;
   struct type *type;
 {
   struct die_info *die;
   struct type *type;
@@ -5624,14 +5971,13 @@ type_at_offset (unsigned int offset, struct objfile *objfile)
       error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
       return NULL;
     }
       error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
       return NULL;
     }
-  type = tag_type_to_type (die, objfile);
+  type = tag_type_to_type (die, cu);
   return type;
 }
 #endif
 
 static struct type *
   return type;
 }
 #endif
 
 static struct type *
-tag_type_to_type (struct die_info *die, struct objfile *objfile,
-                 const struct comp_unit_head *cu_header)
+tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   if (die->type)
     {
 {
   if (die->type)
     {
@@ -5639,141 +5985,273 @@ tag_type_to_type (struct die_info *die, struct objfile *objfile,
     }
   else
     {
     }
   else
     {
-      read_type_die (die, objfile, cu_header);
+      read_type_die (die, cu);
       if (!die->type)
        {
          dump_die (die);
          error ("Dwarf Error: Cannot find type of die [in module %s]", 
       if (!die->type)
        {
          dump_die (die);
          error ("Dwarf Error: Cannot find type of die [in module %s]", 
-                         objfile->name);
+                         cu->objfile->name);
        }
       return die->type;
     }
 }
 
 static void
        }
       return die->type;
     }
 }
 
 static void
-read_type_die (struct die_info *die, struct objfile *objfile,
-              const struct comp_unit_head *cu_header)
+read_type_die (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
+  char *prefix = determine_prefix (die, cu);
+  const char *old_prefix = processing_current_prefix;
+  struct cleanup *back_to = make_cleanup (xfree, prefix);
+  processing_current_prefix = prefix;
+  
   switch (die->tag)
     {
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
   switch (die->tag)
     {
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_scope (die, objfile, cu_header);
+      read_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration (die, objfile, cu_header);
+      read_enumeration (die, cu);
       break;
     case DW_TAG_subprogram:
     case DW_TAG_subroutine_type:
       break;
     case DW_TAG_subprogram:
     case DW_TAG_subroutine_type:
-      read_subroutine_type (die, objfile, cu_header);
+      read_subroutine_type (die, cu);
       break;
     case DW_TAG_array_type:
       break;
     case DW_TAG_array_type:
-      read_array_type (die, objfile, cu_header);
+      read_array_type (die, cu);
       break;
     case DW_TAG_pointer_type:
       break;
     case DW_TAG_pointer_type:
-      read_tag_pointer_type (die, objfile, cu_header);
+      read_tag_pointer_type (die, cu);
       break;
     case DW_TAG_ptr_to_member_type:
       break;
     case DW_TAG_ptr_to_member_type:
-      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
       break;
     case DW_TAG_reference_type:
-      read_tag_reference_type (die, objfile, cu_header);
+      read_tag_reference_type (die, cu);
       break;
     case DW_TAG_const_type:
       break;
     case DW_TAG_const_type:
-      read_tag_const_type (die, objfile, cu_header);
+      read_tag_const_type (die, cu);
       break;
     case DW_TAG_volatile_type:
       break;
     case DW_TAG_volatile_type:
-      read_tag_volatile_type (die, objfile, cu_header);
+      read_tag_volatile_type (die, cu);
       break;
     case DW_TAG_string_type:
       break;
     case DW_TAG_string_type:
-      read_tag_string_type (die, objfile);
+      read_tag_string_type (die, cu);
       break;
     case DW_TAG_typedef:
       break;
     case DW_TAG_typedef:
-      read_typedef (die, objfile, cu_header);
+      read_typedef (die, cu);
+      break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
       break;
     case DW_TAG_base_type:
       break;
     case DW_TAG_base_type:
-      read_base_type (die, objfile);
+      read_base_type (die, cu);
       break;
     default:
       complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'",
                 dwarf_tag_name (die->tag));
       break;
     }
       break;
     default:
       complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'",
                 dwarf_tag_name (die->tag));
       break;
     }
+
+  processing_current_prefix = old_prefix;
+  do_cleanups (back_to);
+}
+
+/* Return the name of the namespace/class that DIE is defined within,
+   or "" if we can't tell.  The caller should xfree the result.  */
+
+/* NOTE: carlton/2004-01-23: See read_func_scope (and the comment
+   therein) for an example of how to use this function to deal with
+   DW_AT_specification.  */
+
+static char *
+determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  char *prefix = determine_prefix_aux (die, cu);
+
+  return prefix ? prefix : xstrdup ("");
+}
+
+/* Return the name of the namespace/class that DIE is defined
+   within, or NULL if we can't tell.  The caller should xfree the
+   result.  */
+
+static char *
+determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *parent;
+
+  if (cu->language != language_cplus)
+    return NULL;
+
+  parent = die->parent;
+
+  if (parent == NULL)
+    {
+      return (processing_has_namespace_info ? xstrdup ("") : NULL);
+    }
+  else
+    {
+      char *parent_prefix = determine_prefix_aux (parent, cu);
+      char *retval;
+
+      switch (parent->tag) {
+      case DW_TAG_namespace:
+       {
+         int dummy;
+
+         retval = typename_concat (parent_prefix,
+                                   namespace_name (parent, &dummy, cu));
+       }
+       break;
+      case DW_TAG_class_type:
+      case DW_TAG_structure_type:
+       {
+         if (parent_prefix != NULL)
+           {
+             const char *parent_name = dwarf2_name (parent, cu);
+
+             if (parent_name != NULL)
+               retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
+             else
+               /* FIXME: carlton/2003-11-10: I'm not sure what the
+                  best thing to do here is.  */
+               retval = typename_concat (parent_prefix,
+                                         "<<anonymous class>>");
+           }
+         else
+           retval = class_name (parent, cu);
+       }
+       break;
+      default:
+       retval = parent_prefix;
+       break;
+      }
+
+      if (retval != parent_prefix)
+       xfree (parent_prefix);
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string formed by concatenating PREFIX,
+   "::", and SUFFIX, except that if PREFIX is NULL or the empty
+   string, just return a copy of SUFFIX.  */
+
+static char *
+typename_concat (const char *prefix, const char *suffix)
+{
+  if (prefix == NULL || prefix[0] == '\0')
+    return xstrdup (suffix);
+  else
+    {
+      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+
+      strcpy (retval, prefix);
+      strcat (retval, "::");
+      strcat (retval, suffix);
+
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string giving the name of the class given
+   by DIE.  */
+
+static char *
+class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *child;
+  const char *name;
+
+  for (child = die->child; child != NULL; child = sibling_die (child))
+    {
+      if (child->tag == DW_TAG_subprogram)
+       return class_name_from_physname (dwarf2_linkage_name (child, cu));
+    }
+
+  name = dwarf2_name (die, cu);
+  if (name != NULL)
+    return xstrdup (name);
+  else
+    return xstrdup ("");
 }
 
 static struct type *
 }
 
 static struct type *
-dwarf_base_type (int encoding, int size, struct objfile *objfile)
+dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+
   /* FIXME - this should not produce a new (struct type *)
      every time.  It should cache base types.  */
   struct type *type;
   switch (encoding)
     {
     case DW_ATE_address:
   /* FIXME - this should not produce a new (struct type *)
      every time.  It should cache base types.  */
   struct type *type;
   switch (encoding)
     {
     case DW_ATE_address:
-      type = dwarf2_fundamental_type (objfile, FT_VOID);
+      type = dwarf2_fundamental_type (objfile, FT_VOID, cu);
       return type;
     case DW_ATE_boolean:
       return type;
     case DW_ATE_boolean:
-      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu);
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu);
        }
       else
        {
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu);
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
        }
       else
        {
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
          break;
        case 2:
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu);
          break;
        default:
        case 4:
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_signed_char:
          break;
        }
       return type;
     case DW_ATE_signed_char:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
          break;
        case 2:
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu);
          break;
        default:
        case 4:
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
-      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
       return type;
     default:
       return type;
     default:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
       return type;
     }
 }
       return type;
     }
 }
@@ -5816,56 +6294,20 @@ copy_die (struct die_info *old_die)
 static struct die_info *
 sibling_die (struct die_info *die)
 {
 static struct die_info *
 sibling_die (struct die_info *die)
 {
-  int nesting_level = 0;
-
-  if (!die->has_children)
-    {
-      if (die->next && (die->next->tag == 0))
-       {
-         return NULL;
-       }
-      else
-       {
-         return die->next;
-       }
-    }
-  else
-    {
-      do
-       {
-         if (die->has_children)
-           {
-             nesting_level++;
-           }
-         if (die->tag == 0)
-           {
-             nesting_level--;
-           }
-         die = die->next;
-       }
-      while (nesting_level);
-      if (die && (die->tag == 0))
-       {
-         return NULL;
-       }
-      else
-       {
-         return die;
-       }
-    }
+  return die->sibling;
 }
 
 /* Get linkage name of a die, return NULL if not found.  */
 
 static char *
 }
 
 /* Get linkage name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_linkage_name (struct die_info *die)
+dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -5874,11 +6316,11 @@ dwarf2_linkage_name (struct die_info *die)
 /* Get name of a die, return NULL if not found.  */
 
 static char *
 /* Get name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_name (struct die_info *die)
+dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -5888,17 +6330,17 @@ dwarf2_name (struct die_info *die)
    is none.  */
 
 static struct die_info *
    is none.  */
 
 static struct die_info *
-dwarf2_extension (struct die_info *die)
+dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
 
 {
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
 
-  attr = dwarf_attr (die, DW_AT_extension);
+  attr = dwarf2_attr (die, DW_AT_extension, cu);
   if (attr == NULL)
     return NULL;
 
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr);
+  ref = dwarf2_get_ref_die_offset (attr, cu);
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
@@ -6721,7 +7163,7 @@ dump_die (struct die_info *die)
   fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
           dwarf_tag_name (die->tag), die->abbrev, die->offset);
   fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
   fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
           dwarf_tag_name (die->tag), die->abbrev, die->offset);
   fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
-          dwarf_bool_name (die->has_children));
+          dwarf_bool_name (die->child != NULL));
 
   fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
   for (i = 0; i < die->num_attrs; ++i)
 
   fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
   for (i = 0; i < die->num_attrs; ++i)
@@ -6784,7 +7226,10 @@ dump_die_list (struct die_info *die)
   while (die)
     {
       dump_die (die);
   while (die)
     {
       dump_die (die);
-      die = die->next;
+      if (die->child != NULL)
+       dump_die_list (die->child);
+      if (die->sibling != NULL)
+       dump_die_list (die->sibling);
     }
 }
 
     }
 }
 
@@ -6808,7 +7253,7 @@ dwarf2_empty_hash_tables (void)
 }
 
 static unsigned int
 }
 
 static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
 {
   unsigned int result = 0;
 
 {
   unsigned int result = 0;
 
@@ -6822,7 +7267,7 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      result = cu_header_offset + DW_UNSND (attr);
+      result = cu->header.offset + DW_UNSND (attr);
       break;
     default:
       complaint (&symfile_complaints,
       break;
     default:
       complaint (&symfile_complaints,
@@ -6832,6 +7277,28 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
   return result;
 }
 
   return result;
 }
 
+/* Return the constant value held by the given attribute.  Return -1
+   if the value held by the attribute is not constant.  */
+
+static int
+dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+{
+  if (attr->form == DW_FORM_sdata)
+    return DW_SND (attr);
+  else if (attr->form == DW_FORM_udata
+           || attr->form == DW_FORM_data1
+           || attr->form == DW_FORM_data2
+           || attr->form == DW_FORM_data4
+           || attr->form == DW_FORM_data8)
+    return DW_UNSND (attr);
+  else
+    {
+      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+                 dwarf_form_name (attr->form));
+      return default_value;
+    }
+}
+
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
@@ -6852,7 +7319,8 @@ follow_die_ref (unsigned int offset)
 }
 
 static struct type *
 }
 
 static struct type *
-dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+dwarf2_fundamental_type (struct objfile *objfile, int typeid,
+                        struct dwarf2_cu *cu)
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
@@ -6864,46 +7332,44 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid)
      one is not found, create and install one appropriate for the
      current language and the current target machine. */
 
      one is not found, create and install one appropriate for the
      current language and the current target machine. */
 
-  if (ftypes[typeid] == NULL)
+  if (cu->ftypes[typeid] == NULL)
     {
     {
-      ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+      cu->ftypes[typeid] = cu->language_defn->la_fund_type (objfile, typeid);
     }
 
     }
 
-  return (ftypes[typeid]);
+  return (cu->ftypes[typeid]);
 }
 
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
    the location and return the value.
 
 }
 
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
    the location and return the value.
 
-   FIXME: This is a kludge until we figure out a better
-   way to handle the location descriptions.
-   Gdb's design does not mesh well with the DWARF2 notion of a location
-   computing interpreter, which is a shame because the flexibility goes unused.
-   FIXME: Implement more operations as necessary.
+   NOTE drow/2003-11-18: This function is called in two situations
+   now: for the address of static or global variables (partial symbols
+   only) and for offsets into structures which are expected to be
+   (more or less) constant.  The partial symbol case should go away,
+   and only the constant case should remain.  That will let this
+   function complain more accurately.  A few special modes are allowed
+   without complaint for global variables (for instance, global
+   register values and thread-local values).
 
    A location description containing no operations indicates that the
 
    A location description containing no operations indicates that the
-   object is optimized out. The global optimized_out flag is set for
-   those, the return value is meaningless.
+   object is optimized out.  The return value is 0 for that case.
+   FIXME drow/2003-11-16: No callers check for this case any more; soon all
+   callers will only want a very basic result and this can become a
+   complaint.
 
    When the result is a register number, the global isreg flag is set,
    otherwise it is cleared.
 
 
    When the result is a register number, the global isreg flag is set,
    otherwise it is cleared.
 
-   When the result is a base register offset, the global offreg flag is set
-   and the register number is returned in basereg, otherwise it is cleared.
-
-   When the DW_OP_fbreg operation is encountered without a corresponding
-   DW_AT_frame_base attribute, the global islocal flag is set.
-   Hopefully the machine dependent code knows how to set up a virtual
-   frame pointer for the local references.
-
    Note that stack[0] is unused except as a default error return.
    Note that stack overflow is not yet handled.  */
 
 static CORE_ADDR
    Note that stack[0] is unused except as a default error return.
    Note that stack overflow is not yet handled.  */
 
 static CORE_ADDR
-decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
-               const struct comp_unit_head *cu_header)
+decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
 {
 {
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
   int i;
   int size = blk->size;
   char *data = blk->data;
   int i;
   int size = blk->size;
   char *data = blk->data;
@@ -6916,14 +7382,9 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
   stacki = 0;
   stack[stacki] = 0;
   isreg = 0;
   stacki = 0;
   stack[stacki] = 0;
   isreg = 0;
-  offreg = 0;
-  isderef = 0;
-  islocal = 0;
-  optimized_out = 1;
 
   while (i < size)
     {
 
   while (i < size)
     {
-      optimized_out = 0;
       op = data[i++];
       switch (op)
        {
       op = data[i++];
       switch (op)
        {
@@ -6996,6 +7457,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
        case DW_OP_reg31:
          isreg = 1;
          stack[++stacki] = op - DW_OP_reg0;
        case DW_OP_reg31:
          isreg = 1;
          stack[++stacki] = op - DW_OP_reg0;
+         if (i < size)
+           dwarf2_complex_location_expr_complaint ();
          break;
 
        case DW_OP_regx:
          break;
 
        case DW_OP_regx:
@@ -7003,74 +7466,13 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
          unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
          i += bytes_read;
          stack[++stacki] = unsnd;
          unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
          i += bytes_read;
          stack[++stacki] = unsnd;
-         break;
-
-       case DW_OP_breg0:
-       case DW_OP_breg1:
-       case DW_OP_breg2:
-       case DW_OP_breg3:
-       case DW_OP_breg4:
-       case DW_OP_breg5:
-       case DW_OP_breg6:
-       case DW_OP_breg7:
-       case DW_OP_breg8:
-       case DW_OP_breg9:
-       case DW_OP_breg10:
-       case DW_OP_breg11:
-       case DW_OP_breg12:
-       case DW_OP_breg13:
-       case DW_OP_breg14:
-       case DW_OP_breg15:
-       case DW_OP_breg16:
-       case DW_OP_breg17:
-       case DW_OP_breg18:
-       case DW_OP_breg19:
-       case DW_OP_breg20:
-       case DW_OP_breg21:
-       case DW_OP_breg22:
-       case DW_OP_breg23:
-       case DW_OP_breg24:
-       case DW_OP_breg25:
-       case DW_OP_breg26:
-       case DW_OP_breg27:
-       case DW_OP_breg28:
-       case DW_OP_breg29:
-       case DW_OP_breg30:
-       case DW_OP_breg31:
-         offreg = 1;
-         basereg = op - DW_OP_breg0;
-         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
-         i += bytes_read;
-         break;
-
-       case DW_OP_bregx:
-         offreg = 1;
-         basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
-         i += bytes_read;
-         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
-         i += bytes_read;
-         break;
-
-       case DW_OP_fbreg:
-         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
-         i += bytes_read;
-         if (frame_base_reg >= 0)
-           {
-             offreg = 1;
-             basereg = frame_base_reg;
-             stack[stacki] += frame_base_offset;
-           }
-         else
-           {
-             complaint (&symfile_complaints,
-                        "DW_AT_frame_base missing for DW_OP_fbreg");
-             islocal = 1;
-           }
+         if (i < size)
+           dwarf2_complex_location_expr_complaint ();
          break;
 
        case DW_OP_addr:
          stack[++stacki] = read_address (objfile->obfd, &data[i],
          break;
 
        case DW_OP_addr:
          stack[++stacki] = read_address (objfile->obfd, &data[i],
-                                         cu_header, &bytes_read);
+                                         cu, &bytes_read);
          i += bytes_read;
          break;
 
          i += bytes_read;
          break;
 
@@ -7136,9 +7538,10 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
          break;
 
        case DW_OP_deref:
          break;
 
        case DW_OP_deref:
-         isderef = 1;
          /* If we're not the last op, then we definitely can't encode
          /* If we're not the last op, then we definitely can't encode
-            this using GDB's address_class enum.  */
+            this using GDB's address_class enum.  This is valid for partial
+            global symbols, although the variable's address will be bogus
+            in the psymtab.  */
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
          break;
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
          break;
@@ -7148,6 +7551,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
             of the thread control block at which the variable is located.  */
          /* Nothing should follow this operator, so the top of stack would
             be returned.  */
             of the thread control block at which the variable is located.  */
          /* Nothing should follow this operator, so the top of stack would
             be returned.  */
+         /* This is valid for partial global symbols, but the variable's
+            address will be bogus in the psymtab.  */
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
           break;
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
           break;
@@ -7252,7 +7657,7 @@ macro_start_file (int file, int line,
   /* We don't create a macro table for this compilation unit
      at all until we actually get a filename.  */
   if (! pending_macros)
   /* We don't create a macro table for this compilation unit
      at all until we actually get a filename.  */
   if (! pending_macros)
-    pending_macros = new_macro_table (&objfile->symbol_obstack,
+    pending_macros = new_macro_table (&objfile->objfile_obstack,
                                       objfile->macro_cache);
 
   if (! current_file)
                                       objfile->macro_cache);
 
   if (! current_file)
@@ -7442,8 +7847,7 @@ parse_macro_definition (struct macro_source_file *file, int line,
 static void
 dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                      char *comp_dir, bfd *abfd,
 static void
 dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                      char *comp_dir, bfd *abfd,
-                     const struct comp_unit_head *cu_header,
-                     struct objfile *objfile)
+                     struct dwarf2_cu *cu)
 {
   char *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
 {
   char *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
@@ -7519,7 +7923,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
             current_file = macro_start_file (file, line,
                                              current_file, comp_dir,
 
             current_file = macro_start_file (file, line,
                                              current_file, comp_dir,
-                                             lh, objfile);
+                                             lh, cu->objfile);
           }
           break;
 
           }
           break;
 
@@ -7590,36 +7994,35 @@ attr_form_is_block (struct attribute *attr)
 
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
-                            const struct comp_unit_head *cu_header,
-                            struct objfile *objfile)
+                            struct dwarf2_cu *cu)
 {
   if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
     {
       struct dwarf2_loclist_baton *baton;
 
 {
   if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
     {
       struct dwarf2_loclist_baton *baton;
 
-      baton = obstack_alloc (&objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_loclist_baton));
                             sizeof (struct dwarf2_loclist_baton));
-      baton->objfile = objfile;
+      baton->objfile = cu->objfile;
 
       /* We don't know how long the location list is, but make sure we
         don't run off the edge of the section.  */
       baton->size = dwarf_loc_size - DW_UNSND (attr);
       baton->data = dwarf_loc_buffer + DW_UNSND (attr);
 
       /* We don't know how long the location list is, but make sure we
         don't run off the edge of the section.  */
       baton->size = dwarf_loc_size - DW_UNSND (attr);
       baton->data = dwarf_loc_buffer + DW_UNSND (attr);
-      baton->base_address = cu_header->base_address;
-      if (cu_header->base_known == 0)
+      baton->base_address = cu->header.base_address;
+      if (cu->header.base_known == 0)
        complaint (&symfile_complaints,
                   "Location list used without specifying the CU base address.");
 
        complaint (&symfile_complaints,
                   "Location list used without specifying the CU base address.");
 
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
     {
       struct dwarf2_locexpr_baton *baton;
 
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
     {
       struct dwarf2_locexpr_baton *baton;
 
-      baton = obstack_alloc (&objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
                             sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = objfile;
+      baton->objfile = cu->objfile;
 
       if (attr_form_is_block (attr))
        {
 
       if (attr_form_is_block (attr))
        {
@@ -7639,7 +8042,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
          baton->data = NULL;
        }
       
          baton->data = NULL;
        }
       
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
This page took 0.093663 seconds and 4 git commands to generate.