2004-02-25 Roland McGrath <roland@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 9c07a04e5bce2b0310fe7c0473ccedee68f45e61..46c3cf4ed7e28df2c43dde5c75ed72b7dc18ff92 100644 (file)
@@ -31,7 +31,6 @@
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
-#include "symfile.h"
 #include "objfiles.h"
 #include "elf/dwarf2.h"
 #include "buildsym.h"
 #include "objfiles.h"
 #include "elf/dwarf2.h"
 #include "buildsym.h"
@@ -231,6 +230,34 @@ struct dwarf2_cu
      should be moved to the dwarf2_cu structure; for instance the abbrevs
      hash table.  */
   struct comp_unit_head header;
      should be moved to the dwarf2_cu structure; for instance the abbrevs
      hash table.  */
   struct comp_unit_head header;
+
+  struct function_range *first_fn, *last_fn, *cached_fn;
+
+  /* The language we are debugging.  */
+  enum language language;
+  const struct language_defn *language_defn;
+
+  /* The generic symbol table building routines have separate lists for
+     file scope symbols and all all other scopes (local scopes).  So
+     we need to select the right one to pass to add_symbol_to_list().
+     We do it by keeping a pointer to the correct list in list_in_scope.
+
+     FIXME: The original dwarf code just treated the file scope as the
+     first local scope, and all other local scopes as nested local
+     scopes, and worked fine.  Check to see if we really need to
+     distinguish these in buildsym.c.  */
+  struct pending **list_in_scope;
+
+  /* Maintain an array of referenced fundamental types for the current
+     compilation unit being read.  For DWARF version 1, we have to construct
+     the fundamental types on the fly, since no information about the
+     fundamental types is supplied.  Each such fundamental type is created by
+     calling a language dependent routine to create the type, and then a
+     pointer to that type is then placed in the array at the index specified
+     by it's FT_<TYPENAME> value.  The array has a fixed size set by the
+     FT_NUM_MEMBERS compile time constant, which is the number of predefined
+     fundamental types gdb knows how to construct.  */
+  struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
 };
 
 /* The line number information for a compilation unit (found in the
 };
 
 /* The line number information for a compilation unit (found in the
@@ -360,8 +387,6 @@ struct function_range
   struct function_range *next;
 };
 
   struct function_range *next;
 };
 
-static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
-
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
@@ -391,19 +416,11 @@ static struct die_info *die_ref_table[REF_HASH_SIZE];
 /* Obstack for allocating temporary storage used during symbol reading.  */
 static struct obstack dwarf2_tmp_obstack;
 
 /* Obstack for allocating temporary storage used during symbol reading.  */
 static struct obstack dwarf2_tmp_obstack;
 
-/* Offset to the first byte of the current compilation unit header,
-   for resolving relative reference dies. */
-static unsigned int cu_header_offset;
-
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
 #endif
 
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
 #endif
 
-/* The language we are debugging.  */
-static enum language cu_language;
-static const struct language_defn *cu_language_defn;
-
 /* Actually data from the sections.  */
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
 /* Actually data from the sections.  */
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
@@ -416,17 +433,6 @@ static char *dwarf_loc_buffer;
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
-/* The generic symbol table building routines have separate lists for
-   file scope symbols and all all other scopes (local scopes).  So
-   we need to select the right one to pass to add_symbol_to_list().
-   We do it by keeping a pointer to the correct list in list_in_scope.
-
-   FIXME:  The original dwarf code just treated the file scope as the first
-   local scope, and all other local scopes as nested local scopes, and worked
-   fine.  Check to see if we really need to distinguish these
-   in buildsym.c.  */
-static struct pending **list_in_scope = &file_symbols;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
@@ -436,15 +442,10 @@ static int isreg;         /* Object lives in register.
                                   decode_locdesc's return value is
                                   the register number.  */
 
                                   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
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.
    The complete dwarf information for an objfile is kept in the
-   psymbol_obstack, so that absolute die references can be handled.
+   objfile_obstack, so that absolute die references can be handled.
    Most of the information in this structure is related to an entire
    object file and could be passed via the sym_private field of the objfile.
    It is however conceivable that dwarf2 might not be the only type
    Most of the information in this structure is related to an entire
    object file and could be passed via the sym_private field of the objfile.
    It is however conceivable that dwarf2 might not be the only type
@@ -525,17 +526,6 @@ struct dwarf2_pinfo
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
 #define DWARF_LOC_BUFFER(p)     (PST_PRIVATE(p)->dwarf_loc_buffer)
 #define DWARF_LOC_SIZE(p)       (PST_PRIVATE(p)->dwarf_loc_size)
 
-/* Maintain an array of referenced fundamental types for the current
-   compilation unit being read.  For DWARF version 1, we have to construct
-   the fundamental types on the fly, since no information about the
-   fundamental types is supplied.  Each such fundamental type is created by
-   calling a language dependent routine to create the type, and then a
-   pointer to that type is then placed in the array at the index specified
-   by it's FT_<TYPENAME> value.  The array has a fixed size set by the
-   FT_NUM_MEMBERS compile time constant, which is the number of predefined
-   fundamental types gdb knows how to construct.  */
-static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
-
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
@@ -591,13 +581,6 @@ struct field_info
 
 /* Various complaints about symbol reading that don't abort the process */
 
 
 /* Various complaints about symbol reading that don't abort the process */
 
-static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
-            arg1);
-}
-
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
@@ -611,13 +594,6 @@ dwarf2_complex_location_expr_complaint (void)
   complaint (&symfile_complaints, "location expression too complex");
 }
 
   complaint (&symfile_complaints, "location expression too complex");
 }
 
-static void
-dwarf2_unsupported_at_frame_base_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints,
-            "unsupported DW_AT_frame_base for function '%s'", arg1);
-}
-
 static void
 dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
 static void
 dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
@@ -666,12 +642,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 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_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,
 static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
                                      char *info_ptr,
                                      struct dwarf2_cu *cu,
@@ -737,11 +720,15 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
 
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
 
-static void set_cu_language (unsigned int);
+static void set_cu_language (unsigned int, struct dwarf2_cu *);
+
+static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
+                                     struct dwarf2_cu *);
 
 
-static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
 
 
-static int die_is_declaration (struct die_info *);
+static struct die_info *die_specification (struct die_info *die,
+                                          struct dwarf2_cu *);
 
 static void free_line_header (struct line_header *lh);
 
 
 static void free_line_header (struct line_header *lh);
 
@@ -777,10 +764,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 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_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 *);
 static void read_file_scope (struct die_info *, struct dwarf2_cu *);
 
 static void read_func_scope (struct die_info *, struct dwarf2_cu *);
@@ -790,6 +787,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 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 *);
 
 static void dwarf2_add_field (struct field_info *, struct die_info *,
                              struct dwarf2_cu *);
 
@@ -809,6 +810,9 @@ static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, 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 *);
 static void read_enumeration (struct die_info *, struct dwarf2_cu *);
 
 static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
@@ -850,11 +854,12 @@ static struct cleanup *make_cleanup_free_die_list (struct die_info *);
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *);
+static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 
 
-static char *dwarf2_name (struct die_info *die);
+static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
 
-static struct die_info *dwarf2_extension (struct die_info *die);
+static struct die_info *dwarf2_extension (struct die_info *die,
+                                         struct dwarf2_cu *);
 
 static char *dwarf_tag_name (unsigned int);
 
 
 static char *dwarf_tag_name (unsigned int);
 
@@ -884,11 +889,15 @@ static void store_in_ref_table (unsigned int, struct die_info *);
 
 static void dwarf2_empty_hash_tables (void);
 
 
 static void dwarf2_empty_hash_tables (void);
 
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
+                                              struct dwarf2_cu *);
+
+static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
 static struct die_info *follow_die_ref (unsigned int);
 
 
 static struct die_info *follow_die_ref (unsigned int);
 
-static struct type *dwarf2_fundamental_type (struct objfile *, int);
+static struct type *dwarf2_fundamental_type (struct objfile *, int,
+                                            struct dwarf2_cu *);
 
 /* memory allocation interface */
 
 
 /* memory allocation interface */
 
@@ -900,9 +909,10 @@ static struct abbrev_info *dwarf_alloc_abbrev (void);
 
 static struct die_info *dwarf_alloc_die (void);
 
 
 static struct die_info *dwarf_alloc_die (void);
 
-static void initialize_cu_func_list (void);
+static void initialize_cu_func_list (struct dwarf2_cu *);
 
 
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
+                                struct dwarf2_cu *);
 
 static void dwarf_decode_macros (struct line_header *, unsigned int,
                                  char *, bfd *, struct dwarf2_cu *);
 
 static void dwarf_decode_macros (struct line_header *, unsigned int,
                                  char *, bfd *, struct dwarf2_cu *);
