2003-11-23 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index a8c3ca3f048f8ab4ff4d2e3b09e2785bca98c203..53dd02f6c187d6a1633f4b5f129f1e4d717510ab 100644 (file)
@@ -230,6 +230,20 @@ struct comp_unit_head
     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;
+};
+
 /* 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 +329,21 @@ struct attr_abbrev
 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 */
-    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 */
   };
 
@@ -421,31 +443,9 @@ static struct pending **list_in_scope = &file_symbols;
    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 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,
@@ -670,12 +670,28 @@ static void dwarf2_build_psymtabs_easy (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);
 
-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);
+
+static char *add_partial_namespace (struct partial_die_info *pdi,
+                                   char *info_ptr,
+                                   CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                                   struct dwarf2_cu *cu,
+                                   const char *namespace);
+
+static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
+                                     char *info_ptr,
+                                     struct dwarf2_cu *cu,
+                                     const char *namespace);
+
+static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
+                                char *info_ptr,
+                                bfd *abfd,
+                                struct dwarf2_cu *cu);
 
 static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
@@ -684,25 +700,24 @@ static void psymtab_to_symtab_1 (struct partial_symtab *);
 char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int,
                           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,
-                                         const struct comp_unit_head *cu_header);
+                                                struct dwarf2_cu *);
 
 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 *,
-                           const struct comp_unit_head *);
+                           struct dwarf2_cu *, int *);
 
 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,
-                            bfd *, char *, const struct comp_unit_head *);
+                            bfd *, char *, struct dwarf2_cu *);
 
 static unsigned int read_1_byte (bfd *, char *);
 
@@ -714,7 +729,7 @@ static unsigned int read_4_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 *,
@@ -744,121 +759,108 @@ 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 *,
-                               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 *,
-                                 struct objfile *, const struct comp_unit_head *);
+                                 struct dwarf2_cu *);
 
 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 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
 
-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 objfile *,
-                          const struct comp_unit_head *);
+static void read_type_die (struct die_info *, struct dwarf2_cu *);
 
-static void read_typedef (struct die_info *, struct objfile *,
-                         const struct comp_unit_head *);
+static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
-static void read_base_type (struct die_info *, struct objfile *);
+static void read_base_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_file_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 objfile *,
-                            const struct comp_unit_head *);
+static void read_func_scope (struct die_info *, struct dwarf2_cu *);
 
-static void read_lexical_block_scope (struct die_info *, struct objfile *,
-                                     const struct comp_unit_head *);
+static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 
 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 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 *,
-                                         struct type *, struct objfile *);
+                                         struct type *, struct dwarf2_cu *);
 
 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 *,
-                                            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 void read_enumeration (struct die_info *, struct dwarf2_cu *);
 
-static void read_enumeration (struct die_info *, struct objfile *,
-                             const struct comp_unit_head *);
+static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
 
-static struct type *dwarf_base_type (int, int, struct objfile *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
 
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
-                                const struct comp_unit_head *);
+static void read_array_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_array_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_pointer_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_ptr_to_member_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_reference_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_const_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_volatile_type (struct die_info *, struct objfile *,
-                                   const struct comp_unit_head *);
+static void read_tag_string_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_tag_string_type (struct die_info *, struct objfile *);
+static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_subroutine_type (struct die_info *, struct objfile *,
-                                 const struct comp_unit_head *);
+static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);
 
-static struct die_info *read_comp_unit (char *, bfd *,
-                                        const struct comp_unit_head *);
+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 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 *);
 
@@ -915,15 +917,13 @@ static void initialize_cu_func_list (void);
 static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
 
 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,
-                            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.  */
@@ -959,61 +959,61 @@ dwarf2_has_info (bfd *abfd)
 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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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;
     }
-  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)
@@ -1023,7 +1023,7 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
           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);
@@ -1245,44 +1245,46 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
      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;
-      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;
        }
-      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]",
-                (long) cu_header.abbrev_offset,
+                (long) cu.header.abbrev_offset,
                 (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]",
-                (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 */
-      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;
 
       /* 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,
-                                  &cu_header);
+                                  &cu);
 
       /* Set the language we're debugging */
       set_cu_language (comp_unit_die.language);
@@ -1321,9 +1323,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          If not, there's no more debug_info for this comp unit. */
       if (comp_unit_die.has_children)
        {
-         info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
-                                          &cu_header);
+         lowpc = ((CORE_ADDR) -1);
+         highpc = ((CORE_ADDR) 0);
 
+         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 (lowpc == ((CORE_ADDR) -1))
+           lowpc = highpc;
+         
          /* If the compilation unit didn't have an explicit address range,
             then use the information extracted from its child dies.  */
          if (! comp_unit_die.has_pc_info)
@@ -1346,51 +1356,46 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          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);
 }
 
