* dwarf2read.c (offset_in_cu_p): New function.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index beeed0282466fc23b496e211e5cee6393045d294..fe95cdbcfc6b434d018319701180c97fd634c365 100644 (file)
@@ -1,31 +1,29 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Inc.  with support from Florida State University (under contract
    with the Ada Joint Program Office), and Silicon Graphics, Inc.
    Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
    based on Fred Fish's (Cygnus Support) implementation of DWARF 1
-   support in dwarfread.c
+   support.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or (at
-   your option) any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "bfd.h"
 #include "dwarf2loc.h"
 #include "cp-support.h"
 #include "hashtab.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "addrmap.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
 #include "gdb_assert.h"
 #include <sys/types.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
 
 /* A note on memory usage for this file.
    
    can be used for any other data associated to the objfile (symbol
    names, type names, location expressions to name a few).  */
 
-#ifndef DWARF2_REG_TO_REGNUM
-#define DWARF2_REG_TO_REGNUM(REG) (REG)
-#endif
-
 #if 0
 /* .debug_info header for a compilation unit
    Because of alignment constraints, this structure has padding and cannot
@@ -141,6 +141,12 @@ typedef struct statement_prologue
   }
 _STATEMENT_PROLOGUE;
 
+/* When set, the file that we're processing is known to have debugging
+   info for C++ namespaces.  GCC 3.3.x did not produce this information,
+   but later versions do.  */
+
+static int processing_has_namespace_info;
+
 static const struct objfile_data *dwarf2_objfile_data_key;
 
 struct dwarf2_per_objfile
@@ -159,13 +165,28 @@ struct dwarf2_per_objfile
   unsigned int eh_frame_size;
 
   /* Loaded data from the sections.  */
-  char *info_buffer;
-  char *abbrev_buffer;
-  char *line_buffer;
-  char *str_buffer;
-  char *macinfo_buffer;
-  char *ranges_buffer;
-  char *loc_buffer;
+  gdb_byte *info_buffer;
+  gdb_byte *abbrev_buffer;
+  gdb_byte *line_buffer;
+  gdb_byte *str_buffer;
+  gdb_byte *macinfo_buffer;
+  gdb_byte *ranges_buffer;
+  gdb_byte *loc_buffer;
+
+  /* A list of all the compilation units.  This is used to locate
+     the target compilation unit of a particular reference.  */
+  struct dwarf2_per_cu_data **all_comp_units;
+
+  /* The number of compilation units in ALL_COMP_UNITS.  */
+  int n_comp_units;
+
+  /* A chain of compilation units that are currently read in, so that
+     they can be freed later.  */
+  struct dwarf2_per_cu_data *read_in_chain;
+
+  /* A flag indicating wether this objfile has a section loaded at a
+     VMA of 0.  */
+  int has_section_at_zero;
 };
 
 static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -184,17 +205,20 @@ asection *dwarf_eh_frame_section;
 
 /* names of the debugging sections */
 
-#define INFO_SECTION     ".debug_info"
-#define ABBREV_SECTION   ".debug_abbrev"
-#define LINE_SECTION     ".debug_line"
-#define PUBNAMES_SECTION ".debug_pubnames"
-#define ARANGES_SECTION  ".debug_aranges"
-#define LOC_SECTION      ".debug_loc"
-#define MACINFO_SECTION  ".debug_macinfo"
-#define STR_SECTION      ".debug_str"
-#define RANGES_SECTION   ".debug_ranges"
-#define FRAME_SECTION    ".debug_frame"
-#define EH_FRAME_SECTION ".eh_frame"
+/* Note that if the debugging section has been compressed, it might
+   have a name like .zdebug_info.  */
+
+#define INFO_SECTION     "debug_info"
+#define ABBREV_SECTION   "debug_abbrev"
+#define LINE_SECTION     "debug_line"
+#define PUBNAMES_SECTION "debug_pubnames"
+#define ARANGES_SECTION  "debug_aranges"
+#define LOC_SECTION      "debug_loc"
+#define MACINFO_SECTION  "debug_macinfo"
+#define STR_SECTION      "debug_str"
+#define RANGES_SECTION   "debug_ranges"
+#define FRAME_SECTION    "debug_frame"
+#define EH_FRAME_SECTION "eh_frame"
 
 /* local data types */
 
@@ -206,43 +230,27 @@ asection *dwarf_eh_frame_section;
 /* The data in a compilation unit header, after target2host
    translation, looks like this.  */
 struct comp_unit_head
-  {
-    unsigned long length;
-    short version;
-    unsigned int abbrev_offset;
-    unsigned char addr_size;
-    unsigned char signed_addr_p;
-    unsigned int offset_size;  /* size of file offsets; either 4 or 8 */
-    unsigned int initial_length_size; /* size of the length field; either
-                                         4 or 12 */
-
-    /* Offset to the first byte of this compilation unit header in the 
-     * .debug_info section, for resolving relative reference dies. */
-
-    unsigned int offset;
-
-    /* Pointer to this compilation unit header in the .debug_info
-     * section */
-
-    char *cu_head_ptr;
-
-    /* Pointer to the first die of this compilatio unit.  This will
-     * be the first byte following the compilation unit header. */
-
-    char *first_die_ptr;
-
-    /* Pointer to the next compilation unit header in the program. */
-
-    struct comp_unit_head *next;
+{
+  unsigned long length;
+  short version;
+  unsigned char addr_size;
+  unsigned char signed_addr_p;
+  unsigned int abbrev_offset;
 
-    /* Base address of this compilation unit.  */
+  /* Size of file offsets; either 4 or 8.  */
+  unsigned int offset_size;
 
-    CORE_ADDR base_address;
+  /* Size of the length field; either 4 or 12.  */
+  unsigned int initial_length_size;
 
-    /* Non-zero if base_address has been set.  */
+  /* Offset to the first byte of this compilation unit header in the
+     .debug_info section, for resolving relative reference dies.  */
+  unsigned int offset;
 
-    int base_known;
-  };
+  /* Offset to first die in this cu from the start of the cu.
+     This will be the first byte following the compilation unit header.  */
+  unsigned int first_die_offset;
+};
 
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
@@ -250,12 +258,15 @@ struct dwarf2_cu
   /* The objfile containing this compilation unit.  */
   struct objfile *objfile;
 
-  /* The header of the compilation unit.
-
-     FIXME drow/2003-11-10: Some of the things from the comp_unit_head
-     should logically be moved to the dwarf2_cu structure.  */
+  /* The header of the compilation unit.  */
   struct comp_unit_head header;
 
+  /* Base address of this compilation unit.  */
+  CORE_ADDR base_address;
+
+  /* Non-zero if base_address has been set.  */
+  int base_known;
+
   struct function_range *first_fn, *last_fn, *cached_fn;
 
   /* The language we are debugging.  */
@@ -275,17 +286,6 @@ struct dwarf2_cu
      distinguish these in buildsym.c.  */
   struct pending **list_in_scope;
 
-  /* Maintain an array of referenced fundamental types for the current
-     compilation unit being read.  For DWARF version 1, we have to construct
-     the fundamental types on the fly, since no information about the
-     fundamental types is supplied.  Each such fundamental type is created by
-     calling a language dependent routine to create the type, and then a
-     pointer to that type is then placed in the array at the index specified
-     by it's FT_<TYPENAME> value.  The array has a fixed size set by the
-     FT_NUM_MEMBERS compile time constant, which is the number of predefined
-     fundamental types gdb knows how to construct.  */
-  struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
-
   /* DWARF abbreviation table associated with this compilation unit.  */
   struct abbrev_info **dwarf2_abbrevs;
 
@@ -295,15 +295,100 @@ struct dwarf2_cu
   /* Hash table holding all the loaded partial DIEs.  */
   htab_t partial_dies;
 
+  /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE.  */
+  unsigned long ranges_offset;
+
   /* Storage for things with the same lifetime as this read-in compilation
      unit, including partial DIEs.  */
   struct obstack comp_unit_obstack;
 
+  /* When multiple dwarf2_cu structures are living in memory, this field
+     chains them all together, so that they can be released efficiently.
+     We will probably also want a generation counter so that most-recently-used
+     compilation units are cached...  */
+  struct dwarf2_per_cu_data *read_in_chain;
+
+  /* Backchain to our per_cu entry if the tree has been built.  */
+  struct dwarf2_per_cu_data *per_cu;
+
+  /* Pointer to the die -> type map.  Although it is stored
+     permanently in per_cu, we copy it here to avoid double
+     indirection.  */
+  htab_t type_hash;
+
+  /* How many compilation units ago was this CU last referenced?  */
+  int last_used;
+
+  /* A hash table of die offsets for following references.  */
+  htab_t die_hash;
+
+  /* Full DIEs if read in.  */
+  struct die_info *dies;
+
+  /* A set of pointers to dwarf2_per_cu_data objects for compilation
+     units referenced by this one.  Only set during full symbol processing;
+     partial symbol tables do not have dependencies.  */
+  htab_t dependencies;
+
+  /* Header data from the line table, during full symbol processing.  */
+  struct line_header *line_header;
+
+  /* Mark used when releasing cached dies.  */
+  unsigned int mark : 1;
+
+  /* This flag will be set if this compilation unit might include
+     inter-compilation-unit references.  */
+  unsigned int has_form_ref_addr : 1;
+
   /* This flag will be set if this compilation unit includes any
      DW_TAG_namespace DIEs.  If we know that there are explicit
      DIEs for namespaces, we don't need to try to infer them
      from mangled names.  */
   unsigned int has_namespace_info : 1;
+
+  /* Field `ranges_offset' is filled in; flag as the value may be zero.  */
+  unsigned int has_ranges_offset : 1;
+};
+
+/* Persistent data held for a compilation unit, even when not
+   processing it.  We put a pointer to this structure in the
+   read_symtab_private field of the psymtab.  If we encounter
+   inter-compilation-unit references, we also maintain a sorted
+   list of all compilation units.  */
+
+struct dwarf2_per_cu_data
+{
+  /* The start offset and length of this compilation unit.  2**30-1
+     bytes should suffice to store the length of any compilation unit
+     - if it doesn't, GDB will fall over anyway.
+     NOTE: Unlike comp_unit_head.length, this length includes
+     initial_length_size.  */
+  unsigned long offset;
+  unsigned long length : 30;
+
+  /* Flag indicating this compilation unit will be read in before
+     any of the current compilation units are processed.  */
+  unsigned long queued : 1;
+
+  /* This flag will be set if we need to load absolutely all DIEs
+     for this compilation unit, instead of just the ones we think
+     are interesting.  It gets set if we look for a DIE in the
+     hash table and don't find it.  */
+  unsigned int load_all_dies : 1;
+
+  /* Set iff currently read in.  */
+  struct dwarf2_cu *cu;
+
+  /* If full symbols for this CU have been read in, then this field
+     holds a map of DIE offsets to types.  It isn't always possible
+     to reconstruct this information later, so we have to preserve
+     it.  */
+  htab_t type_hash;
+
+  /* The partial symbol table associated with this compilation unit,
+     or NULL for partial units (which do not have an associated
+     symtab).  */
+  struct partial_symtab *psymtab;
 };
 
 /* The line number information for a compilation unit (found in the
@@ -344,11 +429,12 @@ struct line_header
     unsigned int mod_time;
     unsigned int length;
     int included_p; /* Non-zero if referenced by the Line Number Program.  */
+    struct symtab *symtab; /* The associated symbol table, if any.  */
   } *file_names;
 
   /* The start and end of the statement program following this
      header.  These point into dwarf2_per_objfile->line_buffer.  */
-  char *statement_program_start, *statement_program_end;
+  gdb_byte *statement_program_start, *statement_program_end;
 };
 
 /* When we construct a partial symbol table entry we only
@@ -378,6 +464,9 @@ struct partial_die_info
        computed.  */
     unsigned int scope_set : 1;
 
+    /* Flag set if the DIE has a byte_size attribute.  */
+    unsigned int has_byte_size : 1;
+
     /* The name of this DIE.  Normally the value of DW_AT_name, but
        sometimes DW_TAG_MIPS_linkage_name or a string computed in some
        other fashion.  */
@@ -398,7 +487,7 @@ struct partial_die_info
 
     /* Pointer into the info_buffer pointing at the target of
        DW_AT_sibling, if any.  */
-    char *sibling;
+    gdb_byte *sibling;
 
     /* If HAS_SPECIFICATION, the offset of the DIE referred to by
        DW_AT_specification (or DW_AT_abstract_origin or
@@ -426,19 +515,40 @@ struct abbrev_info
 
 struct attr_abbrev
   {
-    enum dwarf_attribute name;
-    enum dwarf_form form;
+    ENUM_BITFIELD(dwarf_attribute) name : 16;
+    ENUM_BITFIELD(dwarf_form) form : 16;
+  };
+
+/* Attributes have a name and a value */
+struct attribute
+  {
+    ENUM_BITFIELD(dwarf_attribute) name : 16;
+    ENUM_BITFIELD(dwarf_form) form : 16;
+    union
+      {
+       char *str;
+       struct dwarf_block *blk;
+       unsigned long unsnd;
+       long int snd;
+       CORE_ADDR addr;
+      }
+    u;
   };
 
 /* This data structure holds a complete die structure. */
 struct die_info
   {
-    enum dwarf_tag tag;                /* Tag indicating type of die */
-    unsigned int abbrev;       /* Abbrev number */
-    unsigned int offset;       /* Offset in .debug_info section */
-    unsigned int num_attrs;    /* Number of attributes */
-    struct attribute *attrs;   /* An array of attributes */
-    struct die_info *next_ref; /* Next die in ref hash table */
+    /* DWARF-2 tag for this DIE.  */
+    ENUM_BITFIELD(dwarf_tag) tag : 16;
+
+    /* Number of attributes */
+    unsigned short num_attrs;
+
+    /* Abbrev number */
+    unsigned int abbrev;
+
+    /* Offset in .debug_info section */
+    unsigned int offset;
 
     /* The dies in a compilation unit form an n-ary tree.  PARENT
        points to this die's parent; CHILD points to the first child of
@@ -449,23 +559,10 @@ struct die_info
     struct die_info *sibling;  /* Its next sibling, if any.  */
     struct die_info *parent;   /* Its parent, if any.  */
 
-    struct type *type;         /* Cached type information */
-  };
-
-/* Attributes have a name and a value */
-struct attribute
-  {
-    enum dwarf_attribute name;
-    enum dwarf_form form;
-    union
-      {
-       char *str;
-       struct dwarf_block *blk;
-       unsigned long unsnd;
-       long int snd;
-       CORE_ADDR addr;
-      }
-    u;
+    /* An array of attributes, with NUM_ATTRS elements.  There may be
+       zero, but it's not common and zero-sized arrays are not
+       sufficiently portable C.  */
+    struct attribute attrs[1];
   };
 
 struct function_range
@@ -488,20 +585,13 @@ struct function_range
 struct dwarf_block
   {
     unsigned int size;
-    char *data;
+    gdb_byte *data;
   };
 
 #ifndef ATTR_ALLOC_CHUNK
 #define ATTR_ALLOC_CHUNK 4
 #endif
 
-/* A hash table of die offsets for following references.  */
-#ifndef REF_HASH_SIZE
-#define REF_HASH_SIZE 1021
-#endif
-
-static struct die_info *die_ref_table[REF_HASH_SIZE];
-
 /* Allocate fields for structs, unions and enums in this size.  */
 #ifndef DW_FIELD_ALLOC_CHUNK
 #define DW_FIELD_ALLOC_CHUNK 4
@@ -510,28 +600,6 @@ static struct die_info *die_ref_table[REF_HASH_SIZE];
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
 
-/* 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
-   by decode_locdesc.  */
-
-static int isreg;              /* Object lives in register.
-                                  decode_locdesc's return value is
-                                  the register number.  */
-
-/* We put a pointer to this structure in the read_symtab_private field
-   of the psymtab.  */
-
-struct dwarf2_pinfo
-  {
-    /* Offset in .debug_info for this compilation unit. */
-
-    unsigned long dwarf_info_offset;
-  };
-
-#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
-#define DWARF_INFO_OFFSET(p) (PST_PRIVATE(p)->dwarf_info_offset)
-
 /* 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.  */
@@ -585,19 +653,53 @@ struct field_info
     int nfnfields;
   };
 
+/* One item on the queue of compilation units to read in full symbols
+   for.  */
+struct dwarf2_queue_item
+{
+  struct dwarf2_per_cu_data *per_cu;
+  struct dwarf2_queue_item *next;
+};
+
+/* The current queue.  */
+static struct dwarf2_queue_item *dwarf2_queue, *dwarf2_queue_tail;
+
+/* Loaded secondary compilation units are kept in memory until they
+   have not been referenced for the processing of this many
+   compilation units.  Set this to zero to disable caching.  Cache
+   sizes of up to at least twenty will improve startup time for
+   typical inter-CU-reference binaries, at an obvious memory cost.  */
+static int dwarf2_max_cache_age = 5;
+static void
+show_dwarf2_max_cache_age (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+The upper bound on the age of cached dwarf2 compilation units is %s.\n"),
+                   value);
+}
+
+
 /* Various complaints about symbol reading that don't abort the process */
 
 static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
   complaint (&symfile_complaints,
-            "statement list doesn't fit in .debug_line section");
+            _("statement list doesn't fit in .debug_line section"));
+}
+
+static void
+dwarf2_debug_line_missing_file_complaint (void)
+{
+  complaint (&symfile_complaints,
+            _(".debug_line section has line data without a file"));
 }
 
 static void
 dwarf2_complex_location_expr_complaint (void)
 {
-  complaint (&symfile_complaints, "location expression too complex");
+  complaint (&symfile_complaints, _("location expression too complex"));
 }
 
 static void
@@ -605,7 +707,7 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
                                              int arg3)
 {
   complaint (&symfile_complaints,
-            "const value length mismatch for '%s', got %d, expected %d", arg1,
+            _("const value length mismatch for '%s', got %d, expected %d"), arg1,
             arg2, arg3);
 }
 
@@ -613,14 +715,14 @@ static void
 dwarf2_macros_too_long_complaint (void)
 {
   complaint (&symfile_complaints,
-            "macro info runs off end of `.debug_macinfo' section");
+            _("macro info runs off end of `.debug_macinfo' section"));
 }
 
 static void
 dwarf2_macro_malformed_definition_complaint (const char *arg1)
 {
   complaint (&symfile_complaints,
-            "macro debug info contains a malformed macro definition:\n`%s'",
+            _("macro debug info contains a malformed macro definition:\n`%s'"),
             arg1);
 }
 
@@ -628,7 +730,7 @@ static void
 dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 {
   complaint (&symfile_complaints,
-            "invalid attribute class or form for '%s' in '%s'", arg1, arg2);
+            _("invalid attribute class or form for '%s' in '%s'"), arg1, arg2);
 }
 
 /* local function prototypes */
@@ -664,80 +766,85 @@ static void add_partial_namespace (struct partial_die_info *pdi,
 static void add_partial_enumeration (struct partial_die_info *enum_pdi,
                                     struct dwarf2_cu *cu);
 
-static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
-                                char *info_ptr,
-                                bfd *abfd,
-                                struct dwarf2_cu *cu);
+static void add_partial_subprogram (struct partial_die_info *pdi,
+                                   CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                                   struct dwarf2_cu *cu);
+
+static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
+                                     gdb_byte *info_ptr,
+                                     bfd *abfd,
+                                     struct dwarf2_cu *cu);
 
 static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-char *dwarf2_read_section (struct objfile *, asection *);
+gdb_byte *dwarf2_read_section (struct objfile *, asection *);
 
 static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
 
 static void dwarf2_free_abbrev_table (void *);
 
-static struct abbrev_info *peek_die_abbrev (char *, int *, struct dwarf2_cu *);
+static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
+                                           struct dwarf2_cu *);
 
 static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
                                                 struct dwarf2_cu *);
 
-static struct partial_die_info *load_partial_dies (bfd *, char *, int,
+static struct partial_die_info *load_partial_dies (bfd *, gdb_byte *, int,
                                                   struct dwarf2_cu *);
 
-static char *read_partial_die (struct partial_die_info *,
-                              struct abbrev_info *abbrev, unsigned int,
-                              bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_partial_die (struct partial_die_info *,
+                                   struct abbrev_info *abbrev, unsigned int,
+                                   bfd *, gdb_byte *, struct dwarf2_cu *);
 
 static struct partial_die_info *find_partial_die (unsigned long,
-                                                 struct dwarf2_cu *,
-                                                 struct dwarf2_cu **);
+                                                 struct dwarf2_cu *);
 
 static void fixup_partial_die (struct partial_die_info *,
                               struct dwarf2_cu *);
 
-static char *read_full_die (struct die_info **, bfd *, char *,
-                           struct dwarf2_cu *, int *);
+static gdb_byte *read_full_die (struct die_info **, bfd *, gdb_byte *,
+                                struct dwarf2_cu *, int *);
 
-static char *read_attribute (struct attribute *, struct attr_abbrev *,
-                            bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *,
+                                 bfd *, gdb_byte *, struct dwarf2_cu *);
 
-static char *read_attribute_value (struct attribute *, unsigned,
-                            bfd *, char *, struct dwarf2_cu *);
+static gdb_byte *read_attribute_value (struct attribute *, unsigned,
+                                       bfd *, gdb_byte *, struct dwarf2_cu *);
 
-static unsigned int read_1_byte (bfd *, char *);
+static unsigned int read_1_byte (bfd *, gdb_byte *);
 
-static int read_1_signed_byte (bfd *, char *);
+static int read_1_signed_byte (bfd *, gdb_byte *);
 
-static unsigned int read_2_bytes (bfd *, char *);
+static unsigned int read_2_bytes (bfd *, gdb_byte *);
 
-static unsigned int read_4_bytes (bfd *, char *);
+static unsigned int read_4_bytes (bfd *, gdb_byte *);
 
-static unsigned long read_8_bytes (bfd *, char *);
+static unsigned long read_8_bytes (bfd *, gdb_byte *);
 
-static CORE_ADDR read_address (bfd *, char *ptr, struct dwarf2_cu *,
-                              int *bytes_read);
+static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *,
+                              unsigned int *);
 
-static LONGEST read_initial_length (bfd *, char *,
-                                    struct comp_unit_head *, int *bytes_read);
+static LONGEST read_initial_length (bfd *, gdb_byte *,
+                                    struct comp_unit_head *, unsigned int *);
 
-static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *,
-                            int *bytes_read);
+static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *,
+                            unsigned int *);
 
-static char *read_n_bytes (bfd *, char *, unsigned int);
+static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int);
 
-static char *read_string (bfd *, char *, unsigned int *);
+static char *read_string (bfd *, gdb_byte *, unsigned int *);
 
-static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *,
-                                  unsigned int *);
+static char *read_indirect_string (bfd *, gdb_byte *,
+                                   const struct comp_unit_head *,
+                                   unsigned int *);
 
-static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
+static unsigned long read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
 
-static long read_signed_leb128 (bfd *, char *, unsigned int *);
+static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
 
-static char *skip_leb128 (bfd *, char *);
+static gdb_byte *skip_leb128 (bfd *, gdb_byte *);
 
 static void set_cu_language (unsigned int, struct dwarf2_cu *);
 
@@ -750,7 +857,7 @@ static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
 static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
 
 static struct die_info *die_specification (struct die_info *die,
-                                          struct dwarf2_cu *);
+                                          struct dwarf2_cu **);
 
 static void free_line_header (struct line_header *lh);
 
@@ -764,7 +871,7 @@ static struct line_header *(dwarf_decode_line_header
 static void dwarf_decode_lines (struct line_header *, char *, bfd *,
                                struct dwarf2_cu *, struct partial_symtab *);
 
-static void dwarf2_start_subfile (char *, char *);
+static void dwarf2_start_subfile (char *, char *, char *);
 
 static struct symbol *new_symbol (struct die_info *, struct type *,
                                  struct dwarf2_cu *);
@@ -781,31 +888,26 @@ static struct type *die_type (struct die_info *, struct dwarf2_cu *);
 static struct type *die_containing_type (struct die_info *,
                                         struct dwarf2_cu *);
 
-#if 0
-static struct type *type_at_offset (unsigned int, struct objfile *);
-#endif
-
 static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
 
-static void read_type_die (struct die_info *, struct dwarf2_cu *);
+static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
 
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
-static char *typename_concat (struct obstack *, const char *prefix, const char *suffix,
+static char *typename_concat (struct obstack *,
+                              const char *prefix, 
+                              const char *suffix,
                              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_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 
+static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
+                              struct dwarf2_cu *, struct partial_symtab *);
+
 static int dwarf2_get_pc_bounds (struct die_info *,
                                 CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
 
@@ -813,6 +915,9 @@ static void get_scope_pc_bounds (struct die_info *,
                                 CORE_ADDR *, CORE_ADDR *,
                                 struct dwarf2_cu *);
 
+static void dwarf2_record_block_ranges (struct die_info *, struct block *,
+                                        CORE_ADDR, struct dwarf2_cu *);
+
 static void dwarf2_add_field (struct field_info *, struct die_info *,
                              struct dwarf2_cu *);
 
@@ -826,11 +931,10 @@ static void dwarf2_add_member_fn (struct field_info *,
 static void dwarf2_attach_fn_fields_to_type (struct field_info *,
                                             struct type *, struct dwarf2_cu *);
 
-static void read_structure_type (struct die_info *, struct dwarf2_cu *);
-
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static char *determine_class_name (struct die_info *die, struct dwarf2_cu *cu);
+static const char *determine_class_name (struct die_info *die,
+                                        struct dwarf2_cu *cu);
 
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
@@ -839,50 +943,25 @@ 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_type (struct die_info *, struct dwarf2_cu *);
-
 static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
 
-static struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
-
 static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
 
-static void read_array_type (struct die_info *, struct dwarf2_cu *);
-
 static enum dwarf_array_dim_ordering read_array_order (struct die_info *, 
                                                       struct dwarf2_cu *);
 
-static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_ptr_to_member_type (struct die_info *,
-                                        struct dwarf2_cu *);
-
-static void read_tag_reference_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_const_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_volatile_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_string_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);
+static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *);
 
-static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *);
-
-static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd,
+static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
                                               struct dwarf2_cu *,
-                                              char **new_info_ptr,
+                                              gdb_byte **new_info_ptr,
                                               struct die_info *parent);
 
-static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd,
+static struct die_info *read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
                                               struct dwarf2_cu *,
-                                              char **new_info_ptr,
+                                              gdb_byte **new_info_ptr,
                                               struct die_info *parent);
 
-static void free_die_list (struct die_info *);
-
-static struct cleanup *make_cleanup_free_die_list (struct die_info *);
-
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
@@ -890,7 +969,7 @@ static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
 static struct die_info *dwarf2_extension (struct die_info *die,
-                                         struct dwarf2_cu *);
+                                         struct dwarf2_cu **);
 
 static char *dwarf_tag_name (unsigned int);
 
@@ -906,8 +985,6 @@ static char *dwarf_type_encoding_name (unsigned int);
 
 #if 0
 static char *dwarf_cfi_name (unsigned int);
-
-struct die_info *copy_die (struct die_info *);
 #endif
 
 static struct die_info *sibling_die (struct die_info *);
@@ -916,19 +993,17 @@ static void dump_die (struct die_info *);
 
 static void dump_die_list (struct die_info *);
 
-static void store_in_ref_table (unsigned int, struct die_info *);
-
-static void dwarf2_empty_hash_tables (void);
+static void store_in_ref_table (struct die_info *,
+                               struct dwarf2_cu *);
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
                                               struct dwarf2_cu *);
 
 static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
-static struct die_info *follow_die_ref (unsigned int);
-
-static struct type *dwarf2_fundamental_type (struct objfile *, int,
-                                            struct dwarf2_cu *);
+static struct die_info *follow_die_ref (struct die_info *,
+                                       struct attribute *,
+                                       struct dwarf2_cu **);
 
 /* memory allocation interface */
 
@@ -936,7 +1011,7 @@ static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
 
 static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
 
-static struct die_info *dwarf_alloc_die (void);
+static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
 
 static void initialize_cu_func_list (struct dwarf2_cu *);
 
@@ -948,23 +1023,56 @@ static void dwarf_decode_macros (struct line_header *, unsigned int,
 
 static int attr_form_is_block (struct attribute *);
 
-static void
-dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
-                            struct dwarf2_cu *cu);
+static int attr_form_is_section_offset (struct attribute *);
 
-static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
-                          struct dwarf2_cu *cu);
+static int attr_form_is_constant (struct attribute *);
 
-static void free_stack_comp_unit (void *);
+static void dwarf2_symbol_mark_computed (struct attribute *attr,
+                                        struct symbol *sym,
+                                        struct dwarf2_cu *cu);
 
-static void *hashtab_obstack_allocate (void *data, size_t size, size_t count);
+static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
+                               struct dwarf2_cu *cu);
 
