*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index b151d60ec8d21ba3e4bb7698fe49416168f60d89..ffc76c85875afd285c1cd0400d12f980c3553c93 100644 (file)
@@ -1,5 +1,6 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -30,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
@@ -205,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;
@@ -227,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
@@ -301,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 */
   };
@@ -359,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)
@@ -390,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;
@@ -415,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
@@ -435,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
   {
@@ -524,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.  */
@@ -590,13 +595,6 @@ struct field_info
 
 /* Various complaints about symbol reading that don't abort the process */
 
-static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
-            arg1);
-}
-
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
@@ -610,13 +608,6 @@ dwarf2_complex_location_expr_complaint (void)
   complaint (&symfile_complaints, "location expression too complex");
 }
 
-static void
-dwarf2_unsupported_at_frame_base_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints,
-            "unsupported DW_AT_frame_base for function '%s'", arg1);
-}
-
 static void
 dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
@@ -665,12 +656,19 @@ static char *scan_partial_symbols (char *, CORE_ADDR *, CORE_ADDR *,
 static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
                                const char *namespace);
 
+static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace);
+
 static char *add_partial_namespace (struct partial_die_info *pdi,
                                    char *info_ptr,
                                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
                                    struct dwarf2_cu *cu,
                                    const char *namespace);
 
+static char *add_partial_structure (struct partial_die_info *struct_pdi,
+                                   char *info_ptr,
+                                   struct dwarf2_cu *cu,
+                                   const char *namespace);
+
 static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
                                      char *info_ptr,
                                      struct dwarf2_cu *cu,
@@ -689,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 *);
@@ -736,11 +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 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);
 
@@ -776,10 +780,20 @@ static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
 
 static void read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
+
+static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *);
+
+static char *typename_concat (const char *prefix, const char *suffix);
+
+static char *class_name (struct die_info *die, struct dwarf2_cu *);
+
 static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
 static void read_base_type (struct die_info *, struct dwarf2_cu *);
 
+static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu);
+
 static void read_file_scope (struct die_info *, struct dwarf2_cu *);
 
 static void read_func_scope (struct die_info *, struct dwarf2_cu *);
@@ -789,6 +803,10 @@ static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 static int dwarf2_get_pc_bounds (struct die_info *,
                                 CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
 
+static void get_scope_pc_bounds (struct die_info *,
+                                CORE_ADDR *, CORE_ADDR *,
+                                struct dwarf2_cu *);
+
 static void dwarf2_add_field (struct field_info *, struct die_info *,
                              struct dwarf2_cu *);
 
@@ -808,6 +826,9 @@ 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, struct dwarf2_cu *);
+
 static void read_enumeration (struct die_info *, struct dwarf2_cu *);
 
 static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
@@ -849,11 +870,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);
 
@@ -883,11 +905,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 */
 
@@ -895,13 +921,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 *);
@@ -912,6 +939,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.  */
 
@@ -1139,7 +1169,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;
@@ -1190,6 +1220,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;
 
@@ -1223,16 +1254,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,
@@ -1242,8 +1275,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;
@@ -1303,6 +1335,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);
 }
@@ -1364,11 +1398,18 @@ scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
+             if (!pdi.is_declaration)
+               {
+                 add_partial_symbol (&pdi, cu, namespace);
+               }
+             break;
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
              if (!pdi.is_declaration)
                {
-                 add_partial_symbol (&pdi, cu, namespace);
+                 info_ptr = add_partial_structure (&pdi, info_ptr, cu,
+                                                   namespace);
+                 info_ptr_updated = 1;
                }
              break;
            case DW_TAG_enumeration_type:
@@ -1380,6 +1421,7 @@ scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
                }
              break;
            case DW_TAG_base_type:
+            case DW_TAG_subrange_type:
              /* File scope base type definitions are added to the partial
                 symbol table.  */
              add_partial_symbol (&pdi, cu, namespace);