-/* Read in all interesting dies to the end of the compilation unit.  */
+/* Read in all interesting dies to the end of the compilation unit or
+   to the end of the current namespace.  NAMESPACE is NULL if we
+   haven't yet encountered any DW_TAG_namespace entries; otherwise,
+   it's the name of the current namespace.  In particular, it's the
+   empty string if we're currently in the global namespace but have
+   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)
 {
+  struct objfile *objfile = cu->objfile;
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
 
-  /* This function is called after we've read in the comp_unit_die in
-     order to read its children.  We start the nesting level at 1 since
-     we have pushed 1 level down in order to read the comp unit's children.
-     The comp unit itself is at level 0, so we stop reading when we pop
-     back to that level. */
-
-  int nesting_level = 1;
-
-  /* We only want to read in symbols corresponding to variables or
-     other similar objects that are global or static.  Normally, these
-     are all children of the DW_TAG_compile_unit die, so are all at
-     level 1.  But C++ namespaces give ries to DW_TAG_namespace dies
-     whose children are global objects.  So we keep track of what
-     level we currently think of as referring to file scope; this
-     should always equal 1 plus the number of namespaces that we are
-     currently nested within.  */
-  
-  int file_scope_level = 1;
-
-  *lowpc = ((CORE_ADDR) -1);
-  *highpc = ((CORE_ADDR) 0);
+  /* Now, march along the PDI's, descending into ones which have
+     interesting children but skipping the children of the other ones,
+     until we reach the end of the compilation unit.  */
 
-  while (nesting_level)
+  while (1)
     {
-      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
+      /* This flag tells whether or not info_ptr has gotten updated
+        inside the loop.  */
+      int info_ptr_updated = 0;
 
-      /* Anonymous namespaces have no name but are interesting.  */
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
 
-      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace)
+      /* Anonymous namespaces have no name but have interesting
+        children, so we need to look at them.  Ditto for anonymous
+        enums.  */
+
+      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace
+         || pdi.tag == DW_TAG_enumeration_type)
        {
          switch (pdi.tag)
            {
@@ -1405,93 +1410,75 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
                    {
                      *highpc = pdi.highpc;
                    }
-                 if ((pdi.is_external || nesting_level == file_scope_level)
-                     && !pdi.is_declaration)
+                 if (!pdi.is_declaration)
                    {
-                     add_partial_symbol (&pdi, objfile, cu_header);
+                     add_partial_symbol (&pdi, cu, namespace);
                    }
                }
              break;
            case DW_TAG_variable:
            case DW_TAG_typedef:
+           case DW_TAG_union_type:
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
-           case DW_TAG_union_type:
-           case DW_TAG_enumeration_type:
-             if ((pdi.is_external || nesting_level == file_scope_level)
-                 && !pdi.is_declaration)
+             if (!pdi.is_declaration)
                {
-                 add_partial_symbol (&pdi, objfile, cu_header);
+                 add_partial_symbol (&pdi, cu, namespace);
                }
              break;
-           case DW_TAG_enumerator:
-             /* File scope enumerators are added to the partial
-                symbol table.  They're children of the enumeration
-                type die, so they occur at a level one higher than we
-                normally look for.  */
-             if (nesting_level == file_scope_level + 1)
-               add_partial_symbol (&pdi, objfile, cu_header);
+           case DW_TAG_enumeration_type:
+             if (!pdi.is_declaration)
+               {
+                 info_ptr = add_partial_enumeration (&pdi, info_ptr, cu,
+                                                     namespace);
+                 info_ptr_updated = 1;
+               }
              break;
            case DW_TAG_base_type:
              /* File scope base type definitions are added to the partial
                 symbol table.  */
-             if (nesting_level == file_scope_level)
-               add_partial_symbol (&pdi, objfile, cu_header);
+             add_partial_symbol (&pdi, cu, namespace);
              break;
            case DW_TAG_namespace:
-             /* FIXME: carlton/2002-10-16: we're not yet doing
-                anything useful with this, but for now make sure that
-                these tags at least don't cause us to miss any
-                important symbols.  */
-             if (pdi.has_children)
-               file_scope_level++;
+             /* We've hit a DW_TAG_namespace entry, so we know this
+                file has been compiled using a compiler that
+                generates them; update NAMESPACE to reflect that.  */
+             if (namespace == NULL)
+               namespace = "";
+             info_ptr = add_partial_namespace (&pdi, info_ptr, lowpc, highpc,
+                                               cu, namespace);
+             info_ptr_updated = 1;
+             break;
            default:
              break;
            }
        }
 
-      /* If the die has a sibling, skip to the sibling.  Do not skip
-         enumeration types, we want to record their enumerators.  Do
-         not skip namespaces, we want to record symbols inside
-         them.  */
-      if (pdi.sibling
-         && pdi.tag != DW_TAG_enumeration_type
-         && pdi.tag != DW_TAG_namespace)
-       {
-         info_ptr = pdi.sibling;
-       }
-      else if (pdi.has_children)
-       {
-         /* Die has children, but either the optional DW_AT_sibling
-            attribute is missing or we want to look at them.  */
-         nesting_level++;
-       }
-
       if (pdi.tag == 0)
