(_bfd_link_section_stabs): Do not skip N_EXCL stabs.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index d47f93ae8245463c9e31baca667b7a410e0332eb..285eb6bd7aa3a0c0459586dd06caf01d21beff01 100644 (file)
@@ -31,7 +31,6 @@
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
-#include "symfile.h"
 #include "objfiles.h"
 #include "elf/dwarf2.h"
 #include "buildsym.h"
 #include "gdb_assert.h"
 #include <sys/types.h>
 
+/* A note on memory usage for this file.
+   
+   At the present time, this code reads the debug info sections into
+   the objfile's objfile_obstack.  A definite improvement for startup
+   time, on platforms which do not emit relocations for debug
+   sections, would be to use mmap instead.  The object's complete
+   debug information is loaded into memory, partly to simplify
+   absolute DIE references.
+
+   Whether using obstacks or mmap, the sections should remain loaded
+   until the objfile is released, and pointers into the section data
+   can be used for any other data associated to the objfile (symbol
+   names, type names, location expressions to name a few).  */
+
 #ifndef DWARF2_REG_TO_REGNUM
 #define DWARF2_REG_TO_REGNUM(REG) (REG)
 #endif
@@ -206,10 +219,6 @@ struct comp_unit_head
 
     struct comp_unit_head *next;
 
-    /* DWARF abbreviation table associated with this compilation unit */
-
-    struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
-
     /* Base address of this compilation unit.  */
 
     CORE_ADDR base_address;
@@ -228,9 +237,42 @@ struct dwarf2_cu
   /* 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.  */
+     should logically be moved to the dwarf2_cu structure.  */
   struct comp_unit_head header;
+
+  struct function_range *first_fn, *last_fn, *cached_fn;
+
+  /* The language we are debugging.  */
+  enum language language;
+  const struct language_defn *language_defn;
+
+  /* The generic symbol table building routines have separate lists for
+     file scope symbols and all all other scopes (local scopes).  So
+     we need to select the right one to pass to add_symbol_to_list().
+     We do it by keeping a pointer to the correct list in list_in_scope.
+
+     FIXME: The original dwarf code just treated the file scope as the
+     first local scope, and all other local scopes as nested local
+     scopes, and worked fine.  Check to see if we really need to
+     distinguish these in buildsym.c.  */
+  struct pending **list_in_scope;
+
+  /* Maintain an array of referenced fundamental types for the current
+     compilation unit being read.  For DWARF version 1, we have to construct
+     the fundamental types on the fly, since no information about the
+     fundamental types is supplied.  Each such fundamental type is created by
+     calling a language dependent routine to create the type, and then a
+     pointer to that type is then placed in the array at the index specified
+     by it's FT_<TYPENAME> value.  The array has a fixed size set by the
+     FT_NUM_MEMBERS compile time constant, which is the number of predefined
+     fundamental types gdb knows how to construct.  */
+  struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+
+  /* DWARF abbreviation table associated with this compilation unit.  */
+  struct abbrev_info **dwarf2_abbrevs;
+
+  /* Storage for the abbrev table.  */
+  struct obstack abbrev_obstack;
 };
 
 /* The line number information for a compilation unit (found in the
@@ -302,8 +344,8 @@ struct abbrev_info
   {
     unsigned int number;       /* number identifying abbrev */
     enum dwarf_tag tag;                /* dwarf tag */
-    int has_children;          /* boolean */
-    unsigned int num_attrs;    /* number of attributes */
+    unsigned short has_children;               /* boolean */
+    unsigned short num_attrs;  /* number of attributes */
     struct attr_abbrev *attrs; /* an array of attribute descriptions */
     struct abbrev_info *next;  /* next in chain */
   };
@@ -360,8 +402,6 @@ struct function_range
   struct function_range *next;
 };
 
-static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
-
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
@@ -391,19 +431,11 @@ static struct die_info *die_ref_table[REF_HASH_SIZE];
 /* Obstack for allocating temporary storage used during symbol reading.  */
 static struct obstack dwarf2_tmp_obstack;
 
-/* Offset to the first byte of the current compilation unit header,
-   for resolving relative reference dies. */
-static unsigned int cu_header_offset;
-
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
 #endif
 
-/* The language we are debugging.  */
-static enum language cu_language;
-static const struct language_defn *cu_language_defn;
-
 /* Actually data from the sections.  */
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
@@ -416,17 +448,6 @@ static char *dwarf_loc_buffer;
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
-/* The generic symbol table building routines have separate lists for
-   file scope symbols and all all other scopes (local scopes).  So
-   we need to select the right one to pass to add_symbol_to_list().
-   We do it by keeping a pointer to the correct list in list_in_scope.
-
-   FIXME:  The original dwarf code just treated the file scope as the first
-   local scope, and all other local scopes as nested local scopes, and worked
-   fine.  Check to see if we really need to distinguish these
-   in buildsym.c.  */
-static struct pending **list_in_scope = &file_symbols;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
@@ -436,19 +457,13 @@ static int isreg;         /* Object lives in register.
                                   decode_locdesc's return value is
                                   the register number.  */
 
-/* This value is added to each symbol value.  FIXME:  Generalize to
-   the section_offsets structure used by dbxread (once this is done,
-   pass the appropriate section number to end_symtab).  */
-static CORE_ADDR baseaddr;     /* Add to each symbol value */
-
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.
-   The complete dwarf information for an objfile is kept in the
-   psymbol_obstack, so that absolute die references can be handled.
+
    Most of the information in this structure is related to an entire
-   object file and could be passed via the sym_private field of the objfile.
-   It is however conceivable that dwarf2 might not be the only type
-   of symbols read from an object file.  */
+   object file and could be passed via the sym_private field of the
+   objfile.  It is possible to have both dwarf2 and some other form
+   of debug symbols in one object file.  */
 
 struct dwarf2_pinfo
   {
@@ -525,17 +540,6 @@ struct dwarf2_pinfo
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
-/* Maintain an array of referenced fundamental types for the current
-   compilation unit being read.  For DWARF version 1, we have to construct
-   the fundamental types on the fly, since no information about the
-   fundamental types is supplied.  Each such fundamental type is created by
-   calling a language dependent routine to create the type, and then a
-   pointer to that type is then placed in the array at the index specified
-   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
-   FT_NUM_MEMBERS compile time constant, which is the number of predefined
-   fundamental types gdb knows how to construct.  */
-static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
-
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
@@ -683,7 +687,7 @@ char *dwarf2_read_section (struct objfile *, asection *);
 
 static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
 
-static void dwarf2_empty_abbrev_table (void *);
+static void dwarf2_free_abbrev_table (void *);
 
 static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
                                                 struct dwarf2_cu *);
@@ -730,13 +734,17 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
 
-static void set_cu_language (unsigned int);
+static char *skip_leb128 (bfd *, char *);
 
-static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static void set_cu_language (unsigned int, struct dwarf2_cu *);
 
-static int die_is_declaration (struct die_info *);
+static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
+                                     struct dwarf2_cu *);
 
-static struct die_info *die_specification (struct die_info *die);
+static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
+
+static struct die_info *die_specification (struct die_info *die,
+                                          struct dwarf2_cu *);
 
 static void free_line_header (struct line_header *lh);
 
@@ -772,14 +780,10 @@ static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
 
 static void read_type_die (struct die_info *, struct dwarf2_cu *);
 
-static char *determine_prefix (struct die_info *die);
-
-static char *determine_prefix_aux (struct die_info *die);
+static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
 static char *typename_concat (const char *prefix, const char *suffix);
 
-static char *class_name (struct die_info *die);
-
 static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
 static void read_base_type (struct die_info *, struct dwarf2_cu *);
@@ -812,16 +816,22 @@ static void dwarf2_add_member_fn (struct field_info *,
 static void dwarf2_attach_fn_fields_to_type (struct field_info *,
                                             struct type *, struct dwarf2_cu *);
 
-static void read_structure_scope (struct die_info *, struct dwarf2_cu *);
+static void read_structure_type (struct die_info *, struct dwarf2_cu *);
+
+static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
+
+static char *determine_class_name (struct die_info *die, struct dwarf2_cu *cu);
 
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
 
 static const char *namespace_name (struct die_info *die,
-                                  int *is_anonymous);
+                                  int *is_anonymous, struct dwarf2_cu *);
+
+static void read_enumeration_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_enumeration (struct die_info *, struct dwarf2_cu *);
+static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
 
 static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
 
@@ -862,11 +872,12 @@ static struct cleanup *make_cleanup_free_die_list (struct die_info *);
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *);
+static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_name (struct die_info *die);
+static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
-static struct die_info *dwarf2_extension (struct die_info *die);
+static struct die_info *dwarf2_extension (struct die_info *die,
+                                         struct dwarf2_cu *);
 
 static char *dwarf_tag_name (unsigned int);
 
@@ -896,13 +907,15 @@ static void store_in_ref_table (unsigned int, struct die_info *);
 
 static void dwarf2_empty_hash_tables (void);
 
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
+                                              struct dwarf2_cu *);
 
 static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
 static struct die_info *follow_die_ref (unsigned int);
 