@@ -1423,30 +1465,45 @@ add_partial_symbol (struct partial_die_info *pdi,
 {
   struct objfile *objfile = cu->objfile;
   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.  */
+  
+  if (pdi_needs_namespace (pdi->tag, namespace))
+    {
+      actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
+      strcpy (actual_name, namespace);
+      strcat (actual_name, "::");
+      strcat (actual_name, pdi->name);
+    }
 
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       else
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_file_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_variable:
@@ -1468,11 +1525,11 @@ add_partial_symbol (struct partial_die_info *pdi,
          if (pdi->locdesc)
            addr = decode_locdesc (pdi->locdesc, cu);
          if (pdi->locdesc || pdi->has_type)
-           psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+           psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                        VAR_DOMAIN, LOC_STATIC,
                                        &objfile->global_psymbols,
                                        0, addr + baseaddr,
-                                       cu_language, objfile);
+                                       cu->language, objfile);
        }
       else
        {
@@ -1480,21 +1537,22 @@ add_partial_symbol (struct partial_die_info *pdi,
          if (pdi->locdesc == NULL)
            return;
          addr = decode_locdesc (pdi->locdesc, cu);
-         /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, addr + baseaddr,
             mst_file_data, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+    case DW_TAG_subrange_type:
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
-                          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:
@@ -1502,27 +1560,33 @@ add_partial_symbol (struct partial_die_info *pdi,
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
+      /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+        static vs. global.  */
       if (pdi->has_children == 0)
        return;
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
 
-      if (cu_language == language_cplus)
+      if (cu->language == language_cplus)
        {
          /* For C++, these implicitly act as typedefs as well. */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         add_psymbol_to_list (actual_name, strlen (actual_name),
                               VAR_DOMAIN, LOC_TYPEDEF,
-                              &objfile->static_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+                              &objfile->global_psymbols,
+                              0, (CORE_ADDR) 0, cu->language, objfile);
        }
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_CONST,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     default:
       break;
@@ -1534,7 +1598,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)
@@ -1542,6 +1606,30 @@ add_partial_symbol (struct partial_die_info *pdi,
                                         objfile);
 }
 
+/* Determine whether a die of type TAG living in the C++ namespace
+   NAMESPACE needs to have the name of the namespace prepended to the
+   name listed in the die.  */
+
+static int
+pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
+{
+  if (namespace == NULL || namespace[0] == '\0')
+    return 0;
+
+  switch (tag)
+    {
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
@@ -1565,14 +1653,15 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
-  /* FIXME: carlton/2003-06-27: Once we build qualified names for more
-     symbols than just namespaces, we should replace this by a call to
-     add_partial_symbol.  */
+  /* FIXME: carlton/2003-10-07: We can't just replace this by a call
+     to add_partial_symbol, because we don't have a way to pass in the
+     full name to that function; that might be a flaw in
+     add_partial_symbol's interface.  */
 
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
-                      0, 0, cu_language, objfile);
+                      0, 0, cu->language, objfile);
 
   /* Now scan partial symbols in that namespace.  */
 
@@ -1582,6 +1671,78 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
   return info_ptr;
 }
 
+/* Read a partial die corresponding to a class or structure.  */
+
+static char *
+add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
+                      struct dwarf2_cu *cu,
+                      const char *namespace)
+{
+  bfd *abfd = cu->objfile->obfd;
+  char *actual_class_name = NULL;
+
+  if (cu->language == language_cplus
+      && (namespace == NULL || namespace[0] == '\0')
+      && struct_pdi->name != NULL
+      && struct_pdi->has_children)
+    {
+      /* See if we can figure out if the class lives in a namespace
+        (or is nested within another class.)  We do this by looking
+        for a member function; its demangled name will contain
+        namespace info, if there is any.  */
+
+      /* NOTE: carlton/2003-10-07: Getting the info this way changes
+        what template types look like, because the demangler
+        frequently doesn't give the same name as the debug info.  We
+        could fix this by only using the demangled name to get the
+        prefix (but see comment in read_structure_scope).  */
+
+      /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have
+        the appropriate debug information, so it would be nice to be
+        able to avoid this hack.  But NAMESPACE may not be the
+        namespace where this class was defined: NAMESPACE reflects
+        where STRUCT_PDI occurs in the tree of dies, but because of
+        DW_AT_specification, that may not actually tell us where the
+        class is defined.  (See the comment in read_func_scope for an
+        example of how this could occur.)
+
+         Unfortunately, our current partial symtab data structures are
+         completely unable to deal with DW_AT_specification.  So, for
+         now, the best thing to do is to get nesting information from
+         places other than the tree structure of dies if there's any
+         chance that a DW_AT_specification is involved. :-( */
+
+      char *next_child = info_ptr;
+
+      while (1)
+       {
+         struct partial_die_info child_pdi;
+
+         next_child = read_partial_die (&child_pdi, abfd, next_child,
+                                        cu);
+         if (!child_pdi.tag)
+           break;
+         if (child_pdi.tag == DW_TAG_subprogram)
+           {
+             actual_class_name = class_name_from_physname (child_pdi.name);
+             if (actual_class_name != NULL)
+               struct_pdi->name = actual_class_name;
+             break;
+           }
+         else
+           {
+             next_child = locate_pdi_sibling (&child_pdi, next_child,
+                                              abfd, cu);
+           }
+       }
+    }
+
+  add_partial_symbol (struct_pdi, cu, namespace);
+  xfree (actual_class_name);
+
+  return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
+}
+
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
@@ -1609,8 +1770,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,
@@ -1626,21 +1933,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.  */
@@ -1686,6 +1981,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);
@@ -1702,9 +1998,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
-  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 = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -1719,7 +2017,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);
 
@@ -1734,7 +2036,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);
@@ -1742,7 +2044,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);
@@ -1753,39 +2055,20 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   /* Do line number decoding in read_file_scope () */
   process_die (dies, &cu);
 