@@ -1140,7 +1150,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
-  CORE_ADDR lowpc, highpc;
+  CORE_ADDR lowpc, highpc, baseaddr;
 
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
 
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
@@ -1224,6 +1234,8 @@ 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.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);
       /* 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);
@@ -1233,7 +1245,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                   &cu);
 
       /* Set the language we're debugging */
                                   &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,
 
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
@@ -1243,8 +1255,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
-       obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
-      cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+       obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
       DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
       DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
       DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
       DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
@@ -1365,11 +1376,18 @@ scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
+             if (!pdi.is_declaration)
+               {
+                 add_partial_symbol (&pdi, cu, namespace);
+               }
+             break;
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
              if (!pdi.is_declaration)
                {
            case DW_TAG_class_type:
            case DW_TAG_structure_type:
              if (!pdi.is_declaration)
                {
-                 add_partial_symbol (&pdi, cu, namespace);
+                 info_ptr = add_partial_structure (&pdi, info_ptr, cu,
+                                                   namespace);
+                 info_ptr_updated = 1;
                }
              break;
            case DW_TAG_enumeration_type:
                }
              break;
            case DW_TAG_enumeration_type:
@@ -1381,6 +1399,7 @@ scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
                }
              break;
            case DW_TAG_base_type:
                }
              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);
              /* File scope base type definitions are added to the partial
                 symbol table.  */
              add_partial_symbol (&pdi, cu, namespace);
@@ -1424,30 +1443,45 @@ add_partial_symbol (struct partial_die_info *pdi,
 {
   struct objfile *objfile = cu->objfile;
   CORE_ADDR addr = 0;
 {
   struct objfile *objfile = cu->objfile;
   CORE_ADDR addr = 0;
+  char *actual_name = pdi->name;
   const struct partial_symbol *psym = NULL;
   const struct partial_symbol *psym = NULL;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* If we're not in the global namespace and if the namespace name
+     isn't encoded in a mangled actual_name, add it.  */
+  
+  if (pdi_needs_namespace (pdi->tag, namespace))
+    {
+      actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
+      strcpy (actual_name, namespace);
+      strcat (actual_name, "::");
+      strcat (actual_name, pdi->name);
+    }
 
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
 
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
             mst_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->global_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       else
        {
        }
       else
        {
-         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+         /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_file_text, objfile); */
             mst_file_text, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
                                      VAR_DOMAIN, LOC_BLOCK,
                                      &objfile->static_psymbols,
                                      0, pdi->lowpc + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_variable:
        }
       break;
     case DW_TAG_variable:
@@ -1469,11 +1503,11 @@ add_partial_symbol (struct partial_die_info *pdi,
          if (pdi->locdesc)
            addr = decode_locdesc (pdi->locdesc, cu);
          if (pdi->locdesc || pdi->has_type)
          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,
                                        VAR_DOMAIN, LOC_STATIC,
                                        &objfile->global_psymbols,
                                        0, addr + baseaddr,
-                                       cu_language, objfile);
+                                       cu->language, objfile);
        }
       else
        {
        }
       else
        {
@@ -1481,21 +1515,22 @@ add_partial_symbol (struct partial_die_info *pdi,
          if (pdi->locdesc == NULL)
            return;
          addr = decode_locdesc (pdi->locdesc, cu);
          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); */
             mst_file_data, objfile); */
-         psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         psym = add_psymbol_to_list (actual_name, strlen (actual_name),
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
                                      VAR_DOMAIN, LOC_STATIC,
                                      &objfile->static_psymbols,
                                      0, addr + baseaddr,
-                                     cu_language, objfile);
+                                     cu->language, objfile);
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+    case DW_TAG_subrange_type:
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
       break;
     case DW_TAG_class_type:
     case DW_TAG_structure_type:
@@ -1503,27 +1538,33 @@ add_partial_symbol (struct partial_die_info *pdi,
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
          references.  */
+      /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+        static vs. global.  */
       if (pdi->has_children == 0)
        return;
       if (pdi->has_children == 0)
        return;
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
                           STRUCT_DOMAIN, LOC_TYPEDEF,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
 
 
-      if (cu_language == language_cplus)
+      if (cu->language == language_cplus)
        {
          /* For C++, these implicitly act as typedefs as well. */
        {
          /* For C++, these implicitly act as typedefs as well. */
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
+         add_psymbol_to_list (actual_name, strlen (actual_name),
                               VAR_DOMAIN, LOC_TYPEDEF,
                               VAR_DOMAIN, LOC_TYPEDEF,
-                              &objfile->static_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+                              &objfile->global_psymbols,
+                              0, (CORE_ADDR) 0, cu->language, objfile);
        }
       break;
     case DW_TAG_enumerator:
        }
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (pdi->name, strlen (pdi->name),
+      add_psymbol_to_list (actual_name, strlen (actual_name),
                           VAR_DOMAIN, LOC_CONST,
                           VAR_DOMAIN, LOC_CONST,
-                          &objfile->static_psymbols,
-                          0, (CORE_ADDR) 0, cu_language, objfile);
+                          cu->language == language_cplus
+                          ? &objfile->global_psymbols
+                          : &objfile->static_psymbols,
+                          0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     default:
       break;
       break;
     default:
       break;
@@ -1535,7 +1576,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.  */
 
      (otherwise we'll have psym == NULL), and if we actually had a
      mangled name to begin with.  */
 
-  if (cu_language == language_cplus
+  if (cu->language == language_cplus
       && namespace == NULL
       && psym != NULL
       && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
       && namespace == NULL
       && psym != NULL
       && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
@@ -1543,6 +1584,30 @@ add_partial_symbol (struct partial_die_info *pdi,
                                         objfile);
 }
 
                                         objfile);
 }
 
+/* Determine whether a die of type TAG living in the C++ namespace
+   NAMESPACE needs to have the name of the namespace prepended to the
+   name listed in the die.  */
+
+static int
+pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
+{
+  if (namespace == NULL || namespace[0] == '\0')
+    return 0;
+
+  switch (tag)
+    {
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
 /* 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.  */
@@ -1566,14 +1631,15 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
     strcat (full_name, "::");
   strcat (full_name, new_name);
 
-  /* FIXME: carlton/2003-06-27: Once we build qualified names for more
-     symbols than just namespaces, we should replace this by a call to
-     add_partial_symbol.  */
+  /* FIXME: carlton/2003-10-07: We can't just replace this by a call
+     to add_partial_symbol, because we don't have a way to pass in the
+     full name to that function; that might be a flaw in
+     add_partial_symbol's interface.  */
 
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
 
   add_psymbol_to_list (full_name, strlen (full_name),
                       VAR_DOMAIN, LOC_TYPEDEF,
                       &objfile->global_psymbols,
-                      0, 0, cu_language, objfile);
+                      0, 0, cu->language, objfile);
 
   /* Now scan partial symbols in that namespace.  */
 
 
   /* Now scan partial symbols in that namespace.  */
 
@@ -1583,6 +1649,78 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
   return info_ptr;
 }
 
   return info_ptr;
 }
 
+/* Read a partial die corresponding to a class or structure.  */
+
+static char *
+add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
+                      struct dwarf2_cu *cu,
+                      const char *namespace)
+{
+  bfd *abfd = cu->objfile->obfd;
+  char *actual_class_name = NULL;
+
+  if (cu->language == language_cplus
+      && (namespace == NULL || namespace[0] == '\0')
+      && struct_pdi->name != NULL
+      && struct_pdi->has_children)
+    {
+      /* See if we can figure out if the class lives in a namespace
+        (or is nested within another class.)  We do this by looking
+        for a member function; its demangled name will contain
+        namespace info, if there is any.  */
+
+      /* NOTE: carlton/2003-10-07: Getting the info this way changes
+        what template types look like, because the demangler
+        frequently doesn't give the same name as the debug info.  We
+        could fix this by only using the demangled name to get the
+        prefix (but see comment in read_structure_scope).  */
+
+      /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have
+        the appropriate debug information, so it would be nice to be
+        able to avoid this hack.  But NAMESPACE may not be the
+        namespace where this class was defined: NAMESPACE reflects
+        where STRUCT_PDI occurs in the tree of dies, but because of
+        DW_AT_specification, that may not actually tell us where the
+        class is defined.  (See the comment in read_func_scope for an
+        example of how this could occur.)
+
+         Unfortunately, our current partial symtab data structures are
+         completely unable to deal with DW_AT_specification.  So, for
+         now, the best thing to do is to get nesting information from
+         places other than the tree structure of dies if there's any
+         chance that a DW_AT_specification is involved. :-( */
+
+      char *next_child = info_ptr;
+
+      while (1)
+       {
+         struct partial_die_info child_pdi;
+
+         next_child = read_partial_die (&child_pdi, abfd, next_child,
+                                        cu);
+         if (!child_pdi.tag)
+           break;
+         if (child_pdi.tag == DW_TAG_subprogram)
+           {
+             actual_class_name = class_name_from_physname (child_pdi.name);
+             if (actual_class_name != NULL)
+               struct_pdi->name = actual_class_name;
+             break;
+           }
+         else
+           {
+             next_child = locate_pdi_sibling (&child_pdi, next_child,
+                                              abfd, cu);
+           }
+       }
+    }
+
+  add_partial_symbol (struct_pdi, cu, namespace);
+  xfree (actual_class_name);
+
+  return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
+}
+
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
 /* Read a partial die corresponding to an enumeration type.  */
 
 static char *
@@ -1687,6 +1825,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   struct symtab *symtab;
   struct cleanup *back_to;
   struct attribute *attr;
   struct symtab *symtab;
   struct cleanup *back_to;
   struct attribute *attr;
+  CORE_ADDR baseaddr;
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
 
   /* Set local variables from the partial symbol table info.  */
   offset = DWARF_INFO_OFFSET (pst);
@@ -1703,9 +1842,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
   dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
   dwarf_loc_size = DWARF_LOC_SIZE (pst);
-  baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
-  cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
   info_ptr = dwarf_info_buffer + offset;
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* We're in the global namespace.  */
+  processing_current_prefix = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -1722,6 +1863,10 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf2_read_abbrevs (abfd, &cu);
   make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
 
   dwarf2_read_abbrevs (abfd, &cu);
   make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
 
+  cu.header.offset = offset;
+
+  cu.list_in_scope = &file_symbols;
+
   dies = read_comp_unit (info_ptr, abfd, &cu);
 
   make_cleanup_free_die_list (dies);
   dies = read_comp_unit (info_ptr, abfd, &cu);
 
   make_cleanup_free_die_list (dies);
@@ -1735,7 +1880,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   cu.header.base_known = 0;
   cu.header.base_address = 0;
 
   cu.header.base_known = 0;
   cu.header.base_address = 0;
 
-  attr = dwarf_attr (dies, DW_AT_entry_pc);
+  attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
   if (attr)
     {
       cu.header.base_address = DW_ADDR (attr);
   if (attr)
     {
       cu.header.base_address = DW_ADDR (attr);
@@ -1743,7 +1888,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
     }
   else
     {
     }
   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);
       if (attr)
        {
          cu.header.base_address = DW_ADDR (attr);
@@ -1754,39 +1899,20 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   /* Do line number decoding in read_file_scope () */
   process_die (dies, &cu);
 
   /* 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
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
   /* Set symtab language to language from DW_AT_language.
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
-      && !(cu_language == language_c && symtab->language != language_c))
+      && !(cu.language == language_c && symtab->language != language_c))
     {
     {
-      symtab->language = cu_language;
+      symtab->language = cu.language;
     }
   pst->symtab = symtab;
   pst->readin = 1;
     }
   pst->symtab = symtab;
   pst->readin = 1;
@@ -1848,23 +1974,27 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       break;
     case DW_TAG_base_type:
       read_base_type (die, 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;
        {
          /* 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:
     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:
       read_namespace (die, cu);
       break;
     case DW_TAG_imported_declaration:
@@ -1875,11 +2005,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.  */
         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:
       gdb_assert (die->child == NULL);
       break;
     default:
@@ -1889,9 +2015,9 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 static void
 }
 
 static void
-initialize_cu_func_list (void)
+initialize_cu_func_list (struct dwarf2_cu *cu)
 {
 {
-  cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+  cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
 }
 
 static void
 }
 
 static void
@@ -1908,28 +2034,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;
   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.  */
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
@@ -1938,12 +2047,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   lowpc += baseaddr;
   highpc += baseaddr;
 
   lowpc += baseaddr;
   highpc += baseaddr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr)
     {
       name = DW_STRING (attr);
     }
   if (attr)
     {
       name = DW_STRING (attr);
     }