-static struct type *dwarf2_fundamental_type (struct objfile *, int);
+static struct type *dwarf2_fundamental_type (struct objfile *, int,
+                                            struct dwarf2_cu *);
 
 /* memory allocation interface */
 
@@ -910,13 +923,14 @@ static void dwarf2_free_tmp_obstack (void *);
 
 static struct dwarf_block *dwarf_alloc_block (void);
 
-static struct abbrev_info *dwarf_alloc_abbrev (void);
+static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
 
 static struct die_info *dwarf_alloc_die (void);
 
-static void initialize_cu_func_list (void);
+static void initialize_cu_func_list (struct dwarf2_cu *);
 
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
+                                struct dwarf2_cu *);
 
 static void dwarf_decode_macros (struct line_header *, unsigned int,
                                  char *, bfd *, struct dwarf2_cu *);
@@ -927,6 +941,9 @@ static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
                             struct dwarf2_cu *cu);
 
+static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+                          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.  */
 
@@ -1154,7 +1171,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
-  CORE_ADDR lowpc, highpc;
+  CORE_ADDR lowpc, highpc, baseaddr;
 
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
@@ -1205,6 +1222,7 @@ 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 cleanup *back_to_inner;
       struct dwarf2_cu cu;
       beg_of_comp_unit = info_ptr;
 
@@ -1238,16 +1256,18 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       cu.header.first_die_ptr = info_ptr;
       cu.header.cu_head_ptr = beg_of_comp_unit;
 
+      cu.list_in_scope = &file_symbols;
+
       /* Read the abbrevs for this compilation unit into a table */
       dwarf2_read_abbrevs (abfd, &cu);
-      make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+      back_to_inner = make_cleanup (dwarf2_free_abbrev_table, &cu);
 
       /* Read the compilation unit die */
       info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
                                   &cu);
 
       /* Set the language we're debugging */
-      set_cu_language (comp_unit_die.language);
+      set_cu_language (comp_unit_die.language, &cu);
 
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
@@ -1257,8 +1277,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
-       obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
-      cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+       obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
       DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
       DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
@@ -1318,6 +1337,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       info_ptr = beg_of_comp_unit + cu.header.length 
                                   + cu.header.initial_length_size;
+
+      do_cleanups (back_to_inner);
     }
   do_cleanups (back_to);
 }
@@ -1448,6 +1469,9 @@ add_partial_symbol (struct partial_die_info *pdi,
   CORE_ADDR addr = 0;
   char *actual_name = pdi->name;
   const struct partial_symbol *psym = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   /* If we're not in the global namespace and if the namespace name
      isn't encoded in a mangled actual_name, add it.  */
@@ -1471,7 +1495,7 @@ add_partial_symbol (struct partial_die_info *pdi,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       else
        {
@@ -1481,7 +1505,7 @@ add_partial_symbol (struct partial_die_info *pdi,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_variable:
@@ -1507,7 +1531,7 @@ add_partial_symbol (struct partial_die_info *pdi,
                                        VAR_DOMAIN, LOC_STATIC,
                                        &objfile->global_psymbols,
                                        0, addr + baseaddr,
-                                       cu_language, objfile);
+                                       cu->language, objfile);
        }
       else
        {
@@ -1521,7 +1545,7 @@ add_partial_symbol (struct partial_die_info *pdi,
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_typedef:
@@ -1530,7 +1554,7 @@ add_partial_symbol (struct partial_die_info *pdi,
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
@@ -1544,27 +1568,27 @@ add_partial_symbol (struct partial_die_info *pdi,
        return;
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
-                          cu_language == language_cplus
+                          cu->language == language_cplus
                           ? &objfile->global_psymbols
                           : &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          0, (CORE_ADDR) 0, cu->language, objfile);
 
-      if (cu_language == language_cplus)
+      if (cu->language == language_cplus)
        {
          /* For C++, these implicitly act as typedefs as well. */
          add_psymbol_to_list (actual_name, strlen (actual_name),
                               VAR_DOMAIN, LOC_TYPEDEF,
                               &objfile->global_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+                              0, (CORE_ADDR) 0, cu->language, objfile);
        }
       break;
     case DW_TAG_enumerator:
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_CONST,
-                          cu_language == language_cplus
-                          ? &objfile->static_psymbols
-                          : &objfile->global_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     default:
       break;
@@ -1576,7 +1600,7 @@ add_partial_symbol (struct partial_die_info *pdi,
      (otherwise we'll have psym == NULL), and if we actually had a
      mangled name to begin with.  */
 
-  if (cu_language == language_cplus
+  if (cu->language == language_cplus
       && namespace == NULL
       && psym != NULL
       && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
@@ -1639,7 +1663,7 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
-                      0, 0, cu_language, objfile);
+                      0, 0, cu->language, objfile);
 
   /* Now scan partial symbols in that namespace.  */
 
@@ -1659,13 +1683,13 @@ add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
   bfd *abfd = cu->objfile->obfd;
   char *actual_class_name = NULL;
 
-  if (cu_language == language_cplus
-      && namespace == NULL
+  if (cu->language == language_cplus
+      && (namespace == NULL || namespace[0] == '\0')
       && struct_pdi->name != NULL
       && struct_pdi->has_children)
     {
-      /* We don't have namespace debugging information, so see if we
-        can figure out if this structure lives in a namespace.  Look
+      /* See if we can figure out if the class lives in a namespace
+        (or is nested within another class.)  We do this by looking
         for a member function; its demangled name will contain
         namespace info, if there is any.  */
 
@@ -1673,7 +1697,22 @@ add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
         what template types look like, because the demangler
         frequently doesn't give the same name as the debug info.  We
         could fix this by only using the demangled name to get the
-        prefix (but see comment in read_structure_scope).  */
+        prefix (but see comment in read_structure_type).  */
+
+      /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have
+        the appropriate debug information, so it would be nice to be
+        able to avoid this hack.  But NAMESPACE may not be the
+        namespace where this class was defined: NAMESPACE reflects
+        where STRUCT_PDI occurs in the tree of dies, but because of
+        DW_AT_specification, that may not actually tell us where the
+        class is defined.  (See the comment in read_func_scope for an
+        example of how this could occur.)
+
+         Unfortunately, our current partial symtab data structures are
+         completely unable to deal with DW_AT_specification.  So, for
+         now, the best thing to do is to get nesting information from
+         places other than the tree structure of dies if there's any
+         chance that a DW_AT_specification is involved. :-( */
 
       char *next_child = info_ptr;
 
@@ -1701,7 +1740,7 @@ add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
     }
 
   add_partial_symbol (struct_pdi, cu, namespace);
-  xfree(actual_class_name);
+  xfree (actual_class_name);
 
   return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
 }
@@ -1733,8 +1772,154 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
   return info_ptr;
 }
 
-/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE
-   after ORIG_PDI.  */
+/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
+   Return the corresponding abbrev, or NULL if the number is zero (indicating
+   an empty DIE).  In either case *BYTES_READ will be set to the length of
+   the initial number.  */
+
+static struct abbrev_info *
+peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
+{
+  bfd *abfd = cu->objfile->obfd;
+  unsigned int abbrev_number;
+  struct abbrev_info *abbrev;
+
+  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+
+  if (abbrev_number == 0)
+    return NULL;
+
+  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));
+    }
+
+  return abbrev;
+}
+
+/* Scan the debug information for CU starting at INFO_PTR.  Returns a
+   pointer to the end of a series of DIEs, terminated by an empty
+   DIE.  Any children of the skipped DIEs will also be skipped.  */
+
+static char *
+skip_children (char *info_ptr, struct dwarf2_cu *cu)
+{
+  struct abbrev_info *abbrev;
+  unsigned int bytes_read;
+
+  while (1)
+    {
+      abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+      if (abbrev == NULL)
+       return info_ptr + bytes_read;
+      else
+       info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
+    }
+}
+
+/* Scan the debug information for CU starting at INFO_PTR.  INFO_PTR
+   should point just after the initial uleb128 of a DIE, and the
+   abbrev corresponding to that skipped uleb128 should be passed in
+   ABBREV.  Returns a pointer to this DIE's sibling, skipping any
+   children.  */
+
+static char *
+skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+             struct dwarf2_cu *cu)
+{
+  unsigned int bytes_read;
+  struct attribute attr;
+  bfd *abfd = cu->objfile->obfd;
+  unsigned int form, i;
+
+  for (i = 0; i < abbrev->num_attrs; i++)
+    {
+      /* The only abbrev we care about is DW_AT_sibling.  */
+      if (abbrev->attrs[i].name == DW_AT_sibling)
+       {
+         read_attribute (&attr, &abbrev->attrs[i],
+                         abfd, info_ptr, cu);
+         if (attr.form == DW_FORM_ref_addr)
+           complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+         else
+           return dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
+       }
+
+      /* If it isn't DW_AT_sibling, skip this attribute.  */
+      form = abbrev->attrs[i].form;
+    skip_attribute:
+      switch (form)
+       {
+       case DW_FORM_addr:
+       case DW_FORM_ref_addr:
+         info_ptr += cu->header.addr_size;
+         break;
+       case DW_FORM_data1:
+       case DW_FORM_ref1:
+       case DW_FORM_flag:
+         info_ptr += 1;
+         break;
+       case DW_FORM_data2:
+       case DW_FORM_ref2:
+         info_ptr += 2;
+         break;
+       case DW_FORM_data4:
+       case DW_FORM_ref4:
+         info_ptr += 4;
+         break;
+       case DW_FORM_data8:
+       case DW_FORM_ref8:
+         info_ptr += 8;
+         break;
+       case DW_FORM_string:
+         read_string (abfd, info_ptr, &bytes_read);
+         info_ptr += bytes_read;
+         break;
+       case DW_FORM_strp:
+         info_ptr += cu->header.offset_size;
+         break;
+       case DW_FORM_block:
+         info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+         info_ptr += bytes_read;
+         break;
+       case DW_FORM_block1:
+         info_ptr += 1 + read_1_byte (abfd, info_ptr);
+         break;
+       case DW_FORM_block2:
+         info_ptr += 2 + read_2_bytes (abfd, info_ptr);
+         break;
+       case DW_FORM_block4:
+         info_ptr += 4 + read_4_bytes (abfd, info_ptr);
+         break;
+       case DW_FORM_sdata:
+       case DW_FORM_udata:
+       case DW_FORM_ref_udata:
+         info_ptr = skip_leb128 (abfd, info_ptr);
+         break;
+       case DW_FORM_indirect:
+         form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+         info_ptr += bytes_read;
+         /* We need to continue parsing from here, so just go back to
+            the top.  */
+         goto skip_attribute;
+
+       default:
+         error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+                dwarf_form_name (form),
+                bfd_get_filename (abfd));
+       }
+    }
+
+  if (abbrev->has_children)
+    return skip_children (info_ptr, cu);
+  else
+    return info_ptr;
+}
+
+/* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of
+   the next DIE after ORIG_PDI.  */
 
 static char *
 locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
@@ -1750,21 +1935,9 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
   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);
+  /* Skip the children the long way.  */
 
-      if (pdi.tag == 0)
-       return info_ptr;
-      else
-       info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
-    }
+  return skip_children (info_ptr, cu);
 }
 
 /* Expand this partial symbol table into a full symbol table.  */