-  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, &cu))
-    {
-      /* Some compilers don't define a DW_AT_high_pc attribute for
-         the compilation unit.   If the DW_AT_high_pc is missing,
-         synthesize it, by scanning the DIE's below the compilation unit.  */
-      highpc = 0;
-      if (dies->child != NULL)
-       {
-         child_die = dies->child;
-         while (child_die && child_die->tag)
-           {
-             if (child_die->tag == DW_TAG_subprogram)
-               {
-                 CORE_ADDR low, high;
+  /* Some compilers don't define a DW_AT_high_pc attribute for the
+     compilation unit.  If the DW_AT_high_pc is missing, synthesize
+     it, by scanning the DIE's below the compilation unit.  */
+  get_scope_pc_bounds (dies, &lowpc, &highpc, &cu);
 
-                 if (dwarf2_get_pc_bounds (child_die, &low, &high, &cu))
-                   {
-                     highpc = max (highpc, high);
-                   }
-               }
-             child_die = sibling_die (child_die);
-           }
-       }
-    }
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
   /* Set symtab language to language from DW_AT_language.
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
-      && !(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;
@@ -1847,23 +2130,27 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       break;
     case DW_TAG_base_type:
       read_base_type (die, cu);
-      if (dwarf_attr (die, DW_AT_name))
+      if (dwarf2_attr (die, DW_AT_name, cu))
        {
          /* Add a typedef symbol for the base type definition.  */
          new_symbol (die, die->type, cu);
        }
       break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
+      if (dwarf2_attr (die, DW_AT_name, cu))
+       {
+         /* Add a typedef symbol for the base type definition.  */
+         new_symbol (die, die->type, cu);
+       }
+      break;
     case DW_TAG_common_block:
       read_common_block (die, cu);
       break;
     case DW_TAG_common_inclusion:
       break;
     case DW_TAG_namespace:
-      if (!processing_has_namespace_info)
-       {
-         processing_has_namespace_info = 1;
-         processing_current_namespace = "";
-       }
+      processing_has_namespace_info = 1;
       read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
@@ -1874,11 +2161,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
         shouldn't in the C++ case, but conceivably could in the
         Fortran case, so we'll have to replace this gdb_assert if
         Fortran compilers start generating that info.  */
-      if (!processing_has_namespace_info)
-       {
-         processing_has_namespace_info = 1;
-         processing_current_namespace = "";
-       }
+      processing_has_namespace_info = 1;
       gdb_assert (die->child == NULL);
       break;
     default:
@@ -1888,9 +2171,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
@@ -1907,28 +2190,11 @@ 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));
 
-  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
-    {
-      if (die->child != NULL)
-       {
-         child_die = die->child;
-         while (child_die && child_die->tag)
-           {
-             if (child_die->tag == DW_TAG_subprogram)
-               {
-                 CORE_ADDR low, high;
-
-                 if (dwarf2_get_pc_bounds (child_die, &low, &high, cu))
-                   {
-                     lowpc = min (lowpc, low);
-                     highpc = max (highpc, high);
-                   }
-               }
-             child_die = sibling_die (child_die);
-           }
-       }
-    }
+  get_scope_pc_bounds (die, &lowpc, &highpc, cu);
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
@@ -1937,12 +2203,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);
@@ -1964,10 +2230,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. */
@@ -1982,12 +2248,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)
@@ -2001,7 +2267,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);
@@ -2018,7 +2284,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);
@@ -2029,7 +2295,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;
 
@@ -2041,12 +2308,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
@@ -2059,19 +2326,58 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   struct attribute *attr;
   char *name;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die);
+  name = dwarf2_linkage_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
 
+  if (cu->language == language_cplus)
+    {
+      struct die_info *spec_die = die_specification (die, cu);
+
+      /* NOTE: carlton/2004-01-23: We have to be careful in the
+         presence of DW_AT_specification.  For example, with GCC 3.4,
+         given the code
+
+           namespace N {
+             void foo() {
+               // Definition of N::foo.
+             }
+           }
+
+         then we'll have a tree of DIEs like this:
+
+         1: DW_TAG_compile_unit
+           2: DW_TAG_namespace        // N
+             3: DW_TAG_subprogram     // declaration of N::foo
+           4: DW_TAG_subprogram       // definition of N::foo
+                DW_AT_specification   // refers to die #3
+
+         Thus, when processing die #4, we have to pretend that we're
+         in the context of its DW_AT_specification, namely the contex
+         of die #3.  */
+       
+      if (spec_die != NULL)
+       {
+         char *specification_prefix = determine_prefix (spec_die, cu);
+         processing_current_prefix = specification_prefix;
+         back_to = make_cleanup (xfree, specification_prefix);
+       }
+    }
+
   lowpc += baseaddr;
   highpc += baseaddr;
 
   /* Record the function range for dwarf_decode_lines.  */
-  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)
@@ -2085,11 +2391,20 @@ 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
+       and not in a separate frame-base object.  I guess this hack is
+       to avoid adding some sort of frame-base adjunct/annex to the
+       function's symbol :-(.  The problem with doing this is that it
+       results in a function symbol with a location expression that
+       has nothing to do with the location of the function, ouch!  The
+       relationship should be: a function's symbol has-a frame base; a
+       frame-base has-a location expression.  */
     dwarf2_symbol_mark_computed (attr, new->name, cu);
 
