2003-11-23 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index ee0c9d4b1bb4f49ede27ce400cb2975867290403..53dd02f6c187d6a1633f4b5f129f1e4d717510ab 100644 (file)
 #include "expression.h"
 #include "filenames.h" /* for DOSish file names */
 #include "macrotab.h"
-
 #include "language.h"
 #include "complaints.h"
 #include "bcache.h"
+#include "dwarf2expr.h"
+#include "dwarf2loc.h"
+#include "cp-support.h"
+
 #include <fcntl.h>
 #include "gdb_string.h"
 #include "gdb_assert.h"
@@ -218,11 +221,29 @@ struct comp_unit_head
 
     struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
 
-    /* Pointer to the DIE associated with the compilation unit.  */
+    /* Base address of this compilation unit.  */
+
+    CORE_ADDR base_address;
+
+    /* Non-zero if base_address has been set.  */
 
-    struct die_info *die;
+    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.  */
@@ -308,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 */
   };
 
@@ -393,6 +422,7 @@ static char *dwarf_line_buffer;
 static char *dwarf_str_buffer;
 static char *dwarf_macinfo_buffer;
 static char *dwarf_ranges_buffer;
+static char *dwarf_loc_buffer;
 
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
@@ -413,37 +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.  */
-static int is_thread_local;     /* Variable is at a constant offset in the
-                                   thread-local storage block for the
-                                   current thread and the dynamic linker
-                                   module containing this expression.
-                                   decode_locdesc returns the offset from
-                                   that base.  */
-
-/* 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,
@@ -509,6 +511,13 @@ struct dwarf2_pinfo
 
     unsigned int dwarf_ranges_size;
 
+    /* Pointer to start of dwarf locations buffer for the objfile.  */
+
+    char *dwarf_loc_buffer;
+
+    /* Size of dwarf locations buffer for the objfile.  */
+
+    unsigned int dwarf_loc_size;
   };
 
 #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
@@ -524,6 +533,8 @@ struct dwarf2_pinfo
 #define DWARF_MACINFO_SIZE(p)   (PST_PRIVATE(p)->dwarf_macinfo_size)
 #define DWARF_RANGES_BUFFER(p)  (PST_PRIVATE(p)->dwarf_ranges_buffer)
 #define DWARF_RANGES_SIZE(p)    (PST_PRIVATE(p)->dwarf_ranges_size)
+#define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
+#define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
 /* Maintain an array of referenced fundamental types for the current
    compilation unit being read.  For DWARF version 1, we have to construct
@@ -659,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 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 void add_partial_symbol (struct partial_die_info *, struct objfile *,
-                               const struct comp_unit_head *);
+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 *);
 
@@ -673,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 *);
 
@@ -703,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 *,
@@ -733,124 +759,115 @@ 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_common_block (struct die_info *, struct dwarf2_cu *);
 
-static void read_structure_scope (struct die_info *, struct objfile *,
-                                 const struct comp_unit_head *);
+static void read_namespace (struct die_info *die, struct dwarf2_cu *);
 
-static void read_common_block (struct die_info *, struct objfile *,
-                              const struct comp_unit_head *);
+static void read_enumeration (struct die_info *, struct dwarf2_cu *);
 
-static void read_namespace (struct die_info *die, struct objfile *objfile,
-                           const struct comp_unit_head *cu_header);
+static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
 
-static void read_enumeration (struct die_info *, struct objfile *,
-                             const struct comp_unit_head *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
 
-static struct type *dwarf_base_type (int, int, struct objfile *);
+static void read_array_type (struct die_info *, struct dwarf2_cu *);
 
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
-                                const struct comp_unit_head *);
+static void read_tag_pointer_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_ptr_to_member_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_reference_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_const_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_volatile_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_string_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_subroutine_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_tag_string_type (struct die_info *, struct objfile *);
+static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);
 
-static void read_subroutine_type (struct die_info *, struct objfile *,
-                                 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_comp_unit (char *, bfd *,
-                                        const struct comp_unit_head *);
+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 *);
 
+static char *dwarf2_name (struct die_info *die);
+
+static struct die_info *dwarf2_extension (struct die_info *die);
+
 static char *dwarf_tag_name (unsigned int);
 
 static char *dwarf_attr_name (unsigned int);
@@ -900,11 +917,14 @@ 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,
+                            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.  */
 