@@ -1810,6 +1983,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   struct symtab *symtab;
   struct cleanup *back_to;
   struct attribute *attr;
+  CORE_ADDR baseaddr;
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
@@ -1826,9 +2000,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
-  baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
-  cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   /* We're in the global namespace.  */
   processing_current_prefix = "";
@@ -1846,7 +2019,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 
   /* Read the abbrevs for this compilation unit  */
   dwarf2_read_abbrevs (abfd, &cu);
-  make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+  make_cleanup (dwarf2_free_abbrev_table, &cu);
+
+  cu.header.offset = offset;
+
+  cu.list_in_scope = &file_symbols;
 
   dies = read_comp_unit (info_ptr, abfd, &cu);
 
@@ -1861,7 +2038,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   cu.header.base_known = 0;
   cu.header.base_address = 0;
 
-  attr = dwarf_attr (dies, DW_AT_entry_pc);
+  attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
   if (attr)
     {
       cu.header.base_address = DW_ADDR (attr);
@@ -1869,7 +2046,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
     }
   else
     {
-      attr = dwarf_attr (dies, DW_AT_low_pc);
+      attr = dwarf2_attr (dies, DW_AT_low_pc, &cu);
       if (attr)
        {
          cu.header.base_address = DW_ADDR (attr);
@@ -1891,9 +2068,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
-      && !(cu_language == language_c && symtab->language != language_c))
+      && !(cu.language == language_c && symtab->language != language_c))
     {
-      symtab->language = cu_language;
+      symtab->language = cu.language;
     }
   pst->symtab = symtab;
   pst->readin = 1;
@@ -1930,11 +2107,17 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_scope (die, cu);
+      read_structure_type (die, cu);
+      process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration (die, cu);
+      read_enumeration_type (die, cu);
+      process_enumeration_scope (die, cu);
       break;
+
+    /* FIXME drow/2004-03-14: These initialize die->type, but do not create
+       a symbol or process any children.  Therefore it doesn't do anything
+       that won't be done on-demand by read_type_die.  */
     case DW_TAG_subroutine_type:
       read_subroutine_type (die, cu);
       break;
@@ -1953,21 +2136,19 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_string_type:
       read_tag_string_type (die, cu);
       break;
+    /* END FIXME */
+
     case DW_TAG_base_type:
       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, cu);
-       }
+      /* Add a typedef symbol for the type definition, if it has a
+        DW_AT_name.  */
+      new_symbol (die, die->type, cu);
       break;
     case DW_TAG_subrange_type:
       read_subrange_type (die, cu);
-      if (dwarf_attr (die, DW_AT_name))
-       {
-         /* Add a typedef symbol for the base type definition.  */
-         new_symbol (die, die->type, cu);
-       }
+      /* Add a typedef symbol for the type definition, if it has a
+         DW_AT_name.  */
+      new_symbol (die, die->type, cu);
       break;
     case DW_TAG_common_block:
       read_common_block (die, cu);
@@ -1996,9 +2177,9 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 static void
-initialize_cu_func_list (void)
+initialize_cu_func_list (struct dwarf2_cu *cu)
 {
-  cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+  cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
 }
 
 static void
@@ -2015,6 +2196,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
   struct line_header *line_header = 0;
+  CORE_ADDR baseaddr;
+  
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   get_scope_pc_bounds (die, &lowpc, &highpc, cu);
 
@@ -2025,12 +2209,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   lowpc += baseaddr;
   highpc += baseaddr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr)
     {
       name = DW_STRING (attr);
     }