-  list_in_scope = &local_symbols;
+  cu->list_in_scope = &local_symbols;
 
   if (die->child != NULL)
     {
@@ -2116,7 +2431,11 @@ 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)
+    do_cleanups (back_to);
 }
 
 /* Process all the DIES contained within a lexical block scope.  Start
@@ -2129,6 +2448,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
@@ -2175,11 +2497,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
@@ -2191,7 +2513,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;
@@ -2319,6 +2641,68 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   return ret;
 }
 
+/* Get the low and high pc's represented by the scope DIE, and store
+   them in *LOWPC and *HIGHPC.  If the correct values can't be
+   determined, set *LOWPC to -1 and *HIGHPC to 0.  */
+
+static void
+get_scope_pc_bounds (struct die_info *die,
+                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                    struct dwarf2_cu *cu)
+{
+  CORE_ADDR best_low = (CORE_ADDR) -1;
+  CORE_ADDR best_high = (CORE_ADDR) 0;
+  CORE_ADDR current_low, current_high;
+
+  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu))
+    {
+      best_low = current_low;
+      best_high = current_high;
+    }
+  else
+    {
+      struct die_info *child = die->child;
+
+      while (child && child->tag)
+       {
+         switch (child->tag) {
+         case DW_TAG_subprogram:
+           if (dwarf2_get_pc_bounds (child, &current_low, &current_high, cu))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         case DW_TAG_namespace:
+           /* FIXME: carlton/2004-01-16: Should we do this for
+              DW_TAG_class_type/DW_TAG_structure_type, too?  I think
+              that current GCC's always emit the DIEs corresponding
+              to definitions of methods of classes as children of a
+              DW_TAG_compile_unit or DW_TAG_namespace (as opposed to
+              the DIEs giving the declarations, which could be
+              anywhere).  But I don't see any reason why the
+              standards says that they have to be there.  */
+           get_scope_pc_bounds (child, &current_low, &current_high, cu);
+
+           if (current_low != ((CORE_ADDR) -1))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         default:
+           /* Ignore. */
+           break;
+         }
+
+         child = sibling_die (child);
+       }
+    }
+
+  *lowpc = best_low;
+  *highpc = best_high;
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -2348,18 +2732,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.  */
       
@@ -2369,7 +2753,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);
@@ -2380,7 +2764,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) =
@@ -2388,7 +2772,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)
@@ -2411,7 +2795,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
@@ -2433,15 +2817,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;
@@ -2459,25 +2845,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);
@@ -2592,19 +2978,19 @@ 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++)
     {
-      if (DEPRECATED_STREQ (fip->fnfieldlists[i].name, fieldname))
+      if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0)
        break;
     }
 
@@ -2640,8 +3026,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)
     {
@@ -2669,14 +3056,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))
@@ -2691,12 +3078,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 */
@@ -2772,16 +3159,56 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
+  char *name = NULL;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  /* This says whether or not we want to try to update the structure's
+     name to include enclosing namespace/class information, if
+     any.  */
+  int need_to_update_name = 0;
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      name = DW_STRING (attr);
+
+      if (cu->language == language_cplus)
+       {
+         struct die_info *spec_die = die_specification (die, cu);
+
+         if (spec_die != NULL)
+           {
+             char *specification_prefix = determine_prefix (spec_die, cu);
+             processing_current_prefix = specification_prefix;
+             back_to = make_cleanup (xfree, specification_prefix);
+           }
+       }
+
+      if (processing_has_namespace_info)
+       {
+         /* FIXME: carlton/2003-11-10: This variable exists only for
+            const-correctness reasons.  When I tried to change
+            TYPE_TAG_NAME to be a const char *, I ran into a cascade
+            of changes which would have forced decode_line_1 to take
+            a const char **.  */
+         char *new_prefix = obconcat (&objfile->objfile_obstack,
+                                      processing_current_prefix,
+                                      processing_current_prefix[0] == '\0'
+                                      ? "" : "::",
+                                      name);
+         TYPE_TAG_NAME (type) = new_prefix;
+         processing_current_prefix = new_prefix;
+       }
+      else
+       {
+         /* 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;
+         need_to_update_name = (cu->language == language_cplus);
+       }
     }
 
   if (die->tag == DW_TAG_structure_type)
@@ -2799,7 +3226,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);
@@ -2814,7 +3241,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;
@@ -2841,6 +3268,41 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
              /* C++ member function. */
              process_die (child_die, cu);
              dwarf2_add_member_fn (&fi, child_die, type, cu);
+             if (need_to_update_name)
+               {
+                 /* The demangled names of member functions contain
+                    information about enclosing namespaces/classes,
+                    if any.  */
+
+                 /* FIXME: carlton/2003-11-10: The excessive
+                    demangling here is a bit wasteful, as is the
+                    memory usage for names.  */
+
+                 /* NOTE: carlton/2003-11-10: As commented in
+                    add_partial_structure, the demangler sometimes
+                    prints the type info in a different form from the
+                    debug info.  We could solve this by using the
+                    demangled name to get the prefix; if doing so,
+                    however, we'd need to be careful when reading a
+                    class that's nested inside a template class.
+                    That would also cause problems when trying to
+                    determine RTTI information, since we use the
+                    demangler to determine the appropriate class
+                    name.  */
+                 char *actual_class_name
+                   = class_name_from_physname (dwarf2_linkage_name
+                                               (child_die, cu));
+                 if (actual_class_name != NULL
+                     && strcmp (actual_class_name, name) != 0)
+                   {
+                     TYPE_TAG_NAME (type)
+                       = obsavestring (actual_class_name,
+                                       strlen (actual_class_name),
+                                       &objfile->objfile_obstack);
+                   }
+                 xfree (actual_class_name);
+                 need_to_update_name = 0;
+               }
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
@@ -2865,7 +3327,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);
 