-static void dummy_obstack_deallocate (void *object, void *data);
+static void free_stack_comp_unit (void *);
 
 static hashval_t partial_die_hash (const void *item);
 
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
+static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
+  (unsigned long offset, struct objfile *objfile);
+
+static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
+  (unsigned long offset, struct objfile *objfile);
+
+static void free_one_comp_unit (void *);
+
+static void free_cached_comp_units (void *);
+
+static void age_cached_comp_units (void);
+
+static void free_one_cached_comp_unit (void *);
+
+static struct type *set_die_type (struct die_info *, struct type *,
+                                 struct dwarf2_cu *);
+
+static void create_all_comp_units (struct objfile *);
+
+static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *,
+                                             struct objfile *);
+
+static void process_full_comp_unit (struct dwarf2_per_cu_data *);
+
+static void dwarf2_add_dependence (struct dwarf2_cu *,
+                                  struct dwarf2_per_cu_data *);
+
+static void dwarf2_mark (struct dwarf2_cu *);
+
+static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
+
+static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -993,59 +1101,71 @@ dwarf2_has_info (struct objfile *objfile)
   return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
 }
 
+/* When loading sections, we can either look for ".<name>", or for
+ * ".z<name>", which indicates a compressed section.  */
+
+static int
+section_is_p (asection *sectp, const char *name)
+{
+  return ((sectp->name[0] == '.'
+           && strcmp (sectp->name + 1, name) == 0)
+          || (sectp->name[0] == '.' && sectp->name[1] == 'z'
+              && strcmp (sectp->name + 2, name) == 0));
+}
+
 /* This function is mapped across the sections and remembers the
    offset and size of each of the debugging sections we are interested
    in.  */
 
 static void
-dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
+dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
 {
-  if (strcmp (sectp->name, INFO_SECTION) == 0)
+  if (section_is_p (sectp, INFO_SECTION))
     {
       dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
       dwarf_info_section = sectp;
     }
-  else if (strcmp (sectp->name, ABBREV_SECTION) == 0)
+  else if (section_is_p (sectp, ABBREV_SECTION))
     {
       dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
       dwarf_abbrev_section = sectp;
     }
-  else if (strcmp (sectp->name, LINE_SECTION) == 0)
+  else if (section_is_p (sectp, LINE_SECTION))
     {
       dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
       dwarf_line_section = sectp;
     }
-  else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0)
+  else if (section_is_p (sectp, PUBNAMES_SECTION))
     {
       dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
       dwarf_pubnames_section = sectp;
     }
-  else if (strcmp (sectp->name, ARANGES_SECTION) == 0)
+  else if (section_is_p (sectp, ARANGES_SECTION))
     {
       dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
       dwarf_aranges_section = sectp;
     }
-  else if (strcmp (sectp->name, LOC_SECTION) == 0)
+  else if (section_is_p (sectp, LOC_SECTION))
     {
       dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
       dwarf_loc_section = sectp;
     }
-  else if (strcmp (sectp->name, MACINFO_SECTION) == 0)
+  else if (section_is_p (sectp, MACINFO_SECTION))
     {
       dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
       dwarf_macinfo_section = sectp;
     }
-  else if (strcmp (sectp->name, STR_SECTION) == 0)
+  else if (section_is_p (sectp, STR_SECTION))
     {
       dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
       dwarf_str_section = sectp;
     }
-  else if (strcmp (sectp->name, FRAME_SECTION) == 0)
+  else if (section_is_p (sectp, FRAME_SECTION))
     {
       dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
       dwarf_frame_section = sectp;
     }
-  else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0)
+  else if (section_is_p (sectp, EH_FRAME_SECTION))
     {
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
@@ -1054,11 +1174,49 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
           dwarf_eh_frame_section = sectp;
         }
     }
-  else if (strcmp (sectp->name, RANGES_SECTION) == 0)
+  else if (section_is_p (sectp, RANGES_SECTION))
     {
       dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
       dwarf_ranges_section = sectp;
     }
+  
+  if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
+      && bfd_section_vma (abfd, sectp) == 0)
+    dwarf2_per_objfile->has_section_at_zero = 1;
+}
+
+/* This function is called after decompressing a section, so
+   dwarf2_per_objfile can record its new, uncompressed size.  */
+
+static void
+dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
+{
+  if (section_is_p (sectp, INFO_SECTION))
+    dwarf2_per_objfile->info_size = new_size;
+  else if (section_is_p (sectp, ABBREV_SECTION))
+    dwarf2_per_objfile->abbrev_size = new_size;
+  else if (section_is_p (sectp, LINE_SECTION))
+    dwarf2_per_objfile->line_size = new_size;
+  else if (section_is_p (sectp, PUBNAMES_SECTION))
+    dwarf2_per_objfile->pubnames_size = new_size;
+  else if (section_is_p (sectp, ARANGES_SECTION))
+    dwarf2_per_objfile->aranges_size = new_size;
+  else if (section_is_p (sectp, LOC_SECTION))
+    dwarf2_per_objfile->loc_size = new_size;
+  else if (section_is_p (sectp, MACINFO_SECTION))
+    dwarf2_per_objfile->macinfo_size = new_size;
+  else if (section_is_p (sectp, STR_SECTION))
+    dwarf2_per_objfile->str_size = new_size;
+  else if (section_is_p (sectp, FRAME_SECTION))
+    dwarf2_per_objfile->frame_size = new_size;
+  else if (section_is_p (sectp, EH_FRAME_SECTION))
+    dwarf2_per_objfile->eh_frame_size = new_size;
+  else if (section_is_p (sectp, RANGES_SECTION))
+    dwarf2_per_objfile->ranges_size = new_size;
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("dwarf2_resize_section: missing section_is_p check: %s"),
+                    sectp->name);
 }
 
 /* Build a partial symbol table.  */
@@ -1139,10 +1297,10 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
   while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames_size)
     {
       struct comp_unit_head cu_header;
-      int bytes_read;
+      unsigned int bytes_read;
 
       entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header,
-                                         &bytes_read);
+                                          &bytes_read);
       pubnames_ptr += bytes_read;
       version = read_1_byte (abfd, pubnames_ptr);
       pubnames_ptr += 1;
@@ -1158,15 +1316,27 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
 }
 #endif
 
+/* Return TRUE if OFFSET is within CU_HEADER.  */
+
+static inline int
+offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+{
+  unsigned int bottom = cu_header->offset;
+  unsigned int top = (cu_header->offset
+                     + cu_header->length
+                     + cu_header->initial_length_size);
+  return (offset >= bottom && offset < top);
+}
+
 /* Read in the comp unit header information from the debug_info at
-   info_ptr. */
+   info_ptr.  */
 
-static char *
+static gdb_byte *
 read_comp_unit_head (struct comp_unit_head *cu_header,
-                    char *info_ptr, bfd *abfd)
+                    gdb_byte *info_ptr, bfd *abfd)
 {
   int signed_addr;
-  int bytes_read;
+  unsigned int bytes_read;
   cu_header->length = read_initial_length (abfd, info_ptr, cu_header,
                                            &bytes_read);
   info_ptr += bytes_read;
@@ -1180,35 +1350,35 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
   signed_addr = bfd_get_sign_extend_vma (abfd);
   if (signed_addr < 0)
     internal_error (__FILE__, __LINE__,
-                   "read_comp_unit_head: dwarf from non elf file");
+                   _("read_comp_unit_head: dwarf from non elf file"));
   cu_header->signed_addr_p = signed_addr;
   return info_ptr;
 }
 
-static char *
-partial_read_comp_unit_head (struct comp_unit_head *header, char *info_ptr,
+static gdb_byte *
+partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
                             bfd *abfd)
 {
-  char *beg_of_comp_unit = info_ptr;
+  gdb_byte *beg_of_comp_unit = info_ptr;
 
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
-  if (header->version != 2)
-    error ("Dwarf Error: wrong version in compilation unit header "
-          "(is %d, should be %d) [in module %s]", header->version,
+  if (header->version != 2 && header->version != 3)
+    error (_("Dwarf Error: wrong version in compilation unit header "
+          "(is %d, should be %d) [in module %s]"), header->version,
           2, bfd_get_filename (abfd));
 
   if (header->abbrev_offset >= dwarf2_per_objfile->abbrev_size)
-    error ("Dwarf Error: bad offset (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 6) [in module %s]",
+    error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
+          "(offset 0x%lx + 6) [in module %s]"),
           (long) header->abbrev_offset,
           (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
           bfd_get_filename (abfd));
 
   if (beg_of_comp_unit + header->length + header->initial_length_size
       > dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
-    error ("Dwarf Error: bad length (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 0) [in module %s]",
+    error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
+          "(offset 0x%lx + 0) [in module %s]"),
           (long) header->length,
           (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
           bfd_get_filename (abfd));
@@ -1245,9 +1415,7 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
 
   /* No private part is necessary for include psymtabs.  This property
      can be used to differentiate between such include psymtabs and
-     the regular ones.  If it ever happens that a regular psymtab can
-     legitimally have a NULL private part, then we'll have to add a
-     dedicated field for that in the dwarf2_pinfo structure.  */
+     the regular ones.  */
   subpst->read_symtab_private = NULL;
 }
 
@@ -1287,14 +1455,24 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   /* Instead of reading this into a big buffer, we should probably use
      mmap()  on architectures that support it. (FIXME) */
   bfd *abfd = objfile->obfd;
-  char *info_ptr;
-  char *beg_of_comp_unit;
+  gdb_byte *info_ptr;
+  gdb_byte *beg_of_comp_unit;
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
+  struct cleanup *back_to;
   CORE_ADDR lowpc, highpc, baseaddr;
 
   info_ptr = dwarf2_per_objfile->info_buffer;
 
+  /* Any cached compilation units will be linked by the per-objfile
+     read_in_chain.  Make sure to free them when we're done.  */
+  back_to = make_cleanup (free_cached_comp_units, NULL);
+
+  create_all_comp_units (objfile);
+
+  objfile->psymtabs_addrmap = addrmap_create_mutable
+                                                   (&objfile->objfile_obstack);
+
   /* Since the objects we're extracting from .debug_info vary in
      length, only the individual functions to extract them (like
      read_comp_unit_head and load_partial_die) can really know whether
@@ -1330,43 +1508,80 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       /* Complete the cu_header */
       cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
-      cu.header.first_die_ptr = info_ptr;
-      cu.header.cu_head_ptr = beg_of_comp_unit;
+      cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
 
       cu.list_in_scope = &file_symbols;
 
-      cu.partial_dies = NULL;
-
       /* Read the abbrevs for this compilation unit into a table */
       dwarf2_read_abbrevs (abfd, &cu);
       make_cleanup (dwarf2_free_abbrev_table, &cu);
 
+      this_cu = dwarf2_find_comp_unit (cu.header.offset, objfile);
+
       /* Read the compilation unit die */
       abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu);
       info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
                                   abfd, info_ptr, &cu);
 
+      if (comp_unit_die.tag == DW_TAG_partial_unit)
+       {
+         info_ptr = (beg_of_comp_unit + cu.header.length
+                     + cu.header.initial_length_size);
+         do_cleanups (back_to_inner);
+         continue;
+       }
+
       /* Set the language we're debugging */
       set_cu_language (comp_unit_die.language, &cu);
 
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
                                  comp_unit_die.name ? comp_unit_die.name : "",
-                                 comp_unit_die.lowpc,
+                                 /* TEXTLOW and TEXTHIGH are set below.  */
+                                 0,
                                  objfile->global_psymbols.next,
                                  objfile->static_psymbols.next);
 
-         if (comp_unit_die.dirname)
-        pst->dirname = xstrdup (comp_unit_die.dirname);
+      if (comp_unit_die.dirname)
+       pst->dirname = obsavestring (comp_unit_die.dirname,
+                                    strlen (comp_unit_die.dirname),
+                                    &objfile->objfile_obstack);
+
+      pst->read_symtab_private = (char *) this_cu;
 
-      pst->read_symtab_private = (char *)
-       obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
-      DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
       baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
       /* Store the function that reads in the rest of the symbol table */
       pst->read_symtab = dwarf2_psymtab_to_symtab;
 
+      /* If this compilation unit was already read in, free the
+        cached copy in order to read it in again.  This is
+        necessary because we skipped some symbols when we first
+        read in the compilation unit (see load_partial_dies).
+        This problem could be avoided, but the benefit is
+        unclear.  */
+      if (this_cu->cu != NULL)
+       free_one_cached_comp_unit (this_cu->cu);
+
+      cu.per_cu = this_cu;
+
+      /* Note that this is a pointer to our stack frame, being
+        added to a global data structure.  It will be cleaned up
+        in free_stack_comp_unit when we finish with this
+        compilation unit.  */
+      this_cu->cu = &cu;
+
+      this_cu->psymtab = pst;
+
+      /* Possibly set the default values of LOWPC and HIGHPC from
+         `DW_AT_ranges'.  */
+      if (cu.has_ranges_offset)
+       {
+         if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc,
+                                 &comp_unit_die.highpc, &cu, pst))
+           comp_unit_die.has_pc_info = 1;
+       }
+
       /* Check if comp unit has_children.
          If so, read the rest of the partial symbols from this comp unit.
          If not, there's no more debug_info for this comp unit. */
@@ -1397,6 +1612,12 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       pst->textlow = comp_unit_die.lowpc + baseaddr;
       pst->texthigh = comp_unit_die.highpc + baseaddr;
 
+      /* Store the contiguous range; `DW_AT_ranges' range is stored above.  The
+         range can be also empty for CUs with no code.  */
+      if (!cu.has_ranges_offset && pst->textlow < pst->texthigh)
+       addrmap_set_empty (objfile->psymtabs_addrmap, pst->textlow,
+                          pst->texthigh - 1, pst);
+
       pst->n_global_syms = objfile->global_psymbols.next -
        (objfile->global_psymbols.list + pst->globals_offset);
       pst->n_static_syms = objfile->static_psymbols.next -
@@ -1408,6 +1629,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
          also happen.) This happens in VxWorks.  */
       free_named_symtabs (pst->filename);
 
+      info_ptr = beg_of_comp_unit + cu.header.length
+                                  + cu.header.initial_length_size;
+
       if (comp_unit_die.has_stmt_list)
         {
           /* Get the list of files included in the current compilation unit,
@@ -1415,11 +1639,129 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
           dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst);
         }
 
-      info_ptr = beg_of_comp_unit + cu.header.length
-                                  + cu.header.initial_length_size;
-
       do_cleanups (back_to_inner);
     }
+
+  objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
+                                                   &objfile->objfile_obstack);
+
+  do_cleanups (back_to);
+}
+
+/* Load the DIEs for a secondary CU into memory.  */
+
+static void
+load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
+{
+  bfd *abfd = objfile->obfd;
+  gdb_byte *info_ptr, *beg_of_comp_unit;
+  struct partial_die_info comp_unit_die;
+  struct dwarf2_cu *cu;
+  struct abbrev_info *abbrev;
+  unsigned int bytes_read;
+  struct cleanup *back_to;
+
+  info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset;
+  beg_of_comp_unit = info_ptr;
+
+  cu = xmalloc (sizeof (struct dwarf2_cu));
+  memset (cu, 0, sizeof (struct dwarf2_cu));
+
+  obstack_init (&cu->comp_unit_obstack);
+
+  cu->objfile = objfile;
+  info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd);
+
+  /* Complete the cu_header.  */
+  cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+  cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+
+  /* Read the abbrevs for this compilation unit into a table.  */
+  dwarf2_read_abbrevs (abfd, cu);
+  back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+
+  /* Read the compilation unit die.  */
+  abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+  info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
+                              abfd, info_ptr, cu);
+
+  /* Set the language we're debugging.  */
+  set_cu_language (comp_unit_die.language, cu);
+
+  /* Link this compilation unit into the compilation unit tree.  */
+  this_cu->cu = cu;
+  cu->per_cu = this_cu;
+  cu->type_hash = cu->per_cu->type_hash;
+
+  /* Check if comp unit has_children.
+     If so, read the rest of the partial symbols from this comp unit.
+     If not, there's no more debug_info for this comp unit. */
+  if (comp_unit_die.has_children)
+    load_partial_dies (abfd, info_ptr, 0, cu);
+
+  do_cleanups (back_to);
+}
+
+/* Create a list of all compilation units in OBJFILE.  We do this only
+   if an inter-comp-unit reference is found; presumably if there is one,
+   there will be many, and one will occur early in the .debug_info section.
+   So there's no point in building this list incrementally.  */
+
+static void
+create_all_comp_units (struct objfile *objfile)
+{
+  int n_allocated;
+  int n_comp_units;
+  struct dwarf2_per_cu_data **all_comp_units;
+  gdb_byte *info_ptr = dwarf2_per_objfile->info_buffer;
+
+  n_comp_units = 0;
+  n_allocated = 10;
+  all_comp_units = xmalloc (n_allocated
+                           * sizeof (struct dwarf2_per_cu_data *));
+  
+  while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
+    {
+      struct comp_unit_head cu_header;
+      gdb_byte *beg_of_comp_unit;
+      struct dwarf2_per_cu_data *this_cu;
+      unsigned long offset;
+      unsigned int bytes_read;
+
+      offset = info_ptr - dwarf2_per_objfile->info_buffer;
+
+      /* Read just enough information to find out where the next
+        compilation unit is.  */
+      cu_header.initial_length_size = 0;
+      cu_header.length = read_initial_length (objfile->obfd, info_ptr,
+                                             &cu_header, &bytes_read);
+
+      /* Save the compilation unit for later lookup.  */
+      this_cu = obstack_alloc (&objfile->objfile_obstack,
+                              sizeof (struct dwarf2_per_cu_data));
+      memset (this_cu, 0, sizeof (*this_cu));
+      this_cu->offset = offset;
+      this_cu->length = cu_header.length + cu_header.initial_length_size;
+
+      if (n_comp_units == n_allocated)
+       {
+         n_allocated *= 2;
+         all_comp_units = xrealloc (all_comp_units,
+                                    n_allocated
+                                    * sizeof (struct dwarf2_per_cu_data *));
+       }
+      all_comp_units[n_comp_units++] = this_cu;
+
+      info_ptr = info_ptr + this_cu->length;
+    }
+
+  dwarf2_per_objfile->all_comp_units
+    = obstack_alloc (&objfile->objfile_obstack,
+                    n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+  memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
+         n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+  xfree (all_comp_units);
+  dwarf2_per_objfile->n_comp_units = n_comp_units;
 }
 
 /* Process all loaded DIEs for compilation unit CU, starting at FIRST_DIE.
@@ -1454,21 +1796,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
          switch (pdi->tag)
            {
            case DW_TAG_subprogram:
-             if (pdi->has_pc_info)
-               {
-                 if (pdi->lowpc < *lowpc)
-                   {
-                     *lowpc = pdi->lowpc;
-                   }
-                 if (pdi->highpc > *highpc)
-                   {
-                     *highpc = pdi->highpc;
-                   }
-                 if (!pdi->is_declaration)
-                   {
-                     add_partial_symbol (pdi, cu);
-                   }
-               }
+             add_partial_subprogram (pdi, lowpc, highpc, cu);
              break;
            case DW_TAG_variable:
            case DW_TAG_typedef:
@@ -1479,6 +1807,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
                }
              break;
            case DW_TAG_class_type:
+           case DW_TAG_interface_type:
            case DW_TAG_structure_type:
              if (!pdi->is_declaration)
                {
@@ -1539,15 +1868,13 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 {
   char *grandparent_scope;
   struct partial_die_info *parent, *real_pdi;
-  struct dwarf2_cu *spec_cu;
 
   /* We need to look at our parent DIE; if we have a DW_AT_specification,
      then this means the parent of the specification DIE.  */
 
   real_pdi = pdi;
-  spec_cu = cu;
   while (real_pdi->has_specification)
-    real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
+    real_pdi = find_partial_die (real_pdi->spec_offset, cu);
 
   parent = real_pdi->die_parent;
   if (parent == NULL)
@@ -1558,11 +1885,12 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 
   fixup_partial_die (parent, cu);
 
-  grandparent_scope = partial_die_parent_scope (parent, spec_cu);
+  grandparent_scope = partial_die_parent_scope (parent, cu);
 
   if (parent->tag == DW_TAG_namespace
       || parent->tag == DW_TAG_structure_type
       || parent->tag == DW_TAG_class_type
+      || parent->tag == DW_TAG_interface_type
       || parent->tag == DW_TAG_union_type)
     {
       if (grandparent_scope == NULL)
@@ -1580,7 +1908,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
         function-local names?  For partial symbols, we should probably be
         ignoring them.  */
       complaint (&symfile_complaints,
-                "unhandled containing DIE tag %d for DIE at %d",
+                _("unhandled containing DIE tag %d for DIE at %d"),
                 parent->tag, pdi->offset);
       parent->scope = grandparent_scope;
     }
@@ -1609,7 +1937,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   CORE_ADDR addr = 0;
-  char *actual_name;
+  char *actual_name = NULL;
   const char *my_prefix;
   const struct partial_symbol *psym = NULL;
   CORE_ADDR baseaddr;
@@ -1617,8 +1945,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  actual_name = NULL;
-
   if (pdi_needs_namespace (pdi->tag))
     {
       actual_name = partial_die_full_name (pdi, cu);
@@ -1632,8 +1958,12 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
-      if (pdi->is_external)
+      if (pdi->is_external || cu->language == language_ada)
        {
+          /* brobecker/2007-12-26: Normally, only "external" DIEs are part
+             of the global scope.  But in Ada, we want to be able to access
+             nested procedures globally.  So all Ada subprograms are stored
+             in the global scope.  */
          /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
          psym = add_psymbol_to_list (actual_name, strlen (actual_name),
@@ -1682,7 +2012,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
        {
          /* Static Variable. Skip symbols without location descriptors.  */
          if (pdi->locdesc == NULL)
-           return;
+           {
+             if (built_actual_name)
+               xfree (actual_name);
+             return;
+           }
          addr = decode_locdesc (pdi->locdesc, cu);
          /*prim_record_minimal_symbol (actual_name, addr + baseaddr,
             mst_file_data, objfile); */
@@ -1708,15 +2042,24 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
                           0, (CORE_ADDR) 0, cu->language, objfile);
       break;
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
-      /* Skip aggregate types without children, these are external
-         references.  */
+      /* Skip external references.  The DWARF standard says in the section
+         about "Structure, Union, and Class Type Entries": "An incomplete
+         structure, union or class type is represented by a structure,
+         union or class entry that does not have a byte size attribute
+         and that has a DW_AT_declaration attribute."  */
+      if (!pdi->has_byte_size && pdi->is_declaration)
+       {
+         if (built_actual_name)
+           xfree (actual_name);
+         return;
+       }
+
       /* NOTE: carlton/2003-10-07: See comment in new_symbol about
         static vs. global.  */
-      if (pdi->has_children == 0)
-       return;
       add_psymbol_to_list (actual_name, strlen (actual_name),
                           STRUCT_DOMAIN, LOC_TYPEDEF,
                           (cu->language == language_cplus
@@ -1725,15 +2068,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
                           : &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu->language, objfile);
 
-      if (cu->language == language_cplus
-          || cu->language == language_java)
-       {
-         /* For C++ and Java, these implicitly act as typedefs as well. */
-         add_psymbol_to_list (actual_name, strlen (actual_name),
-                              VAR_DOMAIN, LOC_TYPEDEF,
-                              &objfile->global_psymbols,
-                              0, (CORE_ADDR) 0, cu->language, objfile);
-       }
       break;
     case DW_TAG_enumerator:
       add_psymbol_to_list (actual_name, strlen (actual_name),
@@ -1780,6 +2114,7 @@ pdi_needs_namespace (enum dwarf_tag tag)
     case DW_TAG_namespace:
     case DW_TAG_typedef:
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
@@ -1811,6 +2146,51 @@ add_partial_namespace (struct partial_die_info *pdi,
     scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
 }
 
+/* Read a partial die corresponding to a subprogram and create a partial
+   symbol for that subprogram.  When the CU language allows it, this
+   routine also defines a partial symbol for each nested subprogram
+   that this subprogram contains.
+   
+   DIE my also be a lexical block, in which case we simply search
+   recursively for suprograms defined inside that lexical block.
+   Again, this is only performed when the CU language allows this
+   type of definitions.  */
+
+static void
+add_partial_subprogram (struct partial_die_info *pdi,
+                       CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                       struct dwarf2_cu *cu)
+{
+  if (pdi->tag == DW_TAG_subprogram)
+    {
+      if (pdi->has_pc_info)
+        {
+          if (pdi->lowpc < *lowpc)
+            *lowpc = pdi->lowpc;
+          if (pdi->highpc > *highpc)
+            *highpc = pdi->highpc;
+          if (!pdi->is_declaration)
+            add_partial_symbol (pdi, cu);
+        }
+    }
+  
+  if (! pdi->has_children)
+    return;
+
+  if (cu->language == language_ada)
+    {
+      pdi = pdi->die_child;
+      while (pdi != NULL)
+       {
+         fixup_partial_die (pdi, cu);
+         if (pdi->tag == DW_TAG_subprogram
+             || pdi->tag == DW_TAG_lexical_block)
+           add_partial_subprogram (pdi, lowpc, highpc, cu);
+         pdi = pdi->die_sibling;
+       }
+    }
+}
+
 /* See if we can figure out if the class lives in a namespace.  We do
    this by looking for a member function; its demangled name will
    contain namespace info, if there is any.  */
@@ -1832,16 +2212,14 @@ guess_structure_name (struct partial_die_info *struct_pdi,
 
       struct partial_die_info *child_pdi = struct_pdi->die_child;
       struct partial_die_info *real_pdi;
-      struct dwarf2_cu *spec_cu;
 
       /* If this DIE (this DIE's specification, if any) has a parent, then
         we should not do this.  We'll prepend the parent's fully qualified
          name when we create the partial symbol.  */
 
       real_pdi = struct_pdi;
-      spec_cu = cu;
       while (real_pdi->has_specification)
-       real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
+       real_pdi = find_partial_die (real_pdi->spec_offset, cu);
 
       if (real_pdi->die_parent != NULL)
        return;
@@ -1886,7 +2264,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi,
   while (pdi)
     {
       if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
-       complaint (&symfile_complaints, "malformed enumerator DIE ignored");
+       complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
       else
        add_partial_symbol (pdi, cu);
       pdi = pdi->die_sibling;
@@ -1899,7 +2277,8 @@ add_partial_enumeration (struct partial_die_info *enum_pdi,
    the initial number.  */
 
 static struct abbrev_info *
-peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
+peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
+                struct dwarf2_cu *cu)
 {
   bfd *abfd = cu->objfile->obfd;
   unsigned int abbrev_number;
@@ -1913,7 +2292,7 @@ peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
-      error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
+      error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"), abbrev_number,
                      bfd_get_filename (abfd));
     }
 
@@ -1924,8 +2303,8 @@ peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
    pointer to the end of a series of DIEs, terminated by an empty
    DIE.  Any children of the skipped DIEs will also be skipped.  */
 
-static char *
-skip_children (char *info_ptr, struct dwarf2_cu *cu)
+static gdb_byte *
+skip_children (gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   struct abbrev_info *abbrev;
   unsigned int bytes_read;
@@ -1946,8 +2325,8 @@ skip_children (char *info_ptr, struct dwarf2_cu *cu)
    ABBREV.  Returns a pointer to this DIE's sibling, skipping any
    children.  */
 
-static char *
-skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+static gdb_byte *
+skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
              struct dwarf2_cu *cu)
 {
   unsigned int bytes_read;
@@ -1963,7 +2342,7 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
          read_attribute (&attr, &abbrev->attrs[i],
                          abfd, info_ptr, cu);
          if (attr.form == DW_FORM_ref_addr)
-           complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+           complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
          else
            return dwarf2_per_objfile->info_buffer
              + dwarf2_get_ref_die_offset (&attr, cu);
@@ -2028,7 +2407,7 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
          goto skip_attribute;
 
        default:
-         error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+         error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
                 dwarf_form_name (form),
                 bfd_get_filename (abfd));
        }
@@ -2043,8 +2422,8 @@ skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
 /* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of
    the next DIE after ORIG_PDI.  */
 
-static char *
-locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
+static gdb_byte *
+locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr,
                    bfd *abfd, struct dwarf2_cu *cu)
 {
   /* Do we know the sibling already?  */
@@ -2072,40 +2451,113 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
     {
       if (pst->readin)
        {
-         warning ("bug: psymtab for %s is already read in.", pst->filename);
+         warning (_("bug: psymtab for %s is already read in."), pst->filename);
        }
       else
        {
          if (info_verbose)
            {
-             printf_filtered ("Reading in symbols for %s...", pst->filename);
+             printf_filtered (_("Reading in symbols for %s..."), pst->filename);
              gdb_flush (gdb_stdout);
            }
 
+         /* Restore our global data.  */
+         dwarf2_per_objfile = objfile_data (pst->objfile,
+                                            dwarf2_objfile_data_key);
+
          psymtab_to_symtab_1 (pst);
 
          /* Finish up the debug error message.  */
          if (info_verbose)
-           printf_filtered ("done.\n");
+           printf_filtered (_("done.\n"));
        }
     }
 }
 
+/* Add PER_CU to the queue.  */
+
+static void
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
+{
+  struct dwarf2_queue_item *item;
+
+  per_cu->queued = 1;
+  item = xmalloc (sizeof (*item));
+  item->per_cu = per_cu;
+  item->next = NULL;
+
+  if (dwarf2_queue == NULL)
+    dwarf2_queue = item;
+  else
+    dwarf2_queue_tail->next = item;
+
+  dwarf2_queue_tail = item;
+
+  /* Either PER_CU is the CU we want to process, or we're following a reference
+     pointing into PER_CU.  Either way, we need its DIEs now.  */
+  load_full_comp_unit (item->per_cu, objfile);
+  item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+  dwarf2_per_objfile->read_in_chain = item->per_cu;
+}
+
+/* Process the queue.  */
+
+static void
+process_queue (struct objfile *objfile)
+{
+  struct dwarf2_queue_item *item, *next_item;
+
+  /* The queue starts out with one item, but following a DIE reference
+     may load a new CU, adding it to the end of the queue.  */
+  for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
+    {
+      if (item->per_cu->psymtab && !item->per_cu->psymtab->readin)
+       process_full_comp_unit (item->per_cu);
+
+      item->per_cu->queued = 0;
+      next_item = item->next;
+      xfree (item);
+    }
+
+  dwarf2_queue_tail = NULL;
+}
+
+/* Free all allocated queue entries.  This function only releases anything if
+   an error was thrown; if the queue was processed then it would have been
+   freed as we went along.  */
+
+static void
+dwarf2_release_queue (void *dummy)
+{
+  struct dwarf2_queue_item *item, *last;
+
+  item = dwarf2_queue;
+  while (item)
+    {
+      /* Anything still marked queued is likely to be in an
+        inconsistent state, so discard it.  */
+      if (item->per_cu->queued)
+       {
+         if (item->per_cu->cu != NULL)
+           free_one_cached_comp_unit (item->per_cu->cu);
+         item->per_cu->queued = 0;
+       }
+
+      last = item;
+      item = item->next;
+      xfree (last);
+    }
+
+  dwarf2_queue = dwarf2_queue_tail = NULL;
+}
+
+/* Read in full symbols for PST, and anything it depends on.  */
+
 static void
 psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
-  struct objfile *objfile = pst->objfile;
-  bfd *abfd = objfile->obfd;
-  struct dwarf2_cu cu;
-  struct die_info *dies;
-  unsigned long offset;
-  CORE_ADDR lowpc, highpc;
-  struct die_info *child_die;
-  char *info_ptr;
-  struct symtab *symtab;
+  struct dwarf2_per_cu_data *per_cu;
   struct cleanup *back_to;
-  struct attribute *attr;
-  CORE_ADDR baseaddr;
   int i;
 
   for (i = 0; i < pst->number_of_dependencies; i++)
@@ -2114,6 +2566,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
         /* Inform about additional files that need to be read in.  */
         if (info_verbose)
           {
+           /* FIXME: i18n: Need to make this a single string.  */
             fputs_filtered (" ", gdb_stdout);
             wrap_here ("");
             fputs_filtered ("and ", gdb_stdout);
@@ -2125,7 +2578,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
         psymtab_to_symtab_1 (pst->dependencies[i]);
       }
 
-  if (pst->read_symtab_private == NULL)
+  per_cu = (struct dwarf2_per_cu_data *) pst->read_symtab_private;
+
+  if (per_cu == NULL)
     {
       /* It's an include file, no symbols to read for it.
          Everything is in the parent symtab.  */
@@ -2133,39 +2588,104 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
       return;
     }
 
-  dwarf2_per_objfile = objfile_data (pst->objfile, dwarf2_objfile_data_key);
+  back_to = make_cleanup (dwarf2_release_queue, NULL);
+
+  queue_comp_unit (per_cu, pst->objfile);
+
+  process_queue (pst->objfile);
+
+  /* Age the cache, releasing compilation units that have not
+     been used recently.  */
+  age_cached_comp_units ();
+
+  do_cleanups (back_to);
+}
+
+/* Load the DIEs associated with PST and PER_CU into memory.  */
+
+static struct dwarf2_cu *
+load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
+{
+  bfd *abfd = objfile->obfd;
+  struct dwarf2_cu *cu;
+  unsigned long offset;
+  gdb_byte *info_ptr;
+  struct cleanup *back_to, *free_cu_cleanup;
+  struct attribute *attr;
+  CORE_ADDR baseaddr;
 
   /* Set local variables from the partial symbol table info.  */
-  offset = DWARF_INFO_OFFSET (pst);
+  offset = per_cu->offset;
 
   info_ptr = dwarf2_per_objfile->info_buffer + offset;
-  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  /* We're in the global namespace.  */
-  processing_current_prefix = "";
+  cu = xmalloc (sizeof (struct dwarf2_cu));
+  memset (cu, 0, sizeof (struct dwarf2_cu));
 
-  obstack_init (&cu.comp_unit_obstack);
-  back_to = make_cleanup (free_stack_comp_unit, &cu);
+  /* If an error occurs while loading, release our storage.  */
+  free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
 
-  buildsym_init ();
-  make_cleanup (really_free_pendings, NULL);
-
-  cu.objfile = objfile;
+  cu->objfile = objfile;
 
   /* read in the comp_unit header  */
-  info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
+  info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
 
   /* Read the abbrevs for this compilation unit  */
-  dwarf2_read_abbrevs (abfd, &cu);
-  make_cleanup (dwarf2_free_abbrev_table, &cu);
+  dwarf2_read_abbrevs (abfd, cu);
+  back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
 
-  cu.header.offset = offset;
+  cu->header.offset = offset;
 
-  cu.list_in_scope = &file_symbols;
+  cu->per_cu = per_cu;
+  per_cu->cu = cu;
+  cu->type_hash = per_cu->type_hash;
 
-  dies = read_comp_unit (info_ptr, abfd, &cu);
+  /* We use this obstack for block values in dwarf_alloc_block.  */
+  obstack_init (&cu->comp_unit_obstack);
 
-  make_cleanup_free_die_list (dies);
+  cu->dies = read_comp_unit (info_ptr, abfd, cu);
+
+  /* We try not to read any attributes in this function, because not
+     all objfiles needed for references have been loaded yet, and symbol
+     table processing isn't initialized.  But we have to set the CU language,
+     or we won't be able to build types correctly.  */
+  attr = dwarf2_attr (cu->dies, DW_AT_language, cu);
+  if (attr)
+    set_cu_language (DW_UNSND (attr), cu);
+  else
+    set_cu_language (language_minimal, cu);
+
+  do_cleanups (back_to);
+
+  /* We've successfully allocated this compilation unit.  Let our caller
+     clean it up when finished with it.  */
+  discard_cleanups (free_cu_cleanup);
+
+  return cu;
+}
+
+/* Generate full symbol information for PST and CU, whose DIEs have
+   already been loaded into memory.  */
+
+static void
+process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+{
+  struct partial_symtab *pst = per_cu->psymtab;
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct objfile *objfile = pst->objfile;
+  bfd *abfd = objfile->obfd;
+  CORE_ADDR lowpc, highpc;
+  struct symtab *symtab;
+  struct cleanup *back_to;
+  struct attribute *attr;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  buildsym_init ();
+  back_to = make_cleanup (really_free_pendings, NULL);
+
+  cu->list_in_scope = &file_symbols;
 
   /* Find the base address of the compilation unit for range lists and
      location lists.  It will normally be specified by DW_AT_low_pc.
@@ -2173,32 +2693,32 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      DW_AT_entry_pc.  It's been removed, but GCC still uses this for
      compilation units with discontinuous ranges.  */
 
-  cu.header.base_known = 0;
-  cu.header.base_address = 0;
+  cu->base_known = 0;
+  cu->base_address = 0;
 
-  attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
+  attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu);
   if (attr)
     {
-      cu.header.base_address = DW_ADDR (attr);
-      cu.header.base_known = 1;
+      cu->base_address = DW_ADDR (attr);
+      cu->base_known = 1;
     }
   else
     {
-      attr = dwarf2_attr (dies, DW_AT_low_pc, &cu);
+      attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu);
       if (attr)
        {
-         cu.header.base_address = DW_ADDR (attr);
-         cu.header.base_known = 1;
+         cu->base_address = DW_ADDR (attr);
+         cu->base_known = 1;
        }
     }
 
   /* Do line number decoding in read_file_scope () */
-  process_die (dies, &cu);
+  process_die (cu->dies, 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.  */
-  get_scope_pc_bounds (dies, &lowpc, &highpc, &cu);
+  get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
@@ -2206,9 +2726,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
      If the compilation is from a C file generated by language preprocessors,
      do not set the language if it was already deduced by start_subfile.  */
   if (symtab != NULL
-      && !(cu.language == language_c && symtab->language != language_c))
+      && !(cu->language == language_c && symtab->language != language_c))
     {
-      symtab->language = cu.language;
+      symtab->language = cu->language;
     }
   pst->symtab = symtab;
   pst->readin = 1;
@@ -2229,7 +2749,6 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       read_file_scope (die, cu);
       break;
     case DW_TAG_subprogram:
-      read_subroutine_type (die, cu);
       read_func_scope (die, cu);
       break;
     case DW_TAG_inlined_subroutine:
@@ -2243,50 +2762,32 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       read_lexical_block_scope (die, cu);
       break;
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_type (die, cu);
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration_type (die, cu);
       process_enumeration_scope (die, cu);
       break;
 
-    /* FIXME drow/2004-03-14: These initialize die->type, but do not create
-       a symbol or process any children.  Therefore it doesn't do anything
-       that won't be done on-demand by read_type_die.  */
+    /* These dies have a type, but processing them does not create
+       a symbol or recurse to process the children.  Therefore we can
+       read them on-demand through read_type_die.  */
     case DW_TAG_subroutine_type:
-      read_subroutine_type (die, cu);
-      break;
+    case DW_TAG_set_type:
     case DW_TAG_array_type:
-      read_array_type (die, cu);
-      break;
     case DW_TAG_pointer_type:
-      read_tag_pointer_type (die, cu);
-      break;
     case DW_TAG_ptr_to_member_type:
-      read_tag_ptr_to_member_type (die, cu);
-      break;
     case DW_TAG_reference_type:
-      read_tag_reference_type (die, cu);
-      break;
     case DW_TAG_string_type:
-      read_tag_string_type (die, cu);
       break;
-    /* END FIXME */
 
     case DW_TAG_base_type:
-      read_base_type (die, cu);
-      /* Add a typedef symbol for the type definition, if it has a
-        DW_AT_name.  */
-      new_symbol (die, die->type, cu);
-      break;
     case DW_TAG_subrange_type:
-      read_subrange_type (die, cu);
       /* Add a typedef symbol for the type definition, if it has a
          DW_AT_name.  */
-      new_symbol (die, die->type, cu);
+      new_symbol (die, read_type_die (die, cu), cu);
       break;
     case DW_TAG_common_block:
       read_common_block (die, cu);
@@ -2303,10 +2804,10 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
         information contained in these.  DW_TAG_imported_declaration
         dies shouldn't have children; DW_TAG_imported_module dies
         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.  */
+        Fortran case.  */
       processing_has_namespace_info = 1;
-      gdb_assert (die->child == NULL);
+      complaint (&symfile_complaints, _("unsupported tag: '%s'"),
+                dwarf_tag_name (die->tag));
       break;
     default:
       new_symbol (die, NULL, cu);
@@ -2314,12 +2815,59 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
+/* Return the fully qualified name of DIE, based on its DW_AT_name.
+   If scope qualifiers are appropriate they will be added.  The result
+   will be allocated on the objfile_obstack, or NULL if the DIE does
+   not have a name.  */
+
+static const char *
+dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+  char *prefix, *name;
+  struct ui_file *buf = NULL;
+
+  name = dwarf2_name (die, cu);
+  if (!name)
+    return NULL;
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (cu->language != language_cplus
+      && cu->language != language_java)
+    return name;
+
+  /* If no prefix is necessary for this type of DIE, return the
+     unqualified name.  The other three tags listed could be handled
+     in pdi_needs_namespace, but that requires broader changes.  */
+  if (!pdi_needs_namespace (die->tag)
+      && die->tag != DW_TAG_subprogram
+      && die->tag != DW_TAG_variable
+      && die->tag != DW_TAG_member)
+    return name;
+
+  prefix = determine_prefix (die, cu);
+  if (*prefix != '\0')
+    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
+                           name, cu);
+
+  return name;
+}
+
 static void
 initialize_cu_func_list (struct dwarf2_cu *cu)
 {
   cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
 }
 
+static void
+free_cu_line_header (void *arg)
+{
+  struct dwarf2_cu *cu = arg;
+
+  free_line_header (cu->line_header);
+  cu->line_header = NULL;
+}
+
 static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -2329,7 +2877,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
-  char *name = "<unknown>";
+  char *name = NULL;
   char *comp_dir = NULL;
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
@@ -2347,26 +2895,36 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   lowpc += baseaddr;
   highpc += baseaddr;
 
+  /* Find the filename.  Do not use dwarf2_name here, since the filename
+     is not a source language identifier.  */
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr)
     {
       name = DW_STRING (attr);
     }