-  attr = dwarf_attr (die, DW_AT_comp_dir);
+  attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
   if (attr)
     {
       comp_dir = DW_STRING (attr);
   if (attr)
     {
       comp_dir = DW_STRING (attr);
@@ -1965,10 +2074,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
       objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
       objfile->ei.deprecated_entry_file_highpc = highpc;
     }
 
-  attr = dwarf_attr (die, DW_AT_language);
+  attr = dwarf2_attr (die, DW_AT_language, cu);
   if (attr)
     {
   if (attr)
     {
-      set_cu_language (DW_UNSND (attr));
+      set_cu_language (DW_UNSND (attr), cu);
     }
 
   /* We assume that we're processing GCC output. */
     }
 
   /* We assume that we're processing GCC output. */
@@ -1983,12 +2092,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.  */
 
   /* The compilation unit may be in a different language or objfile,
      zero out all remembered fundamental types.  */
-  memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+  memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
-  initialize_cu_func_list ();
+  initialize_cu_func_list (cu);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -2002,7 +2111,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   /* Decode line number information if present.  */
     }
 
   /* Decode line number information if present.  */
-  attr = dwarf_attr (die, DW_AT_stmt_list);
+  attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
   if (attr)
     {
       unsigned int line_offset = DW_UNSND (attr);
   if (attr)
     {
       unsigned int line_offset = DW_UNSND (attr);
@@ -2019,7 +2128,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.  */
      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);
   if (attr && line_header)
     {
       unsigned int macro_offset = DW_UNSND (attr);
@@ -2030,7 +2139,8 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 static void
 }
 
 static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
+                    struct dwarf2_cu *cu)
 {
   struct function_range *thisfn;
 
 {
   struct function_range *thisfn;
 
@@ -2042,12 +2152,12 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
   thisfn->seen_line = 0;
   thisfn->next = NULL;
 
   thisfn->seen_line = 0;
   thisfn->next = NULL;
 
-  if (cu_last_fn == NULL)
-      cu_first_fn = thisfn;
+  if (cu->last_fn == NULL)
+      cu->first_fn = thisfn;
   else
   else
-      cu_last_fn->next = thisfn;
+      cu->last_fn->next = thisfn;
 
 
-  cu_last_fn = thisfn;
+  cu->last_fn = thisfn;
 }
 
 static void
 }
 
 static void
@@ -2060,19 +2170,58 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   struct attribute *attr;
   char *name;
   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;
 
 
   /* 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.  */
   lowpc += baseaddr;
   highpc += baseaddr;
 
   /* Record the function range for dwarf_decode_lines.  */
-  add_to_cu_func_list (name, lowpc, highpc);
+  add_to_cu_func_list (name, lowpc, highpc, cu);
 
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
 
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
@@ -2086,11 +2235,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.  */
 
   /* 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)
   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);
 
     dwarf2_symbol_mark_computed (attr, new->name, cu);
 
-  list_in_scope = &local_symbols;
+  cu->list_in_scope = &local_symbols;
 
   if (die->child != NULL)
     {
 
   if (die->child != NULL)
     {
@@ -2117,7 +2275,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 ())
   /* 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
 }
 
 /* Process all the DIES contained within a lexical block scope.  Start
@@ -2130,6 +2292,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;
   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
 
   /* Ignore blocks with missing or invalid low and high pc attributes.  */
   /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
@@ -2176,11 +2341,11 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   CORE_ADDR high = 0;
   int ret = 0;
 
   CORE_ADDR high = 0;
   int ret = 0;
 