-       {
-         nesting_level--;
-         /* If this is the end of a DW_TAG_namespace entry, then
-            decrease the file_scope_level, too.  */
-         if (nesting_level < file_scope_level)
-           {
-             file_scope_level--;
-             gdb_assert (nesting_level == file_scope_level);
-           }
-       }
+       break;
+
+      /* If the die has a sibling, skip to the sibling, unless another
+        function has already updated info_ptr for us.  */
+
+      /* NOTE: carlton/2003-06-16: This is a bit hackish, but whether
+        or not we want to update this depends on enough stuff (not
+        only pdi.tag but also whether or not pdi.name is NULL) that
+        this seems like the easiest way to handle the issue.  */
+
+      if (!info_ptr_updated)
+       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
     }
 
-  /* If we didn't find a lowpc, set it to highpc to avoid complaints
-     from `maint check'.  */
-  if (*lowpc == ((CORE_ADDR) -1))
-    *lowpc = *highpc;
   return info_ptr;
 }
 
 static void
-add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
-                   const struct comp_unit_head *cu_header)
+add_partial_symbol (struct partial_die_info *pdi,
+                   struct dwarf2_cu *cu, const char *namespace)
 {
+  struct objfile *objfile = cu->objfile;
   CORE_ADDR addr = 0;
+  const struct partial_symbol *psym = NULL;
 
   switch (pdi->tag)
     {
@@ -1500,19 +1487,21 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
        {
          /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_DOMAIN, LOC_BLOCK,
-                              &objfile->global_psymbols,
-                           0, pdi->lowpc + baseaddr, cu_language, objfile);
+         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                     VAR_DOMAIN, LOC_BLOCK,
+                                     &objfile->global_psymbols,
+                                     0, pdi->lowpc + baseaddr,
+                                     cu_language, objfile);
        }
       else
        {
          /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
             mst_file_text, objfile); */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_DOMAIN, LOC_BLOCK,
-                              &objfile->static_psymbols,
-                           0, pdi->lowpc + baseaddr, cu_language, objfile);
+         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                     VAR_DOMAIN, LOC_BLOCK,
+                                     &objfile->static_psymbols,
+                                     0, pdi->lowpc + baseaddr,
+                                     cu_language, objfile);
        }
       break;
     case DW_TAG_variable:
@@ -1532,25 +1521,27 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
             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)
-           add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                                VAR_DOMAIN, LOC_STATIC,
-                                &objfile->global_psymbols,
-                                0, addr + baseaddr, cu_language, objfile);
+           psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                       VAR_DOMAIN, LOC_STATIC,
+                                       &objfile->global_psymbols,
+                                       0, addr + baseaddr,
+                                       cu_language, objfile);
        }
       else
        {
          /* Static Variable. Skip symbols without location descriptors.  */
          if (pdi->locdesc == NULL)
            return;
-         addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
+         addr = decode_locdesc (pdi->locdesc, cu);
          /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
             mst_file_data, objfile); */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_DOMAIN, LOC_STATIC,
-                              &objfile->static_psymbols,
-                              0, addr + baseaddr, cu_language, objfile);
+         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                     VAR_DOMAIN, LOC_STATIC,
+                                     &objfile->static_psymbols,
+                                     0, addr + baseaddr,
+                                     cu_language, objfile);
        }
       break;
     case DW_TAG_typedef:
@@ -1591,6 +1582,120 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
     default:
       break;
     }
+
+  /* Check to see if we should scan the name for possible namespace
+     info.  Only do this if this is C++, if we don't have namespace
+     debugging info in the file, if the psym is of an appropriate type
+     (otherwise we'll have psym == NULL), and if we actually had a
+     mangled name to begin with.  */
+
+  if (cu_language == language_cplus
+      && namespace == NULL
+      && psym != NULL
+      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
+    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
+                                        objfile);
+}
+
+/* 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,
+                      CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                      struct dwarf2_cu *cu, const char *namespace)
+{
+  struct objfile *objfile = cu->objfile;
+  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);
+  strcpy (full_name, namespace);
+  if (*namespace != '\0')
+    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.  */
+
+  add_psymbol_to_list (full_name, strlen (full_name),
+                      VAR_DOMAIN, LOC_TYPEDEF,
+                      &objfile->global_psymbols,
+                      0, 0, cu_language, objfile);
+
+  /* Now scan partial symbols in that namespace.  */
+
+  if (pdi->has_children)
+    info_ptr = scan_partial_symbols (info_ptr, lowpc, highpc, cu, full_name);
+
+  return 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 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)
+    add_partial_symbol (enum_pdi, cu, namespace);
+  
+  while (1)
+    {
+      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
+       add_partial_symbol (&pdi, cu, namespace);
+    }
+
+  return info_ptr;
+}
+
+/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE
+   after ORIG_PDI.  */
+
+static char *
+locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
+                   bfd *abfd, struct dwarf2_cu *cu)
+{
+  /* Do we know the sibling already?  */
+  
+  if (orig_pdi->sibling)
+    return orig_pdi->sibling;
+
+  /* Are there any children to deal with?  */
+
+  if (!orig_pdi->has_children)
+    return info_ptr;
+
+  /* Okay, we don't know the sibling, but we have children that we
+     want to skip.  So read children until we run into one without a
+     tag; return whatever follows it.  */
+
+  while (1)
+    {
+      struct partial_die_info pdi;
+      
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
+
+      if (pdi.tag == 0)
+       return info_ptr;
+      else
+       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
+    }
 }
 
 /* Expand this partial symbol table into a full symbol table.  */