@@ -2883,7 +3345,9 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                    {
                      char *fieldname = TYPE_FIELD_NAME (t, i);
 
-                     if (DEPRECATED_STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+                     if ((strncmp (fieldname, vptr_name,
+                                    strlen (vptr_name) - 1)
+                           == 0)
                          && is_cplus_marker (fieldname[strlen (vptr_name)]))
                        {
                          TYPE_VPTR_FIELDNO (type) = i;
@@ -2914,6 +3378,10 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
+
+  processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -2940,15 +3408,28 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
   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))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      char *name = DW_STRING (attr);
+
+      if (processing_has_namespace_info)
+       {
+         TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
+                                          processing_current_prefix,
+                                          processing_current_prefix[0] == '\0'
+                                          ? "" : "::",
+                                          name);
+       }
+      else
+       {
+         /* 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);
@@ -2971,7 +3452,7 @@ 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);
@@ -3043,7 +3524,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;
@@ -3055,98 +3536,22 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
-         unsigned int low, high;
-
-         /* Default bounds to an array with unspecified length.  */
-         low = 0;
-         high = -1;
-         if (cu_language == language_fortran)
-           {
-             /* FORTRAN implies a lower bound of 1, if not given.  */
-             low = 1;
-           }
+          read_subrange_type (child_die, cu);
 
-         index_type = die_type (child_die, cu);
-         attr = dwarf_attr (child_die, DW_AT_lower_bound);
-         if (attr)
-           {
-             if (attr->form == DW_FORM_sdata)
-               {
-                 low = DW_SND (attr);
-               }
-             else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4
-                      || attr->form == DW_FORM_data8)
-               {
-                 low = DW_UNSND (attr);
-               }
-             else
-               {
-                 dwarf2_non_const_array_bound_ignored_complaint
-                   (dwarf_form_name (attr->form));
-#ifdef FORTRAN_HACK
-                 die->type = lookup_pointer_type (element_type);
-                 return;
-#else
-                 low = 0;
-#endif
-               }
-           }
-         attr = dwarf_attr (child_die, DW_AT_upper_bound);
-         if (attr)
-           {
-             if (attr->form == DW_FORM_sdata)
-               {
-                 high = DW_SND (attr);
-               }
-             else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4
-                      || attr->form == DW_FORM_data8)
-               {
-                 high = DW_UNSND (attr);
-               }
-             else if (attr->form == DW_FORM_block1)
-               {
-                 /* GCC encodes arrays with unspecified or dynamic length
-                    with a DW_FORM_block1 attribute.
-                    FIXME: GDB does not yet know how to handle dynamic
-                    arrays properly, treat them as arrays with unspecified
-                    length for now.
-
-                     FIXME: jimb/2003-09-22: GDB does not really know
-                     how to handle arrays of unspecified length
-                     either; we just represent them as zero-length
-                     arrays.  Choose an appropriate upper bound given
-                     the lower bound we've computed above.  */
-                 high = low - 1;
-               }
-             else
-               {
-                 dwarf2_non_const_array_bound_ignored_complaint
-                   (dwarf_form_name (attr->form));
-#ifdef FORTRAN_HACK
-                 die->type = lookup_pointer_type (element_type);
-                 return;
-#else
-                 high = 1;
-#endif
-               }
-           }
-
-         /* Create a range type and save it for array type creation.  */
-         if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
-           {
-             range_types = (struct type **)
-               xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
-                         * sizeof (struct type *));
-             if (ndim == 0)
-               make_cleanup (free_current_contents, &range_types);
-           }
-         range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+          if (child_die->type != NULL)
+            {
+             /* The range type was succesfully read. Save it for
+                 the array type creation.  */
+              if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+                {
+                  range_types = (struct type **)
+                    xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                              * sizeof (struct type *));
+                  if (ndim == 0)
+                    make_cleanup (free_current_contents, &range_types);
+               }
+             range_types[ndim++] = child_die->type;
+            }
        }
       child_die = sibling_die (child_die);
     }
@@ -3163,7 +3568,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;
 
@@ -3183,7 +3588,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 */
@@ -3207,7 +3612,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) =
@@ -3225,68 +3630,53 @@ static void
 read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  const char *previous_namespace = processing_current_namespace;