-  attr = dwarf_attr (die, DW_AT_comp_dir);
+  attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
   if (attr)
     {
       comp_dir = DW_STRING (attr);
@@ -2052,10 +2236,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
       objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
-  attr = dwarf_attr (die, DW_AT_language);
+  attr = dwarf2_attr (die, DW_AT_language, cu);
   if (attr)
     {
-      set_cu_language (DW_UNSND (attr));
+      set_cu_language (DW_UNSND (attr), cu);
     }
 
   /* We assume that we're processing GCC output. */
@@ -2070,12 +2254,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* The compilation unit may be in a different language or objfile,
      zero out all remembered fundamental types.  */
-  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+  memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
-  initialize_cu_func_list ();
+  initialize_cu_func_list (cu);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -2089,7 +2273,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   /* Decode line number information if present.  */
-  attr = dwarf_attr (die, DW_AT_stmt_list);
+  attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
   if (attr)
     {
       unsigned int line_offset = DW_UNSND (attr);
@@ -2106,7 +2290,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
      refers to information in the line number info statement program
      header, so we can only read it if we've read the header
      successfully.  */
-  attr = dwarf_attr (die, DW_AT_macro_info);
+  attr = dwarf2_attr (die, DW_AT_macro_info, cu);
   if (attr && line_header)
     {
       unsigned int macro_offset = DW_UNSND (attr);
@@ -2117,7 +2301,8 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
+                    struct dwarf2_cu *cu)
 {
   struct function_range *thisfn;
 
@@ -2129,12 +2314,12 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
   thisfn->seen_line = 0;
   thisfn->next = NULL;
 
-  if (cu_last_fn == NULL)
-      cu_first_fn = thisfn;
+  if (cu->last_fn == NULL)
+      cu->first_fn = thisfn;
   else
-      cu_last_fn->next = thisfn;
+      cu->last_fn->next = thisfn;
 
-  cu_last_fn = thisfn;
+  cu->last_fn = thisfn;
 }
 
 static void
@@ -2149,43 +2334,46 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   char *name;
   const char *previous_prefix = processing_current_prefix;
   struct cleanup *back_to = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die);
+  name = dwarf2_linkage_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
 
-  if (cu_language == language_cplus)
+  if (cu->language == language_cplus)
     {
-      struct die_info *spec_die = die_specification (die);
+      struct die_info *spec_die = die_specification (die, cu);
 
-         /* NOTE: carlton/2004-01-23: We have to be careful in the
-            presence of DW_AT_specification.  For example, with GCC
-            3.4, given the code
+      /* NOTE: carlton/2004-01-23: We have to be careful in the
+         presence of DW_AT_specification.  For example, with GCC 3.4,
+         given the code
 
-               namespace N {
-                void foo() {
-                  // Definition of N::foo.
-                }
-              }
+           namespace N {
+             void foo() {
+               // Definition of N::foo.
+             }
+           }
 
-            then we'll have a tree of DIEs like this:
+         then we'll have a tree of DIEs like this:
 
-            1: DW_TAG_compile_unit
-               2: DW_TAG_namespace        // N
-                 3: DW_TAG_subprogram     // declaration of N::foo
-               4: DW_TAG_subprogram       // definition of N::foo
-                    DW_AT_specification   // refers to die #3
+         1: DW_TAG_compile_unit
+           2: DW_TAG_namespace        // N
+             3: DW_TAG_subprogram     // declaration of N::foo
+           4: DW_TAG_subprogram       // definition of N::foo
+                DW_AT_specification   // refers to die #3
 
-             Thus, when processing die #4, we have to pretend that
-             we're in the context of its DW_AT_specification, namely
-             the contex of die #3.  */
+         Thus, when processing die #4, we have to pretend that we're
+         in the context of its DW_AT_specification, namely the contex
+         of die #3.  */
        
       if (spec_die != NULL)
        {
-         char *specification_prefix = determine_prefix (spec_die);
+         char *specification_prefix = determine_prefix (spec_die, cu);
          processing_current_prefix = specification_prefix;
          back_to = make_cleanup (xfree, specification_prefix);
        }
@@ -2195,7 +2383,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   highpc += baseaddr;
 
   /* Record the function range for dwarf_decode_lines.  */
-  add_to_cu_func_list (name, lowpc, highpc);
+  add_to_cu_func_list (name, lowpc, highpc, cu);
 
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
@@ -2209,7 +2397,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
-  attr = dwarf_attr (die, DW_AT_frame_base);
+  attr = dwarf2_attr (die, DW_AT_frame_base, cu);
   if (attr)
     /* FIXME: cagney/2004-01-26: The DW_AT_frame_base's location
        expression is being recorded directly in the function's symbol
@@ -2222,7 +2410,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
        frame-base has-a location expression.  */
     dwarf2_symbol_mark_computed (attr, new->name, cu);
 
-  list_in_scope = &local_symbols;
+  cu->list_in_scope = &local_symbols;
 
   if (die->child != NULL)
     {
@@ -2249,7 +2437,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   /* If we've finished processing a top-level function, subsequent
      symbols go in the file symbol list.  */
   if (outermost_context_p ())
-    list_in_scope = &file_symbols;
+    cu->list_in_scope = &file_symbols;
 
   processing_current_prefix = previous_prefix;
   if (back_to != NULL)
@@ -2266,6 +2454,9 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct context_stack *new;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   /* Ignore blocks with missing or invalid low and high pc attributes.  */
   /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
@@ -2312,11 +2503,11 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   CORE_ADDR high = 0;
   int ret = 0;
 
-  attr = dwarf_attr (die, DW_AT_high_pc);
+  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
   if (attr)
     {
       high = DW_ADDR (attr);
-      attr = dwarf_attr (die, DW_AT_low_pc);
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr)
        low = DW_ADDR (attr);
       else
@@ -2328,7 +2519,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
     }
   else
     {
-      attr = dwarf_attr (die, DW_AT_ranges);
+      attr = dwarf2_attr (die, DW_AT_ranges, cu);
       if (attr != NULL)
        {
          unsigned int addr_size = cu_header->addr_size;
@@ -2547,18 +2738,18 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     new_field->accessibility = DW_ACCESS_private;
   new_field->virtuality = DW_VIRTUALITY_none;
 
-  attr = dwarf_attr (die, DW_AT_accessibility);
+  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr)
     new_field->accessibility = DW_UNSND (attr);
   if (new_field->accessibility != DW_ACCESS_public)
     fip->non_public_fields = 1;
-  attr = dwarf_attr (die, DW_AT_virtuality);
+  attr = dwarf2_attr (die, DW_AT_virtuality, cu);
   if (attr)
     new_field->virtuality = DW_UNSND (attr);
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die))
+  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
       /* Data member other than a C++ static data member.  */
       
@@ -2568,7 +2759,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       FIELD_STATIC_KIND (*fp) = 0;
 
       /* Get bit size of field (zero if none).  */
-      attr = dwarf_attr (die, DW_AT_bit_size);
+      attr = dwarf2_attr (die, DW_AT_bit_size, cu);
       if (attr)
        {
          FIELD_BITSIZE (*fp) = DW_UNSND (attr);
@@ -2579,7 +2770,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        {
          FIELD_BITPOS (*fp) =
@@ -2587,7 +2778,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
       else
        FIELD_BITPOS (*fp) = 0;
-      attr = dwarf_attr (die, DW_AT_bit_offset);
+      attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
          if (BITS_BIG_ENDIAN)
@@ -2610,7 +2801,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
              int anonymous_size;
              int bit_offset = DW_UNSND (attr);
 
-             attr = dwarf_attr (die, DW_AT_byte_size);
+             attr = dwarf2_attr (die, DW_AT_byte_size, cu);
              if (attr)
                {
                  /* The size of the anonymous object containing
@@ -2632,15 +2823,17 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
-      fp->name = obsavestring (fieldname, strlen (fieldname),
-                              &objfile->type_obstack);
+
+      /* The name is already allocated along with this objfile, so we don't
+        need to duplicate it for the type.  */
+      fp->name = fieldname;
 
       /* Change accessibility for artificial fields (e.g. virtual table
          pointer or virtual base class pointer) to private.  */
-      if (dwarf_attr (die, DW_AT_artificial))
+      if (dwarf2_attr (die, DW_AT_artificial, cu))
        {
          new_field->accessibility = DW_ACCESS_private;
          fip->non_public_fields = 1;
@@ -2658,25 +2851,25 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       char *physname;
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       else
        return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die);
+      physname = dwarf2_linkage_name (die, cu);
 
-      SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
-                                            &objfile->type_obstack));
+      /* The name is already allocated along with this objfile, so we don't
+        need to duplicate it for the type.  */
+      SET_FIELD_PHYSNAME (*fp, physname ? physname : "");
       FIELD_TYPE (*fp) = die_type (die, cu);
-      FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
-                                      &objfile->type_obstack);
+      FIELD_NAME (*fp) = fieldname;
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
                              * bits_per_byte);
@@ -2791,14 +2984,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   struct nextfnfield *new_fnfield;
 
   /* Get name of member function.  */
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     fieldname = DW_STRING (attr);
   else
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die);
+  physname = dwarf2_linkage_name (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -2839,8 +3032,9 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
-  fnp->physname = obsavestring (physname, strlen (physname),
-                               &objfile->type_obstack);
+  /* The name is already allocated along with this objfile, so we don't
+     need to duplicate it for the type.  */
+  fnp->physname = physname ? physname : "";
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
@@ -2868,14 +3062,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
-  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+  if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
     fnp->fcontext = die_containing_type (die, cu);
 
   /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
      and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
 
   /* Get accessibility.  */
-  attr = dwarf_attr (die, DW_AT_accessibility);
+  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr)
     {
       switch (DW_UNSND (attr))
@@ -2890,12 +3084,12 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
 
   /* Check for artificial methods.  */
-  attr = dwarf_attr (die, DW_AT_artificial);
+  attr = dwarf2_attr (die, DW_AT_artificial, cu);
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
   /* Get index in virtual function table if it is a virtual member function.  */
-  attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+  attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
@@ -2966,59 +3160,37 @@ 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 dwarf2_cu *cu)
+read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
-  const char *name = NULL;
   const char *previous_prefix = processing_current_prefix;
   struct cleanup *back_to = NULL;
-  /* This says whether or not we want to try to update the structure's
-     name to include enclosing namespace/class information, if
-     any.  */
-  int need_to_update_name = 0;
+
+  if (die->type)
+    return;
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
-      name = DW_STRING (attr);
-
-      if (cu_language == language_cplus)
-       {
-         struct die_info *spec_die = die_specification (die);
-
-         if (spec_die != NULL)
-           {
-             char *specification_prefix = determine_prefix (spec_die);
-             processing_current_prefix = specification_prefix;
-             back_to = make_cleanup (xfree, specification_prefix);
-           }
-       }
-
-      if (processing_has_namespace_info)
+      if (cu->language == language_cplus)
        {
-         /* FIXME: carlton/2003-11-10: This variable exists only for
-            const-correctness reasons.  When I tried to change
-            TYPE_TAG_NAME to be a const char *, I ran into a cascade
-            of changes which would have forced decode_line_1 to take
-            a const char **.  */
-         char *new_prefix = obconcat (&objfile->type_obstack,
-                                      processing_current_prefix,
-                                      processing_current_prefix[0] == '\0'
-                                      ? "" : "::",
-                                      name);
-         TYPE_TAG_NAME (type) = new_prefix;
+         char *new_prefix = determine_class_name (die, cu);
+         TYPE_TAG_NAME (type) = obsavestring (new_prefix,
+                                              strlen (new_prefix),
+                                              &objfile->objfile_obstack);
+         back_to = make_cleanup (xfree, new_prefix);
          processing_current_prefix = new_prefix;
        }
       else
        {
-         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
-                                              &objfile->type_obstack);
-         need_to_update_name = (cu_language == language_cplus);
+         /* The name is already allocated along with this objfile, so
+            we don't need to duplicate it for the type.  */
+         TYPE_TAG_NAME (type) = DW_STRING (attr);
        }
     }
 
@@ -3037,7 +3209,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3052,7 +3224,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
      type within the structure itself. */
   die->type = type;
 
-  if (die->child != NULL && ! die_is_declaration (die))
+  if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
       struct die_info *child_die;