+
   attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
   if (attr)
+    comp_dir = DW_STRING (attr);
+  else if (name != NULL && IS_ABSOLUTE_PATH (name))
     {
-      comp_dir = DW_STRING (attr);
-      if (comp_dir)
-       {
-         /* Irix 6.2 native cc prepends <machine>.: to the compilation
-            directory, get rid of it.  */
-         char *cp = strchr (comp_dir, ':');
+      comp_dir = ldirname (name);
+      if (comp_dir != NULL)
+       make_cleanup (xfree, comp_dir);
+    }
+  if (comp_dir != NULL)
+    {
+      /* Irix 6.2 native cc prepends <machine>.: to the compilation
+        directory, get rid of it.  */
+      char *cp = strchr (comp_dir, ':');
 
-         if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
-           comp_dir = cp + 1;
-       }
+      if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+       comp_dir = cp + 1;
     }
 
+  if (name == NULL)
+    name = "<unknown>";
+
   attr = dwarf2_attr (die, DW_AT_language, cu);
   if (attr)
     {
@@ -2376,38 +2934,21 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_producer, cu);
   if (attr) 
     cu->producer = DW_STRING (attr);
-  
+
   /* We assume that we're processing GCC output. */
   processing_gcc_compilation = 2;
-#if 0
-  /* FIXME:Do something here.  */
-  if (dip->at_producer != NULL)
-    {
-      handle_producer (dip->at_producer);
-    }
-#endif
 
-  /* The compilation unit may be in a different language or objfile,
-     zero out all remembered fundamental types.  */
-  memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+  processing_has_namespace_info = 0;
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
+  record_producer (cu->producer);
 
   initialize_cu_func_list (cu);
 
-  /* Process all dies in compilation unit.  */
-  if (die->child != NULL)
-    {
-      child_die = die->child;
-      while (child_die && child_die->tag)
-       {
-         process_die (child_die, cu);
-         child_die = sibling_die (child_die);
-       }
-    }
-
-  /* Decode line number information if present.  */
+  /* Decode line number information if present.  We do this before
+     processing child DIEs, so that the line header table is available
+     for DW_AT_decl_file.  */
   attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
   if (attr)
     {
@@ -2415,12 +2956,23 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
       line_header = dwarf_decode_line_header (line_offset, abfd, cu);
       if (line_header)
         {
-          make_cleanup ((make_cleanup_ftype *) free_line_header,
-                        (void *) line_header);
+          cu->line_header = line_header;
+          make_cleanup (free_cu_line_header, cu);
           dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
         }
     }
 
+  /* Process all dies in compilation unit.  */
+  if (die->child != NULL)
+    {
+      child_die = die->child;
+      while (child_die && child_die->tag)
+       {
+         process_die (child_die, cu);
+         child_die = sibling_die (child_die);
+       }
+    }
+
   /* Decode macro information, if present.  Dwarf 2 macro information
      refers to information in the line number info statement program
      header, so we can only read it if we've read the header
@@ -2467,9 +3019,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   struct attribute *attr;
   char *name;
-  const char *previous_prefix = processing_current_prefix;
-  struct cleanup *back_to = NULL;
   CORE_ADDR baseaddr;
+  struct block *block;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -2480,41 +3031,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
     return;
 
-  if (cu->language == language_cplus
-      || cu->language == language_java)
-    {
-      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;
 
@@ -2522,7 +3038,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   add_to_cu_func_list (name, lowpc, highpc, cu);
 
   new = push_context (0, lowpc);
-  new->name = new_symbol (die, die->type, cu);
+  new->name = new_symbol (die, read_type_die (die, cu), cu);
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
@@ -2553,8 +3069,17 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   new = pop_context ();
   /* Make a block for the local symbols within.  */
-  finish_block (new->name, &local_symbols, new->old_blocks,
-               lowpc, highpc, objfile);
+  block = finish_block (new->name, &local_symbols, new->old_blocks,
+                        lowpc, highpc, objfile);
+
+  /* For C++, set the block's scope.  */
+  if (cu->language == language_cplus)
+    cp_set_block_scope (new->name, block, &objfile->objfile_obstack,
+                       determine_prefix (die, cu),
+                       processing_has_namespace_info);
+
+  /* If we have address ranges, record them.  */
+  dwarf2_record_block_ranges (die, block, baseaddr, cu);
   
   /* In C++, we can have functions nested inside functions (e.g., when
      a function declares a class that has methods).  This means that
@@ -2567,10 +3092,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
      symbols go in the file symbol list.  */
   if (outermost_context_p ())
     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
@@ -2611,12 +3132,153 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   if (local_symbols != NULL)
     {
-      finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
-                   highpc, objfile);
+      struct block *block
+        = finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
+                        highpc, objfile);
+
+      /* Note that recording ranges after traversing children, as we
+         do here, means that recording a parent's ranges entails
+         walking across all its children's ranges as they appear in
+         the address map, which is quadratic behavior.
+
+         It would be nicer to record the parent's ranges before
+         traversing its children, simply overriding whatever you find
+         there.  But since we don't even decide whether to create a
+         block until after we've traversed its children, that's hard
+         to do.  */
+      dwarf2_record_block_ranges (die, block, baseaddr, cu);
     }
   local_symbols = new->locals;
 }
 
+/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
+   Return 1 if the attributes are present and valid, otherwise, return 0.
+   If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'.  */
+
+static int
+dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
+                   CORE_ADDR *high_return, struct dwarf2_cu *cu,
+                   struct partial_symtab *ranges_pst)
+{
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
+  bfd *obfd = objfile->obfd;
+  unsigned int addr_size = cu_header->addr_size;
+  CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+  /* Base address selection entry.  */
+  CORE_ADDR base;
+  int found_base;
+  unsigned int dummy;
+  gdb_byte *buffer;
+  CORE_ADDR marker;
+  int low_set;
+  CORE_ADDR low = 0;
+  CORE_ADDR high = 0;
+  CORE_ADDR baseaddr;
+
+  found_base = cu->base_known;
+  base = cu->base_address;
+
+  if (offset >= dwarf2_per_objfile->ranges_size)
+    {
+      complaint (&symfile_complaints,
+                _("Offset %d out of bounds for DW_AT_ranges attribute"),
+                offset);
+      return 0;
+    }
+  buffer = dwarf2_per_objfile->ranges_buffer + offset;
+
+  /* Read in the largest possible address.  */
+  marker = read_address (obfd, buffer, cu, &dummy);
+  if ((marker & mask) == mask)
+    {
+      /* If we found the largest possible address, then
+        read the base address.  */
+      base = read_address (obfd, buffer + addr_size, cu, &dummy);
+      buffer += 2 * addr_size;
+      offset += 2 * addr_size;
+      found_base = 1;
+    }
+
+  low_set = 0;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  while (1)
+    {
+      CORE_ADDR range_beginning, range_end;
+
+      range_beginning = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      range_end = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      offset += 2 * addr_size;
+
+      /* An end of list marker is a pair of zero addresses.  */
+      if (range_beginning == 0 && range_end == 0)
+       /* Found the end of list entry.  */
+       break;
+
+      /* Each base address selection entry is a pair of 2 values.
+        The first is the largest possible address, the second is
+        the base address.  Check for a base address here.  */
+      if ((range_beginning & mask) == mask)
+       {
+         /* If we found the largest possible address, then
+            read the base address.  */
+         base = read_address (obfd, buffer + addr_size, cu, &dummy);
+         found_base = 1;
+         continue;
+       }
+
+      if (!found_base)
+       {
+         /* We have no valid base address for the ranges
+            data.  */
+         complaint (&symfile_complaints,
+                    _("Invalid .debug_ranges data (no base address)"));
+         return 0;
+       }
+
+      range_beginning += base;
+      range_end += base;
+
+      if (ranges_pst != NULL && range_beginning < range_end)
+       addrmap_set_empty (objfile->psymtabs_addrmap,
+                          range_beginning + baseaddr, range_end - 1 + baseaddr,
+                          ranges_pst);
+
+      /* FIXME: This is recording everything as a low-high
+        segment of consecutive addresses.  We should have a
+        data structure for discontiguous block ranges
+        instead.  */
+      if (! low_set)
+       {
+         low = range_beginning;
+         high = range_end;
+         low_set = 1;
+       }
+      else
+       {
+         if (range_beginning < low)
+           low = range_beginning;
+         if (range_end > high)
+           high = range_end;
+       }
+    }
+
+  if (! low_set)
+    /* If the first entry is an end-of-list marker, the range
+       describes an empty scope, i.e. no instructions.  */
+    return 0;
+
+  if (low_return)
+    *low_return = low;
+  if (high_return)
+    *high_return = high;
+  return 1;
+}
+
 /* Get low and high pc attributes from a die.  Return 1 if the attributes
    are present and valid, otherwise, return 0.  Return -1 if the range is
    discontinuous, i.e. derived from DW_AT_ranges information.  */
@@ -2624,10 +3286,7 @@ static int
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                      CORE_ADDR *highpc, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
-  struct comp_unit_head *cu_header = &cu->header;
   struct attribute *attr;
-  bfd *obfd = objfile->obfd;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
   int ret = 0;
@@ -2651,108 +3310,11 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
       attr = dwarf2_attr (die, DW_AT_ranges, cu);
       if (attr != NULL)
        {
-         unsigned int addr_size = cu_header->addr_size;
-         CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
          /* Value of the DW_AT_ranges attribute is the offset in the
             .debug_ranges section.  */
-         unsigned int offset = DW_UNSND (attr);
-         /* Base address selection entry.  */
-         CORE_ADDR base;
-         int found_base;
-         int dummy;
-         char *buffer;
-         CORE_ADDR marker;
-         int low_set;
-         found_base = cu_header->base_known;
-         base = cu_header->base_address;
-
-         if (offset >= dwarf2_per_objfile->ranges_size)
-           {
-             complaint (&symfile_complaints,
-                        "Offset %d out of bounds for DW_AT_ranges attribute",
-                        offset);
-             return 0;
-           }
-         buffer = dwarf2_per_objfile->ranges_buffer + offset;
-
-         /* Read in the largest possible address.  */
-         marker = read_address (obfd, buffer, cu, &dummy);
-         if ((marker & mask) == mask)
-           {
-             /* If we found the largest possible address, then
-                read the base address.  */
-             base = read_address (obfd, buffer + addr_size, cu, &dummy);
-             buffer += 2 * addr_size;
-             offset += 2 * addr_size;
-             found_base = 1;
-           }
-
-         low_set = 0;
-
-         while (1)
-           {
-             CORE_ADDR range_beginning, range_end;
-
-             range_beginning = read_address (obfd, buffer, cu, &dummy);
-             buffer += addr_size;
-             range_end = read_address (obfd, buffer, cu, &dummy);
-             buffer += addr_size;
-             offset += 2 * addr_size;
-
-             /* An end of list marker is a pair of zero addresses.  */
-             if (range_beginning == 0 && range_end == 0)
-               /* Found the end of list entry.  */
-               break;
-
-             /* Each base address selection entry is a pair of 2 values.
-                The first is the largest possible address, the second is
-                the base address.  Check for a base address here.  */
-             if ((range_beginning & mask) == mask)
-               {
-                 /* If we found the largest possible address, then
-                    read the base address.  */
-                 base = read_address (obfd, buffer + addr_size, cu, &dummy);
-                 found_base = 1;
-                 continue;
-               }
-
-             if (!found_base)
-               {
-                 /* We have no valid base address for the ranges
-                    data.  */
-                 complaint (&symfile_complaints,
-                            "Invalid .debug_ranges data (no base address)");
-                 return 0;
-               }
-
-             range_beginning += base;
-             range_end += base;
-
-             /* FIXME: This is recording everything as a low-high
-                segment of consecutive addresses.  We should have a
-                data structure for discontiguous block ranges
-                instead.  */
-             if (! low_set)
-               {
-                 low = range_beginning;
-                 high = range_end;
-                 low_set = 1;
-               }
-             else
-               {
-                 if (range_beginning < low)
-                   low = range_beginning;
-                 if (range_end > high)
-                   high = range_end;
-               }
-           }
-
-         if (! low_set)
-           /* If the first entry is an end-of-list marker, the range
-              describes an empty scope, i.e. no instructions.  */
+         if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL))
            return 0;
-
+         /* Found discontinuous range of addresses.  */
          ret = -1;
        }
     }
@@ -2768,7 +3330,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
      labels are not in the output, so the relocs get a value of 0.
      If this is a discarded function, mark the pc bounds as invalid,
      so that GDB will ignore it.  */
-  if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0)
+  if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
     return 0;
 
   *lowpc = low;
@@ -2776,6 +3338,43 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
   return ret;
 }
 
+/* Assuming that DIE represents a subprogram DIE or a lexical block, get
+   its low and high PC addresses.  Do nothing if these addresses could not
+   be determined.  Otherwise, set LOWPC to the low address if it is smaller,
+   and HIGHPC to the high address if greater than HIGHPC.  */
+
+static void
+dwarf2_get_subprogram_pc_bounds (struct die_info *die,
+                                 CORE_ADDR *lowpc, CORE_ADDR *highpc,
+                                 struct dwarf2_cu *cu)
+{
+  CORE_ADDR low, high;
+  struct die_info *child = die->child;
+
+  if (dwarf2_get_pc_bounds (die, &low, &high, cu))
+    {
+      *lowpc = min (*lowpc, low);
+      *highpc = max (*highpc, high);
+    }
+
+  /* If the language does not allow nested subprograms (either inside
+     subprograms or lexical blocks), we're done.  */
+  if (cu->language != language_ada)
+    return;
+     
+  /* Check all the children of the given DIE.  If it contains nested
+     subprograms, then check their pc bounds.  Likewise, we need to
+     check lexical blocks as well, as they may also contain subprogram
+     definitions.  */
+  while (child && child->tag)
+    {
+      if (child->tag == DW_TAG_subprogram
+          || child->tag == DW_TAG_lexical_block)
+        dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu);
+      child = sibling_die (child);
+    }
+}
+
 /* 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.  */