@@ -1627,7 +1732,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
   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;
@@ -1662,14 +1767,16 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   buildsym_init ();
   make_cleanup (really_free_pendings, NULL);
 
+  cu.objfile = objfile;
+
   /* 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  */
-  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);
+  dies = read_comp_unit (info_ptr, abfd, &cu);
 
   make_cleanup_free_die_list (dies);
 
@@ -1679,45 +1786,44 @@ 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.  */
 
-  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);
   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
     {
       attr = dwarf_attr (dies, DW_AT_low_pc);
       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 () */
-  process_die (dies, objfile, &cu_header);
+  process_die (dies, &cu);
 
-  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header))
+  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, &cu))
     {
       /* 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)
+      if (dies->child != NULL)
        {
-         child_die = dies->next;
+         child_die = dies->child;
          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))
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, &cu))
                    {
                      highpc = max (highpc, high);
                    }
@@ -1745,19 +1851,18 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 /* 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:
-      read_file_scope (die, objfile, cu_header);
+      read_file_scope (die, cu);
       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.
@@ -1767,44 +1872,44 @@ process_die (struct die_info *die, struct objfile *objfile,
     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:
-      read_structure_scope (die, objfile, cu_header);
+      read_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration (die, objfile, cu_header);
+      read_enumeration (die, cu);
       break;
     case DW_TAG_subroutine_type:
-      read_subroutine_type (die, objfile, cu_header);
+      read_subroutine_type (die, cu);
       break;
     case DW_TAG_array_type:
-      read_array_type (die, objfile, cu_header);
+      read_array_type (die, cu);
       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:
-      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      read_tag_ptr_to_member_type (die, cu);
       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:
-      read_tag_string_type (die, objfile);
+      read_tag_string_type (die, cu);
       break;
     case DW_TAG_base_type:
-      read_base_type (die, objfile);
+      read_base_type (die, cu);
       if (dwarf_attr (die, DW_AT_name))
        {
          /* Add a typedef symbol for the base type definition.  */
-         new_symbol (die, die->type, objfile, cu_header);
+         new_symbol (die, die->type, cu);
        }
       break;
     case DW_TAG_common_block:
-      read_common_block (die, objfile, cu_header);
+      read_common_block (die, cu);
       break;
     case DW_TAG_common_inclusion:
       break;
@@ -1814,7 +1919,7 @@ process_die (struct die_info *die, struct objfile *objfile,
          processing_has_namespace_info = 1;
          processing_current_namespace = "";
        }
-      read_namespace (die, objfile, cu_header);
+      read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
@@ -1829,10 +1934,10 @@ process_die (struct die_info *die, struct objfile *objfile,
          processing_has_namespace_info = 1;
          processing_current_namespace = "";
        }
-      gdb_assert (!die->has_children);
+      gdb_assert (die->child == NULL);
       break;
     default:
-      new_symbol (die, NULL, objfile, cu_header);
+      new_symbol (die, NULL, cu);
       break;
     }
 }
@@ -1844,9 +1949,10 @@ initialize_cu_func_list (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);
@@ -1857,19 +1963,18 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   bfd *abfd = objfile->obfd;
   struct line_header *line_header = 0;
 