@@ -3077,53 +3249,14 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
          else if (child_die->tag == DW_TAG_subprogram)
            {
              /* C++ member function. */
-             process_die (child_die, cu);
+             read_type_die (child_die, cu);
              dwarf2_add_member_fn (&fi, child_die, type, cu);
-             if (need_to_update_name)
-               {
-                 /* The demangled names of member functions contain
-                    information about enclosing namespaces/classes,
-                    if any.  */
-
-                 /* FIXME: carlton/2003-11-10: The excessive
-                    demangling here is a bit wasteful, as is the
-                    memory usage for names.  */
-
-                 /* NOTE: carlton/2003-11-10: As commented in
-                    add_partial_structure, the demangler sometimes
-                    prints the type info in a different form from the
-                    debug info.  We could solve this by using the
-                    demangled name to get the prefix; if doing so,
-                    however, we'd need to be careful when reading a
-                    class that's nested inside a template class.
-                    That would also cause problems when trying to
-                    determine RTTI information, since we use the
-                    demangler to determine the appropriate class
-                    name.  */
-                 char *actual_class_name
-                   = class_name_from_physname (dwarf2_linkage_name
-                                               (child_die));
-                 if (actual_class_name != NULL
-                     && strcmp (actual_class_name, name) != 0)
-                   {
-                     TYPE_TAG_NAME (type)
-                       = obsavestring (actual_class_name,
-                                       strlen (actual_class_name),
-                                       &objfile->type_obstack);
-                   }
-                 xfree (actual_class_name);
-                 need_to_update_name = 0;
-               }
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
              /* C++ base class field.  */
              dwarf2_add_field (&fi, child_die, cu);
            }
-         else
-           {
-             process_die (child_die, cu);
-           }
          child_die = sibling_die (child_die);
        }
 
@@ -3138,7 +3271,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
             class itself) which contains the vtable pointer for the current
             class from the DW_AT_containing_type attribute.  */
 
-         if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+         if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
            {
              struct type *t = die_containing_type (die, cu);
 
@@ -3180,8 +3313,6 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
            }
        }
 
-      new_symbol (die, type, cu);
-
       do_cleanups (back_to);
     }
   else
@@ -3195,38 +3326,67 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     do_cleanups (back_to);
 }
 
-/* Given a pointer to a die which begins an enumeration, process all
-   the dies that define the members of the enumeration.
+static void
+process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  const char *previous_prefix = processing_current_prefix;
+  struct die_info *child_die = die->child;
 
-   This will be much nicer in draft 6 of the DWARF spec when our
-   members will be dies instead squished into the DW_AT_element_list
-   attribute.
+  if (TYPE_TAG_NAME (die->type) != NULL)
+    processing_current_prefix = TYPE_TAG_NAME (die->type);
 
-   NOTE: We reverse the order of the element list.  */
+  /* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
+     snapshots) has been known to create a die giving a declaration
+     for a class that has, as a child, a die giving a definition for a
+     nested class.  So we have to process our children even if the
+     current die is a declaration.  Normally, of course, a declaration
+     won't have any children at all.  */
+
+  while (child_die != NULL && child_die->tag)
+    {
+      if (child_die->tag == DW_TAG_member
+         || child_die->tag == DW_TAG_variable
+         || child_die->tag == DW_TAG_inheritance)
+       {
+         /* Do nothing.  */
+       }
+      else
+       process_die (child_die, cu);
+
+      child_die = sibling_die (child_die);
+    }
+
+  if (die->child != NULL && ! die_is_declaration (die, cu))
+    new_symbol (die, die->type, cu);
+
+  processing_current_prefix = previous_prefix;
+}
+
+/* Given a DW_AT_enumeration_type die, set its type.  We do not
+   complete the type's fields yet, or create any symbols.  */
 
 static void
-read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
+read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  struct die_info *child_die;
   struct type *type;
-  struct field *fields;
   struct attribute *attr;
-  struct symbol *sym;
-  int num_fields;
-  int unsigned_enum = 1;
+
+  if (die->type)
+    return;
 
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
-      const char *name = DW_STRING (attr);
+      char *name = DW_STRING (attr);
 
       if (processing_has_namespace_info)
        {
-         TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+         TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
                                           processing_current_prefix,
                                           processing_current_prefix[0] == '\0'
                                           ? "" : "::",
@@ -3234,12 +3394,13 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
        }
       else
        {
-         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
-                                              &objfile->type_obstack);
+         /* The name is already allocated along with this objfile, so
+            we don't need to duplicate it for the type.  */
+         TYPE_TAG_NAME (type) = name;
        }
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3249,6 +3410,82 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
+  die->type = type;
+}
+
+/* Determine the name of the type represented by DIE, which should be
+   a named C++ compound type.  Return the name in question; the caller
+   is responsible for xfree()'ing it.  */
+
+static char *
+determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct cleanup *back_to = NULL;
+  struct die_info *spec_die = die_specification (die, cu);
+  char *new_prefix = NULL;
+
+  /* If this is the definition of a class that is declared by another
+     die, then processing_current_prefix may not be accurate; see
+     read_func_scope for a similar example.  */
+  if (spec_die != NULL)
+    {
+      char *specification_prefix = determine_prefix (spec_die, cu);
+      processing_current_prefix = specification_prefix;
+      back_to = make_cleanup (xfree, specification_prefix);
+    }
+
+  /* If we don't have namespace debug info, guess the name by trying
+     to demangle the names of members, just like we did in
+     add_partial_structure.  */
+  if (!processing_has_namespace_info)
+    {
+      struct die_info *child;
+
+      for (child = die->child;
+          child != NULL && child->tag != 0;
+          child = sibling_die (child))
+       {
+         if (child->tag == DW_TAG_subprogram)
+           {
+             new_prefix = class_name_from_physname (dwarf2_linkage_name
+                                                    (child, cu));
+
+             if (new_prefix != NULL)
+               break;
+           }
+       }
+    }
+
+  if (new_prefix == NULL)
+    {
+      const char *name = dwarf2_name (die, cu);
+      new_prefix = typename_concat (processing_current_prefix,
+                                   name ? name : "<<anonymous>>");
+    }
+
+  if (back_to != NULL)
+    do_cleanups (back_to);
+
+  return new_prefix;
+}
+
+/* Given a pointer to a die which begins an enumeration, process all
+   the dies that define the members of the enumeration, and create the
+   symbol for the enumeration type.
+
+   NOTE: We reverse the order of the element list.  */
+
+static void
+process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct die_info *child_die;
+  struct field *fields;
+  struct attribute *attr;
+  struct symbol *sym;
+  int num_fields;
+  int unsigned_enum = 1;
+
   num_fields = 0;
   fields = NULL;
   if (die->child != NULL)