@@ -2802,11 +3401,7 @@ get_scope_pc_bounds (struct die_info *die,
        {
          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);
-             }
+            dwarf2_get_subprogram_pc_bounds (child, &best_low, &best_high, cu);
            break;
          case DW_TAG_namespace:
            /* FIXME: carlton/2004-01-16: Should we do this for
@@ -2838,6 +3433,100 @@ get_scope_pc_bounds (struct die_info *die,
   *highpc = best_high;
 }
 
+/* Record the address ranges for BLOCK, offset by BASEADDR, as given
+   in DIE.  */
+static void
+dwarf2_record_block_ranges (struct die_info *die, struct block *block,
+                            CORE_ADDR baseaddr, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
+  if (attr)
+    {
+      CORE_ADDR high = DW_ADDR (attr);
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+      if (attr)
+        {
+          CORE_ADDR low = DW_ADDR (attr);
+          record_block_range (block, baseaddr + low, baseaddr + high - 1);
+        }
+    }
+
+  attr = dwarf2_attr (die, DW_AT_ranges, cu);
+  if (attr)
+    {
+      bfd *obfd = cu->objfile->obfd;
+
+      /* The value of the DW_AT_ranges attribute is the offset of the
+         address range list in the .debug_ranges section.  */
+      unsigned long offset = DW_UNSND (attr);
+      gdb_byte *buffer = dwarf2_per_objfile->ranges_buffer + offset;
+
+      /* For some target architectures, but not others, the
+         read_address function sign-extends the addresses it returns.
+         To recognize base address selection entries, we need a
+         mask.  */
+      unsigned int addr_size = cu->header.addr_size;
+      CORE_ADDR base_select_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+
+      /* The base address, to which the next pair is relative.  Note
+         that this 'base' is a DWARF concept: most entries in a range
+         list are relative, to reduce the number of relocs against the
+         debugging information.  This is separate from this function's
+         'baseaddr' argument, which GDB uses to relocate debugging
+         information from a shared library based on the address at
+         which the library was loaded.  */
+      CORE_ADDR base = cu->base_address;
+      int base_known = cu->base_known;
+
+      if (offset >= dwarf2_per_objfile->ranges_size)
+        {
+          complaint (&symfile_complaints,
+                     _("Offset %lu out of bounds for DW_AT_ranges attribute"),
+                     offset);
+          return;
+        }
+
+      for (;;)
+        {
+          unsigned int bytes_read;
+          CORE_ADDR start, end;
+
+          start = read_address (obfd, buffer, cu, &bytes_read);
+          buffer += bytes_read;
+          end = read_address (obfd, buffer, cu, &bytes_read);
+          buffer += bytes_read;
+
+          /* Did we find the end of the range list?  */
+          if (start == 0 && end == 0)
+            break;
+
+          /* Did we find a base address selection entry?  */
+          else if ((start & base_select_mask) == base_select_mask)
+            {
+              base = end;
+              base_known = 1;
+            }
+
+          /* We found an ordinary address range.  */
+          else
+            {
+              if (!base_known)
+                {
+                  complaint (&symfile_complaints,
+                             _("Invalid .debug_ranges data (no base address)"));
+                  return;
+                }
+
+              record_block_range (block, 
+                                  baseaddr + base + start, 
+                                  baseaddr + base + end - 1);
+            }
+        }
+    }
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -2845,6 +3534,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
                  struct dwarf2_cu *cu)
 { 
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct nextfield *new_field;
   struct attribute *attr;
   struct field *fp;
@@ -2902,15 +3592,26 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
        {
-         FIELD_BITPOS (*fp) =
-           decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
+          int byte_offset;
+
+          if (attr_form_is_section_offset (attr))
+            {
+              dwarf2_complex_location_expr_complaint ();
+              byte_offset = 0;
+            }
+          else if (attr_form_is_constant (attr))
+            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+          else
+            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+
+          FIELD_BITPOS (*fp) = byte_offset * bits_per_byte;
        }
       else
        FIELD_BITPOS (*fp) = 0;
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
-         if (BITS_BIG_ENDIAN)
+         if (gdbarch_bits_big_endian (gdbarch))
            {
              /* For big endian bits, the DW_AT_bit_offset gives the
                 additional bit offset from the MSB of the containing
@@ -2952,9 +3653,9 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get name of field.  */
-      attr = dwarf2_attr (die, DW_AT_name, cu);
-      if (attr && DW_STRING (attr))
-       fieldname = DW_STRING (attr);
+      fieldname = dwarf2_name (die, cu);
+      if (fieldname == NULL)
+       fieldname = "";
 
       /* The name is already allocated along with this objfile, so we don't
         need to duplicate it for the type.  */
@@ -2980,10 +3681,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       char *physname;
 
       /* Get name of field.  */
-      attr = dwarf2_attr (die, DW_AT_name, cu);
-      if (attr && DW_STRING (attr))
-       fieldname = DW_STRING (attr);
-      else
+      fieldname = dwarf2_name (die, cu);
+      if (fieldname == NULL)
        return;
 
       /* Get physical name.  */
@@ -3047,11 +3746,11 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
   if (fip->nbaseclasses)
     {
       int num_bytes = B_BYTES (fip->nbaseclasses);
-      char *pointer;
+      unsigned char *pointer;
 
       ALLOCATE_CPLUS_STRUCT_TYPE (type);
-      pointer = (char *) TYPE_ALLOC (type, num_bytes);
-      TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+      pointer = TYPE_ALLOC (type, num_bytes);
+      TYPE_FIELD_VIRTUAL_BITS (type) = pointer;
       B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
       TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
     }
@@ -3078,7 +3777,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
        default:
          /* Unknown accessibility.  Complain and treat it as public.  */
          {
-           complaint (&symfile_complaints, "unsupported accessibility %d",
+           complaint (&symfile_complaints, _("unsupported accessibility %d"),
                       fip->fields->accessibility);
          }
          break;
@@ -3111,12 +3810,11 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   char *fieldname;
   char *physname;
   struct nextfnfield *new_fnfield;
+  struct type *this_type;
 
   /* Get name of member function.  */
-  attr = dwarf2_attr (die, DW_AT_name, cu);
-  if (attr && DW_STRING (attr))
-    fieldname = DW_STRING (attr);
-  else
+  fieldname = dwarf2_name (die, cu);
+  if (fieldname == NULL)
     return;
 
   /* Get the mangled name.  */
@@ -3165,17 +3863,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
      need to duplicate it for the type.  */
   fnp->physname = physname ? physname : "";
   fnp->type = alloc_type (objfile);
-  if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+  this_type = read_type_die (die, cu);
+  if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
     {
-      int nparams = TYPE_NFIELDS (die->type);
+      int nparams = TYPE_NFIELDS (this_type);
 
-      /* TYPE is the domain of this method, and DIE->TYPE is the type
+      /* TYPE is the domain of this method, and THIS_TYPE is the type
           of the method itself (TYPE_CODE_METHOD).  */
       smash_to_method_type (fnp->type, type,
-                           TYPE_TARGET_TYPE (die->type),
-                           TYPE_FIELDS (die->type),
-                           TYPE_NFIELDS (die->type),
-                           TYPE_VARARGS (die->type));
+                           TYPE_TARGET_TYPE (this_type),
+                           TYPE_FIELDS (this_type),
+                           TYPE_NFIELDS (this_type),
+                           TYPE_VARARGS (this_type));
 
       /* Handle static member functions.
          Dwarf2 has no clean way to discern C++ static and non-static
@@ -3183,11 +3882,11 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
          parameter for non-static member functions (which is the
          this pointer) as artificial. We obtain this information
          from read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
-      if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
+      if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (this_type, 0) == 0)
        fnp->voffset = VOFFSET_STATIC;
     }
   else
-    complaint (&symfile_complaints, "member function type missing for '%s'",
+    complaint (&symfile_complaints, _("member function type missing for '%s'"),
               physname);
 
   /* Get fcontext from DW_AT_containing_type if present.  */
@@ -3226,7 +3925,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
         {
           fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
         }
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+      else if (attr_form_is_section_offset (attr))
         {
          dwarf2_complex_location_expr_complaint ();
         }
@@ -3272,7 +3971,6 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
   TYPE_NFN_FIELDS_TOTAL (type) = total_length;
 }
 
-
 /* Returns non-zero if NAME is the name of a vtable member in CU's
    language, zero otherwise.  */
 static int
@@ -3291,6 +3989,70 @@ is_vtable_name (const char *name, struct dwarf2_cu *cu)
   return 0;
 }
 
+/* GCC outputs unnamed structures that are really pointers to member
+   functions, with the ABI-specified layout.  If DIE (from CU) describes
+   such a structure, set its type, and return nonzero.  Otherwise return
+   zero.
+
+   GCC shouldn't do this; it should just output pointer to member DIEs.
+   This is GCC PR debug/28767.  */
+
+static struct type *
+quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct type *type;
+  struct die_info *pfn_die, *delta_die;
+  struct attribute *pfn_name, *delta_name;
+  struct type *pfn_type, *domain_type;
+
+  /* Check for a structure with no name and two children.  */
+  if (die->tag != DW_TAG_structure_type
+      || dwarf2_attr (die, DW_AT_name, cu) != NULL
+      || die->child == NULL
+      || die->child->sibling == NULL
+      || (die->child->sibling->sibling != NULL
+         && die->child->sibling->sibling->tag != DW_TAG_padding))
+    return NULL;
+
+  /* Check for __pfn and __delta members.  */
+  pfn_die = die->child;
+  pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu);
+  if (pfn_die->tag != DW_TAG_member
+      || pfn_name == NULL
+      || DW_STRING (pfn_name) == NULL
+      || strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
+    return NULL;
+
+  delta_die = pfn_die->sibling;
+  delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
+  if (delta_die->tag != DW_TAG_member
+      || delta_name == NULL
+      || DW_STRING (delta_name) == NULL
+      || strcmp ("__delta", DW_STRING (delta_name)) != 0)
+    return NULL;
+
+  /* Find the type of the method.  */
+  pfn_type = die_type (pfn_die, cu);
+  if (pfn_type == NULL
+      || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
+      || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+    return NULL;
+
+  /* Look for the "this" argument.  */
+  pfn_type = TYPE_TARGET_TYPE (pfn_type);
+  if (TYPE_NFIELDS (pfn_type) == 0
+      || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+    return NULL;
+
+  domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
+  type = alloc_type (objfile);
+  smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+                       TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+                       TYPE_VARARGS (pfn_type));
+  type = lookup_methodptr_type (type);
+  return set_die_type (die, type, cu);
+}
 
 /* Called when we find the DIE that starts a structure or union scope
    (definition) to process all dies that define the members of the
@@ -3308,39 +4070,35 @@ is_vtable_name (const char *name, struct dwarf2_cu *cu)
    checking about whether the struct/union is anonymous or not (and
    suppresses creating a symbol table entry itself).  */
 
-static void
+static struct type *
 read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
-  const char *previous_prefix = processing_current_prefix;
-  struct cleanup *back_to = NULL;
+  char *name;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
-  if (die->type)
-    return;
+  type = quirk_gcc_member_function_pointer (die, cu);
+  if (type)
+    return type;
 
   type = alloc_type (objfile);
-
   INIT_CPLUS_SPECIFIC (type);
-  attr = dwarf2_attr (die, DW_AT_name, cu);
-  if (attr && DW_STRING (attr))
+  name = dwarf2_name (die, cu);
+  if (name != NULL)
     {
       if (cu->language == language_cplus
          || cu->language == language_java)
        {
-         char *new_prefix = determine_class_name (die, cu);
-         TYPE_TAG_NAME (type) = obsavestring (new_prefix,
-                                              strlen (new_prefix),
-                                              &objfile->objfile_obstack);
-         back_to = make_cleanup (xfree, new_prefix);
-         processing_current_prefix = new_prefix;
+         const char *new_prefix = determine_class_name (die, cu);
+         TYPE_TAG_NAME (type) = (char *) new_prefix;
        }
       else
        {
          /* The name is already allocated along with this objfile, so
             we don't need to duplicate it for the type.  */
-         TYPE_TAG_NAME (type) = DW_STRING (attr);
+         TYPE_TAG_NAME (type) = name;
        }
     }
 
@@ -3369,19 +4127,19 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
+  TYPE_STUB_SUPPORTED (type) = 1;
   if (die_is_declaration (die, cu))
-    TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+    TYPE_STUB (type) = 1;
 
   /* We need to add the type field to the die immediately so we don't
      infinitely recurse when dealing with pointers to the structure
      type within the structure itself. */
-  die->type = type;
+  set_die_type (die, type, cu);
 
   if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
       struct die_info *child_die;
-      struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
 
       memset (&fi, 0, sizeof (struct field_info));
 
@@ -3402,7 +4160,6 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
          else if (child_die->tag == DW_TAG_subprogram)
            {
              /* C++ member function. */
-             read_type_die (child_die, cu);
              dwarf2_add_member_fn (&fi, child_die, type, cu);
            }
          else if (child_die->tag == DW_TAG_inheritance)
@@ -3450,7 +4207,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                  /* Complain if virtual function table field not found.  */
                  if (i < TYPE_N_BASECLASSES (t))
                    complaint (&symfile_complaints,
-                              "virtual function table pointer not found when defining class '%s'",
+                              _("virtual function table pointer not found when defining class '%s'"),
                               TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) :
                               "");
                }
@@ -3459,25 +4216,45 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                  TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
                }
            }
-       }
+         else if (cu->producer
+                  && strncmp (cu->producer,
+                              "IBM(R) XL C/C++ Advanced Edition", 32) == 0)
+           {
+             /* The IBM XLC compiler does not provide direct indication
+                of the containing type, but the vtable pointer is
+                always named __vfp.  */
 
-      do_cleanups (back_to);
+             int i;
+
+             for (i = TYPE_NFIELDS (type) - 1;
+                  i >= TYPE_N_BASECLASSES (type);
+                  --i)
+               {
+                 if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
+                   {
+                     TYPE_VPTR_FIELDNO (type) = i;
+                     TYPE_VPTR_BASETYPE (type) = type;
+                     break;
+                   }
+               }
+           }
+       }
     }
 
-  processing_current_prefix = previous_prefix;
-  if (back_to != NULL)
-    do_cleanups (back_to);
+  do_cleanups (back_to);
+  return type;
 }
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  const char *previous_prefix = processing_current_prefix;
   struct die_info *child_die = die->child;
+  struct type *this_type;
 
-  if (TYPE_TAG_NAME (die->type) != NULL)
-    processing_current_prefix = TYPE_TAG_NAME (die->type);
+  this_type = get_die_type (die, cu);
+  if (this_type == NULL)
+    this_type = read_structure_type (die, cu);
 
   /* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
      snapshots) has been known to create a die giving a declaration
@@ -3500,46 +4277,31 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       child_die = sibling_die (child_die);
     }
 
-  if (die->child != NULL && ! die_is_declaration (die, cu))
-    new_symbol (die, die->type, cu);
-
-  processing_current_prefix = previous_prefix;
+  /* Do not consider external references.  According to the DWARF standard,
+     these DIEs are identified by the fact that they have no byte_size
+     attribute, and a declaration attribute.  */
+  if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
+      || !die_is_declaration (die, cu))
+    new_symbol (die, this_type, cu);
 }
 
 /* Given a DW_AT_enumeration_type die, set its type.  We do not
    complete the type's fields yet, or create any symbols.  */
 
-static void
+static struct type *
 read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
-
-  if (die->type)
-    return;
+  const char *name;
 
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
-  attr = dwarf2_attr (die, DW_AT_name, cu);
-  if (attr && DW_STRING (attr))
-    {
-      char *name = DW_STRING (attr);
-
-      if (processing_has_namespace_info)
-       {
-         TYPE_TAG_NAME (type) = typename_concat (&objfile->objfile_obstack,
-                                                 processing_current_prefix,
-                                                 name, cu);
-       }
-      else
-       {
-         /* The name is already allocated along with this objfile, so
-            we don't need to duplicate it for the type.  */
-         TYPE_TAG_NAME (type) = name;
-       }
-    }
+  name = dwarf2_full_name (die, cu);
+  if (name != NULL)
+    TYPE_TAG_NAME (type) = (char *) name;
 
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
@@ -3551,29 +4313,25 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
-  die->type = type;
+  /* The enumeration DIE can be incomplete.  In Ada, any type can be
+     declared as private in the package spec, and then defined only
+     inside the package body.  Such types are known as Taft Amendment
+     Types.  When another package uses such a type, an incomplete DIE
+     may be generated by the compiler.  */
+  if (die_is_declaration (die, cu))
+    TYPE_STUB (type) = 1;
+
+  return set_die_type (die, type, cu);
 }
 
 /* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question; the caller
-   is responsible for xfree()'ing it.  */
+   a named C++ or Java compound type.  Return the name in question,
+   allocated on the objfile obstack.  */
 
-static char *
+static const char *
 determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct cleanup *back_to = NULL;
-  struct die_info *spec_die = die_specification (die, cu);
-  char *new_prefix = NULL;
-
-  /* If this is the definition of a class that is declared by another
-     die, then processing_current_prefix may not be accurate; see
-     read_func_scope for a similar example.  */
-  if (spec_die != NULL)
-    {
-      char *specification_prefix = determine_prefix (spec_die, cu);
-      processing_current_prefix = specification_prefix;
-      back_to = make_cleanup (xfree, specification_prefix);
-    }
+  const char *new_prefix = NULL;
 
   /* If we don't have namespace debug info, guess the name by trying
      to demangle the names of members, just like we did in
@@ -3588,27 +4346,25 @@ determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
        {
          if (child->tag == DW_TAG_subprogram)
            {
-             new_prefix 
+             char *phys_prefix
                = language_class_name_from_physname (cu->language_defn,
                                                     dwarf2_linkage_name
                                                     (child, cu));
 
-             if (new_prefix != NULL)
-               break;
+             if (phys_prefix != NULL)
+               {
+                 new_prefix
+                   = obsavestring (phys_prefix, strlen (phys_prefix),
+                                   &cu->objfile->objfile_obstack);
+                 xfree (phys_prefix);
+                 break;
+               }
            }
        }
     }
 
   if (new_prefix == NULL)
-    {
-      const char *name = dwarf2_name (die, cu);
-      new_prefix = typename_concat (NULL, processing_current_prefix,
-                                   name ? name : "<<anonymous>>", 
-                                   cu);
-    }
-
-  if (back_to != NULL)
-    do_cleanups (back_to);
+    new_prefix = dwarf2_full_name (die, cu);
 
   return new_prefix;
 }
@@ -3625,13 +4381,17 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct objfile *objfile = cu->objfile;
   struct die_info *child_die;
   struct field *fields;
-  struct attribute *attr;
   struct symbol *sym;
   int num_fields;
   int unsigned_enum = 1;
+  char *name;
+  struct type *this_type;
 
   num_fields = 0;
   fields = NULL;
+  this_type = get_die_type (die, cu);
+  if (this_type == NULL)
+    this_type = read_enumeration_type (die, cu);
   if (die->child != NULL)
     {
       child_die = die->child;
@@ -3643,10 +4403,10 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
            }
          else
            {
-             attr = dwarf2_attr (child_die, DW_AT_name, cu);
-             if (attr)
+             name = dwarf2_name (child_die, cu);
+             if (name)
                {
-                 sym = new_symbol (child_die, die->type, cu);
+                 sym = new_symbol (child_die, this_type, cu);
                  if (SYMBOL_VALUE (sym) < 0)
                    unsigned_enum = 0;
 
@@ -3658,7 +4418,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
                                  * sizeof (struct field));
                    }
 
-                 FIELD_NAME (fields[num_fields]) = DEPRECATED_SYMBOL_NAME (sym);
+                 FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym);
                  FIELD_TYPE (fields[num_fields]) = NULL;
                  FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
                  FIELD_BITSIZE (fields[num_fields]) = 0;
@@ -3673,25 +4433,25 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 
       if (num_fields)
        {
-         TYPE_NFIELDS (die->type) = num_fields;
-         TYPE_FIELDS (die->type) = (struct field *)
-           TYPE_ALLOC (die->type, sizeof (struct field) * num_fields);
-         memcpy (TYPE_FIELDS (die->type), fields,
+         TYPE_NFIELDS (this_type) = num_fields;
+         TYPE_FIELDS (this_type) = (struct field *)
+           TYPE_ALLOC (this_type, sizeof (struct field) * num_fields);
+         memcpy (TYPE_FIELDS (this_type), fields,
                  sizeof (struct field) * num_fields);
          xfree (fields);
        }
       if (unsigned_enum)
-       TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED;
+       TYPE_UNSIGNED (this_type) = 1;
     }
 
-  new_symbol (die, die->type, cu);
+  new_symbol (die, this_type, cu);
 }
 
 /* Extract all information from a DW_TAG_array_type DIE and put it in
    the DIE's type field.  For now, this only handles one dimensional
    arrays.  */
 
-static void
+static struct type *
 read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
@@ -3702,12 +4462,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   int ndim = 0;
   struct cleanup *back_to;
-
-  /* Return if we've already decoded this type. */
-  if (die->type)
-    {
-      return;
-    }
+  char *name;
 
   element_type = die_type (die, cu);
 
@@ -3715,10 +4470,10 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
      arrays with unspecified length.  */
   if (die->child == NULL)
     {
-      index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
+      index_type = builtin_type_int32;
       range_type = create_range_type (NULL, index_type, 0, -1);
-      die->type = create_array_type (NULL, element_type, range_type);
-      return;
+      type = create_array_type (NULL, element_type, range_type);
+      return set_die_type (die, type, cu);
     }
 
   back_to = make_cleanup (null_cleanup, NULL);
@@ -3727,9 +4482,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
-          read_subrange_type (child_die, cu);
-
-          if (child_die->type != NULL)
+         struct type *child_type = read_type_die (child_die, cu);
+          if (child_type != NULL)
             {
              /* The range type was succesfully read. Save it for
                  the array type creation.  */
@@ -3741,7 +4495,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
                   if (ndim == 0)
                     make_cleanup (free_current_contents, &range_types);
                }
-             range_types[ndim++] = child_die->type;
+             range_types[ndim++] = child_type;
             }
        }
       child_die = sibling_die (child_die);
@@ -3772,12 +4526,16 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
      to functions.  */
   attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
   if (attr)
-    TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+    make_vector_type (type);
 
+  name = dwarf2_name (die, cu);
+  if (name)
+    TYPE_NAME (type) = name;
+  
   do_cleanups (back_to);
 
   /* Install the type in the die. */
-  die->type = type;
+  return set_die_type (die, type, cu);
 }
 
 static enum dwarf_array_dim_ordering
@@ -3814,6 +4572,16 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu)
     };
 }
 
+/* Extract all information from a DW_TAG_set_type DIE and put it in
+   the DIE's type field. */
+
+static struct type *
+read_set_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *set_type = create_set_type (NULL, die_type (die, cu));
+
+  return set_die_type (die, set_type, cu);
+}
 
 /* First cut: install each common block member as a global variable.  */
 
@@ -3833,7 +4601,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
         {
           base = decode_locdesc (DW_BLOCK (attr), cu);
         }
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+      else if (attr_form_is_section_offset (attr))
         {
          dwarf2_complex_location_expr_complaint ();
         }
@@ -3861,55 +4629,74 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Read a C++ namespace.  */
+/* Create a type for a C++ namespace.  */
 
-static void
-read_namespace (struct die_info *die, struct dwarf2_cu *cu)
+static struct type *
+read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  const char *previous_prefix = processing_current_prefix;
-  const char *name;
+  const char *previous_prefix, *name;
   int is_anonymous;
-  struct die_info *current_die;
-  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+  struct type *type;
+
+  /* For extensions, reuse the type of the original namespace.  */
+  if (dwarf2_attr (die, DW_AT_extension, cu) != NULL)
+    {
+      struct die_info *ext_die;
+      struct dwarf2_cu *ext_cu = cu;
+      ext_die = dwarf2_extension (die, &ext_cu);
+      type = read_type_die (ext_die, ext_cu);
+      return set_die_type (die, type, cu);
+    }
 
   name = namespace_name (die, &is_anonymous, cu);
 
   /* Now build the name of the current namespace.  */
 
-  if (previous_prefix[0] == '\0')
-    {
-      processing_current_prefix = name;
-    }
-  else
-    {
-      char *temp_name = typename_concat (NULL, previous_prefix, name, cu);
-      make_cleanup (xfree, temp_name);
-      processing_current_prefix = temp_name;
-    }
+  previous_prefix = determine_prefix (die, cu);
+  if (previous_prefix[0] != '\0')
+    name = typename_concat (&objfile->objfile_obstack,
+                           previous_prefix, name, cu);
+
+  /* Create the type.  */
+  type = init_type (TYPE_CODE_NAMESPACE, 0, 0, NULL,
+                   objfile);
+  TYPE_NAME (type) = (char *) name;
+  TYPE_TAG_NAME (type) = TYPE_NAME (type);
+
+  set_die_type (die, type, cu);
+
+  return type;
+}
+
+/* Read a C++ namespace.  */
+
+static void
+read_namespace (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  const char *name;
+  int is_anonymous;
 
   /* 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, cu) == NULL)
+  if (dwarf2_attr (die, DW_AT_extension, cu) == NULL)
     {
       struct type *type;
 
-      /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
-        this cast will hopefully become unnecessary.  */
-      type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
-                       (char *) processing_current_prefix,
-                       objfile);
-      TYPE_TAG_NAME (type) = TYPE_NAME (type);
-
+      type = read_type_die (die, cu);
       new_symbol (die, type, cu);
-      die->type = type;
 
+      name = namespace_name (die, &is_anonymous, cu);
       if (is_anonymous)
-       cp_add_using_directive (processing_current_prefix,
-                               strlen (previous_prefix),
-                               strlen (processing_current_prefix));
+       {
+         const char *previous_prefix = determine_prefix (die, cu);
+         cp_add_using_directive (TYPE_NAME (type),
+                                 strlen (previous_prefix),
+                                 strlen (TYPE_NAME (type)));
+       }
     }
 
   if (die->child != NULL)
@@ -3922,9 +4709,6 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
          child_die = sibling_die (child_die);
        }
     }
-
-  processing_current_prefix = previous_prefix;
-  do_cleanups (back_to);
 }
 
 /* Return the name of the namespace represented by DIE.  Set
@@ -3941,7 +4725,7 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
 
   for (current_die = die;
        current_die != NULL;
-       current_die = dwarf2_extension (die, cu))
+       current_die = dwarf2_extension (die, &cu))
     {
       name = dwarf2_name (current_die, cu);
       if (name != NULL)
@@ -3960,20 +4744,16 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
    the user defined type vector.  */
 
-static void
+static struct type *
 read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
   struct attribute *attr_address_class;
   int byte_size, addr_class;
 
-  if (die->type)
-    {
-      return;
-    }
-
   type = lookup_pointer_type (die_type (die, cu));
 
   attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
@@ -3993,17 +4773,19 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
      length accordingly.  */
   if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
     {
-      if (ADDRESS_CLASS_TYPE_FLAGS_P ())
+      if (gdbarch_address_class_type_flags_p (gdbarch))
        {
          int type_flags;
 
-         type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class);
-         gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0);
+         type_flags = gdbarch_address_class_type_flags
+                        (gdbarch, byte_size, addr_class);
+         gdb_assert ((type_flags & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
+                     == 0);
          type = make_type_with_address_space (type, type_flags);
        }
       else if (TYPE_LENGTH (type) != byte_size)
        {
-         complaint (&symfile_complaints, "invalid pointer size %d", byte_size);
+         complaint (&symfile_complaints, _("invalid pointer size %d"), byte_size);
        }
       else {
        /* Should we also complain about unhandled address classes?  */
@@ -4011,13 +4793,13 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   TYPE_LENGTH (type) = byte_size;
-  die->type = type;
+  return set_die_type (die, type, cu);
 }
 
 /* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
    the user defined type vector.  */
 
-static void
+static struct type *
 read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
@@ -4025,34 +4807,27 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *to_type;
   struct type *domain;
 
-  if (die->type)
-    {
-      return;
-    }
-
-  type = alloc_type (objfile);
   to_type = die_type (die, cu);
   domain = die_containing_type (die, cu);
-  smash_to_member_type (type, domain, to_type);
 
-  die->type = type;
+  if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+    type = lookup_methodptr_type (to_type);
+  else
+    type = lookup_memberptr_type (to_type, domain);
+
+  return set_die_type (die, type, cu);
 }
 
 /* Extract all information from a DW_TAG_reference_type DIE and add to
    the user defined type vector.  */
 
-static void
+static struct type *
 read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr;
 
-  if (die->type)
-    {
-      return;
-    }
-
   type = lookup_reference_type (die_type (die, cu));
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
@@ -4063,35 +4838,27 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       TYPE_LENGTH (type) = cu_header->addr_size;
     }
-  die->type = type;
+  return set_die_type (die, type, cu);
 }
 
-static void
+static struct type *
 read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct type *base_type;
-
-  if (die->type)
-    {
-      return;
-    }
+  struct type *base_type, *cv_type;
 
   base_type = die_type (die, cu);
-  die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+  cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+  return set_die_type (die, cv_type, cu);
 }
 
-static void
+static struct type *
 read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct type *base_type;
-
-  if (die->type)
-    {
-      return;
-    }
+  struct type *base_type, *cv_type;
 
   base_type = die_type (die, cu);
-  die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+  cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+  return set_die_type (die, cv_type, cu);
 }
 
 /* Extract all information from a DW_TAG_string_type DIE and add to
@@ -4099,7 +4866,7 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
    but it behaves like one, with other DIE's using an AT_user_def_type
    attribute to reference it.  */
 
-static void
+static struct type *
 read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
@@ -4107,11 +4874,6 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   unsigned int length;
 
-  if (die->type)
-    {
-      return;
-    }
-
   attr = dwarf2_attr (die, DW_AT_string_length, cu);
   if (attr)
     {
@@ -4130,20 +4892,12 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
           length = 1;
         }
     }
-  index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
+
+  index_type = builtin_type_int32;
   range_type = create_range_type (NULL, index_type, 1, length);
-  if (cu->language == language_fortran)
-    {
-      /* Need to create a unique string type for bounds
-         information */
-      type = create_string_type (0, range_type);
-    }
-  else
-    {
-      char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
-      type = create_string_type (char_type, range_type);
-    }
-  die->type = type;
+  type = create_string_type (NULL, range_type);
+
+  return set_die_type (die, type, cu);
 }
 
 /* Handle DIES due to C code like:
@@ -4157,28 +4911,30 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
    ('funcp' generates a DW_TAG_subroutine_type DIE)
  */
 
-static void
+static struct type *
 read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;           /* Type that this function returns */
   struct type *ftype;          /* Function that returns above type */
   struct attribute *attr;
 
-  /* Decode the type that this subroutine returns */
-  if (die->type)
-    {
-      return;
-    }
   type = die_type (die, cu);
-  ftype = lookup_function_type (type);
+  ftype = make_function_type (type, (struct type **) 0);
 