@@ -919,6 +939,7 @@ dwarf2_has_info (bfd *abfd)
   dwarf_frame_offset = 0;
   dwarf_eh_frame_offset = 0;
   dwarf_ranges_offset = 0;
+  dwarf_loc_offset = 0;
   
   bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
   if (dwarf_info_offset && dwarf_abbrev_offset)
@@ -938,67 +959,71 @@ 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_loc_section = 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)
     {
-      dwarf_eh_frame_offset = sectp->filepos;
-      dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
-      dwarf_eh_frame_section = sectp;
+      flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
+      if (aflag & SEC_HAS_CONTENTS)
+        {
+          dwarf_eh_frame_offset = sectp->filepos;
+          dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
+          dwarf_eh_frame_section = sectp;
+        }
     }
-  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);
@@ -1055,6 +1080,14 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
   else
     dwarf_ranges_buffer = NULL;
 
+  if (dwarf_loc_offset)
+    dwarf_loc_buffer = dwarf2_read_section (objfile,
+                                           dwarf_loc_offset,
+                                           dwarf_loc_size,
+                                           dwarf_loc_section);
+  else
+    dwarf_loc_buffer = NULL;
+
   if (mainline
       || (objfile->global_psymbols.size == 0
          && objfile->static_psymbols.size == 0))
@@ -1212,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);
@@ -1276,6 +1311,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size;
       DWARF_RANGES_BUFFER (pst) = dwarf_ranges_buffer;
       DWARF_RANGES_SIZE (pst) = dwarf_ranges_size;
+      DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer;
+      DWARF_LOC_SIZE (pst) = dwarf_loc_size;
       baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
       /* Store the function that reads in the rest of the symbol table */
@@ -1286,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)
@@ -1311,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;
+  /* 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.  */
 
-  *lowpc = ((CORE_ADDR) -1);
-  *highpc = ((CORE_ADDR) 0);
-
-  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;
+
+      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
 
-      /* Anonymous namespaces have no name but are interesting.  */
+      /* 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)
+      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace
+         || pdi.tag == DW_TAG_enumeration_type)
        {
          switch (pdi.tag)
            {
@@ -1370,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)
     {
@@ -1465,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_NAMESPACE, 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_NAMESPACE, 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:
@@ -1497,31 +1521,33 @@ 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_NAMESPACE, 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_NAMESPACE, 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:
     case DW_TAG_base_type:
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          VAR_NAMESPACE, LOC_TYPEDEF,
+                          VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
       break;
@@ -1534,7 +1560,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
       if (pdi->has_children == 0)
        return;
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          STRUCT_NAMESPACE, LOC_TYPEDEF,
+                          STRUCT_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
 
@@ -1542,20 +1568,134 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
        {
          /* For C++, these implicitly act as typedefs as well. */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_TYPEDEF,
+                              VAR_DOMAIN, LOC_TYPEDEF,
                               &objfile->static_psymbols,
                               0, (CORE_ADDR) 0, cu_language, objfile);
        }
       break;
     case DW_TAG_enumerator:
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          VAR_NAMESPACE, LOC_CONST,
+                          VAR_DOMAIN, LOC_CONST,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
       break;
     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.  */
@@ -1592,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;
@@ -1600,6 +1740,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   char *info_ptr;
   struct symtab *symtab;
   struct cleanup *back_to;
+  struct attribute *attr;
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
@@ -1614,6 +1755,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
   dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst);
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
+  dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
+  dwarf_loc_size = DWARF_LOC_SIZE (pst);
   baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
   cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
@@ -1624,38 +1767,63 @@ 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);
 
+  /* Find the base address of the compilation unit for range lists and
+     location lists.  It will normally be specified by DW_AT_low_pc.
+     In DWARF-3 draft 4, the base address could be overridden by
+     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;
+
+  attr = dwarf_attr (dies, DW_AT_entry_pc);
+  if (attr)
+    {
+      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;
+       }
+    }
+
   /* Do line number decoding in read_file_scope () */