-  const char *name = NULL;
+  const char *previous_prefix = processing_current_prefix;
+  const char *name;
   int is_anonymous;
   struct die_info *current_die;
 
-  /* Loop through the extensions until we find a name.  */
-
-  for (current_die = die;
-       current_die != NULL;
-       current_die = dwarf2_extension (die))
-    {
-      name = dwarf2_name (current_die);
-      if (name != NULL)
-       break;
-    }
-
-  /* Is it an anonymous namespace?  */
-
-  is_anonymous = (name == NULL);
-  if (is_anonymous)
-    name = "(anonymous namespace)";
+  name = namespace_name (die, &is_anonymous, cu);
 
   /* Now build the name of the current namespace.  */
 
-  if (previous_namespace[0] == '\0')
+  if (previous_prefix[0] == '\0')
     {
-      processing_current_namespace = name;
+      processing_current_prefix = name;
     }
   else
     {
-      /* We need temp_name around because processing_current_namespace
+      /* We need temp_name around because processing_current_prefix
         is a const char *.  */
-      char *temp_name = alloca (strlen (previous_namespace)
+      char *temp_name = alloca (strlen (previous_prefix)
                                + 2 + strlen(name) + 1);
-      strcpy (temp_name, previous_namespace);
+      strcpy (temp_name, previous_prefix);
       strcat (temp_name, "::");
       strcat (temp_name, name);
 
-      processing_current_namespace = temp_name;
+      processing_current_prefix = temp_name;
     }
 
   /* Add a symbol associated to this if we haven't seen the namespace
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
-  if (dwarf2_extension (die) == NULL)
+  if (dwarf2_extension (die, cu) == NULL)
     {
       struct type *type;
 
       /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
         this cast will hopefully become unnecessary.  */
       type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
-                       (char *) processing_current_namespace,
+                       (char *) processing_current_prefix,
                        objfile);
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
       new_symbol (die, type, cu);
 
       if (is_anonymous)
-       cp_add_using_directive (processing_current_namespace,
-                               strlen (previous_namespace),
-                               strlen (processing_current_namespace));
+       cp_add_using_directive (processing_current_prefix,
+                               strlen (previous_prefix),
+                               strlen (processing_current_prefix));
     }
 
   if (die->child != NULL)
@@ -3300,7 +3690,37 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
-  processing_current_namespace = previous_namespace;
+  processing_current_prefix = previous_prefix;
+}
+
+/* Return the name of the namespace represented by DIE.  Set
+   *IS_ANONYMOUS to tell whether or not the namespace is an anonymous
+   namespace.  */
+
+static const char *
+namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
+{
+  struct die_info *current_die;
+  const char *name = NULL;
+
+  /* Loop through the extensions until we find a name.  */
+
+  for (current_die = die;
+       current_die != NULL;
+       current_die = dwarf2_extension (die, cu))
+    {
+      name = dwarf2_name (current_die, cu);
+      if (name != NULL)
+       break;
+    }
+
+  /* Is it an anonymous namespace?  */
+
+  *is_anonymous = (name == NULL);
+  if (*is_anonymous)
+    name = "(anonymous namespace)";
+
+  return name;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
@@ -3322,13 +3742,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
@@ -3400,7 +3820,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);
@@ -3458,7 +3878,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);
@@ -3466,7 +3886,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);
@@ -3476,9 +3896,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 */
@@ -3486,7 +3906,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;
@@ -3519,9 +3939,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)
@@ -3558,7 +3978,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
@@ -3582,7 +4002,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);
@@ -3609,17 +4029,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;
@@ -3656,18 +4076,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
@@ -3677,6 +4098,78 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   die->type = type;
 }
 
+/* Read the given DW_AT_subrange DIE.  */
+
+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *base_type;
+  struct type *range_type;
+  struct attribute *attr;
+  int low = 0;
+  int high = -1;
+  
+  /* If we have already decoded this die, then nothing more to do.  */
+  if (die->type)
+    return;
+
+  base_type = die_type (die, cu);
+  if (base_type == NULL)
+    {
+      complaint (&symfile_complaints,
+                "DW_AT_type missing from DW_TAG_subrange_type");
+      return;
+    }
+
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+    base_type = alloc_type (NULL);
+
+  if (cu->language == language_fortran)
+    { 
+      /* FORTRAN implies a lower bound of 1, if not given.  */
+      low = 1;
+    }
+
+  attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
+  if (attr)
+    low = dwarf2_get_attr_constant_value (attr, 0);
+
+  attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+  if (attr)
+    {       
+      if (attr->form == DW_FORM_block1)
+        {
+          /* GCC encodes arrays with unspecified or dynamic length
+             with a DW_FORM_block1 attribute.
+             FIXME: GDB does not yet know how to handle dynamic
+             arrays properly, treat them as arrays with unspecified
+             length for now.
+
+             FIXME: jimb/2003-09-22: GDB does not really know
+             how to handle arrays of unspecified length
+             either; we just represent them as zero-length
+             arrays.  Choose an appropriate upper bound given
+             the lower bound we've computed above.  */
+          high = low - 1;
+        }
+      else
+        high = dwarf2_get_attr_constant_value (attr, 1);
+    }
+
+  range_type = create_range_type (NULL, base_type, low, high);
+
+  attr = dwarf2_attr (die, DW_AT_name, cu);
+  if (attr && DW_STRING (attr))
+    TYPE_NAME (range_type) = DW_STRING (attr);
+  
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+  if (attr)
+    TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+  die->type = range_type;
+}
+  
+
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
@@ -3799,7 +4292,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)
@@ -3811,7 +4304,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)
@@ -3838,19 +4331,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;
@@ -3866,24 +4368,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
@@ -3900,32 +4408,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;
-
-  abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table;
+  struct dwarf2_cu *cu = ptr_to_cu;
 