-  /* All functions in C++ and Java have prototypes.  */
+  /* All functions in C++, Pascal and Java have prototypes.  */
   attr = dwarf2_attr (die, DW_AT_prototyped, cu);
   if ((attr && (DW_UNSND (attr) != 0))
       || cu->language == language_cplus
-      || cu->language == language_java)
-    TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
-
+      || cu->language == language_java
+      || cu->language == language_pascal)
+    TYPE_PROTOTYPED (ftype) = 1;
+
+  /* Store the calling convention in the type if it's available in
+     the subroutine die.  Otherwise set the calling convention to
+     the default value DW_CC_normal.  */
+  attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
+  TYPE_CALLING_CONVENTION (ftype) = attr ? DW_UNSND (attr) : DW_CC_normal;
+  
   if (die->child != NULL)
     {
       struct die_info *child_die;
@@ -4194,14 +4950,14 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
          if (child_die->tag == DW_TAG_formal_parameter)
            nparams++;
          else if (child_die->tag == DW_TAG_unspecified_parameters)
-           TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS;
+           TYPE_VARARGS (ftype) = 1;
          child_die = sibling_die (child_die);
        }
 
       /* Allocate storage for parameters and fill them in.  */
       TYPE_NFIELDS (ftype) = nparams;
       TYPE_FIELDS (ftype) = (struct field *)
-       TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+       TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
 
       child_die = die->child;
       while (child_die && child_die->tag)
@@ -4225,44 +4981,40 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
-  die->type = ftype;
+  return set_die_type (die, ftype, cu);
 }
 
-static void
+static struct type *
 read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct attribute *attr;
-  char *name = NULL;
+  const char *name = NULL;
+  struct type *this_type;
 
-  if (!die->type)
-    {
-      attr = dwarf2_attr (die, DW_AT_name, cu);
-      if (attr && DW_STRING (attr))
-       {
-         name = DW_STRING (attr);
-       }
-      die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
-      TYPE_TARGET_TYPE (die->type) = die_type (die, cu);
-    }
+  name = dwarf2_full_name (die, cu);
+  this_type = init_type (TYPE_CODE_TYPEDEF, 0,
+                        TYPE_FLAG_TARGET_STUB, NULL, objfile);
+  TYPE_NAME (this_type) = (char *) name;
+  set_die_type (die, this_type, cu);
+  TYPE_TARGET_TYPE (this_type) = die_type (die, cu);
+  return this_type;
 }
 
 /* Find a representation of a given base type and install
    it in the TYPE field of the die.  */
 
-static void
+static struct type *
 read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, size = 0;
-
-  /* If we've already decoded this die, this is a no-op. */
-  if (die->type)
-    {
-      return;
-    }
+  char *name;
+  enum type_code code = TYPE_CODE_INT;
+  int type_flags = 0;
+  struct type *target_type = NULL;
 
   attr = dwarf2_attr (die, DW_AT_encoding, cu);
   if (attr)
@@ -4274,97 +5026,97 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       size = DW_UNSND (attr);
     }
-  attr = dwarf2_attr (die, DW_AT_name, cu);
-  if (attr && DW_STRING (attr))
+  name = dwarf2_name (die, cu);
+  if (!name)
     {
-      enum type_code code = TYPE_CODE_INT;
-      int type_flags = 0;
-
-      switch (encoding)
-       {
-       case DW_ATE_address:
-         /* Turn DW_ATE_address into a void * pointer.  */
-         code = TYPE_CODE_PTR;
-         type_flags |= TYPE_FLAG_UNSIGNED;
-         break;
-       case DW_ATE_boolean:
-         code = TYPE_CODE_BOOL;
-         type_flags |= TYPE_FLAG_UNSIGNED;
-         break;
-       case DW_ATE_complex_float:
-         code = TYPE_CODE_COMPLEX;
-         break;
-       case DW_ATE_float:
-         code = TYPE_CODE_FLT;
-         break;
-       case DW_ATE_signed:
-       case DW_ATE_signed_char:
-         break;
-       case DW_ATE_unsigned:
-       case DW_ATE_unsigned_char:
-         type_flags |= TYPE_FLAG_UNSIGNED;
-         break;
-       default:
-         complaint (&symfile_complaints, "unsupported DW_AT_encoding: '%s'",
-                    dwarf_type_encoding_name (encoding));
-         break;
-       }
-      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,
-                                                          cu);
-      else if (encoding == DW_ATE_complex_float)
-       {
-         if (size == 32)
-           TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
-         else if (size == 16)
-           TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
-         else if (size == 8)
-           TYPE_TARGET_TYPE (type)
-             = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
-       }
+      complaint (&symfile_complaints,
+                _("DW_AT_name missing from DW_TAG_base_type"));
     }
-  else
+
+  switch (encoding)
     {
-      type = dwarf_base_type (encoding, size, cu);
+      case DW_ATE_address:
+       /* Turn DW_ATE_address into a void * pointer.  */
+       code = TYPE_CODE_PTR;
+       type_flags |= TYPE_FLAG_UNSIGNED;
+       target_type = init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
+       break;
+      case DW_ATE_boolean:
+       code = TYPE_CODE_BOOL;
+       type_flags |= TYPE_FLAG_UNSIGNED;
+       break;
+      case DW_ATE_complex_float:
+       code = TYPE_CODE_COMPLEX;
+       target_type = init_type (TYPE_CODE_FLT, size / 2, 0, NULL, objfile);
+       break;
+      case DW_ATE_decimal_float:
+       code = TYPE_CODE_DECFLOAT;
+       break;
+      case DW_ATE_float:
+       code = TYPE_CODE_FLT;
+       break;
+      case DW_ATE_signed:
+       break;
+      case DW_ATE_unsigned:
+       type_flags |= TYPE_FLAG_UNSIGNED;
+       break;
+      case DW_ATE_signed_char:
+       if (cu->language == language_ada || cu->language == language_m2)
+         code = TYPE_CODE_CHAR;
+       break;
+      case DW_ATE_unsigned_char:
+       if (cu->language == language_ada || cu->language == language_m2)
+         code = TYPE_CODE_CHAR;
+       type_flags |= TYPE_FLAG_UNSIGNED;
+       break;
+      default:
+       complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
+                  dwarf_type_encoding_name (encoding));
+       break;
     }
-  die->type = type;
+
+  type = init_type (code, size, type_flags, NULL, objfile);
+  TYPE_NAME (type) = name;
+  TYPE_TARGET_TYPE (type) = target_type;
+
+  if (name && strcmp (name, "char") == 0)
+    TYPE_NOSIGN (type) = 1;
+
+  return set_die_type (die, type, cu);
 }
 
 /* Read the given DW_AT_subrange DIE.  */
 
-static void
+static struct type *
 read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
   struct type *base_type;
   struct type *range_type;
   struct attribute *attr;
   int low = 0;
   int high = -1;
+  char *name;
   
-  /* 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)
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
     {
       complaint (&symfile_complaints,
-                "DW_AT_type missing from DW_TAG_subrange_type");
-      return;
+                _("DW_AT_type missing from DW_TAG_subrange_type"));
+      base_type
+       = init_type (TYPE_CODE_INT, gdbarch_addr_bit (gdbarch) / 8,
+                    0, NULL, cu->objfile);
     }
 
-  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;
     }
 
+  /* FIXME: For variable sized arrays either of these could be
+     a variable rather than a constant value.  We'll allow it,
+     but we don't know how to handle it.  */
   attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
     low = dwarf2_get_attr_constant_value (attr, 0);
@@ -4393,26 +5145,64 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   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);
+  name = dwarf2_name (die, cu);
+  if (name)
+    TYPE_NAME (range_type) = name;
   
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     TYPE_LENGTH (range_type) = DW_UNSND (attr);
 
-  die->type = range_type;
+  return set_die_type (die, range_type, cu);
 }
   
+static struct type *
+read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *type;
+
+  /* For now, we only support the C meaning of an unspecified type: void.  */
+
+  type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile);
+  TYPE_NAME (type) = dwarf2_name (die, cu);
+
+  return set_die_type (die, type, cu);
+}
+
+/* Trivial hash function for die_info: the hash value of a DIE
+   is its offset in .debug_info for this objfile.  */
+
+static hashval_t
+die_hash (const void *item)
+{
+  const struct die_info *die = item;
+  return die->offset;
+}
+
+/* Trivial comparison function for die_info structures: two DIEs
+   are equal if they have the same offset.  */
+
+static int
+die_eq (const void *item_lhs, const void *item_rhs)
+{
+  const struct die_info *die_lhs = item_lhs;
+  const struct die_info *die_rhs = item_rhs;
+  return die_lhs->offset == die_rhs->offset;
+}
 
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
-read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
+read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
 {
-  /* Reset die reference table; we are
-     building new ones now.  */
-  dwarf2_empty_hash_tables ();
+  cu->die_hash
+    = htab_create_alloc_ex (cu->header.length / 12,
+                           die_hash,
+                           die_eq,
+                           NULL,
+                           &cu->comp_unit_obstack,
+                           hashtab_obstack_allocate,
+                           dummy_obstack_deallocate);
 
   return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
 }
@@ -4424,17 +5214,22 @@ read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
    is the parent of the die in question.  */
 
 static struct die_info *
-read_die_and_children (char *info_ptr, bfd *abfd,
+read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
                       struct dwarf2_cu *cu,
-                      char **new_info_ptr,
+                      gdb_byte **new_info_ptr,
                       struct die_info *parent)
 {
   struct die_info *die;
-  char *cur_ptr;
+  gdb_byte *cur_ptr;
   int has_children;
 
   cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children);
-  store_in_ref_table (die->offset, die);
+  if (die == NULL)
+    {
+      *new_info_ptr = cur_ptr;
+      return NULL;
+    }
+  store_in_ref_table (die, cu);
 
   if (has_children)
     {
@@ -4457,13 +5252,13 @@ read_die_and_children (char *info_ptr, bfd *abfd,
    in read_die_and_children.  */
 
 static struct die_info *
-read_die_and_siblings (char *info_ptr, bfd *abfd,
+read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
                       struct dwarf2_cu *cu,
-                      char **new_info_ptr,
+                      gdb_byte **new_info_ptr,
                       struct die_info *parent)
 {
   struct die_info *first_die, *last_sibling;
-  char *cur_ptr;
+  gdb_byte *cur_ptr;
 
   cur_ptr = info_ptr;
   first_die = last_sibling = NULL;
@@ -4473,81 +5268,141 @@ read_die_and_siblings (char *info_ptr, bfd *abfd,
       struct die_info *die
        = read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent);
 
-      if (!first_die)
-       {
-         first_die = die;
-       }
-      else
-       {
-         last_sibling->sibling = die;
-       }
-
-      if (die->tag == 0)
+      if (die == NULL)
        {
          *new_info_ptr = cur_ptr;
          return first_die;
        }
-      else
-       {
-         last_sibling = die;
-       }
-    }
-}
-
-/* Free a linked list of dies.  */
 
-static void
-free_die_list (struct die_info *dies)
-{
-  struct die_info *die, *next;
+      if (!first_die)
+       first_die = die;
+      else
+       last_sibling->sibling = die;
 
-  die = dies;
-  while (die)
-    {
-      if (die->child != NULL)
-       free_die_list (die->child);
-      next = die->sibling;
-      xfree (die->attrs);
-      xfree (die);
-      die = next;
+      last_sibling = die;
     }
 }
 
+/* Decompress a section that was compressed using zlib.  Store the
+   decompressed buffer, and its size, in OUTBUF and OUTSIZE.  */
+
 static void
-do_free_die_list_cleanup (void *dies)
+zlib_decompress_section (struct objfile *objfile, asection *sectp,
+                         gdb_byte **outbuf, bfd_size_type *outsize)
 {
-  free_die_list (dies);
-}
+  bfd *abfd = objfile->obfd;
+#ifndef HAVE_ZLIB_H
+  error (_("Support for zlib-compressed DWARF data (from '%s') "
+           "is disabled in this copy of GDB"),
+         bfd_get_filename (abfd));
+#else
+  bfd_size_type compressed_size = bfd_get_section_size (sectp);
+  gdb_byte *compressed_buffer = xmalloc (compressed_size);
+  bfd_size_type uncompressed_size;
+  gdb_byte *uncompressed_buffer;
+  z_stream strm;
+  int rc;
+  int header_size = 12;
 
-static struct cleanup *
-make_cleanup_free_die_list (struct die_info *dies)
-{
-  return make_cleanup (do_free_die_list_cleanup, dies);
+  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+      || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
+    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+           bfd_get_filename (abfd));
+
+  /* Read the zlib header.  In this case, it should be "ZLIB" followed
+     by the uncompressed section size, 8 bytes in big-endian order.  */
+  if (compressed_size < header_size
+      || strncmp (compressed_buffer, "ZLIB", 4) != 0)
+    error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
+           bfd_get_filename (abfd));
+  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+  uncompressed_size += compressed_buffer[11];
+
+  /* It is possible the section consists of several compressed
+     buffers concatenated together, so we uncompress in a loop.  */
+  strm.zalloc = NULL;
+  strm.zfree = NULL;
+  strm.opaque = NULL;
+  strm.avail_in = compressed_size - header_size;
+  strm.next_in = (Bytef*) compressed_buffer + header_size;
+  strm.avail_out = uncompressed_size;
+  uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
+                                       uncompressed_size);
+  rc = inflateInit (&strm);
+  while (strm.avail_in > 0)
+    {
+      if (rc != Z_OK)
+        error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
+               bfd_get_filename (abfd), rc);
+      strm.next_out = ((Bytef*) uncompressed_buffer
+                       + (uncompressed_size - strm.avail_out));
+      rc = inflate (&strm, Z_FINISH);
+      if (rc != Z_STREAM_END)
+        error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
+               bfd_get_filename (abfd), rc);
+      rc = inflateReset (&strm);
+    }
+  rc = inflateEnd (&strm);
+  if (rc != Z_OK
+      || strm.avail_out != 0)
+    error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
+           bfd_get_filename (abfd), rc);
+
+  xfree (compressed_buffer);
+  *outbuf = uncompressed_buffer;
+  *outsize = uncompressed_size;
+#endif
 }
 
 
 /* Read the contents of the section at OFFSET and of size SIZE from the
-   object file specified by OBJFILE into the objfile_obstack and return it.  */
+   object file specified by OBJFILE into the objfile_obstack and return it.
+   If the section is compressed, uncompress it before returning.  */
 
-char *
+gdb_byte *
 dwarf2_read_section (struct objfile *objfile, asection *sectp)
 {
   bfd *abfd = objfile->obfd;
-  char *buf, *retbuf;
+  gdb_byte *buf, *retbuf;
   bfd_size_type size = bfd_get_section_size (sectp);
+  unsigned char header[4];
 
   if (size == 0)
     return NULL;
 
-  buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
-  retbuf
-    = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
+  /* Check if the file has a 4-byte header indicating compression.  */
+  if (size > sizeof (header)
+      && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
+      && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+    {
+      /* Upon decompression, update the buffer and its size.  */
+      if (strncmp (header, "ZLIB", sizeof (header)) == 0)
+        {
+          zlib_decompress_section (objfile, sectp, &buf, &size);
+          dwarf2_resize_section (sectp, size);
+          return buf;
+        }
+    }
+
+  /* If we get here, we are a normal, not-compressed section.  */
+  buf = obstack_alloc (&objfile->objfile_obstack, size);
+  /* When debugging .o files, we may need to apply relocations; see
+     http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
+     We never compress sections in .o files, so we only need to
+     try this when the section is not compressed.  */
+  retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
   if (retbuf != NULL)
     return retbuf;
 
   if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
       || bfd_bread (buf, size, abfd) != size)
-    error ("Dwarf Error: Can't read DWARF data from '%s'",
+    error (_("Dwarf Error: Can't read DWARF data from '%s'"),
           bfd_get_filename (abfd));
 
   return buf;
@@ -4563,7 +5418,7 @@ static void
 dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
 {
   struct comp_unit_head *cu_header = &cu->header;
-  char *abbrev_ptr;
+  gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   unsigned int abbrev_form, hash_number;
@@ -4614,6 +5469,17 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
                = xrealloc (cur_attrs, (allocated_attrs
                                        * sizeof (struct attr_abbrev)));
            }
+
+         /* Record whether this compilation unit might have
+            inter-compilation-unit references.  If we don't know what form
+            this attribute will have, then it might potentially be a
+            DW_FORM_ref_addr, so we conservatively expect inter-CU
+            references.  */
+
+         if (abbrev_form == DW_FORM_ref_addr
+             || abbrev_form == DW_FORM_indirect)
+           cu->has_form_ref_addr = 1;
+
          cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
          cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
          abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
@@ -4703,6 +5569,7 @@ is_type_tag_for_partial (int tag)
 #endif
     case DW_TAG_base_type:
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
     case DW_TAG_enumeration_type:
     case DW_TAG_structure_type:
     case DW_TAG_subrange_type:
@@ -4717,19 +5584,23 @@ is_type_tag_for_partial (int tag)
 /* Load all DIEs that are interesting for partial symbols into memory.  */
 
 static struct partial_die_info *
-load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
+load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
                   struct dwarf2_cu *cu)
 {
   struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   struct abbrev_info *abbrev;
   unsigned int bytes_read;
+  unsigned int load_all = 0;
 
   int nesting_level = 1;
 
   parent_die = NULL;
   last_die = NULL;
 
+  if (cu->per_cu && cu->per_cu->load_all_dies)
+    load_all = 1;
+
   cu->partial_dies
     = htab_create_alloc_ex (cu->header.length / 12,
                            partial_die_hash,
@@ -4765,12 +5636,18 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
          continue;
        }
 
-      /* Check whether this DIE is interesting enough to save.  */
-      if (!is_type_tag_for_partial (abbrev->tag)
+      /* Check whether this DIE is interesting enough to save.  Normally
+        we would not be interested in members here, but there may be
+        later variables referencing them via DW_AT_specification (for
+        static members).  */
+      if (!load_all
+         && !is_type_tag_for_partial (abbrev->tag)
          && abbrev->tag != DW_TAG_enumerator
          && abbrev->tag != DW_TAG_subprogram
+         && abbrev->tag != DW_TAG_lexical_block
          && abbrev->tag != DW_TAG_variable
-         && abbrev->tag != DW_TAG_namespace)
+         && abbrev->tag != DW_TAG_namespace
+         && abbrev->tag != DW_TAG_member)
        {
          /* Otherwise we skip to the next sibling, if any.  */
          info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
@@ -4823,7 +5700,7 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
          && parent_die->has_specification == 0)
        {
          if (part_die->name == NULL)
-           complaint (&symfile_complaints, "malformed enumerator DIE ignored");
+           complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
          else if (building_psymtab)
            add_psymbol_to_list (part_die->name, strlen (part_die->name),
                                 VAR_DOMAIN, LOC_CONST,
@@ -4870,9 +5747,11 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
 
         Adding more things than necessary to the hash table is harmless
         except for the performance cost.  Adding too few will result in
-        internal errors in find_partial_die.  */
+        wasted time in find_partial_die, when we reread the compilation
+        unit with load_all_dies set.  */
 
-      if (abbrev->tag == DW_TAG_subprogram
+      if (load_all
+         || abbrev->tag == DW_TAG_subprogram
          || abbrev->tag == DW_TAG_variable
          || abbrev->tag == DW_TAG_namespace
          || part_die->is_declaration)
@@ -4888,16 +5767,26 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
                                sizeof (struct partial_die_info));
 
       /* For some DIEs we want to follow their children (if any).  For C
-         we have no reason to follow the children of structures; for other
+        we have no reason to follow the children of structures; for other
         languages we have to, both so that we can get at method physnames
-        to infer fully qualified class names, and for DW_AT_specification.  */
+        to infer fully qualified class names, and for DW_AT_specification.
+
+        For Ada, we need to scan the children of subprograms and lexical
+        blocks as well because Ada allows the definition of nested
+        entities that could be interesting for the debugger, such as
+        nested subprograms for instance.  */
       if (last_die->has_children
-         && (last_die->tag == DW_TAG_namespace
+         && (load_all
+             || last_die->tag == DW_TAG_namespace
              || last_die->tag == DW_TAG_enumeration_type
              || (cu->language != language_c
                  && (last_die->tag == DW_TAG_class_type
+                     || last_die->tag == DW_TAG_interface_type
                      || last_die->tag == DW_TAG_structure_type
-                     || last_die->tag == DW_TAG_union_type))))
+                     || last_die->tag == DW_TAG_union_type))
+             || (cu->language == language_ada
+                 && (last_die->tag == DW_TAG_subprogram
+                     || last_die->tag == DW_TAG_lexical_block))))
        {
          nesting_level++;
          parent_die = last_die;
@@ -4913,16 +5802,25 @@ load_partial_dies (bfd *abfd, char *info_ptr, int building_psymtab,
 
 /* Read a minimal amount of information into the minimal die structure.  */
 
-static char *
+static gdb_byte *
 read_partial_die (struct partial_die_info *part_die,
                  struct abbrev_info *abbrev,
                  unsigned int abbrev_len, bfd *abfd,
-                 char *info_ptr, struct dwarf2_cu *cu)
+                 gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   unsigned int bytes_read, i;
   struct attribute attr;
   int has_low_pc_attr = 0;
   int has_high_pc_attr = 0;
+  CORE_ADDR base_address = 0;
+  enum
+    {
+      base_address_none,
+      base_address_low_pc,
+      /* Overrides BASE_ADDRESS_LOW_PC.  */
+      base_address_entry_pc
+    }
+  base_address_type = base_address_none;
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
@@ -4960,18 +5858,39 @@ read_partial_die (struct partial_die_info *part_die,
        case DW_AT_low_pc:
          has_low_pc_attr = 1;
          part_die->lowpc = DW_ADDR (&attr);
+         if (part_die->tag == DW_TAG_compile_unit
+             && base_address_type < base_address_low_pc)
+           {
+             base_address = DW_ADDR (&attr);
+             base_address_type = base_address_low_pc;
+           }
          break;
        case DW_AT_high_pc:
          has_high_pc_attr = 1;
          part_die->highpc = DW_ADDR (&attr);
          break;
+       case DW_AT_entry_pc:
+         if (part_die->tag == DW_TAG_compile_unit
+             && base_address_type < base_address_entry_pc)
+           {
+             base_address = DW_ADDR (&attr);
+             base_address_type = base_address_entry_pc;
+           }
+         break;
+       case DW_AT_ranges:
+         if (part_die->tag == DW_TAG_compile_unit)
+           {
+             cu->ranges_offset = DW_UNSND (&attr);
+             cu->has_ranges_offset = 1;
+           }
+         break;
        case DW_AT_location:
           /* Support the .debug_loc offsets */
           if (attr_form_is_block (&attr))
             {
               part_die->locdesc = DW_BLOCK (&attr);
             }
-          else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8)
+          else if (attr_form_is_section_offset (&attr))
             {
              dwarf2_complex_location_expr_complaint ();
             }
@@ -5003,7 +5922,7 @@ read_partial_die (struct partial_die_info *part_die,
          /* Ignore absolute siblings, they might point outside of
             the current compile unit.  */
          if (attr.form == DW_FORM_ref_addr)
-           complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+           complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
          else
            part_die->sibling = dwarf2_per_objfile->info_buffer
              + dwarf2_get_ref_die_offset (&attr, cu);
@@ -5012,6 +5931,28 @@ read_partial_die (struct partial_die_info *part_die,
           part_die->has_stmt_list = 1;
           part_die->line_offset = DW_UNSND (&attr);
           break;
+        case DW_AT_byte_size:
+          part_die->has_byte_size = 1;
+          break;
+       case DW_AT_calling_convention:
+         /* DWARF doesn't provide a way to identify a program's source-level
+            entry point.  DW_AT_calling_convention attributes are only meant
+            to describe functions' calling conventions.
+
+            However, because it's a necessary piece of information in
+            Fortran, and because DW_CC_program is the only piece of debugging
+            information whose definition refers to a 'main program' at all,
+            several compilers have begun marking Fortran main programs with
+            DW_CC_program --- even when those functions use the standard
+            calling conventions.
+
+            So until DWARF specifies a way to provide this information and
+            compilers pick up the new representation, we'll support this
+            practice.  */
+         if (DW_UNSND (&attr) == DW_CC_program
+             && cu->language == language_fortran)
+           set_main_name (part_die->name);
+         break;
        default:
          break;
        }
@@ -5028,8 +5969,16 @@ read_partial_die (struct partial_die_info *part_die,
   if (has_low_pc_attr && has_high_pc_attr
       && part_die->lowpc < part_die->highpc
       && (part_die->lowpc != 0
-         || (bfd_get_file_flags (abfd) & HAS_RELOC)))
+         || dwarf2_per_objfile->has_section_at_zero))
     part_die->has_pc_info = 1;
+
+  if (base_address_type != base_address_none && !cu->base_known)
+    {
+      gdb_assert (part_die->tag == DW_TAG_compile_unit);
+      cu->base_known = 1;
+      cu->base_address = base_address;
+    }
+
   return info_ptr;
 }
 
@@ -5044,30 +5993,72 @@ find_partial_die_in_comp_unit (unsigned long offset, struct dwarf2_cu *cu)
   part_die.offset = offset;
   lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
 
-  if (lookup_die == NULL)
-    internal_error (__FILE__, __LINE__,
-                   "could not find partial DIE in cache\n");
-
   return lookup_die;
 }
 
 /* Find a partial DIE at OFFSET, which may or may not be in CU.  */
 
 static struct partial_die_info *
-find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
-                 struct dwarf2_cu **target_cu)
+find_partial_die (unsigned long offset, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_cu_data *per_cu;
+  struct dwarf2_per_cu_data *per_cu = NULL;
+  struct partial_die_info *pd = NULL;
+
+  if (offset_in_cu_p (&cu->header, offset))
+    {
+      pd = find_partial_die_in_comp_unit (offset, cu);
+      if (pd != NULL)
+       return pd;
+    }
+
+  per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+  if (per_cu->cu == NULL)
+    {
+      load_comp_unit (per_cu, cu->objfile);
+      per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = per_cu;
+    }
+
+  per_cu->cu->last_used = 0;
+  pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+
+  if (pd == NULL && per_cu->load_all_dies == 0)
+    {
+      struct cleanup *back_to;
+      struct partial_die_info comp_unit_die;
+      struct abbrev_info *abbrev;
+      unsigned int bytes_read;
+      char *info_ptr;
+
+      per_cu->load_all_dies = 1;
+
+      /* Re-read the DIEs.  */
+      back_to = make_cleanup (null_cleanup, 0);
+      if (per_cu->cu->dwarf2_abbrevs == NULL)
+       {
+         dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
+         back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
+       }
+      info_ptr = (dwarf2_per_objfile->info_buffer
+                 + per_cu->cu->header.offset
+                 + per_cu->cu->header.first_die_offset);
+      abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
+      info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
+                                  per_cu->cu->objfile->obfd, info_ptr,
+                                  per_cu->cu);
+      if (comp_unit_die.has_children)
+       load_partial_dies (per_cu->cu->objfile->obfd, info_ptr, 0, per_cu->cu);
+      do_cleanups (back_to);
 
-  if (offset >= cu->header.offset
-      && offset < cu->header.offset + cu->header.length)
-    {
-      *target_cu = cu;
-      return find_partial_die_in_comp_unit (offset, cu);
+      pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
     }
 
-  internal_error (__FILE__, __LINE__,
-                 "unsupported inter-compilation-unit reference");
+  if (pd == NULL)
+    internal_error (__FILE__, __LINE__,
+                   _("could not find partial DIE 0x%lx in cache [from module %s]\n"),
+                   offset, bfd_get_filename (cu->objfile->obfd));
+  return pd;
 }
 
 /* Adjust PART_DIE before generating a symbol for it.  This function
@@ -5083,11 +6074,10 @@ fixup_partial_die (struct partial_die_info *part_die,
   if (part_die->name == NULL && part_die->has_specification)
     {
       struct partial_die_info *spec_die;
-      struct dwarf2_cu *spec_cu;
 
-      spec_die = find_partial_die (part_die->spec_offset, cu, &spec_cu);
+      spec_die = find_partial_die (part_die->spec_offset, cu);
 
-      fixup_partial_die (spec_die, spec_cu);
+      fixup_partial_die (spec_die, cu);
 
       if (spec_die->name)
        {
@@ -5118,8 +6108,8 @@ fixup_partial_die (struct partial_die_info *part_die,
    child, sibling, and parent fields.  Set HAS_CHILDREN to tell
    whether the die has children or not.  */
 