-  attr = dwarf_attr (die, DW_AT_high_pc);
+  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
   if (attr)
     {
       high = DW_ADDR (attr);
   if (attr)
     {
       high = DW_ADDR (attr);
-      attr = dwarf_attr (die, DW_AT_low_pc);
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr)
        low = DW_ADDR (attr);
       else
       if (attr)
        low = DW_ADDR (attr);
       else
@@ -2192,7 +2357,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
     }
   else
     {
     }
   else
     {
-      attr = dwarf_attr (die, DW_AT_ranges);
+      attr = dwarf2_attr (die, DW_AT_ranges, cu);
       if (attr != NULL)
        {
          unsigned int addr_size = cu_header->addr_size;
       if (attr != NULL)
        {
          unsigned int addr_size = cu_header->addr_size;
@@ -2320,6 +2485,68 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   return ret;
 }
 
   return ret;
 }
 
+/* Get the low and high pc's represented by the scope DIE, and store
+   them in *LOWPC and *HIGHPC.  If the correct values can't be
+   determined, set *LOWPC to -1 and *HIGHPC to 0.  */
+
+static void
+get_scope_pc_bounds (struct die_info *die,
+                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                    struct dwarf2_cu *cu)
+{
+  CORE_ADDR best_low = (CORE_ADDR) -1;
+  CORE_ADDR best_high = (CORE_ADDR) 0;
+  CORE_ADDR current_low, current_high;
+
+  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu))
+    {
+      best_low = current_low;
+      best_high = current_high;
+    }
+  else
+    {
+      struct die_info *child = die->child;
+
+      while (child && child->tag)
+       {
+         switch (child->tag) {
+         case DW_TAG_subprogram:
+           if (dwarf2_get_pc_bounds (child, &current_low, &current_high, cu))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         case DW_TAG_namespace:
+           /* FIXME: carlton/2004-01-16: Should we do this for
+              DW_TAG_class_type/DW_TAG_structure_type, too?  I think
+              that current GCC's always emit the DIEs corresponding
+              to definitions of methods of classes as children of a
+              DW_TAG_compile_unit or DW_TAG_namespace (as opposed to
+              the DIEs giving the declarations, which could be
+              anywhere).  But I don't see any reason why the
+              standards says that they have to be there.  */
+           get_scope_pc_bounds (child, &current_low, &current_high, cu);
+
+           if (current_low != ((CORE_ADDR) -1))
+             {
+               best_low = min (best_low, current_low);
+               best_high = max (best_high, current_high);
+             }
+           break;
+         default:
+           /* Ignore. */
+           break;
+         }
+
+         child = sibling_die (child);
+       }
+    }
+
+  *lowpc = best_low;
+  *highpc = best_high;
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -2349,18 +2576,18 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     new_field->accessibility = DW_ACCESS_private;
   new_field->virtuality = DW_VIRTUALITY_none;
 
     new_field->accessibility = DW_ACCESS_private;
   new_field->virtuality = DW_VIRTUALITY_none;
 
-  attr = dwarf_attr (die, DW_AT_accessibility);
+  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr)
     new_field->accessibility = DW_UNSND (attr);
   if (new_field->accessibility != DW_ACCESS_public)
     fip->non_public_fields = 1;
   if (attr)
     new_field->accessibility = DW_UNSND (attr);
   if (new_field->accessibility != DW_ACCESS_public)
     fip->non_public_fields = 1;
-  attr = dwarf_attr (die, DW_AT_virtuality);
+  attr = dwarf2_attr (die, DW_AT_virtuality, cu);
   if (attr)
     new_field->virtuality = DW_UNSND (attr);
 
   fp = &new_field->field;
 
   if (attr)
     new_field->virtuality = DW_UNSND (attr);
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die))
+  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
       /* Data member other than a C++ static data member.  */
       
     {
       /* Data member other than a C++ static data member.  */
       
@@ -2370,7 +2597,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).  */
       FIELD_STATIC_KIND (*fp) = 0;
 
       /* Get bit size of field (zero if none).  */
-      attr = dwarf_attr (die, DW_AT_bit_size);
+      attr = dwarf2_attr (die, DW_AT_bit_size, cu);
       if (attr)
        {
          FIELD_BITSIZE (*fp) = DW_UNSND (attr);
       if (attr)
        {
          FIELD_BITSIZE (*fp) = DW_UNSND (attr);
@@ -2381,7 +2608,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
        }
 
       /* Get bit offset of field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        {
          FIELD_BITPOS (*fp) =
       if (attr)
        {
          FIELD_BITPOS (*fp) =
@@ -2389,7 +2616,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
       else
        FIELD_BITPOS (*fp) = 0;
        }
       else
        FIELD_BITPOS (*fp) = 0;
-      attr = dwarf_attr (die, DW_AT_bit_offset);
+      attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
          if (BITS_BIG_ENDIAN)
       if (attr)
        {
          if (BITS_BIG_ENDIAN)
@@ -2412,7 +2639,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
              int anonymous_size;
              int bit_offset = DW_UNSND (attr);
 
              int anonymous_size;
              int bit_offset = DW_UNSND (attr);
 
-             attr = dwarf_attr (die, DW_AT_byte_size);
+             attr = dwarf2_attr (die, DW_AT_byte_size, cu);
              if (attr)
                {
                  /* The size of the anonymous object containing
              if (attr)
                {
                  /* The size of the anonymous object containing
@@ -2434,15 +2661,15 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get name of field.  */
        }
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       fp->name = obsavestring (fieldname, strlen (fieldname),
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       fp->name = obsavestring (fieldname, strlen (fieldname),
-                              &objfile->type_obstack);
+                              &objfile->objfile_obstack);
 
       /* Change accessibility for artificial fields (e.g. virtual table
          pointer or virtual base class pointer) to private.  */
 
       /* Change accessibility for artificial fields (e.g. virtual table
          pointer or virtual base class pointer) to private.  */
-      if (dwarf_attr (die, DW_AT_artificial))
+      if (dwarf2_attr (die, DW_AT_artificial, cu))
        {
          new_field->accessibility = DW_ACCESS_private;
          fip->non_public_fields = 1;
        {
          new_field->accessibility = DW_ACCESS_private;
          fip->non_public_fields = 1;
@@ -2460,25 +2687,25 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       char *physname;
 
       /* Get name of field.  */
       char *physname;
 
       /* Get name of field.  */
-      attr = dwarf_attr (die, DW_AT_name);
+      attr = dwarf2_attr (die, DW_AT_name, cu);
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       else
        return;
 
       /* Get physical name.  */
       if (attr && DW_STRING (attr))
        fieldname = DW_STRING (attr);
       else
        return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die);
+      physname = dwarf2_linkage_name (die, cu);
 
       SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
 
       SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
-                                            &objfile->type_obstack));
+                                            &objfile->objfile_obstack));
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
-                                      &objfile->type_obstack);
+                                      &objfile->objfile_obstack);
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
-      attr = dwarf_attr (die, DW_AT_data_member_location);
+      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
                              * bits_per_byte);
       if (attr)
        FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
                              * bits_per_byte);
@@ -2593,14 +2820,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   struct nextfnfield *new_fnfield;
 
   /* Get name of member function.  */
   struct nextfnfield *new_fnfield;
 
   /* Get name of member function.  */
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     fieldname = DW_STRING (attr);
   else
     return;
 
   /* Get the mangled name.  */
   if (attr && DW_STRING (attr))
     fieldname = DW_STRING (attr);
   else
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die);
+  physname = dwarf2_linkage_name (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -2642,7 +2869,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
   fnp->physname = obsavestring (physname, strlen (physname),
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
   fnp->physname = obsavestring (physname, strlen (physname),
-                               &objfile->type_obstack);
+                               &objfile->objfile_obstack);
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
@@ -2670,14 +2897,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
-  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+  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.  */
     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))
   if (attr)
     {
       switch (DW_UNSND (attr))
@@ -2692,12 +2919,12 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
 
   /* Check for artificial methods.  */
     }
 
   /* Check for artificial methods.  */
-  attr = dwarf_attr (die, DW_AT_artificial);
+  attr = dwarf2_attr (die, DW_AT_artificial, cu);
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
   /* Get index in virtual function table if it is a virtual member function.  */
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
   /* Get index in virtual function table if it is a virtual member function.  */
-  attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+  attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
   if (attr)
     {
       /* Support the .debug_loc offsets */
@@ -2773,16 +3000,55 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
+  const char *name = NULL;
+  const char *previous_prefix = processing_current_prefix;
+  struct cleanup *back_to = NULL;
+  /* This says whether or not we want to try to update the structure's
+     name to include enclosing namespace/class information, if
+     any.  */
+  int need_to_update_name = 0;
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      name = DW_STRING (attr);
+
+      if (cu->language == language_cplus)
+       {
+         struct die_info *spec_die = die_specification (die, cu);
+
+         if (spec_die != NULL)
+           {
+             char *specification_prefix = determine_prefix (spec_die, cu);
+             processing_current_prefix = specification_prefix;
+             back_to = make_cleanup (xfree, specification_prefix);
+           }
+       }
+
+      if (processing_has_namespace_info)
+       {
+         /* FIXME: carlton/2003-11-10: This variable exists only for
+            const-correctness reasons.  When I tried to change
+            TYPE_TAG_NAME to be a const char *, I ran into a cascade
+            of changes which would have forced decode_line_1 to take
+            a const char **.  */
+         char *new_prefix = obconcat (&objfile->objfile_obstack,
+                                      processing_current_prefix,
+                                      processing_current_prefix[0] == '\0'
+                                      ? "" : "::",
+                                      name);
+         TYPE_TAG_NAME (type) = new_prefix;
+         processing_current_prefix = new_prefix;
+       }
+      else
+       {
+         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+                                              &objfile->objfile_obstack);
+         need_to_update_name = (cu->language == language_cplus);
+       }
     }
 
   if (die->tag == DW_TAG_structure_type)
     }
 
   if (die->tag == DW_TAG_structure_type)