-  cu_header.die = dies;
-  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);
                    }
@@ -1676,7 +1844,6 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
     }
   pst->symtab = symtab;
   pst->readin = 1;
-  sort_symtab_syms (pst->symtab);
 
   do_cleanups (back_to);
 }
@@ -1684,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.
@@ -1704,49 +1870,56 @@ process_die (struct die_info *die, struct objfile *objfile,
          of a function and make GDB `next' properly over inlined functions.  */
       break;
     case DW_TAG_lexical_block:
-      read_lexical_block_scope (die, objfile, cu_header);
+    case DW_TAG_try_block:
+    case DW_TAG_catch_block:
+      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;
     case DW_TAG_namespace:
-      read_namespace (die, objfile, cu_header);
+      if (!processing_has_namespace_info)
+       {
+         processing_has_namespace_info = 1;
+         processing_current_namespace = "";
+       }
+      read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
@@ -1756,10 +1929,15 @@ process_die (struct die_info *die, struct objfile *objfile,
         shouldn't in the C++ case, but conceivably could in the
         Fortran case, so we'll have to replace this gdb_assert if
         Fortran compilers start generating that info.  */
-      gdb_assert (!die->has_children);
+      if (!processing_has_namespace_info)
+       {
+         processing_has_namespace_info = 1;
+         processing_current_namespace = "";
+       }
+      gdb_assert (die->child == NULL);
       break;
     default:
-      new_symbol (die, NULL, objfile, cu_header);
+      new_symbol (die, NULL, cu);
       break;
     }
 }
@@ -1771,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);
@@ -1784,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);
@@ -1837,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);
@@ -1867,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);
        }
     }
@@ -1882,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);
         }
     }
 
@@ -1901,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);
 }
@@ -1928,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;
@@ -1942,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;
@@ -1958,54 +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;
+  new = push_context (0, lowpc);
+  new->name = new_symbol (die, die->type, cu);
+
+  /* If there is a location expression for DW_AT_frame_base, record
+     it.  */
   attr = dwarf_attr (die, DW_AT_frame_base);
   if (attr)
-    {
-      CORE_ADDR addr;
+    dwarf2_symbol_mark_computed (attr, new->name, cu);
 
-      /* 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);
   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);
        }
     }
@@ -2032,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;
 
@@ -2044,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);
        }
     }
@@ -2074,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;
@@ -2105,51 +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 = 0;
-         int found_base = 0;
+         CORE_ADDR base;
+         int found_base;
          int dummy;
-         unsigned int i;
          char *buffer;
          CORE_ADDR marker;
          int low_set;
  
-         /* The applicable base address is determined by (1) the closest
-            preceding base address selection entry in the range list or
-            (2) the DW_AT_low_pc of the compilation unit.  */
+         found_base = cu_header->base_known;
+         base = cu_header->base_address;
 
-         /* ??? Was in dwarf3 draft4, and has since been removed.
-            GCC still uses it though.  */
-         attr = dwarf_attr (cu_header->die, DW_AT_entry_pc);
-         if (attr)
+         if (offset >= dwarf_ranges_size)
            {
-             base = DW_ADDR (attr);
-             found_base = 1;
-           }
-
-         if (!found_base)
-           {
-             attr = dwarf_attr (cu_header->die, DW_AT_low_pc);
-             if (attr)
-               {
-                 base = DW_ADDR (attr);
-                 found_base = 1;
-               }
+             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;
@@ -2161,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;
 
@@ -2180,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;
                }
@@ -2195,6 +2324,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                  return 0;
                }
 
+             range_beginning += base;
+             range_end += base;
+
              /* FIXME: This is recording everything as a low-high
                 segment of consecutive addresses.  We should have a
                 data structure for discontiguous block ranges
@@ -2246,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;
@@ -2287,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;
 
@@ -2307,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;
@@ -2393,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);
     }
@@ -2402,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++;
     }
@@ -2416,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;
 
@@ -2503,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;
@@ -2527,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;
     }
 
@@ -2568,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
@@ -2594,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.  */
@@ -2626,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)
         {
@@ -2644,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;
@@ -2691,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;
 
@@ -2738,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;
@@ -2746,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)
        {
@@ -2758,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
@@ -2791,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)
@@ -2807,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;
@@ -2829,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);
     }
@@ -2850,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;
@@ -2884,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;
 
@@ -2910,7 +3041,7 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
                                  * sizeof (struct field));
                    }
 
-                 FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+                 FIELD_NAME (fields[num_fields]) = DEPRECATED_SYMBOL_NAME (sym);
                  FIELD_TYPE (fields[num_fields]) = NULL;
                  FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
                  FIELD_BITSIZE (fields[num_fields]) = 0;
@@ -2936,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
@@ -2944,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;
@@ -2961,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);
@@ -2974,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)
@@ -2990,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)
            {
@@ -3039,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
                {
@@ -3094,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;
@@ -3108,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)
         {
@@ -3120,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);
@@ -3140,32 +3276,95 @@ read_common_block (struct die_info *die, struct objfile *objfile,
 
 /* Read a C++ namespace.  */
 
-/* FIXME: carlton/2002-10-16: For now, we don't actually do anything
-   useful with the namespace data: we just process its children.  */
-
 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)
 {
-  if (die->has_children)
+  struct objfile *objfile = cu->objfile;
+  const char *previous_namespace = processing_current_namespace;
+  const char *name = NULL;
+  int is_anonymous;
+  struct die_info *current_die;
+
+  /* Loop through the extensions until we find a name.  */
+
+  for (current_die = die;
+       current_die != NULL;
+       current_die = dwarf2_extension (die))
     {
-      struct die_info *child_die = die->next;
+      name = dwarf2_name (current_die);
+      if (name != NULL)
+       break;
+    }
+
+  /* Is it an anonymous namespace?  */
+
+  is_anonymous = (name == NULL);
+  if (is_anonymous)
+    name = "(anonymous namespace)";
+
+  /* Now build the name of the current namespace.  */
+
+  if (previous_namespace[0] == '\0')
+    {
+      processing_current_namespace = name;
+    }
+  else
+    {
+      /* We need temp_name around because processing_current_namespace
+        is a const char *.  */
+      char *temp_name = alloca (strlen (previous_namespace)
+                               + 2 + strlen(name) + 1);
+      strcpy (temp_name, previous_namespace);
+      strcat (temp_name, "::");
+      strcat (temp_name, name);
+
+      processing_current_namespace = temp_name;
+    }
+
+  /* Add a symbol associated to this if we haven't seen the namespace
+     before.  Also, add a using directive if it's an anonymous
+     namespace.  */
+
+  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);
+
+      new_symbol (die, type, cu);
+
+      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->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);
        }
     }
+
+  processing_current_namespace = previous_namespace;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
    the user defined type vector.  */
 
 static void
-read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
-                      const struct comp_unit_head *cu_header)
+read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
   struct attribute *attr_address_class;
@@ -3176,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)
@@ -3220,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;
@@ -3233,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;
@@ -3244,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;
 
@@ -3255,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)
     {
@@ -3269,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;
 
@@ -3279,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;
 
@@ -3294,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);
 }
 
@@ -3304,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;
@@ -3361,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 */
@@ -3373,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.  */
@@ -3382,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;
@@ -3391,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)
@@ -3406,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)
@@ -3421,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);
@@ -3433,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;
 
@@ -3447,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);
     }
 }
 
@@ -3455,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;
@@ -3530,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;
 }
@@ -3538,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.  */
@@ -3593,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;
@@ -3648,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;
@@ -3713,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)
 {
@@ -3748,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;
 
@@ -3770,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;
@@ -3786,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,
@@ -3799,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.  */
@@ -3877,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;
@@ -3907,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;
@@ -3928,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;
 
@@ -3951,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;
 }
 
@@ -3962,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;
 
@@ -3973,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:
@@ -4068,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]",
@@ -4082,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 */
@@ -4134,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)
@@ -4438,7 +4681,7 @@ set_cu_language (unsigned int lang)
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
-      cu_language = language_unknown;
+      cu_language = language_minimal;
       break;
     }
   cu_language_defn = language_def (cu_language);
@@ -4568,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;
@@ -4609,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;
@@ -4717,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;
@@ -4768,8 +5010,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                * lh->minimum_instruction_length;
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
-             address = check_cu_functions (address);
-             record_line (current_subfile, line, address);
+             record_line (current_subfile, line, 
+                          check_cu_functions (address));
              basic_block = 1;
            }
          else switch (op_code)
@@ -4785,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;
@@ -4815,8 +5057,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                }
              break;
            case DW_LNS_copy:
-             address = check_cu_functions (address);
-             record_line (current_subfile, line, address);
+             record_line (current_subfile, line, 
+                          check_cu_functions (address));
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -4927,6 +5169,62 @@ dwarf2_start_subfile (char *filename, char *dirname)
   start_subfile (filename, dirname);
 }
 
+static void
+var_decode_location (struct attribute *attr, struct symbol *sym,
+                    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
+     necessary for platforms (maybe Alpha, certainly PowerPC GNU/Linux
+     with some versions of binutils) where shared libraries could have
+     relocations against symbols in their debug information - the
+     minimal symbol would have the right address, but the debug info
+     would not.  It's no longer necessary, because we will explicitly
+     apply relocations when we read in the debug information now.  */
+
+  /* A DW_AT_location attribute with no contents indicates that a
+     variable has been optimized away.  */
+  if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0)
+    {
+      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+      return;
+    }
+
+  /* Handle one degenerate form of location expression specially, to
+     preserve GDB's previous behavior when section offsets are
+     specified.  If this is just a DW_OP_addr then mark this symbol
+     as LOC_STATIC.  */
+
+  if (attr_form_is_block (attr)
+      && DW_BLOCK (attr)->size == 1 + cu_header->addr_size
+      && DW_BLOCK (attr)->data[0] == DW_OP_addr)
+    {
+      int dummy;
+
+      SYMBOL_VALUE_ADDRESS (sym) =
+       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));
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+      return;
+    }
+
+  /* NOTE drow/2002-01-30: It might be worthwhile to have a static
+     expression evaluator, and use LOC_COMPUTED only when necessary
+     (i.e. when the value of a register or memory location is
+     referenced, or a thread-local block, etc.).  Then again, it might
+     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);
+  SYMBOL_CLASS (sym) = LOC_COMPUTED;
+}
+
 /* Given a pointer to a DWARF information entry, figure out if we need
    to make a symbol table entry for it, and if so, create a new entry
    and return a pointer to it.
@@ -4934,16 +5232,19 @@ dwarf2_start_subfile (char *filename, char *dirname)
    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,
@@ -4957,12 +5258,12 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       SYMBOL_CLASS (sym) = LOC_STATIC;
       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)
        {
@@ -5004,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);
@@ -5015,106 +5316,12 @@ 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, cu);
              attr2 = dwarf_attr (die, DW_AT_external);
              if (attr2 && (DW_UNSND (attr2) != 0))
-               {
-                  /* Support the .debug_loc offsets */
-                  if (attr_form_is_block (attr))
-                    {
-                     SYMBOL_VALUE_ADDRESS (sym) =
-                       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 ();
-                    }
-                  else
-                    {
-                     dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-                                                            "external variable");
-                    }
-                 add_symbol_to_list (sym, &global_symbols);
-                  if (is_thread_local)
-                    {
-                      /* SYMBOL_VALUE_ADDRESS contains at this point the
-                        offset of the variable within the thread local
-                        storage.  */
-                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
-                      SYMBOL_OBJFILE (sym) = objfile;
-                    }
-
-                 /* In shared libraries the address of the variable
-                    in the location descriptor might still be relocatable,
-                    so its value could be zero.
-                    Enter the symbol as a LOC_UNRESOLVED symbol, if its
-                    value is zero, the address of the variable will then
-                    be determined from the minimal symbol table whenever
-                    the variable is referenced.  */
-                 else if (SYMBOL_VALUE_ADDRESS (sym))
-                   {
-                     fixup_symbol_section (sym, objfile);
-                     SYMBOL_VALUE_ADDRESS (sym) +=
-                       ANOFFSET (objfile->section_offsets,
-                                 SYMBOL_SECTION (sym));
-                     SYMBOL_CLASS (sym) = LOC_STATIC;
-                   }
-                 else
-                   SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
-               }
+               add_symbol_to_list (sym, &global_symbols);
              else
-               {
-                  /* Support the .debug_loc offsets */
-                  if (attr_form_is_block (attr))
-                    {
-                     SYMBOL_VALUE (sym) = 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 ();
-                    }
-                  else
-                    {
-                     dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-                                                            "external variable");
-                      addr = 0;
-                    }
-                 add_symbol_to_list (sym, list_in_scope);
-                 if (optimized_out)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
-                   }
-                 else if (isreg)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_REGISTER;
-                     SYMBOL_VALUE (sym) = 
-                       DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
-                   }
-                 else if (offreg)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_BASEREG;
-                     SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
-                   }
-                 else if (islocal)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_LOCAL;
-                   }
-                  else if (is_thread_local)
-                    {
-                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
-                      SYMBOL_OBJFILE (sym) = objfile;
-                    }
-                 else
-                   {
-                     fixup_symbol_section (sym, objfile);
-                     SYMBOL_VALUE_ADDRESS (sym) =
-                       addr + ANOFFSET (objfile->section_offsets,
-                                        SYMBOL_SECTION (sym));
-                     SYMBOL_CLASS (sym) = LOC_STATIC;
-                   }
-               }
+               add_symbol_to_list (sym, list_in_scope);
            }
          else
            {
@@ -5137,37 +5344,15 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_location);
          if (attr)
            {
-             SYMBOL_VALUE (sym) =
-               decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
-             if (isreg)
-               {
-                 SYMBOL_CLASS (sym) = LOC_REGPARM;
-                 SYMBOL_VALUE (sym) = 
-                   DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
-               }
-             else if (offreg)
-               {
-                 if (isderef)
-                   {
-                     if (basereg != frame_base_reg)
-                       dwarf2_complex_location_expr_complaint ();
-                     SYMBOL_CLASS (sym) = LOC_REF_ARG;
-                   }
-                 else
-                   {
-                     SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
-                     SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
-                   }
-               }
-             else
-               {
-                 SYMBOL_CLASS (sym) = LOC_ARG;
-               }
+             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;
            }
          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;
@@ -5181,7 +5366,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        case DW_TAG_union_type:
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-         SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
          add_symbol_to_list (sym, list_in_scope);
 
          /* The semantics of C++ state that "struct foo { ... }" also
@@ -5193,11 +5378,11 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
              obstack_alloc (&objfile->symbol_obstack,
                             sizeof (struct symbol));
              *typedef_sym = *sym;
-             SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+             SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
              if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
                TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 obsavestring (SYMBOL_NAME (sym),
-                               strlen (SYMBOL_NAME (sym)),
+                 obsavestring (DEPRECATED_SYMBOL_NAME (sym),
+                               strlen (DEPRECATED_SYMBOL_NAME (sym)),
                                &objfile->type_obstack);
              add_symbol_to_list (typedef_sym, list_in_scope);
            }
@@ -5205,17 +5390,21 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        case DW_TAG_typedef:
        case DW_TAG_base_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          add_symbol_to_list (sym, list_in_scope);
          break;
        case DW_TAG_enumerator:
          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
@@ -5233,23 +5422,26 @@ 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)
     {
     case DW_FORM_addr:
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size)
-       dwarf2_const_value_length_mismatch_complaint (SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
                                                      cu_header->addr_size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
        obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
-      store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
-                    DW_ADDR (attr));
+      /* NOTE: cagney/2003-05-09: In-lined store_address call with
+         it's body - store_unsigned_integer.  */
+      store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
+                             DW_ADDR (attr));
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
     case DW_FORM_block1:
@@ -5258,7 +5450,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
     case DW_FORM_block:
       blk = DW_BLOCK (attr);
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
-       dwarf2_const_value_length_mismatch_complaint (SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
                                                      blk->size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
@@ -5332,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;
@@ -5344,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
     {
@@ -5353,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;
 }
@@ -5371,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;
@@ -5387,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;
@@ -5415,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)
     {
@@ -5430,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'",
@@ -5494,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;
@@ -5607,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.  */
@@ -5662,10 +5816,47 @@ dwarf2_linkage_name (struct die_info *die)
   return NULL;
 }
 
+/* Get name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_name (struct die_info *die)
+{
+  struct attribute *attr;
+
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  return NULL;
+}
+
+/* Return the die that this die in an extension of, or NULL if there
+   is none.  */
+
+static struct die_info *
+dwarf2_extension (struct die_info *die)
+{
+  struct attribute *attr;
+  struct die_info *extension_die;
+  unsigned int ref;
+
+  attr = dwarf_attr (die, DW_AT_extension);
+  if (attr == NULL)
+    return NULL;
+
+  ref = dwarf2_get_ref_die_offset (attr);
+  extension_die = follow_die_ref (ref);
+  if (!extension_die)
+    {
+      error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+    }
+
+  return extension_die;
+}
+
 /* Convert a DIE tag into its string name.  */
 
 static char *
-dwarf_tag_name (register unsigned tag)
+dwarf_tag_name (unsigned tag)
 {
   switch (tag)
     {
@@ -5797,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)
     {
@@ -5962,9 +6153,9 @@ dwarf_attr_name (register unsigned attr)
       return "DW_AT_MIPS_loop_unroll_factor";
     case DW_AT_MIPS_software_pipeline_depth:
       return "DW_AT_MIPS_software_pipeline_depth";
+#endif
     case DW_AT_MIPS_linkage_name:
       return "DW_AT_MIPS_linkage_name";
-#endif
 
     case DW_AT_sf_names:
       return "DW_AT_sf_names";
@@ -5988,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)
     {
@@ -6042,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)
     {
@@ -6365,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)
     {
@@ -6396,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)
     {
@@ -6475,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)
@@ -6538,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);
     }
 }
 
@@ -6630,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;
@@ -6670,15 +6862,9 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
   stacki = 0;
   stack[stacki] = 0;
   isreg = 0;
-  offreg = 0;
-  isderef = 0;
-  islocal = 0;
-  is_thread_local = 0;
-  optimized_out = 1;
 
   while (i < size)
     {
-      optimized_out = 0;
       op = data[i++];
       switch (op)
        {
@@ -6751,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:
@@ -6758,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;
 
@@ -6891,19 +7018,21 @@ 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;
 
         case DW_OP_GNU_push_tls_address:
-          is_thread_local = 1;
          /* The top of the stack has the offset from the beginning
             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;
@@ -6919,7 +7048,6 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
 
 /* memory allocation interface */
 
-/* ARGSUSED */
 static void
 dwarf2_free_tmp_obstack (void *ignore)
 {
@@ -7199,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;
@@ -7276,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;
 
@@ -7344,3 +7471,58 @@ attr_form_is_block (struct attribute *attr)
       || attr->form == DW_FORM_block4
       || attr->form == DW_FORM_block);
 }
+
+static void
+dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
+                            struct dwarf2_cu *cu)
+{
+  if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+    {
+      struct dwarf2_loclist_baton *baton;
+
+      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+                            sizeof (struct dwarf2_loclist_baton));
+      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)
+       complaint (&symfile_complaints,
+                  "Location list used without specifying the CU base address.");
+
+      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_LOCATION_BATON (sym) = baton;
+    }
+  else
+    {
+      struct dwarf2_locexpr_baton *baton;
+
+      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+                            sizeof (struct dwarf2_locexpr_baton));
+      baton->objfile = cu->objfile;
+
+      if (attr_form_is_block (attr))
+       {
+         /* Note that we're just copying the block's data pointer
+            here, not the actual data.  We're still pointing into the
+            dwarf_info_buffer for SYM's objfile; right now we never
+            release that buffer, but when we do clean up properly
+            this may need to change.  */
+         baton->size = DW_BLOCK (attr)->size;
+         baton->data = DW_BLOCK (attr)->data;
+       }
+      else
+       {
+         dwarf2_invalid_attrib_class_complaint ("location description",
+                                                SYMBOL_NATURAL_NAME (sym));
+         baton->size = 0;
+         baton->data = NULL;
+       }
+      
+      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_LOCATION_BATON (sym) = baton;
+    }
+}
This page took 0.071458 seconds and 4 git commands to generate.