-static char *
-read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
+static gdb_byte *
+read_full_die (struct die_info **diep, bfd *abfd, gdb_byte *info_ptr,
               struct dwarf2_cu *cu, int *has_children)
 {
   unsigned int abbrev_number, bytes_read, i, offset;
@@ -5131,11 +6121,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   info_ptr += bytes_read;
   if (!abbrev_number)
     {
-      die = dwarf_alloc_die ();
-      die->tag = 0;
-      die->abbrev = abbrev_number;
-      die->type = NULL;
-      *diep = die;
+      *diep = NULL;
       *has_children = 0;
       return info_ptr;
     }
@@ -5143,25 +6129,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
   if (!abbrev)
     {
-      error ("Dwarf Error: could not find abbrev number %d [in module %s]",
+      error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
             abbrev_number,
             bfd_get_filename (abfd));
     }
-  die = dwarf_alloc_die ();
+  die = dwarf_alloc_die (cu, abbrev->num_attrs);
   die->offset = offset;
   die->tag = abbrev->tag;
   die->abbrev = abbrev_number;
-  die->type = NULL;
 
   die->num_attrs = abbrev->num_attrs;
-  die->attrs = (struct attribute *)
-    xmalloc (die->num_attrs * sizeof (struct attribute));
 
   for (i = 0; i < abbrev->num_attrs; ++i)
-    {
-      info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
-                                abfd, info_ptr, cu);
-    }
+    info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+                              abfd, info_ptr, cu);
 
   *diep = die;
   *has_children = abbrev->has_children;
@@ -5170,9 +6151,9 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
 
 /* Read an attribute value described by an attribute form.  */
 
-static char *
+static gdb_byte *
 read_attribute_value (struct attribute *attr, unsigned form,
-                     bfd *abfd, char *info_ptr,
+                     bfd *abfd, gdb_byte *info_ptr,
                      struct dwarf2_cu *cu)
 {
   struct comp_unit_head *cu_header = &cu->header;
@@ -5257,23 +6238,24 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
-      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
       info_ptr += 1;
       break;
     case DW_FORM_ref2:
-      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
       info_ptr += 2;
       break;
     case DW_FORM_ref4:
-      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
       info_ptr += 4;
       break;
     case DW_FORM_ref8:
-      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
-      DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      DW_ADDR (attr) = (cu->header.offset
+                       + read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
       info_ptr += bytes_read;
       break;
     case DW_FORM_indirect:
@@ -5282,18 +6264,36 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu);
       break;
     default:
-      error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+      error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
             dwarf_form_name (form),
             bfd_get_filename (abfd));
     }
+
+  /* We have seen instances where the compiler tried to emit a byte
+     size attribute of -1 which ended up being encoded as an unsigned
+     0xffffffff.  Although 0xffffffff is technically a valid size value,
+     an object of this size seems pretty unlikely so we can relatively
+     safely treat these cases as if the size attribute was invalid and
+     treat them as zero by default.  */
+  if (attr->name == DW_AT_byte_size
+      && form == DW_FORM_data4
+      && DW_UNSND (attr) >= 0xffffffff)
+    {
+      complaint
+        (&symfile_complaints,
+         _("Suspicious DW_AT_byte_size value treated as zero instead of 0x%lx"),
+         DW_UNSND (attr));
+      DW_UNSND (attr) = 0;
+    }
+
   return info_ptr;
 }
 
 /* Read an attribute described by an abbreviated attribute.  */
 
-static char *
+static gdb_byte *
 read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
-               bfd *abfd, char *info_ptr, struct dwarf2_cu *cu)
+               bfd *abfd, gdb_byte *info_ptr, struct dwarf2_cu *cu)
 {
   attr->name = abbrev->name;
   return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu);
@@ -5302,49 +6302,50 @@ read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
 /* read dwarf information from a buffer */
 
 static unsigned int
-read_1_byte (bfd *abfd, char *buf)
+read_1_byte (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_8 (abfd, (bfd_byte *) buf);
+  return bfd_get_8 (abfd, buf);
 }
 
 static int
-read_1_signed_byte (bfd *abfd, char *buf)
+read_1_signed_byte (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_8 (abfd, buf);
 }
 
 static unsigned int
-read_2_bytes (bfd *abfd, char *buf)
+read_2_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_16 (abfd, (bfd_byte *) buf);
+  return bfd_get_16 (abfd, buf);
 }
 
 static int
-read_2_signed_bytes (bfd *abfd, char *buf)
+read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_16 (abfd, buf);
 }
 
 static unsigned int
-read_4_bytes (bfd *abfd, char *buf)
+read_4_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_32 (abfd, (bfd_byte *) buf);
+  return bfd_get_32 (abfd, buf);
 }
 
 static int
-read_4_signed_bytes (bfd *abfd, char *buf)
+read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+  return bfd_get_signed_32 (abfd, buf);
 }
 
 static unsigned long
-read_8_bytes (bfd *abfd, char *buf)
+read_8_bytes (bfd *abfd, gdb_byte *buf)
 {
-  return bfd_get_64 (abfd, (bfd_byte *) buf);
+  return bfd_get_64 (abfd, buf);
 }
 
 static CORE_ADDR
-read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
+read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu,
+             unsigned int *bytes_read)
 {
   struct comp_unit_head *cu_header = &cu->header;
   CORE_ADDR retval = 0;
@@ -5354,17 +6355,17 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
       switch (cu_header->addr_size)
        {
        case 2:
-         retval = bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_16 (abfd, buf);
          break;
        case 4:
-         retval = bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_32 (abfd, buf);
          break;
        case 8:
-         retval = bfd_get_signed_64 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_signed_64 (abfd, buf);
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, signed [in module %s]",
+                         _("read_address: bad switch, signed [in module %s]"),
                          bfd_get_filename (abfd));
        }
     }
@@ -5373,17 +6374,17 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
       switch (cu_header->addr_size)
        {
        case 2:
-         retval = bfd_get_16 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_16 (abfd, buf);
          break;
        case 4:
-         retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_32 (abfd, buf);
          break;
        case 8:
-         retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+         retval = bfd_get_64 (abfd, buf);
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, unsigned [in module %s]",
+                         _("read_address: bad switch, unsigned [in module %s]"),
                          bfd_get_filename (abfd));
        }
     }
@@ -5406,18 +6407,18 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
    sense for the 32-bit format, this initial zero can be considered to
    be an escape value which indicates the presence of the older 64-bit
    format.  As written, the code can't detect (old format) lengths
-   greater than 4GB.  If it becomes necessary to handle lengths somewhat
-   larger than 4GB, we could allow other small values (such as the
-   non-sensical values of 1, 2, and 3) to also be used as escape values
-   indicating the presence of the old format.
+   greater than 4GB.  If it becomes necessary to handle lengths
+   somewhat larger than 4GB, we could allow other small values (such
+   as the non-sensical values of 1, 2, and 3) to also be used as
+   escape values indicating the presence of the old format.
 
-   The value returned via bytes_read should be used to increment
-   the relevant pointer after calling read_initial_length().
+   The value returned via bytes_read should be used to increment the
+   relevant pointer after calling read_initial_length().
    
    As a side effect, this function sets the fields initial_length_size
    and offset_size in cu_header to the values appropriate for the
    length field.  (The format of the initial length field determines
-   the width of file offsets to be fetched later with fetch_offset().)
+   the width of file offsets to be fetched later with read_offset().)
    
    [ Note:  read_initial_length() and read_offset() are based on the
      document entitled "DWARF Debugging Information Format", revision
@@ -5429,85 +6430,83 @@ read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read)
      This document is only a draft and is subject to change.  (So beware.)
 
      Details regarding the older, non-standard 64-bit format were
-     determined empirically by examining 64-bit ELF files produced
-     by the SGI toolchain on an IRIX 6.5 machine.
+     determined empirically by examining 64-bit ELF files produced by
+     the SGI toolchain on an IRIX 6.5 machine.
 
      - Kevin, July 16, 2002
    ] */
 
 static LONGEST
-read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header,
-                     int *bytes_read)
+read_initial_length (bfd *abfd, gdb_byte *buf, struct comp_unit_head *cu_header,
+                     unsigned int *bytes_read)
 {
-  LONGEST retval = 0;
+  LONGEST length = bfd_get_32 (abfd, buf);
 
-  retval = bfd_get_32 (abfd, (bfd_byte *) buf);
-
-  if (retval == 0xffffffff)
+  if (length == 0xffffffff)
     {
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4);
+      length = bfd_get_64 (abfd, buf + 4);
       *bytes_read = 12;
-      if (cu_header != NULL)
-       {
-         cu_header->initial_length_size = 12;
-         cu_header->offset_size = 8;
-       }
     }
-  else if (retval == 0)
+  else if (length == 0)
     {
-      /* Handle (non-standard) 64-bit DWARF2 formats such as that used
-         by IRIX.  */
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */
+      length = bfd_get_64 (abfd, buf);
       *bytes_read = 8;
-      if (cu_header != NULL)
-       {
-         cu_header->initial_length_size = 8;
-         cu_header->offset_size = 8;
-       }
     }
   else
     {
       *bytes_read = 4;
-      if (cu_header != NULL)
-       {
-         cu_header->initial_length_size = 4;
-         cu_header->offset_size = 4;
-       }
     }
 
- return retval;
+  if (cu_header)
+    {
+      gdb_assert (cu_header->initial_length_size == 0
+                 || cu_header->initial_length_size == 4
+                 || cu_header->initial_length_size == 8
+                 || cu_header->initial_length_size == 12);
+
+      if (cu_header->initial_length_size != 0
+         && cu_header->initial_length_size != *bytes_read)
+       complaint (&symfile_complaints,
+                  _("intermixed 32-bit and 64-bit DWARF sections"));
+
+      cu_header->initial_length_size = *bytes_read;
+      cu_header->offset_size = (*bytes_read == 4) ? 4 : 8;
+    }
+
+  return length;
 }
 
 /* Read an offset from the data stream.  The size of the offset is
-   given by cu_header->offset_size. */
+   given by cu_header->offset_size.  */
 
 static LONGEST
-read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
-             int *bytes_read)
+read_offset (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header,
+             unsigned int *bytes_read)
 {
   LONGEST retval = 0;
 
   switch (cu_header->offset_size)
     {
     case 4:
-      retval = bfd_get_32 (abfd, (bfd_byte *) buf);
+      retval = bfd_get_32 (abfd, buf);
       *bytes_read = 4;
       break;
     case 8:
-      retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      retval = bfd_get_64 (abfd, buf);
       *bytes_read = 8;
       break;
     default:
       internal_error (__FILE__, __LINE__,
-                     "read_offset: bad switch [in module %s]",
+                     _("read_offset: bad switch [in module %s]"),
                      bfd_get_filename (abfd));
     }
 
- return retval;
 return retval;
 }
 
-static char *
-read_n_bytes (bfd *abfd, char *buf, unsigned int size)
+static gdb_byte *
+read_n_bytes (bfd *abfd, gdb_byte *buf, unsigned int size)
 {
   /* If the size of a host char is 8 bits, we can return a pointer
      to the buffer, otherwise we have to copy the data to a buffer
@@ -5517,7 +6516,7 @@ read_n_bytes (bfd *abfd, char *buf, unsigned int size)
 }
 
 static char *
-read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   /* If the size of a host char is 8 bits, we can return a pointer
      to the string, otherwise we have to copy the string to a buffer
@@ -5528,38 +6527,38 @@ read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
       *bytes_read_ptr = 1;
       return NULL;
     }
-  *bytes_read_ptr = strlen (buf) + 1;
-  return buf;
+  *bytes_read_ptr = strlen ((char *) buf) + 1;
+  return (char *) buf;
 }
 
 static char *
-read_indirect_string (bfd *abfd, char *buf,
+read_indirect_string (bfd *abfd, gdb_byte *buf,
                      const struct comp_unit_head *cu_header,
                      unsigned int *bytes_read_ptr)
 {
   LONGEST str_offset = read_offset (abfd, buf, cu_header,
-                                   (int *) bytes_read_ptr);
+                                   bytes_read_ptr);
 
   if (dwarf2_per_objfile->str_buffer == NULL)
     {
-      error ("DW_FORM_strp used without .debug_str section [in module %s]",
+      error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
                      bfd_get_filename (abfd));
       return NULL;
     }
   if (str_offset >= dwarf2_per_objfile->str_size)
     {
-      error ("DW_FORM_strp pointing outside of .debug_str section [in module %s]",
+      error (_("DW_FORM_strp pointing outside of .debug_str section [in module %s]"),
                      bfd_get_filename (abfd));
       return NULL;
     }
   gdb_assert (HOST_CHAR_BIT == 8);
   if (dwarf2_per_objfile->str_buffer[str_offset] == '\0')
     return NULL;
-  return dwarf2_per_objfile->str_buffer + str_offset;
+  return (char *) (dwarf2_per_objfile->str_buffer + str_offset);
 }
 
 static unsigned long
-read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   unsigned long result;
   unsigned int num_read;
@@ -5572,7 +6571,7 @@ read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       num_read++;
       result |= ((unsigned long)(byte & 127) << shift);
@@ -5587,20 +6586,19 @@ read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
 }
 
 static long
-read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
+read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
   long result;
-  int i, shift, size, num_read;
+  int i, shift, num_read;
   unsigned char byte;
 
   result = 0;
   shift = 0;
-  size = 32;
   num_read = 0;
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       num_read++;
       result |= ((long)(byte & 127) << shift);
@@ -5610,24 +6608,22 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
          break;
        }
     }
-  if ((shift < size) && (byte & 0x40))
-    {
-      result |= -(1 << shift);
-    }
+  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
+    result |= -(((long)1) << shift);
   *bytes_read_ptr = num_read;
   return result;
 }
 
 /* Return a pointer to just past the end of an LEB128 number in BUF.  */
 
-static char *
-skip_leb128 (bfd *abfd, char *buf)
+static gdb_byte *
+skip_leb128 (bfd *abfd, gdb_byte *buf)
 {
   int byte;
 
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      byte = bfd_get_8 (abfd, buf);
       buf++;
       if ((byte & 128) == 0)
        return buf;
@@ -5659,10 +6655,19 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Ada95:
+      cu->language = language_ada;
+      break;
+    case DW_LANG_Modula2:
+      cu->language = language_m2;
+      break;
+    case DW_LANG_Pascal83:
+      cu->language = language_pascal;
+      break;
+    case DW_LANG_ObjC:
+      cu->language = language_objc;
+      break;
     case DW_LANG_Cobol74:
     case DW_LANG_Cobol85:
-    case DW_LANG_Pascal83:
-    case DW_LANG_Modula2:
     default:
       cu->language = language_minimal;
       break;
@@ -5681,20 +6686,16 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
   for (i = 0; i < die->num_attrs; ++i)
     {
       if (die->attrs[i].name == name)
-       {
-         return &die->attrs[i];
-       }
+       return &die->attrs[i];
       if (die->attrs[i].name == DW_AT_specification
          || die->attrs[i].name == DW_AT_abstract_origin)
        spec = &die->attrs[i];
     }
+
   if (spec)
     {
-      struct die_info *ref_die =
-      follow_die_ref (dwarf2_get_ref_die_offset (spec, cu));
-
-      if (ref_die)
-       return dwarf2_attr (ref_die, name, cu);
+      die = follow_die_ref (die, spec, &cu);
+      return dwarf2_attr (die, name, cu);
     }
 
   return NULL;
@@ -5727,17 +6728,19 @@ die_is_declaration (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 /* Return the die giving the specification for DIE, if there is
-   one.  */
+   one.  *SPEC_CU is the CU containing DIE on input, and the CU
+   containing the return value on output.  */
 
 static struct die_info *
-die_specification (struct die_info *die, struct dwarf2_cu *cu)
+die_specification (struct die_info *die, struct dwarf2_cu **spec_cu)
 {
-  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
+  struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification,
+                                            *spec_cu);
 
   if (spec_attr == NULL)
     return NULL;
   else
-    return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
+    return follow_die_ref (die, spec_attr, spec_cu);
 }
 
 /* Free the line_header structure *LH, and any arrays and strings it
@@ -5815,6 +6818,7 @@ add_file_name (struct line_header *lh,
   fe->mod_time = mod_time;
   fe->length = length;
   fe->included_p = 0;
+  fe->symtab = NULL;
 }
  
 
@@ -5831,19 +6835,19 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
 {
   struct cleanup *back_to;
   struct line_header *lh;
-  char *line_ptr;
-  int bytes_read;
+  gdb_byte *line_ptr;
+  unsigned int bytes_read;
   int i;
   char *cur_dir, *cur_file;
 
   if (dwarf2_per_objfile->line_buffer == NULL)
     {
-      complaint (&symfile_complaints, "missing .debug_line section");
+      complaint (&symfile_complaints, _("missing .debug_line section"));
       return 0;
     }
 
-  /* Make sure that at least there's room for the total_length field.  That
-     could be 12 bytes long, but we're just going to fudge that.  */
+  /* Make sure that at least there's room for the total_length field.
+     That could be 12 bytes long, but we're just going to fudge that.  */
   if (offset + 4 >= dwarf2_per_objfile->line_size)
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
@@ -5857,8 +6861,9 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
 
   line_ptr = dwarf2_per_objfile->line_buffer + offset;
 
-  /* read in the header */
-  lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
+  /* Read in the header.  */
+  lh->total_length = 
+    read_initial_length (abfd, line_ptr, &cu->header, &bytes_read);
   line_ptr += bytes_read;
   if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer
                                     + dwarf2_per_objfile->line_size))
@@ -5882,7 +6887,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
   lh->opcode_base = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
   lh->standard_opcode_lengths
-    = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
+    = xmalloc (lh->opcode_base * sizeof (lh->standard_opcode_lengths[0]));
 
   lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
   for (i = 1; i < lh->opcode_base; ++i)
@@ -5891,7 +6896,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
       line_ptr += 1;
     }
 
-  /* Read directory table  */
+  /* Read directory table.  */
   while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
       line_ptr += bytes_read;
@@ -5899,7 +6904,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
     }
   line_ptr += bytes_read;
 
-  /* Read file name table */
+  /* Read file name table */
   while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
       unsigned int dir_index, mod_time, length;
@@ -5920,7 +6925,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
   if (line_ptr > (dwarf2_per_objfile->line_buffer
                  + dwarf2_per_objfile->line_size))
     complaint (&symfile_complaints,
-              "line number info header doesn't fit in `.debug_line' section");
+              _("line number info header doesn't fit in `.debug_line' section"));
 
   discard_cleanups (back_to);
   return lh;
@@ -5966,7 +6971,7 @@ check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
     return address;
   if (address != fn->lowpc)
     complaint (&symfile_complaints,
-              "misplaced first line number at 0x%lx for '%s'",
+              _("misplaced first line number at 0x%lx for '%s'"),
               (unsigned long) address, fn->name);
   fn->seen_line = 1;
   return fn->lowpc;
@@ -5994,13 +6999,14 @@ static void
 dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                    struct dwarf2_cu *cu, struct partial_symtab *pst)
 {
-  char *line_ptr;
-  char *line_end;
-  unsigned int bytes_read;
+  gdb_byte *line_ptr, *extended_end;
+  gdb_byte *line_end;
+  unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op, adj_opcode;
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->objfile;
   const int decode_for_pst_p = (pst != NULL);
+  struct subfile *last_subfile = NULL, *first_subfile = current_subfile;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -6026,49 +7032,68 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
             directory and file name numbers in the statement program
             are 1-based.  */
           struct file_entry *fe = &lh->file_names[file - 1];
-          char *dir;
+          char *dir = NULL;
+
           if (fe->dir_index)
             dir = lh->include_dirs[fe->dir_index - 1];
-          else
-            dir = comp_dir;
-         dwarf2_start_subfile (fe->name, dir);
+
+         dwarf2_start_subfile (fe->name, dir, comp_dir);
        }
 
-      /* Decode the table. */
+      /* Decode the table.  */
       while (!end_sequence)
        {
          op_code = read_1_byte (abfd, line_ptr);
          line_ptr += 1;
 
          if (op_code >= lh->opcode_base)
-           {           /* Special operand.  */
+           {           
+             /* Special operand.  */
              adj_opcode = op_code - lh->opcode_base;
              address += (adj_opcode / lh->line_range)
                * lh->minimum_instruction_length;
              line += lh->line_base + (adj_opcode % lh->line_range);
-              lh->file_names[file - 1].included_p = 1;
-              if (!decode_for_pst_p)
-                {
-                 /* append row to matrix using current values */
-                 record_line (current_subfile, line, 
-                              check_cu_functions (address, cu));
-                }
+             if (lh->num_file_names < file)
+               dwarf2_debug_line_missing_file_complaint ();
+             else
+               {
+                 lh->file_names[file - 1].included_p = 1;
+                 if (!decode_for_pst_p)
+                    {
+                      if (last_subfile != current_subfile)
+                        {
+                          if (last_subfile)
+                            record_line (last_subfile, 0, address);
+                          last_subfile = current_subfile;
+                        }
+                     /* Append row to matrix using current values.  */
+                     record_line (current_subfile, line, 
+                                  check_cu_functions (address, cu));
+                   }
+               }
              basic_block = 1;
            }
          else switch (op_code)
            {
            case DW_LNS_extended_op:
-             read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+             extended_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
              line_ptr += bytes_read;
+             extended_end = line_ptr + extended_len;
              extended_op = read_1_byte (abfd, line_ptr);
              line_ptr += 1;
              switch (extended_op)
                {
                case DW_LNE_end_sequence:
                  end_sequence = 1;
-                  lh->file_names[file - 1].included_p = 1;
-                  if (!decode_for_pst_p)
-                   record_line (current_subfile, 0, address);
+
+                 if (lh->num_file_names < file)
+                   dwarf2_debug_line_missing_file_complaint ();
+                 else
+                   {
+                     lh->file_names[file - 1].included_p = 1;
+                     if (!decode_for_pst_p)
+                       record_line (current_subfile, 0, address);
+                   }
                  break;
                case DW_LNE_set_address:
                  address = read_address (abfd, line_ptr, cu, &bytes_read);
@@ -6096,15 +7121,37 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                  break;
                default:
                  complaint (&symfile_complaints,
-                            "mangled .debug_line section");
+                            _("mangled .debug_line section"));
+                 return;
+               }
+             /* Make sure that we parsed the extended op correctly.  If e.g.
+                we expected a different address size than the producer used,
+                we may have read the wrong number of bytes.  */
+             if (line_ptr != extended_end)
+               {
+                 complaint (&symfile_complaints,
+                            _("mangled .debug_line section"));
                  return;
                }
              break;
            case DW_LNS_copy:
-              lh->file_names[file - 1].included_p = 1;
-              if (!decode_for_pst_p)
-               record_line (current_subfile, line, 
-                            check_cu_functions (address, cu));
+             if (lh->num_file_names < file)
+               dwarf2_debug_line_missing_file_complaint ();
+             else
+               {
+                 lh->file_names[file - 1].included_p = 1;
+                 if (!decode_for_pst_p)
+                    {
+                      if (last_subfile != current_subfile)
+                        {
+                          if (last_subfile)
+                            record_line (last_subfile, 0, address);
+                          last_subfile = current_subfile;
+                        }
+                      record_line (current_subfile, line, 
+                                   check_cu_functions (address, cu));
+                    }
+               }
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -6118,20 +7165,27 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              break;
            case DW_LNS_set_file:
               {
-                /* lh->include_dirs and lh->file_names are 0-based,
-                   but the directory and file name numbers in the
-                   statement program are 1-based.  */
+                /* The arrays lh->include_dirs and lh->file_names are
+                   0-based, but the directory and file name numbers in
+                   the statement program are 1-based.  */
                 struct file_entry *fe;
-                char *dir;
+                char *dir = NULL;
+
                 file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                 line_ptr += bytes_read;
-                fe = &lh->file_names[file - 1];
-                if (fe->dir_index)
-                  dir = lh->include_dirs[fe->dir_index - 1];
+                if (lh->num_file_names < file)
+                  dwarf2_debug_line_missing_file_complaint ();
                 else
-                  dir = comp_dir;
-                if (!decode_for_pst_p)
-                  dwarf2_start_subfile (fe->name, dir);
+                  {
+                    fe = &lh->file_names[file - 1];
+                    if (fe->dir_index)
+                      dir = lh->include_dirs[fe->dir_index - 1];
+                    if (!decode_for_pst_p)
+                      {
+                        last_subfile = current_subfile;
+                        dwarf2_start_subfile (fe->name, dir, comp_dir);
+                      }
+                  }
               }
              break;
            case DW_LNS_set_column:
@@ -6146,9 +7200,9 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              break;
            /* Add to the address register of the state machine the
               address increment value corresponding to special opcode
-              255.  Ie, this value is scaled by the minimum instruction
-              length since special opcode 255 would have scaled the
-              the increment.  */
+              255.  I.e., this value is scaled by the minimum
+              instruction length since special opcode 255 would have
+              scaled the the increment.  */
            case DW_LNS_const_add_pc:
              address += (lh->minimum_instruction_length
                          * ((255 - lh->opcode_base) / lh->line_range));
@@ -6158,8 +7212,10 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
              line_ptr += 2;
              break;
            default:
-             {  /* Unknown standard opcode, ignore it.  */
+             {
+               /* Unknown standard opcode, ignore it.  */
                int i;
+
                for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
                  {
                    (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
@@ -6179,17 +7235,67 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
       for (file_index = 0; file_index < lh->num_file_names; file_index++)
         if (lh->file_names[file_index].included_p == 1)
           {
-            char *include_name = lh->file_names [file_index].name;
-    
-            if (strcmp (include_name, pst->filename) != 0)
+            const struct file_entry fe = lh->file_names [file_index];
+            char *include_name = fe.name;
+            char *dir_name = NULL;
+            char *pst_filename = pst->filename;
+
+            if (fe.dir_index)
+              dir_name = lh->include_dirs[fe.dir_index - 1];
+
+            if (!IS_ABSOLUTE_PATH (include_name) && dir_name != NULL)
+              {
+                include_name = concat (dir_name, SLASH_STRING,
+                                      include_name, (char *)NULL);
+                make_cleanup (xfree, include_name);
+              }
+
+            if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+              {
+                pst_filename = concat (pst->dirname, SLASH_STRING,
+                                      pst_filename, (char *)NULL);
+                make_cleanup (xfree, pst_filename);
+              }
+
+            if (strcmp (include_name, pst_filename) != 0)
               dwarf2_create_include_psymtab (include_name, pst, objfile);
           }
     }
+  else
+    {
+      /* Make sure a symtab is created for every file, even files
+        which contain only variables (i.e. no code with associated
+        line numbers).  */
+
+      int i;
+      struct file_entry *fe;
+
+      for (i = 0; i < lh->num_file_names; i++)
+       {
+         char *dir = NULL;
+         fe = &lh->file_names[i];
+         if (fe->dir_index)
+           dir = lh->include_dirs[fe->dir_index - 1];
+         dwarf2_start_subfile (fe->name, dir, comp_dir);
+
+         /* Skip the main file; we don't need it, and it must be
+            allocated last, so that it will show up before the
+            non-primary symtabs in the objfile's symtab list.  */
+         if (current_subfile == first_subfile)
+           continue;
+
+         if (current_subfile->symtab == NULL)
+           current_subfile->symtab = allocate_symtab (current_subfile->name,
+                                                      cu->objfile);
+         fe->symtab = current_subfile->symtab;
+       }
+    }
 }
 
 /* Start a subfile for DWARF.  FILENAME is the name of the file and
    DIRNAME the name of the source directory which contains FILENAME
-   or NULL if not known.
+   or NULL if not known.  COMP_DIR is the compilation directory for the
+   linetable's compilation unit or NULL if not known.
    This routine tries to keep line numbers from identical absolute and
    relative file names in a common subfile.
 
@@ -6205,31 +7311,35 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
    files.files[1].dir:  /srcdir
 
    The line number information for list0.c has to end up in a single
-   subfile, so that `break /srcdir/list0.c:1' works as expected.  */
+   subfile, so that `break /srcdir/list0.c:1' works as expected.
+   start_subfile will ensure that this happens provided that we pass the
+   concatenation of files.files[1].dir and files.files[1].name as the
+   subfile's name.  */
 
 static void
-dwarf2_start_subfile (char *filename, char *dirname)
+dwarf2_start_subfile (char *filename, char *dirname, char *comp_dir)
 {
-  /* If the filename isn't absolute, try to match an existing subfile
-     with the full pathname.  */
+  char *fullname;
+
+  /* While reading the DIEs, we call start_symtab(DW_AT_name, DW_AT_comp_dir).
+     `start_symtab' will always pass the contents of DW_AT_comp_dir as
+     second argument to start_subfile.  To be consistent, we do the
+     same here.  In order not to lose the line information directory,
+     we concatenate it to the filename when it makes sense.
+     Note that the Dwarf3 standard says (speaking of filenames in line
+     information): ``The directory index is ignored for file names
+     that represent full path names''.  Thus ignoring dirname in the
+     `else' branch below isn't an issue.  */
 
   if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
-    {
-      struct subfile *subfile;
-      char *fullname = concat (dirname, "/", filename, NULL);
+    fullname = concat (dirname, SLASH_STRING, filename, (char *)NULL);
+  else
+    fullname = filename;
 
-      for (subfile = subfiles; subfile; subfile = subfile->next)
-       {
-         if (FILENAME_CMP (subfile->name, fullname) == 0)
-           {
-             current_subfile = subfile;
-             xfree (fullname);
-             return;
-           }
-       }
-      xfree (fullname);
-    }
-  start_subfile (filename, dirname);
+  start_subfile (fullname, comp_dir);
+
+  if (fullname != filename)
+    xfree (fullname);
 }
 
 static void
@@ -6266,14 +7376,14 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
       && DW_BLOCK (attr)->size == 1 + cu_header->addr_size
       && DW_BLOCK (attr)->data[0] == DW_OP_addr)
     {
-      int dummy;
+      unsigned int dummy;
 
       SYMBOL_VALUE_ADDRESS (sym) =
        read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+      SYMBOL_CLASS (sym) = LOC_STATIC;
       fixup_symbol_section (sym, objfile);
       SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
                                              SYMBOL_SECTION (sym));
-      SYMBOL_CLASS (sym) = LOC_STATIC;
       return;
     }
 
@@ -6298,6 +7408,7 @@ static struct symbol *
 new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol *sym = NULL;
   char *name;
   struct attribute *attr = NULL;
@@ -6325,7 +7436,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
       if (type != NULL)
        SYMBOL_TYPE (sym) = type;
       else
@@ -6335,6 +7446,23 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
        }
+
+      attr = dwarf2_attr (die, DW_AT_decl_file, cu);
+      if (attr)
+       {
+         int file_index = DW_UNSND (attr);
+         if (cu->line_header == NULL
+             || file_index > cu->line_header->num_file_names)
+           complaint (&symfile_complaints,
+                      _("file index out of range"));
+         else if (file_index > 0)
+           {
+             struct file_entry *fe;
+             fe = &cu->line_header->file_names[file_index - 1];
+             SYMBOL_SYMTAB (sym) = fe->symtab;
+           }
+       }
+
       switch (die->tag)
        {
        case DW_TAG_label:
@@ -6350,8 +7478,15 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
          attr2 = dwarf2_attr (die, DW_AT_external, cu);
-         if (attr2 && (DW_UNSND (attr2) != 0))
+         if ((attr2 && (DW_UNSND (attr2) != 0))
+              || cu->language == language_ada)
            {
+              /* Subprograms marked external are stored as a global symbol.
+                 Ada subprograms, whether marked external or not, are always
+                 stored as a global symbol, because we want to be able to
+                 access them globally.  For instance, we want to be able
+                 to break on a nested subprogram without having to
+                 specify the context.  */
              add_symbol_to_list (sym, &global_symbols);
            }
          else
@@ -6364,10 +7499,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             with missing type entries. Change the misleading `void' type
             to something sensible.  */
          if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
-           SYMBOL_TYPE (sym) = init_type (TYPE_CODE_INT,
-                                          TARGET_INT_BIT / HOST_CHAR_BIT, 0,
-                                          "<variable, no debug info>",
-                                          objfile);
+           SYMBOL_TYPE (sym)
+             = builtin_type (gdbarch)->nodebug_data_symbol;
+
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
@@ -6407,13 +7541,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
            }
          break;
        case DW_TAG_formal_parameter:
+         SYMBOL_IS_ARGUMENT (sym) = 1;
          attr = dwarf2_attr (die, DW_AT_location, cu);
          if (attr)
            {
              var_decode_location (attr, sym, cu);
-             /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary?  */
-             if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
-               SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
            }
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
@@ -6428,8 +7560,10 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             (FIXME?) */
          break;
        case DW_TAG_class_type:
+       case DW_TAG_interface_type:
        case DW_TAG_structure_type:
        case DW_TAG_union_type:
+       case DW_TAG_set_type:
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
@@ -6476,33 +7610,21 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
            /* The semantics of C++ state that "struct foo { ... }" also
               defines a typedef for "foo".  A Java class declaration also
-              defines a typedef for the class.  Synthesize a typedef symbol
-              so that "ptype foo" works as expected.  */
+              defines a typedef for the class.  */
            if (cu->language == language_cplus
-               || cu->language == language_java)
+               || cu->language == language_java
+               || cu->language == language_ada)
              {
-               struct symbol *typedef_sym = (struct symbol *)
-                 obstack_alloc (&objfile->objfile_obstack,
-                                sizeof (struct symbol));
-               *typedef_sym = *sym;
-               SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
                /* The symbol's name is already allocated along with
                   this objfile, so we don't need to duplicate it for
                   the type.  */
                if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-                 TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NATURAL_NAME (sym);
-               add_symbol_to_list (typedef_sym, list_to_add);
+                 TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_SEARCH_NAME (sym);
              }
          }
          break;
        case DW_TAG_typedef:
-         if (processing_has_namespace_info
-             && processing_current_prefix[0] != '\0')
-           {
-             SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
-                                                          processing_current_prefix,
-                                                          name, cu);
-           }
+         SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          add_symbol_to_list (sym, cu->list_in_scope);
@@ -6514,13 +7636,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
          add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_enumerator:
-         if (processing_has_namespace_info
-             && processing_current_prefix[0] != '\0')
-           {
-             SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
-                                                          processing_current_prefix,
-                                                          name, cu);
-           }
+         SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
          if (attr)
            {
@@ -6549,10 +7665,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
             trash data, but since we must specifically ignore things
             we don't recognize, there is nothing else we should do at
             this point. */
-         complaint (&symfile_complaints, "unsupported tag: '%s'",
+         complaint (&symfile_complaints, _("unsupported tag: '%s'"),
                     dwarf_tag_name (die->tag));
          break;
        }
+
+      /* For the benefit of old versions of GCC, check for anonymous
+        namespaces based on the demangled name.  */
+      if (!processing_has_namespace_info
+         && cu->language == language_cplus
+         && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+       cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
 }
@@ -6571,11 +7694,11 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
     {
     case DW_FORM_addr:
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size)
-       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (SYMBOL_PRINT_NAME (sym),
                                                      cu_header->addr_size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
-      SYMBOL_VALUE_BYTES (sym) = (char *)
+      SYMBOL_VALUE_BYTES (sym) = 
        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.  */
@@ -6583,17 +7706,23 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                              DW_ADDR (attr));
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
+    case DW_FORM_strp:
+      /* DW_STRING is already allocated on the obstack, point directly
+        to it.  */
+      SYMBOL_VALUE_BYTES (sym) = (gdb_byte *) DW_STRING (attr);
+      SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+      break;
     case DW_FORM_block1:
     case DW_FORM_block2:
     case DW_FORM_block4:
     case DW_FORM_block:
       blk = DW_BLOCK (attr);
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
-       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (SYMBOL_PRINT_NAME (sym),
                                                      blk->size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
-      SYMBOL_VALUE_BYTES (sym) = (char *)
+      SYMBOL_VALUE_BYTES (sym) =
        obstack_alloc (&objfile->objfile_obstack, blk->size);
       memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
@@ -6629,7 +7758,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
 
     default:
       complaint (&symfile_complaints,
-                "unsupported const value attribute form: '%s'",
+                _("unsupported const value attribute form: '%s'"),
                 dwarf_form_name (attr->form));
       SYMBOL_VALUE (sym) = 0;
       SYMBOL_CLASS (sym) = LOC_CONST;
@@ -6665,33 +7794,25 @@ dwarf2_const_value_data (struct attribute *attr,
 static struct type *
 die_type (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
   struct type *type;
   struct attribute *type_attr;
   struct die_info *type_die;
-  unsigned int ref;
 
   type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
       /* A missing DW_AT_type represents a void type.  */
-      return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
+      return builtin_type (gdbarch)->builtin_void;
     }
   else
-    {
-      ref = dwarf2_get_ref_die_offset (type_attr, cu);
-      type_die = follow_die_ref (ref);
-      if (!type_die)
-       {
-         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
-                         ref, cu->objfile->name);
-         return NULL;
-       }
-    }
+    type_die = follow_die_ref (die, type_attr, &cu);
+
   type = tag_type_to_type (type_die, cu);
   if (!type)
     {
       dump_die (type_die);
-      error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]",
+      error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"),
                      cu->objfile->name);
     }
   return type;
@@ -6706,202 +7827,190 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *type = NULL;
   struct attribute *type_attr;
   struct die_info *type_die = NULL;
-  unsigned int ref;
 
   type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (type_attr)
     {
-      ref = dwarf2_get_ref_die_offset (type_attr, cu);
-      type_die = follow_die_ref (ref);
-      if (!type_die)
-       {
-         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
-                         cu->objfile->name);
-         return NULL;
-       }
+      type_die = follow_die_ref (die, type_attr, &cu);
       type = tag_type_to_type (type_die, cu);
     }
   if (!type)
     {
       if (type_die)
        dump_die (type_die);
-      error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]"
+      error (_("Dwarf Error: Problem turning containing type into gdb type [in module %s]")
                      cu->objfile->name);
     }
   return type;
 }
 
-#if 0
 static struct type *
-type_at_offset (unsigned int offset, struct dwarf2_cu *cu)
+tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct die_info *die;
-  struct type *type;
+  struct type *this_type;
 
-  die = follow_die_ref (offset);
-  if (!die)
+  this_type = read_type_die (die, cu);
+  if (!this_type)
     {
-      error ("Dwarf Error: Cannot find type referent at offset %d.", offset);
-      return NULL;
+      dump_die (die);
+      error (_("Dwarf Error: Cannot find type of die [in module %s]"), 
+            cu->objfile->name);
     }
-  type = tag_type_to_type (die, cu);
-  return type;
+  return this_type;
 }
-#endif
 
 static struct type *
-tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
-{
-  if (die->type)
-    {
-      return die->type;
-    }
-  else
-    {
-      read_type_die (die, cu);
-      if (!die->type)
-       {
-         dump_die (die);
-         error ("Dwarf Error: Cannot find type of die [in module %s]", 
-                         cu->objfile->name);
-       }
-      return die->type;
-    }
-}
-
-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;
-  
+  struct type *this_type;
+
+  this_type = get_die_type (die, cu);
+  if (this_type)
+    return this_type;
+
   switch (die->tag)
     {
     case DW_TAG_class_type:
+    case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
-      read_structure_type (die, cu);
+      this_type = read_structure_type (die, cu);
       break;
     case DW_TAG_enumeration_type:
-      read_enumeration_type (die, cu);
+      this_type = read_enumeration_type (die, cu);
       break;
     case DW_TAG_subprogram:
     case DW_TAG_subroutine_type:
-      read_subroutine_type (die, cu);
+      this_type = read_subroutine_type (die, cu);
       break;
     case DW_TAG_array_type:
-      read_array_type (die, cu);
+      this_type = read_array_type (die, cu);
+      break;
+    case DW_TAG_set_type:
+      this_type = read_set_type (die, cu);
       break;
     case DW_TAG_pointer_type:
-      read_tag_pointer_type (die, cu);
+      this_type = read_tag_pointer_type (die, cu);
       break;
     case DW_TAG_ptr_to_member_type:
-      read_tag_ptr_to_member_type (die, cu);
+      this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu);
       break;
     case DW_TAG_const_type:
-      read_tag_const_type (die, cu);
+      this_type = read_tag_const_type (die, cu);
       break;
     case DW_TAG_volatile_type:
-      read_tag_volatile_type (die, cu);
+      this_type = read_tag_volatile_type (die, cu);
       break;
     case DW_TAG_string_type:
-      read_tag_string_type (die, cu);
+      this_type = read_tag_string_type (die, cu);
       break;
     case DW_TAG_typedef:
-      read_typedef (die, cu);
+      this_type = read_typedef (die, cu);
       break;
     case DW_TAG_subrange_type:
-      read_subrange_type (die, cu);
+      this_type = read_subrange_type (die, cu);
       break;
     case DW_TAG_base_type:
-      read_base_type (die, cu);
+      this_type = read_base_type (die, cu);
+      break;
+    case DW_TAG_unspecified_type:
+      this_type = read_unspecified_type (die, cu);
+      break;
+    case DW_TAG_namespace:
+      this_type = read_namespace_type (die, cu);
       break;
     default:
-      complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'",
+      complaint (&symfile_complaints, _("unexpected tag in read_type_die: '%s'"),
                 dwarf_tag_name (die->tag));
       break;
     }
 
-  processing_current_prefix = old_prefix;
-  do_cleanups (back_to);
+  return this_type;
 }
 
 /* Return the name of the namespace/class that DIE is defined within,
-   or "" if we can't tell.  The caller should xfree the result.  */
+   or "" if we can't tell.  The caller should not xfree the result.
+
+   For example, if we're within the method foo() in the following
+   code:
 
-/* 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.  */
+   namespace N {
+     class C {
+       void foo () {
+       }
+     };
+   }
+
+   then determine_prefix on foo's die will return "N::C".  */
 
 static char *
 determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct die_info *parent;
+  struct die_info *parent, *spec_die;
+  struct dwarf2_cu *spec_cu;
+  struct type *parent_type;
 
   if (cu->language != language_cplus
       && cu->language != language_java)
-    return NULL;
+    return "";
 
-  parent = die->parent;
+  /* We have to be careful in the presence of DW_AT_specification.
+     For example, with GCC 3.4, given the code
 
-  if (parent == NULL)
+     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.  */
+  spec_cu = cu;
+  spec_die = die_specification (die, &spec_cu);
+  if (spec_die == NULL)
+    parent = die->parent;
+  else
     {
-      return xstrdup ("");
+      parent = spec_die->parent;
+      cu = spec_cu;
     }
+
+  if (parent == NULL)
+    return "";
   else
-    {
-      switch (parent->tag) {
+    switch (parent->tag)
+      {
       case DW_TAG_namespace:
-       {
-         /* FIXME: carlton/2004-03-05: Should I follow extension dies
-            before doing this check?  */
-         if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
-           {
-             return xstrdup (TYPE_TAG_NAME (parent->type));
-           }
-         else
-           {
-             int dummy;
-             char *parent_prefix = determine_prefix (parent, cu);
-             char *retval = typename_concat (NULL, parent_prefix,
-                                             namespace_name (parent, &dummy,
-                                                             cu),
-                                             cu);
-             xfree (parent_prefix);
-             return retval;
-           }
-       }
-       break;
+       parent_type = read_type_die (parent, cu);
+       /* We give a name to even anonymous namespaces.  */
+       return TYPE_TAG_NAME (parent_type);
       case DW_TAG_class_type:
+      case DW_TAG_interface_type:
       case DW_TAG_structure_type:
-       {
-         if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
-           {
-             return xstrdup (TYPE_TAG_NAME (parent->type));
-           }
-         else
-           {
-             const char *old_prefix = processing_current_prefix;
-             char *new_prefix = determine_prefix (parent, cu);
-             char *retval;
-
-             processing_current_prefix = new_prefix;
-             retval = determine_class_name (parent, cu);
-             processing_current_prefix = old_prefix;
-
-             xfree (new_prefix);
-             return retval;
-           }
-       }
+      case DW_TAG_union_type:
+       parent_type = read_type_die (parent, cu);
+       if (TYPE_TAG_NAME (parent_type) != NULL)
+         return TYPE_TAG_NAME (parent_type);
+       else
+         /* An anonymous structure is only allowed non-static data
+            members; no typedefs, no member functions, et cetera.
+            So it does not need a prefix.  */
+         return "";
       default:
        return determine_prefix (parent, cu);
       }
-    }
 }
 
 /* Return a newly-allocated string formed by concatenating PREFIX and
@@ -6943,120 +8052,9 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix,
   else
     {
       /* We have an obstack.  */
-      return obconcat (obs, prefix, sep, suffix);
-    }
-}
-
-static struct type *
-dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
-{
-  struct objfile *objfile = cu->objfile;
-
-  /* FIXME - this should not produce a new (struct type *)
-     every time.  It should cache base types.  */
-  struct type *type;
-  switch (encoding)
-    {
-    case DW_ATE_address:
-      type = dwarf2_fundamental_type (objfile, FT_VOID, cu);
-      return type;
-    case DW_ATE_boolean:
-      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu);
-      return type;
-    case DW_ATE_complex_float:
-      if (size == 16)
-       {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu);
-       }
-      else
-       {
-         type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu);
-       }
-      return type;
-    case DW_ATE_float:
-      if (size == 8)
-       {
-         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
-       }
-      else
-       {
-         type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
-       }
-      return type;
-    case DW_ATE_signed:
-      switch (size)
-       {
-       case 1:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
-         break;
-       case 2:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu);
-         break;
-       default:
-       case 4:
-         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
-         break;
-       }
-      return type;
-    case DW_ATE_signed_char:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
-      return type;
-    case DW_ATE_unsigned:
-      switch (size)
-       {
-       case 1:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
-         break;
-       case 2:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu);
-         break;
-       default:
-       case 4:
-         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu);
-         break;
-       }
-      return type;
-    case DW_ATE_unsigned_char:
-      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
-      return type;
-    default:
-      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
-      return type;
-    }
-}
-
-#if 0
-struct die_info *
-copy_die (struct die_info *old_die)
-{
-  struct die_info *new_die;
-  int i, num_attrs;
-
-  new_die = (struct die_info *) xmalloc (sizeof (struct die_info));
-  memset (new_die, 0, sizeof (struct die_info));
-
-  new_die->tag = old_die->tag;
-  new_die->has_children = old_die->has_children;
-  new_die->abbrev = old_die->abbrev;
-  new_die->offset = old_die->offset;
-  new_die->type = NULL;
-
-  num_attrs = old_die->num_attrs;
-  new_die->num_attrs = num_attrs;
-  new_die->attrs = (struct attribute *)
-    xmalloc (num_attrs * sizeof (struct attribute));
-
-  for (i = 0; i < old_die->num_attrs; ++i)
-    {
-      new_die->attrs[i].name = old_die->attrs[i].name;
-      new_die->attrs[i].form = old_die->attrs[i].form;
-      new_die->attrs[i].u.addr = old_die->attrs[i].u.addr;
+      return obconcat (obs, prefix, sep, suffix);
     }
-
-  new_die->next = NULL;
-  return new_die;
 }
-#endif
 
 /* Return sibling of die, NULL if no sibling.  */
 
@@ -7096,27 +8094,19 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 /* Return the die that this die in an extension of, or NULL if there
-   is none.  */
+   is none.  *EXT_CU is the CU containing DIE on input, and the CU
+   containing the return value on output.  */
 
 static struct die_info *
-dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu)
 {
   struct attribute *attr;
-  struct die_info *extension_die;
-  unsigned int ref;
 
-  attr = dwarf2_attr (die, DW_AT_extension, cu);
+  attr = dwarf2_attr (die, DW_AT_extension, *ext_cu);
   if (attr == NULL)
     return NULL;
 
-  ref = dwarf2_get_ref_die_offset (attr, cu);
-  extension_die = follow_die_ref (ref);
-  if (!extension_die)
-    {
-      error ("Dwarf Error: Cannot find referent at offset %d.", ref);
-    }
-
-  return extension_die;
+  return follow_die_ref (die, attr, ext_cu);
 }
 
 /* Convert a DIE tag into its string name.  */
@@ -7238,14 +8228,34 @@ dwarf_tag_name (unsigned tag)
       return "DW_TAG_partial_unit";
     case DW_TAG_imported_unit:
       return "DW_TAG_imported_unit";
+    case DW_TAG_condition:
+      return "DW_TAG_condition";
+    case DW_TAG_shared_type:
+      return "DW_TAG_shared_type";
     case DW_TAG_MIPS_loop:
       return "DW_TAG_MIPS_loop";
+    case DW_TAG_HP_array_descriptor:
+      return "DW_TAG_HP_array_descriptor";
     case DW_TAG_format_label:
       return "DW_TAG_format_label";
     case DW_TAG_function_template:
       return "DW_TAG_function_template";
     case DW_TAG_class_template:
       return "DW_TAG_class_template";
+    case DW_TAG_GNU_BINCL:
+      return "DW_TAG_GNU_BINCL";
+    case DW_TAG_GNU_EINCL:
+      return "DW_TAG_GNU_EINCL";
+    case DW_TAG_upc_shared_type:
+      return "DW_TAG_upc_shared_type";
+    case DW_TAG_upc_strict_type:
+      return "DW_TAG_upc_strict_type";
+    case DW_TAG_upc_relaxed_type:
+      return "DW_TAG_upc_relaxed_type";
+    case DW_TAG_PGI_kanji_type:
+      return "DW_TAG_PGI_kanji_type";
+    case DW_TAG_PGI_interface_block:
+      return "DW_TAG_PGI_interface_block";
     default:
       return "DW_TAG_<unknown>";
     }
@@ -7320,8 +8330,8 @@ dwarf_attr_name (unsigned attr)
       return "DW_AT_return_addr";
     case DW_AT_start_scope:
       return "DW_AT_start_scope";
-    case DW_AT_stride_size:
-      return "DW_AT_stride_size";
+    case DW_AT_bit_stride:
+      return "DW_AT_bit_stride";
     case DW_AT_upper_bound:
       return "DW_AT_upper_bound";
     case DW_AT_abstract_origin:
@@ -7382,14 +8392,15 @@ dwarf_attr_name (unsigned attr)
       return "DW_AT_virtuality";
     case DW_AT_vtable_elem_location:
       return "DW_AT_vtable_elem_location";
+    /* DWARF 3 values.  */
     case DW_AT_allocated:
       return "DW_AT_allocated";
     case DW_AT_associated:
       return "DW_AT_associated";
     case DW_AT_data_location:
       return "DW_AT_data_location";
-    case DW_AT_stride:
-      return "DW_AT_stride";
+    case DW_AT_byte_stride:
+      return "DW_AT_byte_stride";
     case DW_AT_entry_pc:
       return "DW_AT_entry_pc";
     case DW_AT_use_UTF8:
@@ -7406,7 +8417,38 @@ dwarf_attr_name (unsigned attr)
       return "DW_AT_call_file";
     case DW_AT_call_line:
       return "DW_AT_call_line";
+    case DW_AT_description:
+      return "DW_AT_description";
+    case DW_AT_binary_scale:
+      return "DW_AT_binary_scale";
+    case DW_AT_decimal_scale:
+      return "DW_AT_decimal_scale";
+    case DW_AT_small:
+      return "DW_AT_small";
+    case DW_AT_decimal_sign:
+      return "DW_AT_decimal_sign";
+    case DW_AT_digit_count:
+      return "DW_AT_digit_count";
+    case DW_AT_picture_string:
+      return "DW_AT_picture_string";
+    case DW_AT_mutable:
+      return "DW_AT_mutable";
+    case DW_AT_threads_scaled:
+      return "DW_AT_threads_scaled";
+    case DW_AT_explicit:
+      return "DW_AT_explicit";
+    case DW_AT_object_pointer:
+      return "DW_AT_object_pointer";
+    case DW_AT_endianity:
+      return "DW_AT_endianity";
+    case DW_AT_elemental:
+      return "DW_AT_elemental";
+    case DW_AT_pure:
+      return "DW_AT_pure";
+    case DW_AT_recursive:
+      return "DW_AT_recursive";
 #ifdef MIPS
+    /* SGI/MIPS extensions.  */
     case DW_AT_MIPS_fde:
       return "DW_AT_MIPS_fde";
     case DW_AT_MIPS_loop_begin:
@@ -7419,10 +8461,47 @@ dwarf_attr_name (unsigned attr)
       return "DW_AT_MIPS_loop_unroll_factor";
     case DW_AT_MIPS_software_pipeline_depth:
       return "DW_AT_MIPS_software_pipeline_depth";
-#endif
     case DW_AT_MIPS_linkage_name:
       return "DW_AT_MIPS_linkage_name";
-
+    case DW_AT_MIPS_stride:
+      return "DW_AT_MIPS_stride";
+    case DW_AT_MIPS_abstract_name:
+      return "DW_AT_MIPS_abstract_name";
+    case DW_AT_MIPS_clone_origin:
+      return "DW_AT_MIPS_clone_origin";
+    case DW_AT_MIPS_has_inlines:
+      return "DW_AT_MIPS_has_inlines";
+#endif
+    /* HP extensions.  */
+    case DW_AT_HP_block_index:
+      return "DW_AT_HP_block_index";
+    case DW_AT_HP_unmodifiable:
+      return "DW_AT_HP_unmodifiable";
+    case DW_AT_HP_actuals_stmt_list:
+      return "DW_AT_HP_actuals_stmt_list";
+    case DW_AT_HP_proc_per_section:
+      return "DW_AT_HP_proc_per_section";
+    case DW_AT_HP_raw_data_ptr:
+      return "DW_AT_HP_raw_data_ptr";
+    case DW_AT_HP_pass_by_reference:
+      return "DW_AT_HP_pass_by_reference";
+    case DW_AT_HP_opt_level:
+      return "DW_AT_HP_opt_level";
+    case DW_AT_HP_prof_version_id:
+      return "DW_AT_HP_prof_version_id";
+    case DW_AT_HP_opt_flags:
+      return "DW_AT_HP_opt_flags";
+    case DW_AT_HP_cold_region_low_pc:
+      return "DW_AT_HP_cold_region_low_pc";
+    case DW_AT_HP_cold_region_high_pc:
+      return "DW_AT_HP_cold_region_high_pc";
+    case DW_AT_HP_all_variables_modifiable:
+      return "DW_AT_HP_all_variables_modifiable";
+    case DW_AT_HP_linkage_name:
+      return "DW_AT_HP_linkage_name";
+    case DW_AT_HP_prof_flags:
+      return "DW_AT_HP_prof_flags";
+    /* GNU extensions.  */
     case DW_AT_sf_names:
       return "DW_AT_sf_names";
     case DW_AT_src_info:
@@ -7437,6 +8516,19 @@ dwarf_attr_name (unsigned attr)
       return "DW_AT_body_end";
     case DW_AT_GNU_vector:
       return "DW_AT_GNU_vector";
+    /* VMS extensions.  */
+    case DW_AT_VMS_rtnbeg_pd_address:
+      return "DW_AT_VMS_rtnbeg_pd_address";
+    /* UPC extension.  */
+    case DW_AT_upc_threads_scaled:
+      return "DW_AT_upc_threads_scaled";
+    /* PGI (STMicroelectronics) extensions.  */
+    case DW_AT_PGI_lbase:
+      return "DW_AT_PGI_lbase";
+    case DW_AT_PGI_soffset:
+      return "DW_AT_PGI_soffset";
+    case DW_AT_PGI_lstride:
+      return "DW_AT_PGI_lstride";
     default:
       return "DW_AT_<unknown>";
     }
@@ -7793,7 +8885,7 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_xderef_size";
     case DW_OP_nop:
       return "DW_OP_nop";
-      /* DWARF 3 extensions.  */
+    /* DWARF 3 extensions.  */
     case DW_OP_push_object_address:
       return "DW_OP_push_object_address";
     case DW_OP_call2:
@@ -7802,9 +8894,30 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_call4";
     case DW_OP_call_ref:
       return "DW_OP_call_ref";
-      /* GNU extensions.  */
+    /* GNU extensions.  */
+    case DW_OP_form_tls_address:
+      return "DW_OP_form_tls_address";
+    case DW_OP_call_frame_cfa:
+      return "DW_OP_call_frame_cfa";
+    case DW_OP_bit_piece:
+      return "DW_OP_bit_piece";
     case DW_OP_GNU_push_tls_address:
       return "DW_OP_GNU_push_tls_address";
+    case DW_OP_GNU_uninit:
+      return "DW_OP_GNU_uninit";
+    /* HP extensions. */ 
+    case DW_OP_HP_is_value:
+      return "DW_OP_HP_is_value";
+    case DW_OP_HP_fltconst4:
+      return "DW_OP_HP_fltconst4";
+    case DW_OP_HP_fltconst8:
+      return "DW_OP_HP_fltconst8";
+    case DW_OP_HP_mod_range:
+      return "DW_OP_HP_mod_range";
+    case DW_OP_HP_unmod_range:
+      return "DW_OP_HP_unmod_range";
+    case DW_OP_HP_tls:
+      return "DW_OP_HP_tls";
     default:
       return "OP_<unknown>";
     }