@@ -2800,7 +3066,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
       TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -2815,7 +3081,7 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
      type within the structure itself. */
   die->type = type;
 
      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;
     {
       struct field_info fi;
       struct die_info *child_die;
@@ -2842,6 +3108,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);
              /* 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)
            {
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
@@ -2866,7 +3167,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.  */
 
             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);
 
            {
              struct type *t = die_containing_type (die, cu);
 
@@ -2917,6 +3218,10 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
+
+  processing_current_prefix = previous_prefix;
+  if (back_to != NULL)
+    do_cleanups (back_to);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -2943,15 +3248,27 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
   if (attr && DW_STRING (attr))
     {
-      TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
-                                          strlen (DW_STRING (attr)),
-                                          &objfile->type_obstack);
+      const char *name = DW_STRING (attr);
+
+      if (processing_has_namespace_info)
+       {
+         TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
+                                          processing_current_prefix,
+                                          processing_current_prefix[0] == '\0'
+                                          ? "" : "::",
+                                          name);
+       }
+      else
+       {
+         TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+                                              &objfile->objfile_obstack);
+       }
     }
 
     }
 
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -2974,7 +3291,7 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
            }
          else
            {
            }
          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);
              if (attr)
                {
                  sym = new_symbol (child_die, type, cu);
@@ -3046,7 +3363,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
      arrays with unspecified length.  */
   if (die->child == NULL)
     {
      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;
       range_type = create_range_type (NULL, index_type, 0, -1);
       die->type = create_array_type (NULL, element_type, range_type);
       return;
@@ -3058,88 +3375,22 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
-         unsigned int low, high;
+          read_subrange_type (child_die, cu);
 
 
-         /* 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;
-           }
-
-         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));
-                 low = 0;
-               }
-           }
-         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));
-                 high = 1;
-               }
-           }
-
-         /* Create a range type and save it for array type creation.  */
-         if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
-           {
-             range_types = (struct type **)
-               xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
-                         * sizeof (struct type *));
-             if (ndim == 0)
-               make_cleanup (free_current_contents, &range_types);
-           }
-         range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+          if (child_die->type != NULL)
+            {
+             /* The range type was succesfully read. Save it for
+                 the array type creation.  */
+              if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+                {
+                  range_types = (struct type **)
+                    xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                              * sizeof (struct type *));
+                  if (ndim == 0)
+                    make_cleanup (free_current_contents, &range_types);
+               }
+             range_types[ndim++] = child_die->type;
+            }
        }
       child_die = sibling_die (child_die);
     }
        }
       child_die = sibling_die (child_die);
     }
@@ -3156,7 +3407,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.  */
      custom vendor extension.  The main difference between a regular
      array and the vector variant is that vectors are passed by value
      to functions.  */
-  attr = dwarf_attr (die, DW_AT_GNU_vector);
+  attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
   if (attr)
     TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
 
   if (attr)
     TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
 
@@ -3176,7 +3427,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
 
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
 
-  attr = dwarf_attr (die, DW_AT_location);
+  attr = dwarf2_attr (die, DW_AT_location, cu);
   if (attr)
     {
       /* Support the .debug_loc offsets */
   if (attr)
     {
       /* Support the .debug_loc offsets */
@@ -3200,7 +3451,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);
       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) =
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) =
@@ -3218,68 +3469,53 @@ static void
 read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
 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;
 
   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.  */
 
 
   /* Now build the name of the current namespace.  */
 
-  if (previous_namespace[0] == '\0')
+  if (previous_prefix[0] == '\0')
     {
     {
-      processing_current_namespace = name;
+      processing_current_prefix = name;
     }
   else
     {
     }
   else
     {
-      /* We need temp_name around because processing_current_namespace
+      /* We need temp_name around because processing_current_prefix
         is a const char *.  */
         is a const char *.  */
-      char *temp_name = alloca (strlen (previous_namespace)
+      char *temp_name = alloca (strlen (previous_prefix)
                                + 2 + strlen(name) + 1);
                                + 2 + strlen(name) + 1);
-      strcpy (temp_name, previous_namespace);
+      strcpy (temp_name, previous_prefix);
       strcat (temp_name, "::");
       strcat (temp_name, name);
 
       strcat (temp_name, "::");
       strcat (temp_name, name);
 
-      processing_current_namespace = temp_name;
+      processing_current_prefix = temp_name;
     }
 
   /* Add a symbol associated to this if we haven't seen the namespace
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
     }
 
   /* Add a symbol associated to this if we haven't seen the namespace
      before.  Also, add a using directive if it's an anonymous
      namespace.  */
 
-  if (dwarf2_extension (die) == NULL)
+  if (dwarf2_extension (die, cu) == NULL)
     {
       struct type *type;
 
       /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
         this cast will hopefully become unnecessary.  */
       type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
     {
       struct type *type;
 
       /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
         this cast will hopefully become unnecessary.  */
       type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
-                       (char *) processing_current_namespace,
+                       (char *) processing_current_prefix,
                        objfile);
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
       new_symbol (die, type, cu);
 
       if (is_anonymous)
                        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)
     }
 
   if (die->child != NULL)
@@ -3293,7 +3529,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
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
@@ -3315,13 +3581,13 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = lookup_pointer_type (die_type (die, 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;
 
   if (attr_byte_size)
     byte_size = DW_UNSND (attr_byte_size);
   else
     byte_size = cu_header->addr_size;
 
-  attr_address_class = dwarf_attr (die, DW_AT_address_class);
+  attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu);
   if (attr_address_class)
     addr_class = DW_UNSND (attr_address_class);
   else
   if (attr_address_class)
     addr_class = DW_UNSND (attr_address_class);
   else
@@ -3393,7 +3659,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   type = lookup_reference_type (die_type (die, 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);
   if (attr)
     {
       TYPE_LENGTH (type) = DW_UNSND (attr);
@@ -3451,7 +3717,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_string_length);
+  attr = dwarf2_attr (die, DW_AT_string_length, cu);
   if (attr)
     {
       length = DW_UNSND (attr);
   if (attr)
     {
       length = DW_UNSND (attr);
@@ -3459,7 +3725,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
   else
     {
       /* check for the DW_AT_byte_size attribute */
   else
     {
       /* check for the DW_AT_byte_size attribute */
-      attr = dwarf_attr (die, DW_AT_byte_size);
+      attr = dwarf2_attr (die, DW_AT_byte_size, cu);
       if (attr)
         {
           length = DW_UNSND (attr);
       if (attr)
         {
           length = DW_UNSND (attr);
@@ -3469,9 +3735,9 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
           length = 1;
         }
     }
           length = 1;
         }
     }
-  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
   range_type = create_range_type (NULL, index_type, 1, length);
   range_type = create_range_type (NULL, index_type, 1, length);
-  if (cu_language == language_fortran)
+  if (cu->language == language_fortran)
     {
       /* Need to create a unique string type for bounds
          information */
     {
       /* Need to create a unique string type for bounds
          information */
@@ -3479,7 +3745,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
     }
   else
     {
     }
   else
     {
-      char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+      char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
       type = create_string_type (char_type, range_type);
     }
   die->type = type;
       type = create_string_type (char_type, range_type);
     }
   die->type = type;
@@ -3512,9 +3778,9 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
   ftype = lookup_function_type (type);
 
   /* All functions in C++ have prototypes.  */
-  attr = dwarf_attr (die, DW_AT_prototyped);
+  attr = dwarf2_attr (die, DW_AT_prototyped, cu);
   if ((attr && (DW_UNSND (attr) != 0))
   if ((attr && (DW_UNSND (attr) != 0))
-      || cu_language == language_cplus)
+      || cu->language == language_cplus)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
   if (die->child != NULL)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
   if (die->child != NULL)
@@ -3551,7 +3817,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.  */
                 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
              if (attr)
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
              else
@@ -3575,7 +3841,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 
   if (!die->type)
     {
 
   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);
       if (attr && DW_STRING (attr))
        {
          name = DW_STRING (attr);
@@ -3602,17 +3868,17 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
       return;
     }
 
-  attr = dwarf_attr (die, DW_AT_encoding);
+  attr = dwarf2_attr (die, DW_AT_encoding, cu);
   if (attr)
     {
       encoding = DW_UNSND (attr);
     }
   if (attr)
     {
       encoding = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_byte_size);
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
       size = DW_UNSND (attr);
     }
   if (attr)
     {
       size = DW_UNSND (attr);
     }
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
@@ -3649,18 +3915,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 = init_type (code, size, type_flags, DW_STRING (attr), objfile);
       if (encoding == DW_ATE_address)
-       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+       TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID,
+                                                          cu);
       else if (encoding == DW_ATE_complex_float)
        {
          if (size == 32)
            TYPE_TARGET_TYPE (type)
       else if (encoding == DW_ATE_complex_float)
        {
          if (size == 32)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
          else if (size == 16)
            TYPE_TARGET_TYPE (type)
          else if (size == 16)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
          else if (size == 8)
            TYPE_TARGET_TYPE (type)
          else if (size == 8)
            TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_FLOAT);
+             = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
     }
   else
        }
     }
   else