-  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile, cu_header))
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     {
-      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_subprogram)
                {
                  CORE_ADDR low, high;
 
-                 if (dwarf2_get_pc_bounds (child_die, &low, &high,
-                                           objfile, cu_header))
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, cu))
                    {
                      lowpc = min (lowpc, low);
                      highpc = max (highpc, high);
@@ -1910,8 +2015,8 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
     {
-      objfile->ei.entry_file_lowpc = lowpc;
-      objfile->ei.entry_file_highpc = highpc;
+      objfile->ei.deprecated_entry_file_lowpc = lowpc;
+      objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
   attr = dwarf_attr (die, DW_AT_language);
@@ -1940,12 +2045,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   initialize_cu_func_list ();
 
   /* 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)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
@@ -1955,13 +2060,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   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);
-          dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
+          dwarf_decode_lines (line_header, comp_dir, abfd, cu);
         }
     }
 
@@ -1974,7 +2078,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
     {
       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);
 }
@@ -2001,10 +2105,10 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
 }
 
 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)
 {
-  register struct context_stack *new;
+  struct objfile *objfile = cu->objfile;
+  struct context_stack *new;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
   struct die_info *child_die;
@@ -2015,7 +2119,7 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
 
   /* 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;
 
   lowpc += baseaddr;
@@ -2031,61 +2135,23 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
       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->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 = dwarf_attr (die, DW_AT_frame_base);
   if (attr)
-    dwarf2_symbol_mark_computed (attr, new->name, cu_header, objfile);
+    dwarf2_symbol_mark_computed (attr, new->name, cu);
 
   list_in_scope = &local_symbols;
 
-  if (die->has_children)
+  if (die->child != NULL)
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
@@ -2112,10 +2178,10 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
    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)
 {
-  register struct context_stack *new;
+  struct objfile *objfile = cu->objfile;
+  struct context_stack *new;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
 
@@ -2124,18 +2190,18 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile,
      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);
-  if (die->has_children)
+  if (die->child != NULL)
     {
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
@@ -2154,9 +2220,10 @@ 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,
-                     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;
@@ -2185,29 +2252,35 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
          unsigned int addr_size = cu_header->addr_size;
          CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
          /* Value of the DW_AT_ranges attribute is the offset in the
-            .debug_renges section.  */
+            .debug_ranges section.  */
          unsigned int offset = DW_UNSND (attr);
          /* Base address selection entry.  */
          CORE_ADDR base;
          int found_base;
          int dummy;
-         unsigned int i;
          char *buffer;
          CORE_ADDR marker;
          int low_set;
  
          found_base = cu_header->base_known;
          base = cu_header->base_address;
+
+         if (offset >= dwarf_ranges_size)
+           {
+             complaint (&symfile_complaints,
+                        "Offset %d out of bounds for DW_AT_ranges attribute",
+                        offset);
+             return 0;
+           }
          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.  */
-             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;
@@ -2219,10 +2292,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
            {
              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;
-             range_end = read_address (obfd, buffer, cu_header, &dummy);
+             range_end = read_address (obfd, buffer, cu, &dummy);
              buffer += addr_size;
              offset += 2 * addr_size;
 
@@ -2238,8 +2310,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                {
                  /* 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;
                }
@@ -2307,9 +2378,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 
 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;
@@ -2348,7 +2419,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       /* 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;
 
@@ -2368,7 +2439,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       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;
@@ -2454,7 +2525,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
       SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
                                             &objfile->type_obstack));
-      FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
+      FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
                                       &objfile->type_obstack);
     }
@@ -2463,11 +2534,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       /* C++ base class field.  */
       attr = dwarf_attr (die, DW_AT_data_member_location);
       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;
-      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++;
     }
@@ -2477,7 +2548,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,
-                             struct objfile *objfile)
+                             struct dwarf2_cu *cu)
 {
   int nfields = fip->nfields;
 
@@ -2564,9 +2635,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,
-                     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;
@@ -2588,7 +2659,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
     {
-      if (STREQ (fip->fnfieldlists[i].name, fieldname))
+      if (DEPRECATED_STREQ (fip->fnfieldlists[i].name, fieldname))
        break;
     }
 
@@ -2629,7 +2700,6 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   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
@@ -2655,7 +2725,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
   /* 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);
+    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.  */
@@ -2687,7 +2757,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
       /* 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)
         {
@@ -2705,7 +2775,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,
-                                struct objfile *objfile)
+                                struct dwarf2_cu *cu)
 {
   struct fnfieldlist *flp;
   int total_length = 0;
@@ -2752,9 +2822,9 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
    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;
 
@@ -2799,7 +2869,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
      type within the structure itself. */
   die->type = type;
 
-  if (die->has_children && ! die_is_declaration (die))
+  if (die->child != NULL && ! die_is_declaration (die))
     {
       struct field_info fi;
       struct die_info *child_die;
@@ -2807,7 +2877,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
 
       memset (&fi, 0, sizeof (struct field_info));
 
-      child_die = die->next;
+      child_die = die->child;
 
       while (child_die && child_die->tag)
        {
@@ -2819,32 +2889,32 @@ 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.  */
-             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. */
-             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);
            }
          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
            {
-             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)
-       dwarf2_attach_fields_to_type (&fi, type, objfile);
+       dwarf2_attach_fields_to_type (&fi, type, cu);
       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
@@ -2852,7 +2922,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
 
          if (dwarf_attr (die, DW_AT_containing_type) != 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)
@@ -2868,7 +2938,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
                    {
                      char *fieldname = TYPE_FIELD_NAME (t, i);
 
-                     if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+                     if (DEPRECATED_STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
                          && is_cplus_marker (fieldname[strlen (vptr_name)]))
                        {
                          TYPE_VPTR_FIELDNO (type) = i;
@@ -2890,7 +2960,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);
     }
@@ -2911,9 +2981,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
    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;
@@ -2945,21 +3015,21 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
 
   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)
            {
-             process_die (child_die, objfile, cu_header);
+             process_die (child_die, cu);
            }
          else
            {
              attr = dwarf_attr (child_die, DW_AT_name);
              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;
 
@@ -2997,7 +3067,7 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
        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
@@ -3005,9 +3075,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
    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;
@@ -3022,11 +3092,11 @@ read_array_type (struct die_info *die, struct objfile *objfile,
       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.  */
-  if (die->has_children == 0)
+  if (die->child == NULL)
     {
       index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
       range_type = create_range_type (NULL, index_type, 0, -1);
@@ -3035,7 +3105,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
     }
 
   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)
@@ -3051,7 +3121,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
              low = 1;
            }
 
-         index_type = die_type (child_die, objfile, cu_header);
+         index_type = die_type (child_die, cu);
          attr = dwarf_attr (child_die, DW_AT_lower_bound);
          if (attr)
            {
@@ -3100,8 +3170,14 @@ read_array_type (struct die_info *die, struct objfile *objfile,
                     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;
+                    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
                {
@@ -3155,8 +3231,7 @@ read_array_type (struct die_info *die, struct objfile *objfile,
 /* 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;
@@ -3169,7 +3244,7 @@ read_common_block (struct die_info *die, struct objfile *objfile,
       /* 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)
         {
@@ -3181,17 +3256,17 @@ read_common_block (struct die_info *die, struct objfile *objfile,
                                                 "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)
        {
-         sym = new_symbol (child_die, NULL, objfile, cu_header);
+         sym = new_symbol (child_die, NULL, cu);
          attr = dwarf_attr (child_die, DW_AT_data_member_location);
          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);
@@ -3202,9 +3277,9 @@ read_common_block (struct die_info *die, struct objfile *objfile,
 /* Read a C++ namespace.  */
 
 static void
-read_namespace (struct die_info *die, struct objfile *objfile,
-               const struct comp_unit_head *cu_header)
+read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct objfile *objfile = cu->objfile;
   const char *previous_namespace = processing_current_namespace;
   const char *name = NULL;
   int is_anonymous;
@@ -3246,21 +3321,36 @@ read_namespace (struct die_info *die, struct objfile *objfile,
       processing_current_namespace = temp_name;
     }
 
-  /* If it's an anonymous namespace that we're seeing for the first
-     time, add a using directive.  */
+  /* 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)
+    {
+      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,
+                       objfile);
+      TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
-  if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
-    cp_add_using_directive (processing_current_namespace,
-                           strlen (previous_namespace),
-                           strlen (processing_current_namespace));
+      new_symbol (die, type, cu);
 
-  if (die->has_children)
+      if (is_anonymous)
+       cp_add_using_directive (processing_current_namespace,
+                               strlen (previous_namespace),
+                               strlen (processing_current_namespace));
+    }
+
+  if (die->child != NULL)
     {
-      struct die_info *child_die = die->next;
+      struct die_info *child_die = die->child;
       
       while (child_die && child_die->tag)
        {
-         process_die (child_die, objfile, cu_header);
+         process_die (child_die, cu);
          child_die = sibling_die (child_die);
        }
     }
@@ -3272,9 +3362,9 @@ read_namespace (struct die_info *die, struct objfile *objfile,
    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;
@@ -3285,7 +3375,7 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
       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);
   if (attr_byte_size)
@@ -3329,9 +3419,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
    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;
@@ -3342,8 +3432,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *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;
@@ -3353,9 +3443,9 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile,
    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;
 
@@ -3364,7 +3454,7 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile,
       return;
     }
 
-  type = lookup_reference_type (die_type (die, objfile, cu_header));
+  type = lookup_reference_type (die_type (die, cu));
   attr = dwarf_attr (die, DW_AT_byte_size);
   if (attr)
     {
@@ -3378,8 +3468,7 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile,
 }
 
 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;
 
@@ -3388,13 +3477,12 @@ read_tag_const_type (struct die_info *die, struct objfile *objfile,
       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
-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;
 
@@ -3403,7 +3491,7 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
       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);
 }
 
@@ -3413,8 +3501,9 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile,
    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;
@@ -3470,8 +3559,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
  */
 
 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 */
@@ -3482,7 +3570,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
     {
       return;
     }
-  type = die_type (die, objfile, cu_header);
+  type = die_type (die, cu);
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
@@ -3491,7 +3579,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
       || cu_language == language_cplus)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
-  if (die->has_children)
+  if (die->child != NULL)
     {
       struct die_info *child_die;
       int nparams = 0;
@@ -3500,7 +3588,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.  */
-      child_die = die->next;
+      child_die = die->child;
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
@@ -3515,7 +3603,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
       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)
@@ -3530,8 +3618,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
                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);
@@ -3542,9 +3629,9 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile,
 }
 
 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;
 
@@ -3556,7 +3643,7 @@ read_typedef (struct die_info *die, struct objfile *objfile,
          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);
     }
 }
 