@@ -3262,10 +3499,10 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
            }
          else
            {
-             attr = dwarf_attr (child_die, DW_AT_name);
+             attr = dwarf2_attr (child_die, DW_AT_name, cu);
              if (attr)
                {
-                 sym = new_symbol (child_die, type, cu);
+                 sym = new_symbol (child_die, die->type, cu);
                  if (SYMBOL_VALUE (sym) < 0)
                    unsigned_enum = 0;
 
@@ -3292,18 +3529,18 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
 
       if (num_fields)
        {
-         TYPE_NFIELDS (type) = num_fields;
-         TYPE_FIELDS (type) = (struct field *)
-           TYPE_ALLOC (type, sizeof (struct field) * num_fields);
-         memcpy (TYPE_FIELDS (type), fields,
+         TYPE_NFIELDS (die->type) = num_fields;
+         TYPE_FIELDS (die->type) = (struct field *)
+           TYPE_ALLOC (die->type, sizeof (struct field) * num_fields);
+         memcpy (TYPE_FIELDS (die->type), fields,
                  sizeof (struct field) * num_fields);
          xfree (fields);
        }
       if (unsigned_enum)
-       TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+       TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED;
     }
-  die->type = type;
-  new_symbol (die, type, cu);
+
+  new_symbol (die, die->type, cu);
 }
 
 /* Extract all information from a DW_TAG_array_type DIE and put it in
@@ -3334,7 +3571,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
      arrays with unspecified length.  */
   if (die->child == NULL)
     {
-      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
       range_type = create_range_type (NULL, index_type, 0, -1);
       die->type = create_array_type (NULL, element_type, range_type);
       return;
@@ -3378,7 +3615,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
      custom vendor extension.  The main difference between a regular
      array and the vector variant is that vectors are passed by value
      to functions.  */
-  attr = dwarf_attr (die, DW_AT_GNU_vector);
+  attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
   if (attr)
     TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
 
@@ -3398,7 +3635,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
 
-  attr = dwarf_attr (die, DW_AT_location);
+  attr = dwarf2_attr (die, DW_AT_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
@@ -3422,7 +3659,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          sym = new_symbol (child_die, NULL, cu);
-         attr = dwarf_attr (child_die, DW_AT_data_member_location);
+         attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) =
@@ -3445,7 +3682,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
   int is_anonymous;
   struct die_info *current_die;
 
-  name = namespace_name (die, &is_anonymous);
+  name = namespace_name (die, &is_anonymous, cu);
 
   /* Now build the name of the current namespace.  */
 
@@ -3470,7 +3707,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
-  if (dwarf2_extension (die) == NULL)
+  if (dwarf2_extension (die, cu) == NULL)
     {
       struct type *type;
 
@@ -3482,6 +3719,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
       new_symbol (die, type, cu);
+      die->type = type;
 
       if (is_anonymous)
        cp_add_using_directive (processing_current_prefix,
@@ -3508,7 +3746,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
    namespace.  */
 
 static const char *
-namespace_name (struct die_info *die, int *is_anonymous)
+namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
 {
   struct die_info *current_die;
   const char *name = NULL;
@@ -3517,9 +3755,9 @@ namespace_name (struct die_info *die, int *is_anonymous)
 
   for (current_die = die;
        current_die != NULL;
-       current_die = dwarf2_extension (die))
+       current_die = dwarf2_extension (die, cu))
     {
-      name = dwarf2_name (current_die);
+      name = dwarf2_name (current_die, cu);
       if (name != NULL)
        break;
     }
@@ -3552,13 +3790,13 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = lookup_pointer_type (die_type (die, cu));
 
-  attr_byte_size = dwarf_attr (die, DW_AT_byte_size);
+  attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr_byte_size)
     byte_size = DW_UNSND (attr_byte_size);
   else
     byte_size = cu_header->addr_size;
 
-  attr_address_class = dwarf_attr (die, DW_AT_address_class);
+  attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu);
   if (attr_address_class)
     addr_class = DW_UNSND (attr_address_class);
   else
@@ -3630,7 +3868,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   type = lookup_reference_type (die_type (die, cu));
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3688,7 +3926,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_string_length);
+  attr = dwarf2_attr (die, DW_AT_string_length, cu);
   if (attr)
     {
       length = DW_UNSND (attr);
@@ -3696,7 +3934,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
   else
     {
       /* check for the DW_AT_byte_size attribute */
-      attr = dwarf_attr (die, DW_AT_byte_size);
+      attr = dwarf2_attr (die, DW_AT_byte_size, cu);
       if (attr)
         {
           length = DW_UNSND (attr);
@@ -3706,9 +3944,9 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
           length = 1;
         }
     }
-  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
   range_type = create_range_type (NULL, index_type, 1, length);
-  if (cu_language == language_fortran)
+  if (cu->language == language_fortran)
     {
       /* Need to create a unique string type for bounds
          information */
@@ -3716,7 +3954,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
     }
   else
     {
-      char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+      char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
       type = create_string_type (char_type, range_type);
     }
   die->type = type;
@@ -3749,9 +3987,9 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
-  attr = dwarf_attr (die, DW_AT_prototyped);
+  attr = dwarf2_attr (die, DW_AT_prototyped, cu);
   if ((attr && (DW_UNSND (attr) != 0))
-      || cu_language == language_cplus)
+      || cu->language == language_cplus)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
   if (die->child != NULL)
@@ -3788,7 +4026,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
                 parameter for non-static member functions (which is the
                 this pointer) as artificial. We pass this information
                 to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
-             attr = dwarf_attr (child_die, DW_AT_artificial);
+             attr = dwarf2_attr (child_die, DW_AT_artificial, cu);
              if (attr)
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
              else
@@ -3812,7 +4050,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 
   if (!die->type)
     {
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        {
          name = DW_STRING (attr);
@@ -3839,17 +4077,17 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_encoding);
+  attr = dwarf2_attr (die, DW_AT_encoding, cu);
   if (attr)
     {
       encoding = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       size = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
@@ -3886,18 +4124,19 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
        }
       type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
       if (encoding == DW_ATE_address)
-       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID,
+                                                          cu);
       else if (encoding == DW_ATE_complex_float)
        {
          if (size == 32)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
          else if (size == 16)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
          else if (size == 8)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
     }
   else
@@ -3933,17 +4172,17 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
     base_type = alloc_type (NULL);
 
-  if (cu_language == language_fortran)
+  if (cu->language == language_fortran)
     { 
       /* FORTRAN implies a lower bound of 1, if not given.  */
       low = 1;
     }
 
-  attr = dwarf_attr (die, DW_AT_lower_bound);
+  attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
     low = dwarf2_get_attr_constant_value (attr, 0);
 
-  attr = dwarf_attr (die, DW_AT_upper_bound);
+  attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
   if (attr)
     {       
       if (attr->form == DW_FORM_block1)
@@ -3967,11 +4206,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, base_type, low, high);
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     TYPE_NAME (range_type) = DW_STRING (attr);
   
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     TYPE_LENGTH (range_type) = DW_UNSND (attr);
 
@@ -4101,7 +4340,7 @@ make_cleanup_free_die_list (struct die_info *dies)
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
-   object file specified by OBJFILE into the psymbol_obstack and return it.  */
+   object file specified by OBJFILE into the objfile_obstack and return it.  */
 
 char *
 dwarf2_read_section (struct objfile *objfile, asection *sectp)
@@ -4113,7 +4352,7 @@ dwarf2_read_section (struct objfile *objfile, asection *sectp)
   if (size == 0)
     return NULL;
 
-  buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+  buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
   retbuf
     = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
@@ -4140,19 +4379,28 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   unsigned int abbrev_form, hash_number;
+  struct attr_abbrev *cur_attrs;
+  unsigned int allocated_attrs;
 
   /* Initialize dwarf2 abbrevs */
-  memset (cu_header->dwarf2_abbrevs, 0,
-          ABBREV_HASH_SIZE*sizeof (struct abbrev_info *));
+  obstack_init (&cu->abbrev_obstack);
+  cu->dwarf2_abbrevs = obstack_alloc (&cu->abbrev_obstack,
+                                     (ABBREV_HASH_SIZE
+                                      * sizeof (struct abbrev_info *)));
+  memset (cu->dwarf2_abbrevs, 0,
+          ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
 
   abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset;
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
+  allocated_attrs = ATTR_ALLOC_CHUNK;
+  cur_attrs = xmalloc (allocated_attrs * sizeof (struct attr_abbrev));
+  
   /* loop until we reach an abbrev number of 0 */
   while (abbrev_number)
     {
-      cur_abbrev = dwarf_alloc_abbrev ();
+      cur_abbrev = dwarf_alloc_abbrev (cu);
 
       /* read in abbrev header */
       cur_abbrev->number = abbrev_number;
@@ -4168,24 +4416,30 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
       abbrev_ptr += bytes_read;
       while (abbrev_name)
        {
-         if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+         if (cur_abbrev->num_attrs == allocated_attrs)
            {
-             cur_abbrev->attrs = (struct attr_abbrev *)
-               xrealloc (cur_abbrev->attrs,
-                         (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
-                         * sizeof (struct attr_abbrev));
+             allocated_attrs += ATTR_ALLOC_CHUNK;
+             cur_attrs
+               = xrealloc (cur_attrs, (allocated_attrs
+                                       * sizeof (struct attr_abbrev)));
            }
-         cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
-         cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+         cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
+         cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
          abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
          abbrev_ptr += bytes_read;
          abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
          abbrev_ptr += bytes_read;
        }
 
+      cur_abbrev->attrs = obstack_alloc (&cu->abbrev_obstack,
+                                        (cur_abbrev->num_attrs
+                                         * sizeof (struct attr_abbrev)));
+      memcpy (cur_abbrev->attrs, cur_attrs,
+             cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
+
       hash_number = abbrev_number % ABBREV_HASH_SIZE;
-      cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number];
-      cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev;
+      cur_abbrev->next = cu->dwarf2_abbrevs[hash_number];
+      cu->dwarf2_abbrevs[hash_number] = cur_abbrev;
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
@@ -4202,32 +4456,19 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
       if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
        break;
     }
+
+  xfree (cur_attrs);
 }
 
-/* Empty the abbrev table for a new compilation unit.  */
+/* Release the memory used by the abbrev table for a compilation unit.  */
 
 static void
-dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
+dwarf2_free_abbrev_table (void *ptr_to_cu)
 {
-  int i;
-  struct abbrev_info *abbrev, *next;
-  struct abbrev_info **abbrevs;
+  struct dwarf2_cu *cu = ptr_to_cu;
 
-  abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table;
-
-  for (i = 0; i < ABBREV_HASH_SIZE; ++i)
-    {
-      next = NULL;
-      abbrev = abbrevs[i];
-      while (abbrev)
-       {
-         next = abbrev->next;
-         xfree (abbrev->attrs);
-         xfree (abbrev);
-         abbrev = next;
-       }
-      abbrevs[i] = NULL;
-    }
+  obstack_free (&cu->abbrev_obstack, NULL);
+  cu->dwarf2_abbrevs = NULL;
 }
 
 /* Lookup an abbrev_info structure in the abbrev hash table.  */
@@ -4235,12 +4476,11 @@ dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
 static struct abbrev_info *
 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;
 
   hash_number = number % ABBREV_HASH_SIZE;
-  abbrev = cu_header->dwarf2_abbrevs[hash_number];
+  abbrev = cu->dwarf2_abbrevs[hash_number];
 
   while (abbrev)
     {
@@ -4348,7 +4588,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
            complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
          else
            part_die->sibling =
-             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
          break;
        default:
          break;
@@ -4363,7 +4603,8 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
       struct partial_die_info spec_die;
       char *spec_ptr;
 
-      spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+      spec_ptr = dwarf_info_buffer
+       + dwarf2_get_ref_die_offset (&spec_attr, cu);
       read_partial_die (&spec_die, abfd, spec_ptr, cu);
       if (spec_die.name)
        {
@@ -4896,28 +5137,44 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
   return result;
 }
 
+/* Return a pointer to just past the end of an LEB128 number in BUF.  */
+
+static char *
+skip_leb128 (bfd *abfd, char *buf)
+{
+  int byte;
+
+  while (1)
+    {
+      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      buf++;
+      if ((byte & 128) == 0)
+       return buf;
+    }
+}
+
 static void
-set_cu_language (unsigned int lang)
+set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
 {
   switch (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
-      cu_language = language_c;
+      cu->language = language_c;
       break;
     case DW_LANG_C_plus_plus:
-      cu_language = language_cplus;
+      cu->language = language_cplus;
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
-      cu_language = language_fortran;
+      cu->language = language_fortran;
       break;
     case DW_LANG_Mips_Assembler:
-      cu_language = language_asm;
+      cu->language = language_asm;
       break;
     case DW_LANG_Java:
-      cu_language = language_java;
+      cu->language = language_java;
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
@@ -4926,16 +5183,16 @@ set_cu_language (unsigned int lang)
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
-      cu_language = language_minimal;
+      cu->language = language_minimal;
       break;
     }
-  cu_language_defn = language_def (cu_language);
+  cu->language_defn = language_def (cu->language);
 }
 
 /* Return the named attribute or NULL if not there.  */
 
 static struct attribute *
-dwarf_attr (struct die_info *die, unsigned int name)
+dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
 {
   unsigned int i;
   struct attribute *spec = NULL;
@@ -4953,34 +5210,34 @@ dwarf_attr (struct die_info *die, unsigned int name)
   if (spec)
     {
       struct die_info *ref_die =
-      follow_die_ref (dwarf2_get_ref_die_offset (spec));
+      follow_die_ref (dwarf2_get_ref_die_offset (spec, cu));
 
       if (ref_die)
-       return dwarf_attr (ref_die, name);
+       return dwarf2_attr (ref_die, name, cu);
     }
 
   return NULL;
 }
 
 static int
-die_is_declaration (struct die_info *die)
+die_is_declaration (struct die_info *die, struct dwarf2_cu *cu)
 {
-  return (dwarf_attr (die, DW_AT_declaration)
-         && ! dwarf_attr (die, DW_AT_specification));
+  return (dwarf2_attr (die, DW_AT_declaration, cu)
+         && ! dwarf2_attr (die, DW_AT_specification, cu));
 }
 
 /* Return the die giving the specification for DIE, if there is
    one.  */
 
 static struct die_info *
-die_specification (struct die_info *die)
+die_specification (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
 
   if (spec_attr == NULL)
     return NULL;
   else
-    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
 }
 
 /* Free the line_header structure *LH, and any arrays and strings it
@@ -5174,26 +5431,26 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
    addresses passed to record_line.  */
 
 static CORE_ADDR
-check_cu_functions (CORE_ADDR address)
+check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
 {
   struct function_range *fn;
 
   /* Find the function_range containing address.  */
-  if (!cu_first_fn)
+  if (!cu->first_fn)
     return address;
 
-  if (!cu_cached_fn)
-    cu_cached_fn = cu_first_fn;
+  if (!cu->cached_fn)
+    cu->cached_fn = cu->first_fn;
 
-  fn = cu_cached_fn;
+  fn = cu->cached_fn;
   while (fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
       fn = fn->next;
 
-  fn = cu_first_fn;
-  while (fn && fn != cu_cached_fn)
+  fn = cu->first_fn;
+  while (fn && fn != cu->cached_fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
@@ -5224,6 +5481,10 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
   char *line_end;
   unsigned int bytes_read;
   unsigned char op_code, extended_op, adj_opcode;
+  CORE_ADDR baseaddr;
+  struct objfile *objfile = cu->objfile;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
@@ -5269,7 +5530,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 1;
            }
          else switch (op_code)
@@ -5316,7 +5577,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              break;
            case DW_LNS_copy:
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -5497,21 +5758,24 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die);
+    name = dwarf2_linkage_name (die, cu);
   else
     name = TYPE_NAME (type);
 
   if (name)
     {
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+      sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
-      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_LANGUAGE (sym) = cu->language;
       SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
@@ -5522,7 +5786,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
        SYMBOL_TYPE (sym) = type;
       else
        SYMBOL_TYPE (sym) = die_type (die, cu);
-      attr = dwarf_attr (die, DW_AT_decl_line);
+      attr = dwarf2_attr (die, DW_AT_decl_line, cu);
       if (attr)
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
@@ -5530,7 +5794,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       switch (die->tag)
        {
        case DW_TAG_label:
-         attr = dwarf_attr (die, DW_AT_low_pc);
+         attr = dwarf2_attr (die, DW_AT_low_pc, cu);
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
@@ -5541,14 +5805,14 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
-         attr2 = dwarf_attr (die, DW_AT_external);
+         attr2 = dwarf2_attr (die, DW_AT_external, cu);
          if (attr2 && (DW_UNSND (attr2) != 0))
            {
              add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
-             add_symbol_to_list (sym, list_in_scope);
+             add_symbol_to_list (sym, cu->list_in_scope);
            }
          break;
        case DW_TAG_variable:
@@ -5560,26 +5824,26 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
                                           TARGET_INT_BIT / HOST_CHAR_BIT, 0,
                                           "<variable, no debug info>",
                                           objfile);
-         attr = dwarf_attr (die, DW_AT_const_value);
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
              dwarf2_const_value (attr, sym, cu);
-             attr2 = dwarf_attr (die, DW_AT_external);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
              break;
            }
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
              var_decode_location (attr, sym, cu);
-             attr2 = dwarf_attr (die, DW_AT_external);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
            }
          else
            {
@@ -5589,9 +5853,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
                 The address of the variable will then be determined from
                 the minimal symbol table whenever the variable is
                 referenced.  */
-             attr2 = dwarf_attr (die, DW_AT_external);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0)
-                 && dwarf_attr (die, DW_AT_type) != NULL)
+                 && dwarf2_attr (die, DW_AT_type, cu) != NULL)
                {
                  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                  add_symbol_to_list (sym, &global_symbols);
@@ -5599,7 +5863,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            }
          break;
        case DW_TAG_formal_parameter:
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
              var_decode_location (attr, sym, cu);
@@ -5607,12 +5871,12 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
              if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
                SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
            }