@@ -3670,6 +3937,78 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   die->type = type;
 }
 
   die->type = type;
 }
 
+/* Read the given DW_AT_subrange DIE.  */
+
+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *base_type;
+  struct type *range_type;
+  struct attribute *attr;
+  int low = 0;
+  int high = -1;
+  
+  /* If we have already decoded this die, then nothing more to do.  */
+  if (die->type)
+    return;
+
+  base_type = die_type (die, cu);
+  if (base_type == NULL)
+    {
+      complaint (&symfile_complaints,
+                "DW_AT_type missing from DW_TAG_subrange_type");
+      return;
+    }
+
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+    base_type = alloc_type (NULL);
+
+  if (cu->language == language_fortran)
+    { 
+      /* FORTRAN implies a lower bound of 1, if not given.  */
+      low = 1;
+    }
+
+  attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
+  if (attr)
+    low = dwarf2_get_attr_constant_value (attr, 0);
+
+  attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+  if (attr)
+    {       
+      if (attr->form == DW_FORM_block1)
+        {
+          /* GCC encodes arrays with unspecified or dynamic length
+             with a DW_FORM_block1 attribute.
+             FIXME: GDB does not yet know how to handle dynamic
+             arrays properly, treat them as arrays with unspecified
+             length for now.
+
+             FIXME: jimb/2003-09-22: GDB does not really know
+             how to handle arrays of unspecified length
+             either; we just represent them as zero-length
+             arrays.  Choose an appropriate upper bound given
+             the lower bound we've computed above.  */
+          high = low - 1;
+        }
+      else
+        high = dwarf2_get_attr_constant_value (attr, 1);
+    }
+
+  range_type = create_range_type (NULL, base_type, low, high);
+
+  attr = dwarf2_attr (die, DW_AT_name, cu);
+  if (attr && DW_STRING (attr))
+    TYPE_NAME (range_type) = DW_STRING (attr);
+  
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+  if (attr)
+    TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+  die->type = range_type;
+}
+  
+
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
@@ -3792,7 +4131,7 @@ make_cleanup_free_die_list (struct die_info *dies)
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
-   object file specified by OBJFILE into the psymbol_obstack and return it.  */
+   object file specified by OBJFILE into the objfile_obstack and return it.  */
 
 char *
 dwarf2_read_section (struct objfile *objfile, asection *sectp)
 
 char *
 dwarf2_read_section (struct objfile *objfile, asection *sectp)
@@ -3804,7 +4143,7 @@ dwarf2_read_section (struct objfile *objfile, asection *sectp)
   if (size == 0)
     return NULL;
 
   if (size == 0)
     return NULL;
 
-  buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+  buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
   retbuf
     = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
   retbuf
     = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
@@ -4039,7 +4378,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
            complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
          else
            part_die->sibling =
            complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
          else
            part_die->sibling =
-             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
          break;
        default:
          break;
          break;
        default:
          break;
@@ -4054,7 +4393,8 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
       struct partial_die_info spec_die;
       char *spec_ptr;
 
       struct partial_die_info spec_die;
       char *spec_ptr;
 
-      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)
        {
       read_partial_die (&spec_die, abfd, spec_ptr, cu);
       if (spec_die.name)
        {
@@ -4588,27 +4928,27 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
 }
 
 static void
 }
 
 static void
-set_cu_language (unsigned int lang)
+set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
 {
   switch (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
 {
   switch (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
-      cu_language = language_c;
+      cu->language = language_c;
       break;
     case DW_LANG_C_plus_plus:
       break;
     case DW_LANG_C_plus_plus:
-      cu_language = language_cplus;
+      cu->language = language_cplus;
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
-      cu_language = language_fortran;
+      cu->language = language_fortran;
       break;
     case DW_LANG_Mips_Assembler:
       break;
     case DW_LANG_Mips_Assembler:
-      cu_language = language_asm;
+      cu->language = language_asm;
       break;
     case DW_LANG_Java:
       break;
     case DW_LANG_Java:
-      cu_language = language_java;
+      cu->language = language_java;
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
@@ -4617,16 +4957,16 @@ set_cu_language (unsigned int lang)
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
-      cu_language = language_minimal;
+      cu->language = language_minimal;
       break;
     }
       break;
     }
-  cu_language_defn = language_def (cu_language);
+  cu->language_defn = language_def (cu->language);
 }
 
 /* Return the named attribute or NULL if not there.  */
 
 static struct attribute *
 }
 
 /* Return the named attribute or NULL if not there.  */
 
 static struct attribute *
-dwarf_attr (struct die_info *die, unsigned int name)
+dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
 {
   unsigned int i;
   struct attribute *spec = NULL;
 {
   unsigned int i;
   struct attribute *spec = NULL;
@@ -4644,22 +4984,35 @@ dwarf_attr (struct die_info *die, unsigned int name)
   if (spec)
     {
       struct die_info *ref_die =
   if (spec)
     {
       struct die_info *ref_die =
-      follow_die_ref (dwarf2_get_ref_die_offset (spec));
+      follow_die_ref (dwarf2_get_ref_die_offset (spec, cu));
 
       if (ref_die)
 
       if (ref_die)
-       return dwarf_attr (ref_die, name);
+       return dwarf2_attr (ref_die, name, cu);
     }
 
   return NULL;
 }
 
 static int
     }
 
   return NULL;
 }
 
 static int
-die_is_declaration (struct die_info *die)
+die_is_declaration (struct die_info *die, struct dwarf2_cu *cu)
 {
 {
-  return (dwarf_attr (die, DW_AT_declaration)
-         && ! dwarf_attr (die, DW_AT_specification));
+  return (dwarf2_attr (die, DW_AT_declaration, cu)
+         && ! dwarf2_attr (die, DW_AT_specification, cu));
 }
 
 }
 
+/* Return the die giving the specification for DIE, if there is
+   one.  */
+
+static struct die_info *
+die_specification (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
+
+  if (spec_attr == NULL)
+    return NULL;
+  else
+    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
+}
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
 
 /* Free the line_header structure *LH, and any arrays and strings it
    refers to.  */
@@ -4852,26 +5205,26 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
    addresses passed to record_line.  */
 
 static CORE_ADDR
    addresses passed to record_line.  */
 
 static CORE_ADDR