@@ -7826,6 +8939,8 @@ dwarf_type_encoding_name (unsigned enc)
 {
   switch (enc)
     {
+    case DW_ATE_void:
+      return "DW_ATE_void";
     case DW_ATE_address:
       return "DW_ATE_address";
     case DW_ATE_boolean:
@@ -7842,8 +8957,36 @@ dwarf_type_encoding_name (unsigned enc)
       return "DW_ATE_unsigned";
     case DW_ATE_unsigned_char:
       return "DW_ATE_unsigned_char";
+    /* DWARF 3.  */
     case DW_ATE_imaginary_float:
       return "DW_ATE_imaginary_float";
+    case DW_ATE_packed_decimal:
+      return "DW_ATE_packed_decimal";
+    case DW_ATE_numeric_string:
+      return "DW_ATE_numeric_string";
+    case DW_ATE_edited:
+      return "DW_ATE_edited";
+    case DW_ATE_signed_fixed:
+      return "DW_ATE_signed_fixed";
+    case DW_ATE_unsigned_fixed:
+      return "DW_ATE_unsigned_fixed";
+    case DW_ATE_decimal_float:
+      return "DW_ATE_decimal_float";
+    /* HP extensions.  */
+    case DW_ATE_HP_float80:
+      return "DW_ATE_HP_float80";
+    case DW_ATE_HP_complex_float80:
+      return "DW_ATE_HP_complex_float80";
+    case DW_ATE_HP_float128:
+      return "DW_ATE_HP_float128";
+    case DW_ATE_HP_complex_float128:
+      return "DW_ATE_HP_complex_float128";
+    case DW_ATE_HP_floathpintel:
+      return "DW_ATE_HP_floathpintel";
+    case DW_ATE_HP_imaginary_float80:
+      return "DW_ATE_HP_imaginary_float80";
+    case DW_ATE_HP_imaginary_float128:
+      return "DW_ATE_HP_imaginary_float128";
     default:
       return "DW_ATE_<unknown>";
     }
@@ -7893,8 +9036,7 @@ dwarf_cfi_name (unsigned cfi_opc)
       return "DW_CFA_def_cfa_register";
     case DW_CFA_def_cfa_offset:
       return "DW_CFA_def_cfa_offset";
-
-    /* DWARF 3 */
+    /* DWARF 3.  */
     case DW_CFA_def_cfa_expression:
       return "DW_CFA_def_cfa_expression";
     case DW_CFA_expression:
@@ -7905,19 +9047,22 @@ dwarf_cfi_name (unsigned cfi_opc)
       return "DW_CFA_def_cfa_sf";
     case DW_CFA_def_cfa_offset_sf:
       return "DW_CFA_def_cfa_offset_sf";
-
-      /* SGI/MIPS specific */
+    case DW_CFA_val_offset:
+      return "DW_CFA_val_offset";
+    case DW_CFA_val_offset_sf:
+      return "DW_CFA_val_offset_sf";
+    case DW_CFA_val_expression:
+      return "DW_CFA_val_expression";
+    /* SGI/MIPS specific.  */
     case DW_CFA_MIPS_advance_loc8:
       return "DW_CFA_MIPS_advance_loc8";
-
-    /* GNU extensions */
+    /* GNU extensions.  */
     case DW_CFA_GNU_window_save:
       return "DW_CFA_GNU_window_save";
     case DW_CFA_GNU_args_size:
       return "DW_CFA_GNU_args_size";
     case DW_CFA_GNU_negative_offset_extended:
       return "DW_CFA_GNU_negative_offset_extended";
-
     default:
       return "DW_CFA_<unknown>";
     }
@@ -7945,7 +9090,7 @@ dump_die (struct die_info *die)
        case DW_FORM_ref_addr:
        case DW_FORM_addr:
          fprintf_unfiltered (gdb_stderr, "address: ");
-         print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
+         fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), gdb_stderr);
          break;
        case DW_FORM_block2:
        case DW_FORM_block4:
@@ -7953,13 +9098,16 @@ dump_die (struct die_info *die)
        case DW_FORM_block1:
          fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
          break;
+       case DW_FORM_ref1:
+       case DW_FORM_ref2:
+       case DW_FORM_ref4:
+         fprintf_unfiltered (gdb_stderr, "constant ref: %ld (adjusted)",
+                             (long) (DW_ADDR (&die->attrs[i])));
+         break;
        case DW_FORM_data1:
        case DW_FORM_data2:
        case DW_FORM_data4:
        case DW_FORM_data8:
-       case DW_FORM_ref1:
-       case DW_FORM_ref2:
-       case DW_FORM_ref4:
        case DW_FORM_udata:
        case DW_FORM_sdata:
          fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
@@ -8003,22 +9151,13 @@ dump_die_list (struct die_info *die)
 }
 
 static void
-store_in_ref_table (unsigned int offset, struct die_info *die)
+store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
 {
-  int h;
-  struct die_info *old;
-
-  h = (offset % REF_HASH_SIZE);
-  old = die_ref_table[h];
-  die->next_ref = old;
-  die_ref_table[h] = die;
-}
+  void **slot;
 
+  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT);
 
-static void
-dwarf2_empty_hash_tables (void)
-{
-  memset (die_ref_table, 0, sizeof (die_ref_table));
+  *slot = die;
 }
 
 static unsigned int
@@ -8029,18 +9168,16 @@ dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
   switch (attr->form)
     {
     case DW_FORM_ref_addr:
-      result = DW_ADDR (attr);
-      break;
     case DW_FORM_ref1:
     case DW_FORM_ref2:
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      result = cu->header.offset + DW_UNSND (attr);
+      result = DW_ADDR (attr);
       break;
     default:
       complaint (&symfile_complaints,
-                "unsupported die ref attribute form: '%s'",
+                _("unsupported die ref attribute form: '%s'"),
                 dwarf_form_name (attr->form));
     }
   return result;
@@ -8062,51 +9199,72 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
     return DW_UNSND (attr);
   else
     {
-      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+      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)
+/* THIS_CU has a reference to PER_CU.  If necessary, load the new compilation
+   unit and add it to our queue.  */
+
+static void
+maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
+                      struct dwarf2_per_cu_data *per_cu)
 {
-  struct die_info *die;
-  int h;
+  /* Mark the dependence relation so that we don't flush PER_CU
+     too early.  */
+  dwarf2_add_dependence (this_cu, per_cu);
 
-  h = (offset % REF_HASH_SIZE);
-  die = die_ref_table[h];
-  while (die)
+  /* If it's already on the queue, we have nothing to do.  */
+  if (per_cu->queued)
+    return;
+
+  /* If the compilation unit is already loaded, just mark it as
+     used.  */
+  if (per_cu->cu != NULL)
     {
-      if (die->offset == offset)
-       {
-         return die;
-       }
-      die = die->next_ref;
+      per_cu->cu->last_used = 0;
+      return;
     }
-  return NULL;
+
+  /* Add it to the queue.  */
+  queue_comp_unit (per_cu, this_cu->objfile);
 }
 
-static struct type *
-dwarf2_fundamental_type (struct objfile *objfile, int typeid,
-                        struct dwarf2_cu *cu)
+static struct die_info *
+follow_die_ref (struct die_info *src_die, struct attribute *attr,
+               struct dwarf2_cu **ref_cu)
 {
-  if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
-    {
-      error ("Dwarf Error: internal error - invalid fundamental type id %d [in module %s]",
-            typeid, objfile->name);
-    }
+  struct die_info *die;
+  unsigned int offset;
+  struct die_info temp_die;
+  struct dwarf2_cu *target_cu, *cu = *ref_cu;
 
-  /* Look for this particular type in the fundamental type vector.  If
-     one is not found, create and install one appropriate for the
-     current language and the current target machine. */
+  offset = dwarf2_get_ref_die_offset (attr, cu);
 
-  if (cu->ftypes[typeid] == NULL)
+  if (! offset_in_cu_p (&cu->header, offset))
     {
-      cu->ftypes[typeid] = cu->language_defn->la_fund_type (objfile, typeid);
+      struct dwarf2_per_cu_data *per_cu;
+      per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+      /* If necessary, add it to the queue and load its DIEs.  */
+      maybe_queue_comp_unit (cu, per_cu);
+
+      target_cu = per_cu->cu;
     }
+  else
+    target_cu = cu;
 
-  return (cu->ftypes[typeid]);
+  *ref_cu = target_cu;
+  temp_die.offset = offset;
+  die = htab_find_with_hash (target_cu->die_hash, &temp_die, offset);
+  if (die)
+    return die;
+
+  error (_("Dwarf Error: Cannot find DIE at 0x%lx referenced from DIE "
+        "at 0x%lx [in module %s]"),
+        (long) offset, (long) src_die->offset, cu->objfile->name);
 }
 
 /* Decode simple location descriptions.
@@ -8128,9 +9286,6 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid,
    callers will only want a very basic result and this can become a
    complaint.
 
-   When the result is a register number, the global isreg flag is set,
-   otherwise it is cleared.
-
    Note that stack[0] is unused except as a default error return.
    Note that stack overflow is not yet handled.  */
 
@@ -8141,16 +9296,15 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
   struct comp_unit_head *cu_header = &cu->header;
   int i;
   int size = blk->size;
-  char *data = blk->data;
+  gdb_byte *data = blk->data;
   CORE_ADDR stack[64];
   int stacki;
   unsigned int bytes_read, unsnd;
-  unsigned char op;
+  gdb_byte op;
 
   i = 0;
   stacki = 0;
   stack[stacki] = 0;
-  isreg = 0;
 
   while (i < size)
     {
@@ -8224,14 +9378,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         isreg = 1;
          stack[++stacki] = op - DW_OP_reg0;
          if (i < size)
            dwarf2_complex_location_expr_complaint ();
          break;
 
        case DW_OP_regx:
-         isreg = 1;
          unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
          i += bytes_read;
          stack[++stacki] = unsnd;
@@ -8326,8 +9478,11 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
            dwarf2_complex_location_expr_complaint ();
           break;
 
+       case DW_OP_GNU_uninit:
+         break;
+
        default:
-         complaint (&symfile_complaints, "unsupported stack op: '%s'",
+         complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
                     dwarf_stack_op_name (op));
          return (stack[stacki]);
        }
@@ -8359,11 +9514,15 @@ dwarf_alloc_abbrev (struct dwarf2_cu *cu)
 }
 
 static struct die_info *
-dwarf_alloc_die (void)
+dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
 {
   struct die_info *die;
+  size_t size = sizeof (struct die_info);
 
-  die = (struct die_info *) xmalloc (sizeof (struct die_info));
+  if (num_attrs > 1)
+    size += (num_attrs - 1) * sizeof (struct attribute);
+
+  die = (struct die_info *) obstack_alloc (&cu->comp_unit_obstack, size);
   memset (die, 0, sizeof (struct die_info));
   return (die);
 }
@@ -8379,32 +9538,51 @@ dwarf_alloc_die (void)
 static char *
 file_full_name (int file, struct line_header *lh, const char *comp_dir)
 {
-  struct file_entry *fe = &lh->file_names[file - 1];
+  /* Is the file number a valid index into the line header's file name
+     table?  Remember that file numbers start with one, not zero.  */
+  if (1 <= file && file <= lh->num_file_names)
+    {
+      struct file_entry *fe = &lh->file_names[file - 1];
   
-  if (IS_ABSOLUTE_PATH (fe->name))
-    return xstrdup (fe->name);
+      if (IS_ABSOLUTE_PATH (fe->name))
+        return xstrdup (fe->name);
+      else
+        {
+          const char *dir;
+          int dir_len;
+          char *full_name;
+
+          if (fe->dir_index)
+            dir = lh->include_dirs[fe->dir_index - 1];
+          else
+            dir = comp_dir;
+
+          if (dir)
+            {
+              dir_len = strlen (dir);
+              full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
+              strcpy (full_name, dir);
+              full_name[dir_len] = '/';
+              strcpy (full_name + dir_len + 1, fe->name);
+              return full_name;
+            }
+          else
+            return xstrdup (fe->name);
+        }
+    }
   else
     {
-      const char *dir;
-      int dir_len;
-      char *full_name;
+      /* The compiler produced a bogus file number.  We can at least
+         record the macro definitions made in the file, even if we
+         won't be able to find the file by name.  */
+      char fake_name[80];
+      sprintf (fake_name, "<bad macro file number %d>", file);
 
-      if (fe->dir_index)
-        dir = lh->include_dirs[fe->dir_index - 1];
-      else
-        dir = comp_dir;
+      complaint (&symfile_complaints, 
+                 _("bad file number in macro information (%d)"),
+                 file);
 
-      if (dir)
-        {
-          dir_len = strlen (dir);
-          full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
-          strcpy (full_name, dir);
-          full_name[dir_len] = '/';
-          strcpy (full_name + dir_len + 1, fe->name);
-          return full_name;
-        }
-      else
-        return xstrdup (fe->name);
+      return xstrdup (fake_name);
     }
 }
 
@@ -8456,7 +9634,7 @@ consume_improper_spaces (const char *p, const char *body)
   if (*p == ' ')
     {
       complaint (&symfile_complaints,
-                "macro definition contains spaces in formal argument list:\n`%s'",
+                _("macro definition contains spaces in formal argument list:\n`%s'"),
                 body);
 
       while (*p == ' ')
@@ -8613,12 +9791,12 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                      char *comp_dir, bfd *abfd,
                      struct dwarf2_cu *cu)
 {
-  char *mac_ptr, *mac_end;
+  gdb_byte *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
 
   if (dwarf2_per_objfile->macinfo_buffer == NULL)
     {
-      complaint (&symfile_complaints, "missing .debug_macinfo section");
+      complaint (&symfile_complaints, _("missing .debug_macinfo section"));
       return;
     }
 
@@ -8650,7 +9828,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
         case DW_MACINFO_define:
         case DW_MACINFO_undef:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int line;
             char *body;
 
@@ -8661,7 +9839,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
             if (! current_file)
              complaint (&symfile_complaints,
-                        "debug info gives macro %s outside of any file: %s",
+                        _("debug info gives macro %s outside of any file: %s"),
                         macinfo_type ==
                         DW_MACINFO_define ? "definition" : macinfo_type ==
                         DW_MACINFO_undef ? "undefinition" :
@@ -8678,7 +9856,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
         case DW_MACINFO_start_file:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int line, file;
 
             line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
@@ -8695,7 +9873,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
         case DW_MACINFO_end_file:
           if (! current_file)
            complaint (&symfile_complaints,
-                      "macro debug info has an unmatched `close_file' directive");
+                      _("macro debug info has an unmatched `close_file' directive"));
           else
             {
               current_file = current_file->included_by;
@@ -8720,7 +9898,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
                   next_type = read_1_byte (abfd, mac_ptr);
                   if (next_type != 0)
                    complaint (&symfile_complaints,
-                              "no terminating 0-type entry for macros in `.debug_macinfo' section");
+                              _("no terminating 0-type entry for macros in `.debug_macinfo' section"));
 
                   return;
                 }
@@ -8729,7 +9907,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
         case DW_MACINFO_vendor_ext:
           {
-            int bytes_read;
+            unsigned int bytes_read;
             int constant;
             char *string;
 
@@ -8757,26 +9935,76 @@ attr_form_is_block (struct attribute *attr)
       || attr->form == DW_FORM_block);
 }
 
+/* Return non-zero if ATTR's value is a section offset --- classes
+   lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
+   You may use DW_UNSND (attr) to retrieve such offsets.
+
+   Section 7.5.4, "Attribute Encodings", explains that no attribute
+   may have a value that belongs to more than one of these classes; it
+   would be ambiguous if we did, because we use the same forms for all
+   of them.  */
+static int
+attr_form_is_section_offset (struct attribute *attr)
+{
+  return (attr->form == DW_FORM_data4
+          || attr->form == DW_FORM_data8);
+}
+
+
+/* Return non-zero if ATTR's value falls in the 'constant' class, or
+   zero otherwise.  When this function returns true, you can apply
+   dwarf2_get_attr_constant_value to it.
+
+   However, note that for some attributes you must check
+   attr_form_is_section_offset before using this test.  DW_FORM_data4
+   and DW_FORM_data8 are members of both the constant class, and of
+   the classes that contain offsets into other debug sections
+   (lineptr, loclistptr, macptr or rangelistptr).  The DWARF spec says
+   that, if an attribute's can be either a constant or one of the
+   section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
+   taken as section offsets, not constants.  */
+static int
+attr_form_is_constant (struct attribute *attr)
+{
+  switch (attr->form)
+    {
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
                             struct dwarf2_cu *cu)
 {
-  if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+  if (attr_form_is_section_offset (attr)
+      /* ".debug_loc" may not exist at all, or the offset may be outside
+        the section.  If so, fall through to the complaint in the
+        other branch.  */
+      && DW_UNSND (attr) < dwarf2_per_objfile->loc_size)
     {
       struct dwarf2_loclist_baton *baton;
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_loclist_baton));
-      baton->objfile = cu->objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       /* We don't know how long the location list is, but make sure we
         don't run off the edge of the section.  */
       baton->size = dwarf2_per_objfile->loc_size - DW_UNSND (attr);
       baton->data = dwarf2_per_objfile->loc_buffer + DW_UNSND (attr);
-      baton->base_address = cu->header.base_address;
-      if (cu->header.base_known == 0)
+      baton->base_address = cu->base_address;
+      if (cu->base_known == 0)
        complaint (&symfile_complaints,
-                  "Location list used without specifying the CU base address.");
+                  _("Location list used without specifying the CU base address."));
 
       SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
@@ -8787,7 +10015,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = cu->objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       if (attr_form_is_block (attr))
        {
@@ -8812,9 +10041,120 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     }
 }
 
+/* Return the OBJFILE associated with the compilation unit CU.  */
+
+struct objfile *
+dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+{
+  struct objfile *objfile = per_cu->psymtab->objfile;
+
+  /* Return the master objfile, so that we can report and look up the
+     correct file containing this variable.  */
+  if (objfile->separate_debug_objfile_backlink)
+    objfile = objfile->separate_debug_objfile_backlink;
+
+  return objfile;
+}
+
+/* Return the address size given in the compilation unit header for CU.  */
+
+CORE_ADDR
+dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+  if (per_cu->cu)
+    return per_cu->cu->header.addr_size;
+  else
+    {
+      /* If the CU is not currently read in, we re-read its header.  */
+      struct objfile *objfile = per_cu->psymtab->objfile;
+      struct dwarf2_per_objfile *per_objfile
+       = objfile_data (objfile, dwarf2_objfile_data_key);
+      gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
+
+      struct comp_unit_head cu_header;
+      memset (&cu_header, 0, sizeof cu_header);
+      read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+      return cu_header.addr_size;
+    }
+}
+
+/* Locate the compilation unit from CU's objfile which contains the
+   DIE at OFFSET.  Raises an error on failure.  */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_containing_comp_unit (unsigned long offset,
+                                 struct objfile *objfile)
+{
+  struct dwarf2_per_cu_data *this_cu;
+  int low, high;
+
+  low = 0;
+  high = dwarf2_per_objfile->n_comp_units - 1;
+  while (high > low)
+    {
+      int mid = low + (high - low) / 2;
+      if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+       high = mid;
+      else
+       low = mid + 1;
+    }
+  gdb_assert (low == high);
+  if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+    {
+      if (low == 0)
+       error (_("Dwarf Error: could not find partial DIE containing "
+              "offset 0x%lx [in module %s]"),
+              (long) offset, bfd_get_filename (objfile->obfd));
+
+      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+      return dwarf2_per_objfile->all_comp_units[low-1];
+    }
+  else
+    {
+      this_cu = dwarf2_per_objfile->all_comp_units[low];
+      if (low == dwarf2_per_objfile->n_comp_units - 1
+         && offset >= this_cu->offset + this_cu->length)
+       error (_("invalid dwarf2 offset %ld"), offset);
+      gdb_assert (offset < this_cu->offset + this_cu->length);
+      return this_cu;
+    }
+}
+
+/* Locate the compilation unit from OBJFILE which is located at exactly
+   OFFSET.  Raises an error on failure.  */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_comp_unit (unsigned long offset, struct objfile *objfile)
+{
+  struct dwarf2_per_cu_data *this_cu;
+  this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
+  if (this_cu->offset != offset)
+    error (_("no compilation unit with offset %ld."), offset);
+  return this_cu;
+}
+
+/* Release one cached compilation unit, CU.  We unlink it from the tree
+   of compilation units, but we don't remove it from the read_in_chain;
+   the caller is responsible for that.  */
+
+static void
+free_one_comp_unit (void *data)
+{
+  struct dwarf2_cu *cu = data;
+
+  if (cu->per_cu != NULL)
+    cu->per_cu->cu = NULL;
+  cu->per_cu = NULL;
+
+  obstack_free (&cu->comp_unit_obstack, NULL);
+
+  xfree (cu);
+}
+
 /* This cleanup function is passed the address of a dwarf2_cu on the stack
-   when we're finished with it.  We can't free the pointer itself, but
-   release any associated storage.
+   when we're finished with it.  We can't free the pointer itself, but be
+   sure to unlink it from the cache.  Also release any associated storage
+   and perform cache maintenance.
 
    Only used during partial symbol parsing.  */
 
@@ -8825,28 +10165,264 @@ free_stack_comp_unit (void *data)
 
   obstack_free (&cu->comp_unit_obstack, NULL);
   cu->partial_dies = NULL;
+
+  if (cu->per_cu != NULL)
+    {
+      /* This compilation unit is on the stack in our caller, so we
+        should not xfree it.  Just unlink it.  */
+      cu->per_cu->cu = NULL;
+      cu->per_cu = NULL;
+
+      /* If we had a per-cu pointer, then we may have other compilation
+        units loaded, so age them now.  */
+      age_cached_comp_units ();
+    }
+}
+
+/* Free all cached compilation units.  */
+
+static void
+free_cached_comp_units (void *data)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      free_one_comp_unit (per_cu->cu);
+      *last_chain = next_cu;
+
+      per_cu = next_cu;
+    }
+}
+
+/* Increase the age counter on each cached compilation unit, and free
+   any that are too old.  */
+
+static void
+age_cached_comp_units (void)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      per_cu->cu->last_used ++;
+      if (per_cu->cu->last_used <= dwarf2_max_cache_age)
+       dwarf2_mark (per_cu->cu);
+      per_cu = per_cu->cu->read_in_chain;
+    }
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      if (!per_cu->cu->mark)
+       {
+         free_one_comp_unit (per_cu->cu);
+         *last_chain = next_cu;
+       }
+      else
+       last_chain = &per_cu->cu->read_in_chain;
+
+      per_cu = next_cu;
+    }
+}
+
+/* Remove a single compilation unit from the cache.  */
+
+static void
+free_one_cached_comp_unit (void *target_cu)
+{
+  struct dwarf2_per_cu_data *per_cu, **last_chain;
+
+  per_cu = dwarf2_per_objfile->read_in_chain;
+  last_chain = &dwarf2_per_objfile->read_in_chain;
+  while (per_cu != NULL)
+    {
+      struct dwarf2_per_cu_data *next_cu;
+
+      next_cu = per_cu->cu->read_in_chain;
+
+      if (per_cu->cu == target_cu)
+       {
+         free_one_comp_unit (per_cu->cu);
+         *last_chain = next_cu;
+         break;
+       }
+      else
+       last_chain = &per_cu->cu->read_in_chain;
+
+      per_cu = next_cu;
+    }
+}
+
+/* Release all extra memory associated with OBJFILE.  */
+
+void
+dwarf2_free_objfile (struct objfile *objfile)
+{
+  dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+
+  if (dwarf2_per_objfile == NULL)
+    return;
+
+  /* Cached DIE trees use xmalloc and the comp_unit_obstack.  */
+  free_cached_comp_units (NULL);
+
+  /* Everything else should be on the objfile obstack.  */
+}
+
+/* A pair of DIE offset and GDB type pointer.  We store these
+   in a hash table separate from the DIEs, and preserve them
+   when the DIEs are flushed out of cache.  */
+
+struct dwarf2_offset_and_type
+{
+  unsigned int offset;
+  struct type *type;
+};
+
+/* Hash function for a dwarf2_offset_and_type.  */
+
+static hashval_t
+offset_and_type_hash (const void *item)
+{
+  const struct dwarf2_offset_and_type *ofs = item;
+  return ofs->offset;
+}
+
+/* Equality function for a dwarf2_offset_and_type.  */
+
+static int
+offset_and_type_eq (const void *item_lhs, const void *item_rhs)
+{
+  const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
+  const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
+  return ofs_lhs->offset == ofs_rhs->offset;
+}
+
+/* Set the type associated with DIE to TYPE.  Save it in CU's hash
+   table if necessary.  For convenience, return TYPE.  */
+
+static struct type *
+set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
+{
+  struct dwarf2_offset_and_type **slot, ofs;
+
+  if (cu->type_hash == NULL)
+    {
+      gdb_assert (cu->per_cu != NULL);
+      cu->per_cu->type_hash
+       = htab_create_alloc_ex (cu->header.length / 24,
+                               offset_and_type_hash,
+                               offset_and_type_eq,
+                               NULL,
+                               &cu->objfile->objfile_obstack,
+                               hashtab_obstack_allocate,
+                               dummy_obstack_deallocate);
+      cu->type_hash = cu->per_cu->type_hash;
+    }
+
+  ofs.offset = die->offset;
+  ofs.type = type;
+  slot = (struct dwarf2_offset_and_type **)
+    htab_find_slot_with_hash (cu->type_hash, &ofs, ofs.offset, INSERT);
+  *slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot));
+  **slot = ofs;
+  return type;
+}
+
+/* Find the type for DIE in CU's type_hash, or return NULL if DIE does
+   not have a saved type.  */
+
+static struct type *
+get_die_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct dwarf2_offset_and_type *slot, ofs;
+  htab_t type_hash = cu->type_hash;
+
+  if (type_hash == NULL)
+    return NULL;
+
+  ofs.offset = die->offset;
+  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+  if (slot)
+    return slot->type;
+  else
+    return NULL;
+}
+
+/* Set the mark field in CU and in every other compilation unit in the
+   cache that we must keep because we are keeping CU.  */
+
+/* Add a dependence relationship from CU to REF_PER_CU.  */
+
+static void
+dwarf2_add_dependence (struct dwarf2_cu *cu,
+                      struct dwarf2_per_cu_data *ref_per_cu)
+{
+  void **slot;
+
+  if (cu->dependencies == NULL)
+    cu->dependencies
+      = htab_create_alloc_ex (5, htab_hash_pointer, htab_eq_pointer,
+                             NULL, &cu->comp_unit_obstack,
+                             hashtab_obstack_allocate,
+                             dummy_obstack_deallocate);
+
+  slot = htab_find_slot (cu->dependencies, ref_per_cu, INSERT);
+  if (*slot == NULL)
+    *slot = ref_per_cu;
 }
 
-/* Allocation function for the libiberty hash table which uses an
-   obstack.  */
+/* Set the mark field in CU and in every other compilation unit in the
+   cache that we must keep because we are keeping CU.  */
 
-static void *
-hashtab_obstack_allocate (void *data, size_t size, size_t count)
+static int
+dwarf2_mark_helper (void **slot, void *data)
 {
-  unsigned int total = size * count;
-  void *ptr = obstack_alloc ((struct obstack *) data, total);
-  memset (ptr, 0, total);
-  return ptr;
+  struct dwarf2_per_cu_data *per_cu;
+
+  per_cu = (struct dwarf2_per_cu_data *) *slot;
+  if (per_cu->cu->mark)
+    return 1;
+  per_cu->cu->mark = 1;
+
+  if (per_cu->cu->dependencies != NULL)
+    htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
+
+  return 1;
 }
 
-/* Trivial deallocation function for the libiberty splay tree and hash
-   table - don't deallocate anything.  Rely on later deletion of the
-   obstack.  */
+static void
+dwarf2_mark (struct dwarf2_cu *cu)
+{
+  if (cu->mark)
+    return;
+  cu->mark = 1;
+  if (cu->dependencies != NULL)
+    htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
+}
 
 static void
-dummy_obstack_deallocate (void *object, void *data)
+dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
 {
-  return;
+  while (per_cu)
+    {
+      per_cu->cu->mark = 0;
+      per_cu = per_cu->cu->read_in_chain;
+    }
 }
 
 /* Trivial hash function for partial_die_info: the hash value of a DIE
@@ -8870,10 +10446,49 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
   return part_die_lhs->offset == part_die_rhs->offset;
 }
 
+static struct cmd_list_element *set_dwarf2_cmdlist;
+static struct cmd_list_element *show_dwarf2_cmdlist;
+
+static void
+set_dwarf2_cmd (char *args, int from_tty)
+{
+  help_list (set_dwarf2_cmdlist, "maintenance set dwarf2 ", -1, gdb_stdout);
+}
+
+static void
+show_dwarf2_cmd (char *args, int from_tty)
+{ 
+  cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
+}
+
 void _initialize_dwarf2_read (void);
 
 void
 _initialize_dwarf2_read (void)
 {
   dwarf2_objfile_data_key = register_objfile_data ();
+
+  add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\
+Set DWARF 2 specific variables.\n\
+Configure DWARF 2 variables such as the cache size"),
+                  &set_dwarf2_cmdlist, "maintenance set dwarf2 ",
+                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+
+  add_prefix_cmd ("dwarf2", class_maintenance, show_dwarf2_cmd, _("\
+Show DWARF 2 specific variables\n\
+Show DWARF 2 variables such as the cache size"),
+                  &show_dwarf2_cmdlist, "maintenance show dwarf2 ",
+                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+
+  add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
+                           &dwarf2_max_cache_age, _("\
+Set the upper bound on the age of cached dwarf2 compilation units."), _("\
+Show the upper bound on the age of cached dwarf2 compilation units."), _("\
+A higher limit means that cached compilation units will be stored\n\
+in memory longer, and more total memory will be used.  Zero disables\n\
+caching, which can slow down startup."),
+                           NULL,
+                           show_dwarf2_max_cache_age,
+                           &set_dwarf2_cmdlist,
+                           &show_dwarf2_cmdlist);
 }
This page took 0.121135 seconds and 4 git commands to generate.