-  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.  */
@@ -3933,12 +4428,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)
     {
@@ -4046,7 +4540,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;
@@ -4061,7 +4555,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)
        {
@@ -4594,28 +5089,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:
@@ -4624,16 +5135,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;
@@ -4651,22 +5162,35 @@ 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, struct dwarf2_cu *cu)
+{
+  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
+
+  if (spec_attr == NULL)
+    return NULL;
+  else
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
+}
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
@@ -4859,26 +5383,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
@@ -4909,6 +5433,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;
@@ -4954,7 +5482,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)
@@ -5001,7 +5529,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:
@@ -5182,21 +5710,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.
@@ -5207,7 +5738,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);
@@ -5215,7 +5746,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;
@@ -5226,14 +5757,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:
@@ -5245,26 +5776,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
            {
@@ -5274,9 +5805,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);
@@ -5284,7 +5815,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);
@@ -5292,12 +5823,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
@@ -5310,39 +5841,109 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
 
-         /* The semantics of C++ state that "struct foo { ... }" also
-            defines a typedef for "foo". Synthesize a typedef symbol so
-            that "ptype foo" works as expected.  */
-         if (cu_language == language_cplus)
+         /* Make sure that the symbol includes appropriate enclosing
+            classes/namespaces in its name.  These are calculated in
+            read_structure_scope, and the correct name is saved in
+            the type.  */
+
+         if (cu->language == language_cplus)
            {
-             struct symbol *typedef_sym = (struct symbol *)
-             obstack_alloc (&objfile->symbol_obstack,
-                            sizeof (struct symbol));
-             *typedef_sym = *sym;
-             SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
-             if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-               TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 obsavestring (DEPRECATED_SYMBOL_NAME (sym),
-                               strlen (DEPRECATED_SYMBOL_NAME (sym)),
-                               &objfile->type_obstack);
-             add_symbol_to_list (typedef_sym, list_in_scope);
+             struct type *type = SYMBOL_TYPE (sym);
+             
+             if (TYPE_TAG_NAME (type) != NULL)
+               {
+                 /* FIXME: carlton/2003-11-10: Should this use
+                    SYMBOL_SET_NAMES instead?  (The same problem also
+                    arises 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);
+               }
            }
+
+         {
+           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+              really ever be static objects: otherwise, if you try
+              to, say, break of a class's method and you're in a file
+              which doesn't mention that class, it won't work unless
+              the check for all static symbols in lookup_symbol_aux
+              saves you.  See the OtherFileClass tests in
+              gdb.c++/namespace.exp.  */
+
+           struct pending **list_to_add;
+
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
+         
+           add_symbol_to_list (sym, list_to_add);
+
+           /* The semantics of C++ state that "struct foo { ... }" also
+              defines a typedef for "foo". Synthesize a typedef symbol so
+              that "ptype foo" works as expected.  */
+           if (cu->language == language_cplus)
+             {
+               struct symbol *typedef_sym = (struct symbol *)
+                 obstack_alloc (&objfile->objfile_obstack,
+                                sizeof (struct symbol));
+               *typedef_sym = *sym;
+               SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+               /* 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)) = SYMBOL_NATURAL_NAME (sym);
+               add_symbol_to_list (typedef_sym, list_to_add);
+             }
+         }
          break;
        case DW_TAG_typedef:
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         add_symbol_to_list (sym, cu->list_in_scope);
+         break;
        case DW_TAG_base_type:
+        case DW_TAG_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:
-         attr = dwarf_attr (die, DW_AT_const_value);
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
              dwarf2_const_value (attr, sym, cu);
            }
-         add_symbol_to_list (sym, list_in_scope);
+         {
+           /* NOTE: carlton/2003-11-10: See comment above in the
+              DW_TAG_class_type, etc. block.  */
+
+           struct pending **list_to_add;
+
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
+         
+           add_symbol_to_list (sym, list_to_add);
+         }
          break;
        case DW_TAG_namespace:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -5380,7 +5981,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,
@@ -5398,7 +5999,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;
@@ -5474,15 +6075,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)
        {
@@ -5512,10 +6113,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)
        {
@@ -5576,6 +6177,11 @@ 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, cu);
+  const char *old_prefix = processing_current_prefix;
+  struct cleanup *back_to = make_cleanup (xfree, prefix);
+  processing_current_prefix = prefix;
+  
   switch (die->tag)
     {
     case DW_TAG_class_type:
@@ -5614,6 +6220,9 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_typedef:
       read_typedef (die, cu);
       break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
+      break;
     case DW_TAG_base_type:
       read_base_type (die, cu);
       break;
@@ -5622,6 +6231,129 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
                 dwarf_tag_name (die->tag));
       break;
     }