-check_cu_functions (CORE_ADDR address)
+check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
 {
   struct function_range *fn;
 
   /* Find the function_range containing address.  */
 {
   struct function_range *fn;
 
   /* Find the function_range containing address.  */
-  if (!cu_first_fn)
+  if (!cu->first_fn)
     return address;
 
     return address;
 
-  if (!cu_cached_fn)
-    cu_cached_fn = cu_first_fn;
+  if (!cu->cached_fn)
+    cu->cached_fn = cu->first_fn;
 
 
-  fn = cu_cached_fn;
+  fn = cu->cached_fn;
   while (fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
       fn = fn->next;
 
   while (fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
       fn = fn->next;
 
-  fn = cu_first_fn;
-  while (fn && fn != cu_cached_fn)
+  fn = cu->first_fn;
+  while (fn && fn != cu->cached_fn)
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
     if (fn->lowpc <= address && fn->highpc > address)
       goto found;
     else
@@ -4902,6 +5255,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;
   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;
 
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
@@ -4947,7 +5304,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
              record_line (current_subfile, line, 
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 1;
            }
          else switch (op_code)
              basic_block = 1;
            }
          else switch (op_code)
@@ -4994,7 +5351,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              break;
            case DW_LNS_copy:
              record_line (current_subfile, line, 
              break;
            case DW_LNS_copy:
              record_line (current_subfile, line, 
-                          check_cu_functions (address));
+                          check_cu_functions (address, cu));
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -5175,21 +5532,24 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
   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)
 
   if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die);
+    name = dwarf2_linkage_name (die, cu);
   else
     name = TYPE_NAME (type);
 
   if (name)
     {
   else
     name = TYPE_NAME (type);
 
   if (name)
     {
-      sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+      sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
-      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_LANGUAGE (sym) = cu->language;
       SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
       SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
@@ -5200,7 +5560,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);
        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);
       if (attr)
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
@@ -5208,7 +5568,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       switch (die->tag)
        {
        case DW_TAG_label:
       switch (die->tag)
        {
        case DW_TAG_label:
-         attr = dwarf_attr (die, DW_AT_low_pc);
+         attr = dwarf2_attr (die, DW_AT_low_pc, cu);
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
          if (attr)
            {
              SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
@@ -5219,14 +5579,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;
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
-         attr2 = dwarf_attr (die, DW_AT_external);
+         attr2 = dwarf2_attr (die, DW_AT_external, cu);
          if (attr2 && (DW_UNSND (attr2) != 0))
            {
              add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
          if (attr2 && (DW_UNSND (attr2) != 0))
            {
              add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
-             add_symbol_to_list (sym, list_in_scope);
+             add_symbol_to_list (sym, cu->list_in_scope);
            }
          break;
        case DW_TAG_variable:
            }
          break;
        case DW_TAG_variable:
@@ -5238,26 +5598,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);
                                           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);
          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
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
              break;
            }
              break;
            }
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
              var_decode_location (attr, sym, 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
              if (attr2 && (DW_UNSND (attr2) != 0))
                add_symbol_to_list (sym, &global_symbols);
              else
-               add_symbol_to_list (sym, list_in_scope);
+               add_symbol_to_list (sym, cu->list_in_scope);
            }
          else
            {
            }
          else
            {
@@ -5267,9 +5627,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.  */
                 The address of the variable will then be determined from
                 the minimal symbol table whenever the variable is
                 referenced.  */
-             attr2 = dwarf_attr (die, DW_AT_external);
+             attr2 = dwarf2_attr (die, DW_AT_external, cu);
              if (attr2 && (DW_UNSND (attr2) != 0)
              if (attr2 && (DW_UNSND (attr2) != 0)
-                 && dwarf_attr (die, DW_AT_type) != NULL)
+                 && dwarf2_attr (die, DW_AT_type, cu) != NULL)
                {
                  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                  add_symbol_to_list (sym, &global_symbols);
                {
                  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                  add_symbol_to_list (sym, &global_symbols);
@@ -5277,7 +5637,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            }
          break;
        case DW_TAG_formal_parameter:
            }
          break;
        case DW_TAG_formal_parameter:
-         attr = dwarf_attr (die, DW_AT_location);
+         attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
              var_decode_location (attr, sym, cu);
          if (attr)
            {
              var_decode_location (attr, sym, cu);
@@ -5285,12 +5645,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;
            }
              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);
            }
          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
          break;
        case DW_TAG_unspecified_parameters:
          /* From varargs functions; gdb doesn't seem to have any
@@ -5303,39 +5663,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;
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
 
 
-         /* The semantics of C++ state that "struct foo { ... }" also
-            defines a typedef for "foo". Synthesize a typedef symbol so
-            that "ptype foo" works as expected.  */
-         if (cu_language == language_cplus)
+         /* Make sure that the symbol includes appropriate enclosing
+            classes/namespaces in its name.  These are calculated in
+            read_structure_scope, and the correct name is saved in
+            the type.  */
+
+         if (cu->language == language_cplus)
            {
            {
-             struct symbol *typedef_sym = (struct symbol *)
-             obstack_alloc (&objfile->symbol_obstack,
-                            sizeof (struct symbol));
-             *typedef_sym = *sym;
-             SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
-             if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-               TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 obsavestring (DEPRECATED_SYMBOL_NAME (sym),
-                               strlen (DEPRECATED_SYMBOL_NAME (sym)),
-                               &objfile->type_obstack);
-             add_symbol_to_list (typedef_sym, list_in_scope);
+             struct type *type = SYMBOL_TYPE (sym);
+             
+             if (TYPE_TAG_NAME (type) != NULL)
+               {
+                 /* FIXME: carlton/2003-11-10: Should this use
+                    SYMBOL_SET_NAMES instead?  (The same problem also
+                    arises a further down in the function.)  */
+                 SYMBOL_LINKAGE_NAME (sym)
+                   = obsavestring (TYPE_TAG_NAME (type),
+                                   strlen (TYPE_TAG_NAME (type)),
+                                   &objfile->objfile_obstack);
+               }
            }
            }
+
+         {
+           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+              really ever be static objects: otherwise, if you try
+              to, say, break of a class's method and you're in a file
+              which doesn't mention that class, it won't work unless
+              the check for all static symbols in lookup_symbol_aux
+              saves you.  See the OtherFileClass tests in
+              gdb.c++/namespace.exp.  */
+
+           struct pending **list_to_add;
+
+           list_to_add = (cu->list_in_scope == &file_symbols
+                          && cu->language == language_cplus
+                          ? &global_symbols : cu->list_in_scope);
+         
+           add_symbol_to_list (sym, list_to_add);
+
+           /* The semantics of C++ state that "struct foo { ... }" also
+              defines a typedef for "foo". Synthesize a typedef symbol so
+              that "ptype foo" works as expected.  */
+           if (cu->language == language_cplus)
+             {
+               struct symbol *typedef_sym = (struct symbol *)
+                 obstack_alloc (&objfile->objfile_obstack,
+                                sizeof (struct symbol));
+               *typedef_sym = *sym;
+               SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+               if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+                 TYPE_NAME (SYMBOL_TYPE (sym)) =
+                   obsavestring (SYMBOL_NATURAL_NAME (sym),
+                                 strlen (SYMBOL_NATURAL_NAME (sym)),
+                                 &objfile->objfile_obstack);
+               add_symbol_to_list (typedef_sym, list_to_add);
+             }
+         }
          break;
        case DW_TAG_typedef:
          break;
        case DW_TAG_typedef:
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         add_symbol_to_list (sym, cu->list_in_scope);
+         break;
        case DW_TAG_base_type:
        case DW_TAG_base_type:
+        case DW_TAG_subrange_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-         add_symbol_to_list (sym, list_in_scope);
+         add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_enumerator:
          break;
        case DW_TAG_enumerator:
-         attr = dwarf_attr (die, DW_AT_const_value);
+         if (processing_has_namespace_info
+             && processing_current_prefix[0] != '\0')
+           {
+             SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
+                                                   processing_current_prefix,
+                                                   "::",
+                                                   name);
+           }
+         attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
              dwarf2_const_value (attr, sym, 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;
          break;
        case DW_TAG_namespace:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -5373,7 +5803,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+       obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size);
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
       store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
       /* NOTE: cagney/2003-05-09: In-lined store_address call with
          it's body - store_unsigned_integer.  */
       store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
@@ -5391,7 +5821,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
-       obstack_alloc (&objfile->symbol_obstack, blk->size);
+       obstack_alloc (&objfile->objfile_obstack, blk->size);
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
@@ -5467,15 +5897,15 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *type_die;
   unsigned int ref;
 
   struct die_info *type_die;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_type);
+  type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
-      return dwarf2_fundamental_type (cu->objfile, FT_VOID);
+      return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
     }
   else
     {
     }
   else
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
@@ -5505,10 +5935,10 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *type_die = NULL;
   unsigned int ref;
 
   struct die_info *type_die = NULL;
   unsigned int ref;
 
-  type_attr = dwarf_attr (die, DW_AT_containing_type);
+  type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (type_attr)
     {
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr);
+      ref = dwarf2_get_ref_die_offset (type_attr, cu);
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
@@ -5569,6 +5999,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)
 {
 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:
   switch (die->tag)
     {
     case DW_TAG_class_type:
@@ -5607,6 +6042,9 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_typedef:
       read_typedef (die, cu);
       break;
     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;
     case DW_TAG_base_type:
       read_base_type (die, cu);
       break;
@@ -5615,6 +6053,129 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
                 dwarf_tag_name (die->tag));
       break;
     }
                 dwarf_tag_name (die->tag));
       break;
     }