-         attr = dwarf_attr (die, DW_AT_const_value);
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
              dwarf2_const_value (attr, sym, cu);
            }
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_unspecified_parameters:
          /* From varargs functions; gdb doesn't seem to have any
@@ -5628,10 +5892,10 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
          /* Make sure that the symbol includes appropriate enclosing
             classes/namespaces in its name.  These are calculated in
-            read_structure_scope, and the correct name is saved in
+            read_structure_type, and the correct name is saved in
             the type.  */
 
-         if (cu_language == language_cplus)
+         if (cu->language == language_cplus)
            {
              struct type *type = SYMBOL_TYPE (sym);
              
@@ -5639,11 +5903,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
                {
                  /* FIXME: carlton/2003-11-10: Should this use
                     SYMBOL_SET_NAMES instead?  (The same problem also
-                    arises a further down in the function.)  */
-                 SYMBOL_LINKAGE_NAME (sym)
-                   = obsavestring (TYPE_TAG_NAME (type),
-                                   strlen (TYPE_TAG_NAME (type)),
-                                   &objfile->symbol_obstack);
+                    arises further down in this function.)  */
+                 /* The type's name is already allocated along with
+                    this objfile, so we don't need to duplicate it
+                    for the symbol.  */
+                 SYMBOL_LINKAGE_NAME (sym) = TYPE_TAG_NAME (type);
                }
            }
 
@@ -5658,27 +5922,27 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
            struct pending **list_to_add;
 
-           list_to_add = (list_in_scope == &file_symbols
-                          && cu_language == language_cplus
-                          ? &global_symbols : list_in_scope);
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
          
            add_symbol_to_list (sym, list_to_add);
 
            /* The semantics of C++ state that "struct foo { ... }" also
               defines a typedef for "foo". Synthesize a typedef symbol so
               that "ptype foo" works as expected.  */
-           if (cu_language == language_cplus)
+           if (cu->language == language_cplus)
              {
                struct symbol *typedef_sym = (struct symbol *)
-                 obstack_alloc (&objfile->symbol_obstack,
+                 obstack_alloc (&objfile->objfile_obstack,
                                 sizeof (struct symbol));
                *typedef_sym = *sym;
                SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+               /* The symbol's name is already allocated along with
+                  this objfile, so we don't need to duplicate it for
+                  the type.  */
                if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-                 TYPE_NAME (SYMBOL_TYPE (sym)) =
-                   obsavestring (SYMBOL_NATURAL_NAME (sym),
-                                 strlen (SYMBOL_NATURAL_NAME (sym)),
-                                 &objfile->type_obstack);
+                 TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NATURAL_NAME (sym);
                add_symbol_to_list (typedef_sym, list_to_add);
              }
          }