+
+  processing_current_prefix = old_prefix;
+  do_cleanups (back_to);
+}
+
+/* Return the name of the namespace/class that DIE is defined within,
+   or "" if we can't tell.  The caller should xfree the result.  */
+
+/* NOTE: carlton/2004-01-23: See read_func_scope (and the comment
+   therein) for an example of how to use this function to deal with
+   DW_AT_specification.  */
+
+static char *
+determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  char *prefix = determine_prefix_aux (die, cu);
+
+  return prefix ? prefix : xstrdup ("");
+}
+
+/* Return the name of the namespace/class that DIE is defined
+   within, or NULL if we can't tell.  The caller should xfree the
+   result.  */
+
+static char *
+determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *parent;
+
+  if (cu->language != language_cplus)
+    return NULL;
+
+  parent = die->parent;
+
+  if (parent == NULL)
+    {
+      return (processing_has_namespace_info ? xstrdup ("") : NULL);
+    }
+  else
+    {
+      char *parent_prefix = determine_prefix_aux (parent, cu);
+      char *retval;
+
+      switch (parent->tag) {
+      case DW_TAG_namespace:
+       {
+         int dummy;
+
+         retval = typename_concat (parent_prefix,
+                                   namespace_name (parent, &dummy, cu));
+       }
+       break;
+      case DW_TAG_class_type:
+      case DW_TAG_structure_type:
+       {
+         if (parent_prefix != NULL)
+           {
+             const char *parent_name = dwarf2_name (parent, cu);
+
+             if (parent_name != NULL)
+               retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
+             else
+               /* FIXME: carlton/2003-11-10: I'm not sure what the
+                  best thing to do here is.  */
+               retval = typename_concat (parent_prefix,
+                                         "<<anonymous class>>");
+           }
+         else
+           retval = class_name (parent, cu);
+       }
+       break;
+      default:
+       retval = parent_prefix;
+       break;
+      }
+
+      if (retval != parent_prefix)
+       xfree (parent_prefix);
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string formed by concatenating PREFIX,
+   "::", and SUFFIX, except that if PREFIX is NULL or the empty
+   string, just return a copy of SUFFIX.  */
+
+static char *
+typename_concat (const char *prefix, const char *suffix)
+{
+  if (prefix == NULL || prefix[0] == '\0')
+    return xstrdup (suffix);
+  else
+    {
+      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+
+      strcpy (retval, prefix);
+      strcat (retval, "::");
+      strcat (retval, suffix);
+
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string giving the name of the class given
+   by DIE.  */
+
+static char *
+class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *child;
+  const char *name;
+
+  for (child = die->child; child != NULL; child = sibling_die (child))
+    {
+      if (child->tag == DW_TAG_subprogram)
+       return class_name_from_physname (dwarf2_linkage_name (child, cu));
+    }
+
+  name = dwarf2_name (die, cu);
+  if (name != NULL)
+    return xstrdup (name);
+  else
+    return xstrdup ("");
 }
 
 static struct type *
@@ -5635,69 +6367,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;
     }
 }
@@ -5746,14 +6478,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;
@@ -5762,11 +6494,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;
@@ -5776,17 +6508,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)
     {
@@ -6699,7 +7431,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;
 
@@ -6713,7 +7445,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,
@@ -6723,6 +7455,28 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
   return result;
 }
 
+/* Return the constant value held by the given attribute.  Return -1
+   if the value held by the attribute is not constant.  */
+
+static int
+dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+{
+  if (attr->form == DW_FORM_sdata)
+    return DW_SND (attr);
+  else if (attr->form == DW_FORM_udata
+           || attr->form == DW_FORM_data1
+           || attr->form == DW_FORM_data2
+           || attr->form == DW_FORM_data4
+           || attr->form == DW_FORM_data8)
+    return DW_UNSND (attr);
+  else
+    {
+      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+                 dwarf_form_name (attr->form));
+      return default_value;
+    }
+}
+
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
@@ -6743,7 +7497,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)
     {
@@ -6755,12 +7510,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.
@@ -7008,11 +7763,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);
 }
@@ -7080,7 +7836,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)
@@ -7423,7 +8179,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;
 
@@ -7436,14 +8192,14 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
        complaint (&symfile_complaints,
                   "Location list used without specifying the CU base address.");
 
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
     {
       struct dwarf2_locexpr_baton *baton;
 
-      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
       baton->objfile = cu->objfile;
 
@@ -7465,7 +8221,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
          baton->data = NULL;
        }
       
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
This page took 0.06698 seconds and 4 git commands to generate.