+
+  processing_current_prefix = old_prefix;
+  do_cleanups (back_to);
+}
+
+/* Return the name of the namespace/class that DIE is defined within,
+   or "" if we can't tell.  The caller should xfree the result.  */
+
+/* NOTE: carlton/2004-01-23: See read_func_scope (and the comment
+   therein) for an example of how to use this function to deal with
+   DW_AT_specification.  */
+
+static char *
+determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  char *prefix = determine_prefix_aux (die, cu);
+
+  return prefix ? prefix : xstrdup ("");
+}
+
+/* Return the name of the namespace/class that DIE is defined
+   within, or NULL if we can't tell.  The caller should xfree the
+   result.  */
+
+static char *
+determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *parent;
+
+  if (cu->language != language_cplus)
+    return NULL;
+
+  parent = die->parent;
+
+  if (parent == NULL)
+    {
+      return (processing_has_namespace_info ? xstrdup ("") : NULL);
+    }
+  else
+    {
+      char *parent_prefix = determine_prefix_aux (parent, cu);
+      char *retval;
+
+      switch (parent->tag) {
+      case DW_TAG_namespace:
+       {
+         int dummy;
+
+         retval = typename_concat (parent_prefix,
+                                   namespace_name (parent, &dummy, cu));
+       }
+       break;
+      case DW_TAG_class_type:
+      case DW_TAG_structure_type:
+       {
+         if (parent_prefix != NULL)
+           {
+             const char *parent_name = dwarf2_name (parent, cu);
+
+             if (parent_name != NULL)
+               retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
+             else
+               /* FIXME: carlton/2003-11-10: I'm not sure what the
+                  best thing to do here is.  */
+               retval = typename_concat (parent_prefix,
+                                         "<<anonymous class>>");
+           }
+         else
+           retval = class_name (parent, cu);
+       }
+       break;
+      default:
+       retval = parent_prefix;
+       break;
+      }
+
+      if (retval != parent_prefix)
+       xfree (parent_prefix);
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string formed by concatenating PREFIX,
+   "::", and SUFFIX, except that if PREFIX is NULL or the empty
+   string, just return a copy of SUFFIX.  */
+
+static char *
+typename_concat (const char *prefix, const char *suffix)
+{
+  if (prefix == NULL || prefix[0] == '\0')
+    return xstrdup (suffix);
+  else
+    {
+      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+
+      strcpy (retval, prefix);
+      strcat (retval, "::");
+      strcat (retval, suffix);
+
+      return retval;
+    }
+}
+
+/* Return a newly-allocated string giving the name of the class given
+   by DIE.  */
+
+static char *
+class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct die_info *child;
+  const char *name;
+
+  for (child = die->child; child != NULL; child = sibling_die (child))
+    {
+      if (child->tag == DW_TAG_subprogram)
+       return class_name_from_physname (dwarf2_linkage_name (child, cu));
+    }
+
+  name = dwarf2_name (die, cu);
+  if (name != NULL)
+    return xstrdup (name);
+  else
+    return xstrdup ("");
 }
 
 static struct type *
 }
 
 static struct type *
@@ -5628,69 +6189,69 @@ dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
   switch (encoding)
     {
     case DW_ATE_address:
   switch (encoding)
     {
     case DW_ATE_address:
-      type = dwarf2_fundamental_type (objfile, FT_VOID);
+      type = dwarf2_fundamental_type (objfile, FT_VOID, cu);
       return type;
     case DW_ATE_boolean:
       return type;
     case DW_ATE_boolean:
-      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu);
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu);
        }
       else
        {
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu);
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
        }
       else
        {
        }
       else
        {
-         type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
          break;
        case 2:
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu);
          break;
        default:
        case 4:
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_signed_char:
          break;
        }
       return type;
     case DW_ATE_signed_char:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
          break;
        case 2:
          break;
        case 2:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu);
          break;
        default:
        case 4:
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu);
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
-      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
       return type;
     default:
       return type;
     default:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
       return type;
     }
 }
       return type;
     }
 }
@@ -5739,14 +6300,14 @@ sibling_die (struct die_info *die)
 /* Get linkage name of a die, return NULL if not found.  */
 
 static char *
 /* Get linkage name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_linkage_name (struct die_info *die)
+dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -5755,11 +6316,11 @@ dwarf2_linkage_name (struct die_info *die)
 /* Get name of a die, return NULL if not found.  */
 
 static char *
 /* Get name of a die, return NULL if not found.  */
 
 static char *
-dwarf2_name (struct die_info *die)
+dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
 {
   struct attribute *attr;
 
-  attr = dwarf_attr (die, DW_AT_name);
+  attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
   if (attr && DW_STRING (attr))
     return DW_STRING (attr);
   return NULL;
@@ -5769,17 +6330,17 @@ dwarf2_name (struct die_info *die)
    is none.  */
 
 static struct die_info *
    is none.  */
 
 static struct die_info *
-dwarf2_extension (struct die_info *die)
+dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
 
 {
   struct attribute *attr;
   struct die_info *extension_die;
   unsigned int ref;
 
-  attr = dwarf_attr (die, DW_AT_extension);
+  attr = dwarf2_attr (die, DW_AT_extension, cu);
   if (attr == NULL)
     return NULL;
 
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr);
+  ref = dwarf2_get_ref_die_offset (attr, cu);
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
   extension_die = follow_die_ref (ref);
   if (!extension_die)
     {
@@ -6692,7 +7253,7 @@ dwarf2_empty_hash_tables (void)
 }
 
 static unsigned int
 }
 
 static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
 {
   unsigned int result = 0;
 
 {
   unsigned int result = 0;
 
@@ -6706,7 +7267,7 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      result = cu_header_offset + DW_UNSND (attr);
+      result = cu->header.offset + DW_UNSND (attr);
       break;
     default:
       complaint (&symfile_complaints,
       break;
     default:
       complaint (&symfile_complaints,
@@ -6716,6 +7277,28 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
   return result;
 }
 
   return result;
 }
 
+/* Return the constant value held by the given attribute.  Return -1
+   if the value held by the attribute is not constant.  */
+
+static int
+dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+{
+  if (attr->form == DW_FORM_sdata)
+    return DW_SND (attr);
+  else if (attr->form == DW_FORM_udata
+           || attr->form == DW_FORM_data1
+           || attr->form == DW_FORM_data2
+           || attr->form == DW_FORM_data4
+           || attr->form == DW_FORM_data8)
+    return DW_UNSND (attr);
+  else
+    {
+      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+                 dwarf_form_name (attr->form));
+      return default_value;
+    }
+}
+
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
 static struct die_info *
 follow_die_ref (unsigned int offset)
 {
@@ -6736,7 +7319,8 @@ follow_die_ref (unsigned int offset)
 }
 
 static struct type *
 }
 
 static struct type *
-dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+dwarf2_fundamental_type (struct objfile *objfile, int typeid,
+                        struct dwarf2_cu *cu)
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
@@ -6748,12 +7332,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. */
 
      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.
 }
 
 /* Decode simple location descriptions.
@@ -7073,7 +7657,7 @@ macro_start_file (int file, int line,
   /* We don't create a macro table for this compilation unit
      at all until we actually get a filename.  */
   if (! pending_macros)
   /* We don't create a macro table for this compilation unit
      at all until we actually get a filename.  */
   if (! pending_macros)
-    pending_macros = new_macro_table (&objfile->symbol_obstack,
+    pending_macros = new_macro_table (&objfile->objfile_obstack,
                                       objfile->macro_cache);
 
   if (! current_file)
                                       objfile->macro_cache);
 
   if (! current_file)
@@ -7416,7 +8000,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     {
       struct dwarf2_loclist_baton *baton;
 
     {
       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;
 
                             sizeof (struct dwarf2_loclist_baton));
       baton->objfile = cu->objfile;
 
@@ -7429,14 +8013,14 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
        complaint (&symfile_complaints,
                   "Location list used without specifying the CU base address.");
 
        complaint (&symfile_complaints,
                   "Location list used without specifying the CU base address.");
 
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
     {
       struct dwarf2_locexpr_baton *baton;
 
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
     {
       struct dwarf2_locexpr_baton *baton;
 
-      baton = obstack_alloc (&cu->objfile->symbol_obstack,
+      baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
       baton->objfile = cu->objfile;
 
                             sizeof (struct dwarf2_locexpr_baton));
       baton->objfile = cu->objfile;
 
@@ -7458,7 +8042,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
          baton->data = NULL;
        }
       
          baton->data = NULL;
        }
       
-      SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
This page took 0.063046 seconds and 4 git commands to generate.