@@ -3564,8 +3651,9 @@ read_typedef (struct die_info *die, struct objfile *objfile,
    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;
@@ -3639,7 +3727,7 @@ read_base_type (struct die_info *die, struct objfile *objfile)
     }
   else
     {
-      type = dwarf_base_type (encoding, size, objfile);
+      type = dwarf_base_type (encoding, size, cu);
     }
   die->type = type;
 }
@@ -3647,49 +3735,90 @@ read_base_type (struct die_info *die, struct objfile *objfile)
 /* 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 ();
 
+  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;
-  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
        {
-         last_die->next = die;
-         last_die = die;
+         last_sibling = die;
        }
     }
-  while (nesting_level > 0);
-  return first_die;
 }
 
 /* Free a linked list of dies.  */
@@ -3702,7 +3831,9 @@ free_die_list (struct die_info *dies)
   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;
@@ -3757,8 +3888,9 @@ dwarf2_read_section (struct objfile *objfile, file_ptr offset,
    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;
@@ -3822,14 +3954,13 @@ 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;
-      if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL)
+      if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
        break;
     }
 }
 
 /* Empty the abbrev table for a new compilation unit.  */
 
-/* ARGSUSED */
 static void
 dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
 {
@@ -3857,8 +3988,9 @@ dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
 /* 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;
 
@@ -3879,7 +4011,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,
-                 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;
@@ -3895,7 +4027,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
   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,
@@ -3908,8 +4040,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
 
   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.  */
@@ -3986,10 +4117,9 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
     {
       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);
+      read_partial_die (&spec_die, abfd, spec_ptr, cu);
       if (spec_die.name)
        {
          part_die->name = spec_die.name;
@@ -4016,12 +4146,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
   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,
-              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;
@@ -4037,19 +4169,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
       die->abbrev = abbrev_number;
       die->type = NULL;
       *diep = die;
+      *has_children = 0;
       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, 
-                     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->has_children = abbrev->has_children;
   die->abbrev = abbrev_number;
   die->type = NULL;
 
@@ -4060,10 +4193,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],
-                                abfd, info_ptr, cu_header);
+                                abfd, info_ptr, cu);
     }
 
   *diep = die;