@@ -5687,31 +5951,31 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
          if (processing_has_namespace_info
              && processing_current_prefix[0] != '\0')
            {
-             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
                                                    processing_current_prefix,
                                                    "::",
                                                    name);
            }
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_base_type:
         case DW_TAG_subrange_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_enumerator:
          if (processing_has_namespace_info
              && processing_current_prefix[0] != '\0')
            {
-             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
                                                    processing_current_prefix,
                                                    "::",
                                                    name);
            }
-         attr = dwarf_attr (die, DW_AT_const_value);
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
              dwarf2_const_value (attr, sym, cu);
@@ -5722,9 +5986,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
            struct pending **list_to_add;
 
-           list_to_add = (list_in_scope == &file_symbols
-                          && cu_language == language_cplus
-                          ? &global_symbols : list_in_scope);
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
          
            add_symbol_to_list (sym, list_to_add);
          }
@@ -5765,7 +6029,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+       obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size);
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
       store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
@@ -5783,7 +6047,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, blk->size);
+       obstack_alloc (&objfile->objfile_obstack, blk->size);
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
@@ -5859,15 +6123,15 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *type_die;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_type);
+  type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
-      return dwarf2_fundamental_type (cu->objfile, FT_VOID);
+      return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
     }
   else
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
@@ -5897,10 +6161,10 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *type_die = NULL;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_containing_type);
+  type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
@@ -5961,7 +6225,7 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_type_die (struct die_info *die, struct dwarf2_cu *cu)
 {
-  char *prefix = determine_prefix (die);
+  char *prefix = determine_prefix (die, cu);
   const char *old_prefix = processing_current_prefix;
   struct cleanup *back_to = make_cleanup (xfree, prefix);
   processing_current_prefix = prefix;
@@ -5971,10 +6235,10 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_scope (die, cu);
+      read_structure_type (die, cu);
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration (die, cu);
+      read_enumeration_type (die, cu);
       break;
     case DW_TAG_subprogram:
     case DW_TAG_subroutine_type:
@@ -6028,72 +6292,66 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
    DW_AT_specification.  */
 
 static char *
-determine_prefix (struct die_info *die)
-{
-  char *prefix = determine_prefix_aux (die);
-
-  return prefix ? prefix : xstrdup ("");
-}
-
-/* Return the name of the namespace/class that DIE is defined
-   within, or NULL if we can't tell.  The caller should xfree the
-   result.  */
-
-static char *
-determine_prefix_aux (struct die_info *die)
+determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct die_info *parent;
 
-  if (cu_language != language_cplus)
+  if (cu->language != language_cplus)
     return NULL;
 
   parent = die->parent;
 
   if (parent == NULL)
     {
-      return (processing_has_namespace_info ? xstrdup ("") : NULL);
+      return xstrdup ("");
     }
   else
     {
-      char *parent_prefix = determine_prefix_aux (parent);
-      char *retval;
-
       switch (parent->tag) {
       case DW_TAG_namespace:
        {
-         int dummy;
-
-         retval = typename_concat (parent_prefix,
-                                   namespace_name (parent, &dummy));
+         /* FIXME: carlton/2004-03-05: Should I follow extension dies
+            before doing this check?  */
+         if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+           {
+             return xstrdup (TYPE_TAG_NAME (parent->type));
+           }
+         else
+           {
+             int dummy;
+             char *parent_prefix = determine_prefix (parent, cu);
+             char *retval = typename_concat (parent_prefix,
+                                             namespace_name (parent, &dummy,
+                                                             cu));
+             xfree (parent_prefix);
+             return retval;
+           }
        }
        break;
       case DW_TAG_class_type:
       case DW_TAG_structure_type:
        {
-         if (parent_prefix != NULL)
+         if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
            {
-             const char *parent_name = dwarf2_name (parent);
-
-             if (parent_name != NULL)
-               retval = typename_concat (parent_prefix, dwarf2_name (parent));
-             else
-               /* FIXME: carlton/2003-11-10: I'm not sure what the
-                  best thing to do here is.  */
-               retval = typename_concat (parent_prefix,
-                                         "<<anonymous class>>");
+             return xstrdup (TYPE_TAG_NAME (parent->type));
            }
          else
-           retval = class_name (parent);
+           {
+             const char *old_prefix = processing_current_prefix;
+             char *new_prefix = determine_prefix (parent, cu);
+             char *retval;
+
+             processing_current_prefix = new_prefix;
+             retval = determine_class_name (parent, cu);
+             processing_current_prefix = old_prefix;
+
+             xfree (new_prefix);
+             return retval;
+           }
        }
-       break;
       default:
-       retval = parent_prefix;
-       break;
+       return determine_prefix (parent, cu);
       }
-
-      if (retval != parent_prefix)
-       xfree (parent_prefix);
-      return retval;
     }
 }
 
@@ -6118,28 +6376,6 @@ typename_concat (const char *prefix, const char *suffix)
     }
 }
 
-/* Return a newly-allocated string giving the name of the class given
-   by DIE.  */
-
-static char *
-class_name (struct die_info *die)
-{
-  struct die_info *child;
-  const char *name;
-
-  for (child = die->child; child != NULL; child = sibling_die (child))
-    {
-      if (child->tag == DW_TAG_subprogram)
-       return class_name_from_physname (dwarf2_linkage_name (child));
-    }
-
-  name = dwarf2_name (die);
-  if (name != NULL)
-    return xstrdup (name);
-  else
-    return xstrdup ("");
-}
-
 static struct type *
 dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
 {
@@ -6151,69 +6387,69 @@ dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
   switch (encoding)
     {
     case DW_ATE_address:
-      type = dwarf2_fundamental_type (objfile, FT_VOID);
+      type = dwarf2_fundamental_type (objfile, FT_VOID, cu);
       return type;
     case DW_ATE_boolean:
-      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu);
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu);
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu);
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu);
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_signed_char:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu);
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
-      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
       return type;
     default:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
       return type;
     }
 }
@@ -6262,14 +6498,14 @@ sibling_die (struct die_info *die)
 /* Get linkage name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_linkage_name (struct die_info *die)
+dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -6278,11 +6514,11 @@ dwarf2_linkage_name (struct die_info *die)
 /* Get name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_name (struct die_info *die)
+dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -6292,17 +6528,17 @@ dwarf2_name (struct die_info *die)
    is none.  */
 
 static struct die_info *
-dwarf2_extension (struct die_info *die)
+dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
 
-  attr = dwarf_attr (die, DW_AT_extension);
+  attr = dwarf2_attr (die, DW_AT_extension, cu);
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr);
+  ref = dwarf2_get_ref_die_offset (attr, cu);
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
@@ -7215,7 +7451,7 @@ dwarf2_empty_hash_tables (void)
 }
 
 static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
 {
   unsigned int result = 0;
 
@@ -7229,7 +7465,7 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      result = cu_header_offset + DW_UNSND (attr);
+      result = cu->header.offset + DW_UNSND (attr);
       break;
     default:
       complaint (&symfile_complaints,
@@ -7281,7 +7517,8 @@ follow_die_ref (unsigned int offset)
 }
 
 static struct type *
-dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+dwarf2_fundamental_type (struct objfile *objfile, int typeid,
+                        struct dwarf2_cu *cu)
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
@@ -7293,12 +7530,12 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid)
      one is not found, create and install one appropriate for the
      current language and the current target machine. */
 
-  if (ftypes[typeid] == NULL)
+  if (cu->ftypes[typeid] == NULL)
     {
-      ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+      cu->ftypes[typeid] = cu->language_defn->la_fund_type (objfile, typeid);
     }
 
-  return (ftypes[typeid]);
+  return (cu->ftypes[typeid]);
 }
 
 /* Decode simple location descriptions.
@@ -7546,11 +7783,12 @@ dwarf_alloc_block (void)
 }
 
 static struct abbrev_info *
-dwarf_alloc_abbrev (void)
+dwarf_alloc_abbrev (struct dwarf2_cu *cu)
 {
   struct abbrev_info *abbrev;
 
-  abbrev = (struct abbrev_info *) xmalloc (sizeof (struct abbrev_info));
+  abbrev = (struct abbrev_info *)
+    obstack_alloc (&cu->abbrev_obstack, sizeof (struct abbrev_info));
   memset (abbrev, 0, sizeof (struct abbrev_info));
   return (abbrev);
 }
@@ -7618,7 +7856,7 @@ macro_start_file (int file, int line,
   /* We don't create a macro table for this compilation unit
      at all until we actually get a filename.  */
   if (! pending_macros)
-    pending_macros = new_macro_table (&objfile->symbol_obstack,
+    pending_macros = new_macro_table (&objfile->objfile_obstack,
                                       objfile->macro_cache);
 
   if (! current_file)
@@ -7961,7 +8199,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     {
       struct dwarf2_loclist_baton *baton;
 
-      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_loclist_baton));
       baton->objfile = cu->objfile;
 
@@ -7981,7 +8219,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     {
       struct dwarf2_locexpr_baton *baton;
 
-      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
       baton->objfile = cu->objfile;
 
This page took 0.099551 seconds and 4 git commands to generate.