+  *has_children = abbrev->has_children;
   return info_ptr;
 }
 
@@ -4071,9 +4205,10 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
 
 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;
 
@@ -4082,7 +4217,7 @@ read_attribute_value (struct attribute *attr, unsigned form,
     {
     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:
@@ -4177,7 +4312,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;
-      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]",
@@ -4191,11 +4326,10 @@ read_attribute_value (struct attribute *attr, unsigned form,
 
 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;
-  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 */
@@ -4243,9 +4377,9 @@ read_8_bytes (bfd *abfd, char *buf)
 }
 
 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)
@@ -4677,7 +4811,7 @@ add_file_name (struct line_header *lh,
    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;
@@ -4718,7 +4852,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->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;
@@ -4826,12 +4960,11 @@ check_cu_functions (CORE_ADDR address)
 
 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;
-  unsigned int i, bytes_read;
-  char *cur_dir;
+  unsigned int bytes_read;
   unsigned char op_code, extended_op, adj_opcode;
 
   line_ptr = lh->statement_program_start;
@@ -4894,7 +5027,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:
-                 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;
@@ -5038,9 +5171,11 @@ dwarf2_start_subfile (char *filename, char *dirname)
 
 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
@@ -5071,8 +5206,7 @@ var_decode_location (struct attribute *attr, struct symbol *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));
@@ -5087,7 +5221,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.  */
 
-  dwarf2_symbol_mark_computed (attr, sym, cu_header, objfile);
+  dwarf2_symbol_mark_computed (attr, sym, cu);
   SYMBOL_CLASS (sym) = LOC_COMPUTED;
 }
 
@@ -5098,16 +5232,19 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
    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;
-  CORE_ADDR addr = 0;
 
-  name = dwarf2_linkage_name (die);
+  if (die->tag != DW_TAG_namespace)
+    name = dwarf2_linkage_name (die);
+  else
+    name = TYPE_NAME (type);
+
   if (name)
     {
       sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
@@ -5126,7 +5263,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
       if (type != NULL)
        SYMBOL_TYPE (sym) = type;
       else
-       SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
+       SYMBOL_TYPE (sym) = die_type (die, cu);
       attr = dwarf_attr (die, DW_AT_decl_line);
       if (attr)
        {
@@ -5168,7 +5305,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_const_value);
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
+             dwarf2_const_value (attr, sym, cu);
              attr2 = dwarf_attr (die, DW_AT_external);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
@@ -5179,7 +5316,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_location);
          if (attr)
            {
-             var_decode_location (attr, sym, objfile, cu_header);
+             var_decode_location (attr, sym, cu);
              attr2 = dwarf_attr (die, DW_AT_external);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
@@ -5207,7 +5344,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_location);
          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;
@@ -5215,7 +5352,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_const_value);
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
+             dwarf2_const_value (attr, sym, cu);
            }
          add_symbol_to_list (sym, list_in_scope);
          break;
@@ -5260,10 +5397,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_const_value);
          if (attr)
            {
-             dwarf2_const_value (attr, sym, objfile, cu_header);
+             dwarf2_const_value (attr, sym, cu);
            }
          add_symbol_to_list (sym, list_in_scope);
          break;
+       case DW_TAG_namespace:
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         add_symbol_to_list (sym, &global_symbols);
+         break;
        default:
          /* Not a tag we recognize.  Hopefully we aren't processing
             trash data, but since we must specifically ignore things
@@ -5281,9 +5422,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
 
 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)
@@ -5382,8 +5524,7 @@ dwarf2_const_value_data (struct attribute *attr,
 /* 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;
@@ -5394,7 +5535,7 @@ die_type (struct die_info *die, struct objfile *objfile,
   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);
     }
   else
     {
@@ -5403,16 +5544,16 @@ die_type (struct die_info *die, struct objfile *objfile,
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
-                         ref, objfile->name);
+                         ref, cu->objfile->name);
          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]",
-                     objfile->name);
+                     cu->objfile->name);
     }
   return type;
 }
@@ -5421,8 +5562,7 @@ die_type (struct die_info *die, struct objfile *objfile,
    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;
@@ -5437,24 +5577,24 @@ die_containing_type (struct die_info *die, struct objfile *objfile,
       if (!type_die)
        {
          error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
-                         objfile->name);
+                         cu->objfile->name);
          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]", 
-                     objfile->name);
+                     cu->objfile->name);
     }
   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;
@@ -5465,14 +5605,13 @@ type_at_offset (unsigned int offset, struct objfile *objfile)
       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 *
-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)
     {
@@ -5480,61 +5619,60 @@ tag_type_to_type (struct die_info *die, struct objfile *objfile,
     }
   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]", 
-                         objfile->name);
+                         cu->objfile->name);
        }
       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)
 {
   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:
-      read_enumeration (die, objfile, cu_header);
+      read_enumeration (die, cu);
       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:
-      read_array_type (die, objfile, cu_header);
+      read_array_type (die, cu);
       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:
-      read_tag_ptr_to_member_type (die, objfile, cu_header);
+      read_tag_ptr_to_member_type (die, cu);
       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:
-      read_tag_const_type (die, objfile, cu_header);
+      read_tag_const_type (die, cu);
       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:
-      read_tag_string_type (die, objfile);
+      read_tag_string_type (die, cu);
       break;
     case DW_TAG_typedef:
-      read_typedef (die, objfile, cu_header);
+      read_typedef (die, cu);
       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'",
@@ -5544,8 +5682,10 @@ read_type_die (struct die_info *die, struct objfile *objfile,
 }
 
 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;
@@ -5657,43 +5797,7 @@ copy_die (struct die_info *old_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.  */
@@ -5752,7 +5856,7 @@ dwarf2_extension (struct die_info *die)
 /* Convert a DIE tag into its string name.  */
 
 static char *
-dwarf_tag_name (register unsigned tag)
+dwarf_tag_name (unsigned tag)
 {
   switch (tag)
     {
@@ -5884,7 +5988,7 @@ dwarf_tag_name (register unsigned tag)
 /* Convert a DWARF attribute code into its string name.  */
 
 static char *
-dwarf_attr_name (register unsigned attr)
+dwarf_attr_name (unsigned attr)
 {
   switch (attr)
     {
@@ -6075,7 +6179,7 @@ dwarf_attr_name (register unsigned attr)
 /* Convert a DWARF value form code into its string name.  */
 
 static char *
-dwarf_form_name (register unsigned form)
+dwarf_form_name (unsigned form)
 {
   switch (form)
     {
@@ -6129,7 +6233,7 @@ dwarf_form_name (register unsigned form)
 /* Convert a DWARF stack opcode into its string name.  */
 
 static char *
-dwarf_stack_op_name (register unsigned op)
+dwarf_stack_op_name (unsigned op)
 {
   switch (op)
     {
@@ -6452,7 +6556,7 @@ dwarf_bool_name (unsigned mybool)
 /* Convert a DWARF type code into its string name.  */
 
 static char *
-dwarf_type_encoding_name (register unsigned enc)
+dwarf_type_encoding_name (unsigned enc)
 {
   switch (enc)
     {
@@ -6483,7 +6587,7 @@ dwarf_type_encoding_name (register unsigned enc)
 
 #if 0
 static char *
-dwarf_cfi_name (register unsigned cfi_opc)
+dwarf_cfi_name (unsigned cfi_opc)
 {
   switch (cfi_opc)
     {
@@ -6562,7 +6666,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",
-          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)
@@ -6625,7 +6729,10 @@ dump_die_list (struct die_info *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);
     }
 }
 
@@ -6717,34 +6824,32 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid)
    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
-   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 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
-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;
@@ -6757,14 +6862,9 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
   stacki = 0;
   stack[stacki] = 0;
   isreg = 0;
-  offreg = 0;
-  isderef = 0;
-  islocal = 0;
-  optimized_out = 1;
 
   while (i < size)
     {
-      optimized_out = 0;
       op = data[i++];
       switch (op)
        {
@@ -6837,6 +6937,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
        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:
@@ -6844,74 +6946,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;
-         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],
-                                         cu_header, &bytes_read);
+                                         cu, &bytes_read);
          i += bytes_read;
          break;
 
@@ -6977,9 +7018,10 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
          break;
 
        case DW_OP_deref:
-         isderef = 1;
          /* 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;
@@ -6989,6 +7031,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.  */
+         /* 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;
@@ -7004,7 +7048,6 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
 
 /* memory allocation interface */
 
-/* ARGSUSED */
 static void
 dwarf2_free_tmp_obstack (void *ignore)
 {
@@ -7284,8 +7327,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,
-                     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;
@@ -7361,7 +7403,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
             current_file = macro_start_file (file, line,
                                              current_file, comp_dir,
-                                             lh, objfile);
+                                             lh, cu->objfile);
           }
           break;
 
@@ -7432,23 +7474,22 @@ attr_form_is_block (struct attribute *attr)
 
 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;
 
-      baton = obstack_alloc (&objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->symbol_obstack,
                             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);
-      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.");
 
@@ -7459,9 +7500,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     {
       struct dwarf2_locexpr_baton *baton;
 
-      baton = obstack_alloc (&objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->symbol_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = objfile;
+      baton->objfile = cu->objfile;
 
       if (attr_form_is_block (attr))
        {
This page took 0.066159 seconds and 4 git commands to generate.