Add a symbol's value to the computed frag offset, rather than overwriting it.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 5338a3f7dcfcf5f1d40fa7277bdd130e491a2d2d..67898e431593dc95c6a24ef31fc847e3b7d3451e 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Inc.  with support from Florida State University (under contract
@@ -8,24 +8,26 @@
    based on Fred Fish's (Cygnus Support) implementation of DWARF 1
    support in dwarfread.c
 
-This file is part of GDB.
+   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.
+   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.
 
-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.  */
+   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.  */
 
 #include "defs.h"
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "symfile.h"
@@ -142,22 +144,14 @@ static unsigned int dwarf_str_size;
 #define MACINFO_SECTION  ".debug_macinfo"
 #define STR_SECTION      ".debug_str"
 
-/* Get at parts of an attribute structure */
-
-#define DW_STRING(attr)    ((attr)->u.str)
-#define DW_UNSND(attr)     ((attr)->u.unsnd)
-#define DW_BLOCK(attr)     ((attr)->u.blk)
-#define DW_SND(attr)       ((attr)->u.snd)
-#define DW_ADDR(attr)     ((attr)->u.addr)
-
 /* local data types */
 
 /* The data in a compilation unit header looks like this.  */
 struct comp_unit_head
   {
-    int length;
+    unsigned int length;
     short version;
-    int abbrev_offset;
+    unsigned int abbrev_offset;
     unsigned char addr_size;
   };
 
@@ -179,10 +173,11 @@ struct line_head
    need this much information. */
 struct partial_die_info
   {
-    unsigned short tag;
+    enum dwarf_tag tag;
     unsigned char has_children;
     unsigned char is_external;
     unsigned char is_declaration;
+    unsigned char has_type;
     unsigned int offset;
     unsigned int abbrev;
     char *name;
@@ -190,14 +185,14 @@ struct partial_die_info
     CORE_ADDR highpc;
     struct dwarf_block *locdesc;
     unsigned int language;
-    int value;
+    char *sibling;
   };
 
 /* This data structure holds the information of an abbrev. */
 struct abbrev_info
   {
     unsigned int number;       /* number identifying abbrev */
-    unsigned int tag;          /* dwarf tag */
+    enum dwarf_tag tag;                /* dwarf tag */
     int has_children;          /* boolean */
     unsigned int num_attrs;    /* number of attributes */
     struct attr_abbrev *attrs; /* an array of attribute descriptions */
@@ -206,29 +201,29 @@ struct abbrev_info
 
 struct attr_abbrev
   {
-    unsigned int name;
-    unsigned int form;
+    enum dwarf_attribute name;
+    enum dwarf_form form;
   };
 
 /* This data structure holds a complete die structure. */
 struct die_info
   {
-    unsigned short tag;                 /* Tag indicating type of die */
-    unsigned short has_children; /* Does the die have children */
-    unsigned int abbrev;        /* Abbrev number */
-    unsigned int offset;        /* Offset in .debug_info section */
-    unsigned int num_attrs;     /* Number of attributes */
-    struct attribute *attrs;    /* An array of attributes */
-    struct die_info *next_ref;  /* Next die in ref hash table */
-    struct die_info *next;      /* Next die in linked list */
-    struct type *type;          /* Cached type information */
+    enum dwarf_tag tag;                /* Tag indicating type of die */
+    unsigned short has_children;       /* Does the die have children */
+    unsigned int abbrev;       /* Abbrev number */
+    unsigned int offset;       /* Offset in .debug_info section */
+    unsigned int num_attrs;    /* Number of attributes */
+    struct attribute *attrs;   /* An array of attributes */
+    struct die_info *next_ref; /* Next die in ref hash table */
+    struct die_info *next;     /* Next die in linked list */
+    struct type *type;         /* Cached type information */
   };
 
 /* Attributes have a name and a value */
 struct attribute
   {
-    unsigned short name;
-    unsigned short form;
+    enum dwarf_attribute name;
+    enum dwarf_form form;
     union
       {
        char *str;
@@ -240,6 +235,14 @@ struct attribute
     u;
   };
 
+/* Get at parts of an attribute structure */
+
+#define DW_STRING(attr)    ((attr)->u.str)
+#define DW_UNSND(attr)     ((attr)->u.unsnd)
+#define DW_BLOCK(attr)     ((attr)->u.blk)
+#define DW_SND(attr)       ((attr)->u.snd)
+#define DW_ADDR(attr)     ((attr)->u.addr)
+
 /* Blocks are a bunch of untyped bytes. */
 struct dwarf_block
   {
@@ -300,13 +303,28 @@ static struct partial_die_info zeroed_partial_die;
    in buildsym.c.  */
 static struct pending **list_in_scope = &file_symbols;
 
-/* FIXME: The following variables pass additional information from
-   decode_locdesc to the caller.  */
-static int optimized_out;      /* Kludge to identify optimized out variables */
-static int isreg;              /* Kludge to identify register variables */
-static int offreg;             /* Kludge to identify basereg references */
-static int basereg;            /* Which base register is it relative to?  */
-static int islocal;            /* Kludge to identify local variables */
+/* 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 optimized_out;      /* No ops in location in expression,
+                                  so object was optimized out.  */
+static int isreg;              /* Object lives in register.
+                                  decode_locdesc's return value is
+                                  the register number.  */
+static int offreg;             /* Object's address is the sum of the
+                                  register specified by basereg, plus
+                                  the offset returned.  */
+static int basereg;            /* See `offreg'.  */
+static int isderef;            /* Value described by flags above is
+                                  the address of a pointer to the object.  */
+static int islocal;            /* Variable is at the returned offset
+                                  from the frame start, but there's
+                                  no identified frame pointer for
+                                  this function, so we can't say
+                                  which register it's relative to;
+                                  use LOC_LOCAL.  */
 
 /* DW_AT_frame_base values for the current function.
    frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
@@ -331,27 +349,27 @@ static CORE_ADDR baseaddr;        /* Add to each symbol value */
    of symbols read from an object file.  */
 
 struct dwarf2_pinfo
-{
-  /* Pointer to start of dwarf info buffer for the objfile.  */
+  {
+    /* Pointer to start of dwarf info buffer for the objfile.  */
 
-  char *dwarf_info_buffer;
+    char *dwarf_info_buffer;
 
-  /* Offset in dwarf_info_buffer for this compilation unit. */
+    /* Offset in dwarf_info_buffer for this compilation unit. */
 
-  unsigned long dwarf_info_offset;
+    unsigned long dwarf_info_offset;
 
-  /* Pointer to start of dwarf abbreviation buffer for the objfile.  */
+    /* Pointer to start of dwarf abbreviation buffer for the objfile.  */
 
-  char *dwarf_abbrev_buffer;
+    char *dwarf_abbrev_buffer;
 
-  /* Size of dwarf abbreviation section for the objfile.  */
+    /* Size of dwarf abbreviation section for the objfile.  */
 
-  unsigned int dwarf_abbrev_size;
+    unsigned int dwarf_abbrev_size;
 
-  /* Pointer to start of dwarf line buffer for the objfile.  */
+    /* Pointer to start of dwarf line buffer for the objfile.  */
 
-  char *dwarf_line_buffer;
-};
+    char *dwarf_line_buffer;
+  };
 
 #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
 #define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer)
@@ -371,9 +389,70 @@ struct dwarf2_pinfo
    fundamental types gdb knows how to construct.  */
 static struct type *ftypes[FT_NUM_MEMBERS];    /* Fundamental types */
 
-/* FIXME - set from bfd function */
+/* 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.  */
 static int bits_per_byte = 8;
 
+/* The routines that read and process dies for a C struct or C++ class
+   pass lists of data member fields and lists of member function fields
+   in an instance of a field_info structure, as defined below.  */
+struct field_info
+  {
+    /* List of data member and baseclasses fields. */
+    struct nextfield
+      {
+       struct nextfield *next;
+       int accessibility;
+       int virtuality;
+       struct field field;
+      }
+     *fields;
+
+    /* Number of fields.  */
+    int nfields;
+
+    /* Number of baseclasses.  */
+    int nbaseclasses;
+
+    /* Set if the accesibility of one of the fields is not public.  */
+    int non_public_fields;
+
+    /* Member function fields array, entries are allocated in the order they
+       are encountered in the object file.  */
+    struct nextfnfield
+      {
+       struct nextfnfield *next;
+       struct fn_field fnfield;
+      }
+     *fnfields;
+
+    /* Member function fieldlist array, contains name of possibly overloaded
+       member function, number of overloaded member functions and a pointer
+       to the head of the member function field chain.  */
+    struct fnfieldlist
+      {
+       char *name;
+       int length;
+       struct nextfnfield *head;
+      }
+     *fnfieldlists;
+
+    /* Number of entries in the fnfieldlists array.  */
+    int nfnfields;
+  };
+
+/* FIXME: Kludge to mark a varargs function type for C++ member function
+   argument processing.  */
+#define TYPE_FLAG_VARARGS      (1 << 10)
+
+/* Dwarf2 has no clean way to discern C++ static and non-static member
+   functions. G++ helps GDB by marking the first parameter for non-static
+   member functions (which is the this pointer) as artificial.
+   We pass this information between dwarf2_add_member_fn and
+   read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
+#define TYPE_FIELD_ARTIFICIAL  TYPE_FIELD_BITPOS
+
 /* Various complaints about symbol reading that don't abort the process */
 
 static struct complaint dwarf2_const_ignored =
@@ -386,7 +465,7 @@ static struct complaint dwarf2_volatile_ignored =
 };
 static struct complaint dwarf2_non_const_array_bound_ignored =
 {
-  "non-constant array bounds form %s ignored", 0, 0
+  "non-constant array bounds form '%s' ignored", 0, 0
 };
 static struct complaint dwarf2_missing_line_number_section =
 {
@@ -398,12 +477,16 @@ static struct complaint dwarf2_mangled_line_number_section =
 };
 static struct complaint dwarf2_unsupported_die_ref_attr =
 {
-  "unsupported die ref attribute form: %s", 0, 0
+  "unsupported die ref attribute form: '%s'", 0, 0
 };
 static struct complaint dwarf2_unsupported_stack_op =
 {
   "unsupported stack op: '%s'", 0, 0
 };
+static struct complaint dwarf2_complex_location_expr =
+{
+  "location expression too complex", 0, 0
+};
 static struct complaint dwarf2_unsupported_tag =
 {
   "unsupported tag: '%s'", 0, 0
@@ -416,13 +499,45 @@ static struct complaint dwarf2_unsupported_at_frame_base =
 {
   "unsupported DW_AT_frame_base for function '%s'", 0, 0
 };
+static struct complaint dwarf2_unexpected_tag =
+{
+  "unexepected tag in read_type_die: '%s'", 0, 0
+};
 static struct complaint dwarf2_missing_at_frame_base =
 {
   "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0
 };
 static struct complaint dwarf2_bad_static_member_name =
 {
-  "unrecognized static data member name %s", 0, 0
+  "unrecognized static data member name '%s'", 0, 0
+};
+static struct complaint dwarf2_unsupported_accessibility =
+{
+  "unsupported accessibility %d", 0, 0
+};
+static struct complaint dwarf2_bad_member_name_complaint =
+{
+  "cannot extract member name from '%s'", 0, 0
+};
+static struct complaint dwarf2_missing_member_fn_type_complaint =
+{
+  "member function type missing for '%s'", 0, 0
+};
+static struct complaint dwarf2_vtbl_not_found_complaint =
+{
+  "virtual function table pointer not found when defining class '%s'", 0, 0
+};
+static struct complaint dwarf2_absolute_sibling_complaint =
+{
+  "ignoring absolute DW_AT_sibling", 0, 0
+};
+static struct complaint dwarf2_const_value_length_mismatch =
+{
+  "const value length mismatch for '%s', got %d, expected %d", 0, 0
+};
+static struct complaint dwarf2_unsupported_const_value_attr =
+{
+  "unsupported const value attribute form: '%s'", 0, 0
 };
 
 /* Remember the addr_size read from the dwarf.
@@ -431,6 +546,15 @@ static struct complaint dwarf2_bad_static_member_name =
    whatever scope is currently getting read. */
 static int address_size;
 
+/* Some elf32 object file formats while linked for a 32 bit address
+   space contain debug information that has assumed 64 bit
+   addresses. Eg 64 bit MIPS target produced by GCC/GAS/LD where the
+   symbol table contains 32bit address values while its .debug_info
+   section contains 64 bit address values.
+   ADDRESS_SIGNIFICANT_SIZE specifies the number significant bits in
+   the ADDRESS_SIZE bytes read from the file */
+static int address_significant_size;
+
 /* Externals references.  */
 extern int info_verbose;       /* From main.c; nonzero => verbose */
 
@@ -439,14 +563,10 @@ extern int info_verbose;  /* From main.c; nonzero => verbose */
 static void dwarf2_locate_sections PARAMS ((bfd *, asection *, PTR));
 
 #if 0
-static void dwarf2_build_psymtabs_easy PARAMS ((struct objfile *,
-                                               struct section_offsets *,
-                                               int));
+static void dwarf2_build_psymtabs_easy PARAMS ((struct objfile *, int));
 #endif
 
-static void dwarf2_build_psymtabs_hard PARAMS ((struct objfile *,
-                                               struct section_offsets *,
-                                               int));
+static void dwarf2_build_psymtabs_hard PARAMS ((struct objfile *, int));
 
 static char *scan_partial_symbols PARAMS ((char *, struct objfile *,
                                           CORE_ADDR *, CORE_ADDR *));
@@ -472,6 +592,9 @@ static char *read_partial_die PARAMS ((struct partial_die_info *,
 
 static char *read_full_die PARAMS ((struct die_info **, bfd *, char *));
 
+static char *read_attribute PARAMS ((struct attribute *, struct attr_abbrev *,
+                                    bfd *, char *));
+
 static unsigned int read_1_byte PARAMS ((bfd *, char *));
 
 static int read_1_signed_byte PARAMS ((bfd *, char *));
@@ -498,6 +621,8 @@ static void set_cu_language PARAMS ((unsigned int));
 static struct attribute *dwarf_attr PARAMS ((struct die_info *,
                                             unsigned int));
 
+static int die_is_declaration (struct die_info *);
+
 static void dwarf_decode_lines PARAMS ((unsigned int, char *, bfd *));
 
 static void dwarf2_start_subfile PARAMS ((char *, char *));
@@ -505,6 +630,13 @@ static void dwarf2_start_subfile PARAMS ((char *, char *));
 static struct symbol *new_symbol PARAMS ((struct die_info *, struct type *,
                                          struct objfile *));
 
+static void dwarf2_const_value PARAMS ((struct attribute *, struct symbol *,
+                                       struct objfile *));
+
+static void dwarf2_const_value_data (struct attribute *attr,
+                                    struct symbol *sym,
+                                    int bits);
+
 static struct type *die_type PARAMS ((struct die_info *, struct objfile *));
 
 static struct type *die_containing_type PARAMS ((struct die_info *,
@@ -530,19 +662,37 @@ static void read_func_scope PARAMS ((struct die_info *, struct objfile *));
 static void read_lexical_block_scope PARAMS ((struct die_info *,
                                              struct objfile *));
 
+static int dwarf2_get_pc_bounds PARAMS ((struct die_info *,
+                                        CORE_ADDR *, CORE_ADDR *,
+                                        struct objfile *));
+
+static void dwarf2_add_field PARAMS ((struct field_info *, struct die_info *,
+                                     struct objfile *));
+
+static void dwarf2_attach_fields_to_type PARAMS ((struct field_info *,
+                                                 struct type *,
+                                                 struct objfile *));
+
+static void dwarf2_add_member_fn PARAMS ((struct field_info *,
+                                         struct die_info *, struct type *,
+                                         struct objfile * objfile));
+
+static void dwarf2_attach_fn_fields_to_type PARAMS ((struct field_info *,
+                                                    struct type *,
+                                                    struct objfile *));
+
 static void read_structure_scope PARAMS ((struct die_info *, struct objfile *));
 
 static void read_common_block PARAMS ((struct die_info *, struct objfile *));
 
 static void read_enumeration PARAMS ((struct die_info *, struct objfile *));
 
-static struct type * dwarf_base_type PARAMS ((int, int));
+static struct type *dwarf_base_type PARAMS ((int, int, struct objfile *));
 
 static CORE_ADDR decode_locdesc PARAMS ((struct dwarf_block *,
                                         struct objfile *));
 
-static void dwarf_read_array_type PARAMS ((struct die_info *,
-                                          struct objfile *));
+static void read_array_type PARAMS ((struct die_info *, struct objfile *));
 
 static void read_tag_pointer_type PARAMS ((struct die_info *,
                                           struct objfile *));
@@ -570,6 +720,8 @@ static void free_die_list PARAMS ((struct die_info *));
 
 static void process_die PARAMS ((struct die_info *, struct objfile *));
 
+static char *dwarf2_linkage_name PARAMS ((struct die_info *));
+
 static char *dwarf_tag_name PARAMS ((unsigned int));
 
 static char *dwarf_attr_name PARAMS ((unsigned int));
@@ -580,8 +732,6 @@ static char *dwarf_stack_op_name PARAMS ((unsigned int));
 
 static char *dwarf_bool_name PARAMS ((unsigned int));
 
-static char *dwarf_bool_name PARAMS ((unsigned int));
-
 static char *dwarf_type_encoding_name PARAMS ((unsigned int));
 
 #if 0
@@ -690,10 +840,9 @@ dwarf2_locate_sections (ignore_abfd, sectp, ignore_ptr)
 /* Build a partial symbol table.  */
 
 void
-dwarf2_build_psymtabs (objfile, section_offsets, mainline)
-    struct objfile *objfile;
-    struct section_offsets *section_offsets;
-    int mainline;
+dwarf2_build_psymtabs (objfile, mainline)
+     struct objfile *objfile;
+     int mainline;
 {
 
   /* We definitely need the .debug_info and .debug_abbrev sections */
@@ -717,17 +866,17 @@ dwarf2_build_psymtabs (objfile, section_offsets, mainline)
 #if 0
   if (dwarf_aranges_offset && dwarf_pubnames_offset)
     {
-      /* Things are significanlty easier if we have .debug_aranges and
+      /* Things are significantly easier if we have .debug_aranges and
          .debug_pubnames sections */
 
-      dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline);
+      dwarf2_build_psymtabs_easy (objfile, mainline);
     }
   else
 #endif
     /* only test this case for now */
-    {          
+    {
       /* In this case we have to work a bit harder */
-      dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline);
+      dwarf2_build_psymtabs_hard (objfile, mainline);
     }
 }
 
@@ -736,9 +885,8 @@ dwarf2_build_psymtabs (objfile, section_offsets, mainline)
    .debug_pubnames and .debug_aranges sections.  */
 
 static void
-dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline)
+dwarf2_build_psymtabs_easy (objfile, mainline)
      struct objfile *objfile;
-     struct section_offsets *section_offsets;
      int mainline;
 {
   bfd *abfd = objfile->obfd;
@@ -773,9 +921,8 @@ dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline)
    .debug_info and .debug_abbrev sections.  */
 
 static void
-dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
+dwarf2_build_psymtabs_hard (objfile, mainline)
      struct objfile *objfile;
-     struct section_offsets *section_offsets;
      int mainline;
 {
   /* Instead of reading this into a big buffer, we should probably use
@@ -790,6 +937,9 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
   int comp_unit_has_pc_info;
   CORE_ADDR lowpc, highpc;
 
+  /* Number of bytes of any addresses that are signficant */
+  address_significant_size = get_elf_backend_data (abfd)->s->arch_size / 8;
+
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
 
@@ -797,7 +947,7 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
   while ((unsigned int) (info_ptr - dwarf_info_buffer)
-         + ((info_ptr - dwarf_info_buffer) % 4) < dwarf_info_size)
+        + ((info_ptr - dwarf_info_buffer) % 4) < dwarf_info_size)
     {
       beg_of_comp_unit = info_ptr;
       cu_header.length = read_4_bytes (abfd, info_ptr);
@@ -815,6 +965,27 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
          error ("Dwarf Error: wrong version in compilation unit header.");
          return;
        }
+      if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+       {
+         error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+                (long) cu_header.abbrev_offset,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      if (beg_of_comp_unit + cu_header.length + 4
+         > dwarf_info_buffer + dwarf_info_size)
+       {
+         error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+                (long) cu_header.length,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      if (address_size < address_significant_size)
+       {
+         error ("Dwarf Error: bad address size (%ld) in compilation unit header (offset 0x%lx + 11).",
+                (long) cu_header.addr_size,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+       }
 
       /* Read the abbrevs for this compilation unit into a table */
       dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
@@ -828,35 +999,41 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
       set_cu_language (comp_unit_die.language);
 
       /* Allocate a new partial symbol table structure */
-      pst = start_psymtab_common (objfile, section_offsets,
-                                 comp_unit_die.name,
+      pst = start_psymtab_common (objfile, objfile->section_offsets,
+                                 comp_unit_die.name ? comp_unit_die.name : "",
                                  comp_unit_die.lowpc,
                                  objfile->global_psymbols.next,
                                  objfile->static_psymbols.next);
 
       pst->read_symtab_private = (char *)
        obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
-      DWARF_INFO_BUFFER(pst) = dwarf_info_buffer;
-      DWARF_INFO_OFFSET(pst) = beg_of_comp_unit - dwarf_info_buffer;
-      DWARF_ABBREV_BUFFER(pst) = dwarf_abbrev_buffer;
-      DWARF_ABBREV_SIZE(pst) = dwarf_abbrev_size;
-      DWARF_LINE_BUFFER(pst) = dwarf_line_buffer;
-      baseaddr = ANOFFSET (section_offsets, 0);
+      cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+      DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
+      DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
+      DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
+      DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
+      DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
+      baseaddr = ANOFFSET (objfile->section_offsets, 0);
 
       /* Store the function that reads in the rest of the symbol table */
       pst->read_symtab = dwarf2_psymtab_to_symtab;
 
-      /* Read the rest of the partial symbols from this comp unit */
-      info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc);
-
-      /* If the compilation unit didn't have an explicit address range,
-        then use the information extracted from its child dies.  */
-      if (!comp_unit_has_pc_info)
+      /* 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)
        {
-         comp_unit_die.lowpc  = lowpc;
-         comp_unit_die.highpc = highpc;
-        }
-      pst->textlow  = comp_unit_die.lowpc + baseaddr;
+         info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc);
+
+         /* If the compilation unit didn't have an explicit address range,
+            then use the information extracted from its child dies.  */
+         if (!comp_unit_has_pc_info)
+           {
+             comp_unit_die.lowpc = lowpc;
+             comp_unit_die.highpc = highpc;
+           }
+       }
+      pst->textlow = comp_unit_die.lowpc + baseaddr;
       pst->texthigh = comp_unit_die.highpc + baseaddr;
 
       pst->n_global_syms = objfile->global_psymbols.next -
@@ -886,61 +1063,96 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc)
 {
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
-  int nesting_level = 1;       /* we've already read in comp_unit_die */
+
+  /* This function is called after we've read in the comp_unit_die in
+     order to read its children.  We start the nesting level at 1 since
+     we have pushed 1 level down in order to read the comp unit's children.
+     The comp unit itself is at level 0, so we stop reading when we pop
+     back to that level. */
+
+  int nesting_level = 1;
   int has_pc_info;
 
-  *lowpc  = ((CORE_ADDR) -1);
+  *lowpc = ((CORE_ADDR) -1);
   *highpc = ((CORE_ADDR) 0);
-  do
+
+  while (nesting_level)
     {
       info_ptr = read_partial_die (&pdi, abfd, info_ptr, &has_pc_info);
-      switch (pdi.tag)
+
+      if (pdi.name)
        {
-       case DW_TAG_subprogram:
-       case DW_TAG_variable:
-       case DW_TAG_typedef:
-       case DW_TAG_class_type:
-       case DW_TAG_structure_type:
-       case DW_TAG_union_type:
-       case DW_TAG_enumeration_type:
-         if (pdi.is_external || nesting_level == 1)
+         switch (pdi.tag)
            {
-             if (pdi.name && !pdi.is_declaration)
+           case DW_TAG_subprogram:
+             if (has_pc_info)
+               {
+                 if (pdi.lowpc < *lowpc)
+                   {
+                     *lowpc = pdi.lowpc;
+                   }
+                 if (pdi.highpc > *highpc)
+                   {
+                     *highpc = pdi.highpc;
+                   }
+                 if ((pdi.is_external || nesting_level == 1)
+                     && !pdi.is_declaration)
+                   {
+                     add_partial_symbol (&pdi, objfile);
+                   }
+               }
+             break;
+           case DW_TAG_variable:
+           case DW_TAG_typedef:
+           case DW_TAG_class_type:
+           case DW_TAG_structure_type:
+           case DW_TAG_union_type:
+           case DW_TAG_enumeration_type:
+             if ((pdi.is_external || nesting_level == 1)
+                 && !pdi.is_declaration)
                {
                  add_partial_symbol (&pdi, objfile);
                }
+             break;
+           case DW_TAG_enumerator:
+             /* File scope enumerators are added to the partial symbol
+                table.  */
+             if (nesting_level == 2)
+               add_partial_symbol (&pdi, objfile);
+             break;
+           case DW_TAG_base_type:
+             /* File scope base type definitions are added to the partial
+                symbol table.  */
+             if (nesting_level == 1)
+               add_partial_symbol (&pdi, objfile);
+             break;
+           default:
+             break;
            }
-          if (has_pc_info)
-            {
-              if (pdi.lowpc < *lowpc)
-                {
-                  *lowpc = pdi.lowpc;
-                }
-              if (pdi.highpc > *highpc)
-                {
-                  *highpc = pdi.highpc;
-                }
-            }
-         break;
-       case DW_TAG_enumerator:
-         /* File scope enumerators are added to the partial symbol table.  */
-         if (pdi.name && nesting_level == 2)
-           add_partial_symbol (&pdi, objfile);
-         break;
        }
-      if (pdi.has_children)
+
+      /* If the die has a sibling, skip to the sibling.
+         Do not skip enumeration types, we want to record their
+         enumerators.  */
+      if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type)
+       {
+         info_ptr = pdi.sibling;
+       }
+      else if (pdi.has_children)
        {
+         /* Die has children, but the optional DW_AT_sibling attribute
+            is missing.  */
          nesting_level++;
        }
+
       if (pdi.tag == 0)
        {
          nesting_level--;
        }
     }
-  while (nesting_level);
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
-     from `maint check.  */
+     from `maint check'.  */
   if (*lowpc == ((CORE_ADDR) -1))
     *lowpc = *highpc;
   return info_ptr;
@@ -951,57 +1163,70 @@ add_partial_symbol (pdi, objfile)
      struct partial_die_info *pdi;
      struct objfile *objfile;
 {
+  CORE_ADDR addr = 0;
+
   switch (pdi->tag)
     {
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
-         prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
-                                     mst_text, objfile);
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+            mst_text, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_BLOCK,
                               &objfile->global_psymbols,
-                              0, pdi->lowpc + baseaddr, cu_language, objfile);
+                           0, pdi->lowpc + baseaddr, cu_language, objfile);
        }
       else
        {
-         prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
-                                     mst_file_text, objfile);
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+            mst_file_text, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_BLOCK,
                               &objfile->static_psymbols,
-                              0, pdi->lowpc + baseaddr, cu_language, objfile);
+                           0, pdi->lowpc + baseaddr, cu_language, objfile);
        }
       break;
     case DW_TAG_variable:
-      /* Skip symbols without location desciptors, these are external
-        references. */
-      if (pdi->locdesc == NULL)
-       return;
       if (pdi->is_external)
        {
-         prim_record_minimal_symbol (pdi->name,
-                                     decode_locdesc (pdi->locdesc, objfile)
-                                       + baseaddr,
-                                     mst_data, objfile);
-         add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_STATIC,
-                              &objfile->global_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+         /* Global Variable.
+            Don't enter into the minimal symbol tables as there is
+            a minimal symbol table entry from the ELF symbols already.
+            Enter into partial symbol table if it has a location
+            descriptor or a type.
+            If the location descriptor is missing, new_symbol will create
+            a LOC_UNRESOLVED symbol, the address of the variable will then
+            be determined from the minimal symbol table whenever the variable
+            is referenced.
+            The address for the partial symbol table entry is not
+            used by GDB, but it comes in handy for debugging partial symbol
+            table building.  */
+
+         if (pdi->locdesc)
+           addr = decode_locdesc (pdi->locdesc, objfile);
+         if (pdi->locdesc || pdi->has_type)
+           add_psymbol_to_list (pdi->name, strlen (pdi->name),
+                                VAR_NAMESPACE, LOC_STATIC,
+                                &objfile->global_psymbols,
+                                0, addr + baseaddr, cu_language, objfile);
        }
       else
        {
-         prim_record_minimal_symbol (pdi->name,
-                                     decode_locdesc (pdi->locdesc, objfile)
-                                       + baseaddr,
-                                     mst_file_data, objfile);
+         /* Static Variable. Skip symbols without location descriptors.  */
+         if (pdi->locdesc == NULL)
+           return;
+         addr = decode_locdesc (pdi->locdesc, objfile);
+         /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+            mst_file_data, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_STATIC,
                               &objfile->static_psymbols,
-                              0, (CORE_ADDR) 0, cu_language, objfile);
+                              0, addr + baseaddr, cu_language, objfile);
        }
       break;
     case DW_TAG_typedef:
+    case DW_TAG_base_type:
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
                           VAR_NAMESPACE, LOC_TYPEDEF,
                           &objfile->static_psymbols,
@@ -1012,7 +1237,7 @@ add_partial_symbol (pdi, objfile)
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
       /* Skip aggregate types without children, these are external
-        references.  */
+         references.  */
       if (pdi->has_children == 0)
        return;
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
@@ -1035,6 +1260,8 @@ add_partial_symbol (pdi, objfile)
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
       break;
+    default:
+      break;
     }
 }
 
@@ -1076,21 +1303,19 @@ psymtab_to_symtab_1 (pst)
   bfd *abfd = objfile->obfd;
   struct comp_unit_head cu_header;
   struct die_info *dies;
-  struct attribute *attr;
   unsigned long offset;
-  CORE_ADDR highpc;
-  struct attribute *high_pc_attr;
+  CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
   char *info_ptr;
   struct symtab *symtab;
   struct cleanup *back_to;
 
   /* Set local variables from the partial symbol table info.  */
-  offset = DWARF_INFO_OFFSET(pst);
-  dwarf_info_buffer = DWARF_INFO_BUFFER(pst);
-  dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER(pst);
-  dwarf_abbrev_size = DWARF_ABBREV_SIZE(pst);
-  dwarf_line_buffer = DWARF_LINE_BUFFER(pst);
+  offset = DWARF_INFO_OFFSET (pst);
+  dwarf_info_buffer = DWARF_INFO_BUFFER (pst);
+  dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
+  dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
+  dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
   baseaddr = ANOFFSET (pst->section_offsets, 0);
   cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
@@ -1117,21 +1342,16 @@ psymtab_to_symtab_1 (pst)
 
   dies = read_comp_unit (info_ptr, abfd);
 
-  make_cleanup (free_die_list, dies);
+  make_cleanup ((make_cleanup_func) free_die_list, dies);
 
   /* Do line number decoding in read_file_scope () */
   process_die (dies, objfile);
 
-  attr = dwarf_attr (dies, DW_AT_high_pc);
-  if (attr)
-    {
-      highpc = DW_ADDR (attr);
-    }
-  else
+  if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile))
     {
       /* 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.  */
+         the compilation unit.   If the DW_AT_high_pc is missing,
+         synthesize it, by scanning the DIE's below the compilation unit.  */
       highpc = 0;
       if (dies->has_children)
        {
@@ -1140,10 +1360,11 @@ psymtab_to_symtab_1 (pst)
            {
              if (child_die->tag == DW_TAG_subprogram)
                {
-                 high_pc_attr = dwarf_attr (child_die, DW_AT_high_pc);
-                 if (high_pc_attr)
+                 CORE_ADDR low, high;
+
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
                    {
-                     highpc = max (highpc, DW_ADDR (high_pc_attr));
+                     highpc = max (highpc, high);
                    }
                }
              child_die = sibling_die (child_die);
@@ -1183,10 +1404,12 @@ process_die (die, objfile)
       break;
     case DW_TAG_subprogram:
       read_subroutine_type (die, objfile);
-      if (dwarf_attr (die, DW_AT_low_pc))
-       {
-         read_func_scope (die, objfile);
-       }
+      read_func_scope (die, objfile);
+      break;
+    case DW_TAG_inlined_subroutine:
+      /* FIXME:  These are ignored for now.
+         They could be used to set breakpoints on all inlined instances
+         of a function and make GDB `next' properly over inlined functions.  */
       break;
     case DW_TAG_lexical_block:
       read_lexical_block_scope (die, objfile);
@@ -1203,7 +1426,7 @@ process_die (die, objfile)
       read_subroutine_type (die, objfile);
       break;
     case DW_TAG_array_type:
-      dwarf_read_array_type (die, objfile);
+      read_array_type (die, objfile);
       break;
     case DW_TAG_pointer_type:
       read_tag_pointer_type (die, objfile);
@@ -1219,6 +1442,11 @@ process_die (die, objfile)
       break;
     case DW_TAG_base_type:
       read_base_type (die, objfile);
+      if (dwarf_attr (die, DW_AT_name))
+       {
+         /* Add a typedef symbol for the base type definition.  */
+         new_symbol (die, die->type, objfile);
+       }
       break;
     case DW_TAG_common_block:
       read_common_block (die, objfile);
@@ -1237,25 +1465,15 @@ read_file_scope (die, objfile)
      struct objfile *objfile;
 {
   unsigned int line_offset = 0;
-  CORE_ADDR lowpc  = ((CORE_ADDR) -1);
+  CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
-  struct attribute *attr, *low_pc_attr, *high_pc_attr;
+  struct attribute *attr;
   char *name = "<unknown>";
   char *comp_dir = NULL;
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
 
-  low_pc_attr = dwarf_attr (die, DW_AT_low_pc);
-  if (low_pc_attr)
-    {
-      lowpc = DW_ADDR (low_pc_attr);
-    }
-  high_pc_attr = dwarf_attr (die, DW_AT_high_pc);
-  if (high_pc_attr)
-    {
-      highpc = DW_ADDR (high_pc_attr);
-    }
-  if (!low_pc_attr || !high_pc_attr)
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
     {
       if (die->has_children)
        {
@@ -1264,15 +1482,12 @@ read_file_scope (die, objfile)
            {
              if (child_die->tag == DW_TAG_subprogram)
                {
-                 low_pc_attr = dwarf_attr (child_die, DW_AT_low_pc);
-                 if (low_pc_attr)
-                   {
-                     lowpc = min (lowpc, DW_ADDR (low_pc_attr));
-                   }
-                 high_pc_attr = dwarf_attr (child_die, DW_AT_high_pc);
-                 if (high_pc_attr)
+                 CORE_ADDR low, high;
+
+                 if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
                    {
-                     highpc = max (highpc, DW_ADDR (high_pc_attr));
+                     lowpc = min (lowpc, low);
+                     highpc = max (highpc, high);
                    }
                }
              child_die = sibling_die (child_die);
@@ -1320,9 +1535,11 @@ read_file_scope (die, objfile)
       set_cu_language (DW_UNSND (attr));
     }
 
+  /* We assume that we're processing GCC output. */
+  processing_gcc_compilation = 2;
 #if 0
-    /* FIXME:Do something here.  */
-    if (dip->at_producer != NULL)
+  /* FIXME:Do something here.  */
+  if (dip->at_producer != NULL)
     {
       handle_producer (dip->at_producer);
     }
@@ -1333,6 +1550,7 @@ read_file_scope (die, objfile)
   memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
 
   start_symtab (name, comp_dir, lowpc);
+  record_debugformat ("DWARF 2");
 
   /* Decode line number information if present.  */
   attr = dwarf_attr (die, DW_AT_stmt_list);
@@ -1360,29 +1578,19 @@ read_func_scope (die, objfile)
      struct objfile *objfile;
 {
   register struct context_stack *new;
-  CORE_ADDR lowpc  = 0;
-  CORE_ADDR highpc = 0;
+  CORE_ADDR lowpc;
+  CORE_ADDR highpc;
   struct die_info *child_die;
   struct attribute *attr;
-  char *name = "<unknown>";
+  char *name;
 
-  attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
-    {
-      name = DW_STRING (attr);
-    }
+  name = dwarf2_linkage_name (die);
 
-  attr = dwarf_attr (die, DW_AT_low_pc);
-  if (attr)
-    {
-      lowpc = DW_ADDR (attr);
-    }
+  /* Ignore functions with missing or empty names and functions with
+     missing or invalid low and high pc attributes.  */
+  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+    return;
 
-  attr = dwarf_attr (die, DW_AT_high_pc);
-  if (attr)
-    {
-      highpc = DW_ADDR (attr);
-    }
   lowpc += baseaddr;
   highpc += baseaddr;
 
@@ -1393,12 +1601,6 @@ read_func_scope (die, objfile)
       objfile->ei.entry_func_highpc = highpc;
     }
 
-  if (STREQ (name, "main"))    /* FIXME: hardwired name */
-    {
-      objfile->ei.main_func_lowpc = lowpc;
-      objfile->ei.main_func_highpc = highpc;
-    }
-
   /* Decode DW_AT_frame_base location descriptor if present, keep result
      for DW_OP_fbreg operands in decode_locdesc.  */
   frame_base_reg = -1;
@@ -1407,7 +1609,9 @@ read_func_scope (die, objfile)
   if (attr)
     {
       CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile);
-      if (isreg)
+      if (isderef)
+       complain (&dwarf2_unsupported_at_frame_base, name);
+      else if (isreg)
        frame_base_reg = addr;
       else if (offreg)
        {
@@ -1448,20 +1652,12 @@ read_lexical_block_scope (die, objfile)
      struct objfile *objfile;
 {
   register struct context_stack *new;
-  CORE_ADDR lowpc = 0, highpc = 0;
-  struct attribute *attr;
+  CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
 
-  attr = dwarf_attr (die, DW_AT_low_pc);
-  if (attr)
-    {
-      lowpc = DW_ADDR (attr);
-    }
-  attr = dwarf_attr (die, DW_AT_high_pc);
-  if (attr)
-    {
-      highpc = DW_ADDR (attr);
-    }
+  /* Ignore blocks with missing or invalid low and high pc attributes.  */
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
+    return;
   lowpc += baseaddr;
   highpc += baseaddr;
 
@@ -1485,6 +1681,464 @@ read_lexical_block_scope (die, objfile)
   local_symbols = new->locals;
 }
 
+/* Get low and high pc attributes from a die.
+   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+
+static int
+dwarf2_get_pc_bounds (die, lowpc, highpc, objfile)
+     struct die_info *die;
+     CORE_ADDR *lowpc;
+     CORE_ADDR *highpc;
+     struct objfile *objfile;
+{
+  struct attribute *attr;
+  CORE_ADDR low;
+  CORE_ADDR high;
+
+  attr = dwarf_attr (die, DW_AT_low_pc);
+  if (attr)
+    low = DW_ADDR (attr);
+  else
+    return 0;
+  attr = dwarf_attr (die, DW_AT_high_pc);
+  if (attr)
+    high = DW_ADDR (attr);
+  else
+    return 0;
+
+  if (high < low)
+    return 0;
+
+  /* When using the GNU linker, .gnu.linkonce. sections are used to
+     eliminate duplicate copies of functions and vtables and such.
+     The linker will arbitrarily choose one and discard the others.
+     The AT_*_pc values for such functions refer to local labels in
+     these sections.  If the section from that file was discarded, the
+     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 (objfile->obfd) & HAS_RELOC) == 0)
+    return 0;
+
+  *lowpc = low;
+  *highpc = high;
+  return 1;
+}
+
+/* Add an aggregate field to the field list.  */
+
+static void
+dwarf2_add_field (fip, die, objfile)
+     struct field_info *fip;
+     struct die_info *die;
+     struct objfile *objfile;
+{
+  struct nextfield *new_field;
+  struct attribute *attr;
+  struct field *fp;
+  char *fieldname = "";
+
+  /* Allocate a new field list entry and link it in.  */
+  new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+  make_cleanup (free, new_field);
+  memset (new_field, 0, sizeof (struct nextfield));
+  new_field->next = fip->fields;
+  fip->fields = new_field;
+  fip->nfields++;
+
+  /* Handle accessibility and virtuality of field.
+     The default accessibility for members is public, the default
+     accessibility for inheritance is private.  */
+  if (die->tag != DW_TAG_inheritance)
+    new_field->accessibility = DW_ACCESS_public;
+  else
+    new_field->accessibility = DW_ACCESS_private;
+  new_field->virtuality = DW_VIRTUALITY_none;
+
+  attr = dwarf_attr (die, DW_AT_accessibility);
+  if (attr)
+    new_field->accessibility = DW_UNSND (attr);
+  if (new_field->accessibility != DW_ACCESS_public)
+    fip->non_public_fields = 1;
+  attr = dwarf_attr (die, DW_AT_virtuality);
+  if (attr)
+    new_field->virtuality = DW_UNSND (attr);
+
+  fp = &new_field->field;
+  if (die->tag == DW_TAG_member)
+    {
+      /* Get type of field.  */
+      fp->type = die_type (die, objfile);
+
+      /* Get bit size of field (zero if none).  */
+      attr = dwarf_attr (die, DW_AT_bit_size);
+      if (attr)
+       {
+         FIELD_BITSIZE (*fp) = DW_UNSND (attr);
+       }
+      else
+       {
+         FIELD_BITSIZE (*fp) = 0;
+       }
+
+      /* Get bit offset of field.  */
+      attr = dwarf_attr (die, DW_AT_data_member_location);
+      if (attr)
+       {
+         FIELD_BITPOS (*fp) =
+           decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
+       }
+      else
+       FIELD_BITPOS (*fp) = 0;
+      attr = dwarf_attr (die, DW_AT_bit_offset);
+      if (attr)
+       {
+         if (BITS_BIG_ENDIAN)
+           {
+             /* For big endian bits, the DW_AT_bit_offset gives the
+                additional bit offset from the MSB of the containing
+                anonymous object to the MSB of the field.  We don't
+                have to do anything special since we don't need to
+                know the size of the anonymous object.  */
+             FIELD_BITPOS (*fp) += DW_UNSND (attr);
+           }
+         else
+           {
+             /* For little endian bits, compute the bit offset to the
+                MSB of the anonymous object, subtract off the number of
+                bits from the MSB of the field to the MSB of the
+                object, and then subtract off the number of bits of
+                the field itself.  The result is the bit offset of
+                the LSB of the field.  */
+             int anonymous_size;
+             int bit_offset = DW_UNSND (attr);
+
+             attr = dwarf_attr (die, DW_AT_byte_size);
+             if (attr)
+               {
+                 /* The size of the anonymous object containing
+                    the bit field is explicit, so use the
+                    indicated size (in bytes).  */
+                 anonymous_size = DW_UNSND (attr);
+               }
+             else
+               {
+                 /* The size of the anonymous object containing
+                    the bit field must be inferred from the type
+                    attribute of the data member containing the
+                    bit field.  */
+                 anonymous_size = TYPE_LENGTH (fp->type);
+               }
+             FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
+               - bit_offset - FIELD_BITSIZE (*fp);
+           }
+       }
+
+      /* Get name of field.  */
+      attr = dwarf_attr (die, DW_AT_name);
+      if (attr && DW_STRING (attr))
+       fieldname = DW_STRING (attr);
+      fp->name = obsavestring (fieldname, strlen (fieldname),
+                              &objfile->type_obstack);
+
+      /* Change accessibility for artificial fields (e.g. virtual table
+         pointer or virtual base class pointer) to private.  */
+      if (dwarf_attr (die, DW_AT_artificial))
+       {
+         new_field->accessibility = DW_ACCESS_private;
+         fip->non_public_fields = 1;
+       }
+    }
+  else if (die->tag == DW_TAG_variable)
+    {
+      char *physname;
+
+      /* C++ static member.
+        Get name of field.  */
+      attr = dwarf_attr (die, DW_AT_name);
+      if (attr && DW_STRING (attr))
+       fieldname = DW_STRING (attr);
+      else
+       return;
+
+      /* Get physical name.  */
+      physname = dwarf2_linkage_name (die);
+
+      SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
+                                            &objfile->type_obstack));
+      FIELD_TYPE (*fp) = die_type (die, objfile);
+      FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
+                                      &objfile->type_obstack);
+    }
+  else if (die->tag == DW_TAG_inheritance)
+    {
+      /* C++ base class field.  */
+      attr = dwarf_attr (die, DW_AT_data_member_location);
+      if (attr)
+       FIELD_BITPOS (*fp) = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
+      FIELD_BITSIZE (*fp) = 0;
+      FIELD_TYPE (*fp) = die_type (die, objfile);
+      FIELD_NAME (*fp) = type_name_no_tag (fp->type);
+      fip->nbaseclasses++;
+    }
+}
+
+/* Create the vector of fields, and attach it to the type.  */
+
+static void
+dwarf2_attach_fields_to_type (fip, type, objfile)
+     struct field_info *fip;
+     struct type *type;
+     struct objfile *objfile;
+{
+  int nfields = fip->nfields;
+
+  /* Record the field count, allocate space for the array of fields,
+     and create blank accessibility bitfields if necessary.  */
+  TYPE_NFIELDS (type) = nfields;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ALLOC (type, sizeof (struct field) * nfields);
+  memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
+
+  if (fip->non_public_fields)
+    {
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+
+      TYPE_FIELD_PRIVATE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
+
+      TYPE_FIELD_PROTECTED_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+      TYPE_FIELD_IGNORE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
+    }
+
+  /* If the type has baseclasses, allocate and clear a bit vector for
+     TYPE_FIELD_VIRTUAL_BITS.  */
+  if (fip->nbaseclasses)
+    {
+      int num_bytes = B_BYTES (fip->nbaseclasses);
+      char *pointer;
+
+      ALLOCATE_CPLUS_STRUCT_TYPE (type);
+      pointer = (char *) TYPE_ALLOC (type, num_bytes);
+      TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+      B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
+      TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
+    }
+
+  /* Copy the saved-up fields into the field vector.  Start from the head
+     of the list, adding to the tail of the field array, so that they end
+     up in the same order in the array in which they were added to the list.  */
+  while (nfields-- > 0)
+    {
+      TYPE_FIELD (type, nfields) = fip->fields->field;
+      switch (fip->fields->accessibility)
+       {
+       case DW_ACCESS_private:
+         SET_TYPE_FIELD_PRIVATE (type, nfields);
+         break;
+
+       case DW_ACCESS_protected:
+         SET_TYPE_FIELD_PROTECTED (type, nfields);
+         break;
+
+       case DW_ACCESS_public:
+         break;
+
+       default:
+         /* Unknown accessibility.  Complain and treat it as public.  */
+         {
+           complain (&dwarf2_unsupported_accessibility,
+                     fip->fields->accessibility);
+         }
+         break;
+       }
+      if (nfields < fip->nbaseclasses)
+       {
+         switch (fip->fields->virtuality)
+           {
+           case DW_VIRTUALITY_virtual:
+           case DW_VIRTUALITY_pure_virtual:
+             SET_TYPE_FIELD_VIRTUAL (type, nfields);
+             break;
+           }
+       }
+      fip->fields = fip->fields->next;
+    }
+}
+
+/* Add a member function to the proper fieldlist.  */
+
+static void
+dwarf2_add_member_fn (fip, die, type, objfile)
+     struct field_info *fip;
+     struct die_info *die;
+     struct type *type;
+     struct objfile *objfile;
+{
+  struct attribute *attr;
+  struct fnfieldlist *flp;
+  int i;
+  struct fn_field *fnp;
+  char *fieldname;
+  char *physname;
+  struct nextfnfield *new_fnfield;
+
+  /* Get name of member function.  */
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    fieldname = DW_STRING (attr);
+  else
+    return;
+
+  /* Get the mangled name.  */
+  physname = dwarf2_linkage_name (die);
+
+  /* Look up member function name in fieldlist.  */
+  for (i = 0; i < fip->nfnfields; i++)
+    {
+      if (STREQ (fip->fnfieldlists[i].name, fieldname))
+       break;
+    }
+
+  /* Create new list element if necessary.  */
+  if (i < fip->nfnfields)
+    flp = &fip->fnfieldlists[i];
+  else
+    {
+      if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
+       {
+         fip->fnfieldlists = (struct fnfieldlist *)
+           xrealloc (fip->fnfieldlists,
+                     (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
+                     * sizeof (struct fnfieldlist));
+         if (fip->nfnfields == 0)
+           make_cleanup ((make_cleanup_func) free_current_contents,
+                         &fip->fnfieldlists);
+       }
+      flp = &fip->fnfieldlists[fip->nfnfields];
+      flp->name = fieldname;
+      flp->length = 0;
+      flp->head = NULL;
+      fip->nfnfields++;
+    }
+
+  /* Create a new member function field and chain it to the field list
+     entry. */
+  new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield));
+  make_cleanup (free, new_fnfield);
+  memset (new_fnfield, 0, sizeof (struct nextfnfield));
+  new_fnfield->next = flp->head;
+  flp->head = new_fnfield;
+  flp->length++;
+
+  /* Fill in the member function field info.  */
+  fnp = &new_fnfield->fnfield;
+  fnp->physname = obsavestring (physname, strlen (physname),
+                               &objfile->type_obstack);
+  fnp->type = alloc_type (objfile);
+  if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+    {
+      struct type *return_type = TYPE_TARGET_TYPE (die->type);
+      struct type **arg_types;
+      int nparams = TYPE_NFIELDS (die->type);
+      int iparams;
+
+      /* Copy argument types from the subroutine type.  */
+      arg_types = (struct type **)
+       TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *));
+      for (iparams = 0; iparams < nparams; iparams++)
+       arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams);
+
+      /* Set last entry in argument type vector.  */
+      if (TYPE_FLAGS (die->type) & TYPE_FLAG_VARARGS)
+       arg_types[nparams] = NULL;
+      else
+       arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID);
+
+      smash_to_method_type (fnp->type, type, return_type, arg_types);
+
+      /* Handle static member functions.
+         Dwarf2 has no clean way to discern C++ static and non-static
+         member functions. G++ helps GDB by marking the first
+         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)
+       fnp->voffset = VOFFSET_STATIC;
+    }
+  else
+    complain (&dwarf2_missing_member_fn_type_complaint, physname);
+
+  /* Get fcontext from DW_AT_containing_type if present.  */
+  if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+    fnp->fcontext = die_containing_type (die, objfile);
+
+  /* dwarf2 doesn't have stubbed physical names, so the setting of is_const
+     and is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
+
+  /* Get accessibility.  */
+  attr = dwarf_attr (die, DW_AT_accessibility);
+  if (attr)
+    {
+      switch (DW_UNSND (attr))
+       {
+       case DW_ACCESS_private:
+         fnp->is_private = 1;
+         break;
+       case DW_ACCESS_protected:
+         fnp->is_protected = 1;
+         break;
+       }
+    }
+
+  /* Get index in virtual function table if it is a virtual member function.  */
+  attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+  if (attr)
+    fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile) + 2;
+}
+
+/* Create the vector of member function fields, and attach it to the type.  */
+
+static void
+dwarf2_attach_fn_fields_to_type (fip, type, objfile)
+     struct field_info *fip;
+     struct type *type;
+     struct objfile *objfile;
+{
+  struct fnfieldlist *flp;
+  int total_length = 0;
+  int i;
+
+  ALLOCATE_CPLUS_STRUCT_TYPE (type);
+  TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+    TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
+
+  for (i = 0, flp = fip->fnfieldlists; i < fip->nfnfields; i++, flp++)
+    {
+      struct nextfnfield *nfp = flp->head;
+      struct fn_fieldlist *fn_flp = &TYPE_FN_FIELDLIST (type, i);
+      int k;
+
+      TYPE_FN_FIELDLIST_NAME (type, i) = flp->name;
+      TYPE_FN_FIELDLIST_LENGTH (type, i) = flp->length;
+      fn_flp->fn_fields = (struct fn_field *)
+       TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
+      for (k = flp->length; (k--, nfp); nfp = nfp->next)
+       fn_flp->fn_fields[k] = nfp->fnfield;
+
+      total_length += flp->length;
+    }
+
+  TYPE_NFN_FIELDS (type) = fip->nfnfields;
+  TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+}
+
 /* Called when we find the DIE that starts a structure or union scope
    (definition) to process all dies that define the members of the
    structure or union.
@@ -1507,17 +2161,13 @@ read_structure_scope (die, objfile)
      struct objfile *objfile;
 {
   struct type *type;
-  struct field *fields;
-  struct die_info *child_die;
   struct attribute *attr;
-  struct symbol *sym;
-  int num_fields;
 
   type = alloc_type (objfile);
 
   INIT_CPLUS_SPECIFIC (type);
   attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
+  if (attr && DW_STRING (attr))
     {
       TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
                                           strlen (DW_STRING (attr)),
@@ -1534,9 +2184,9 @@ read_structure_scope (die, objfile)
     }
   else
     {
-      /* FIXME: This should be changed to TYPE_CODE_CLASS when the rest
-        of GDB knows how to handle it.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
+         in gdbtypes.h.  */
+      TYPE_CODE (type) = TYPE_CODE_CLASS;
     }
 
   attr = dwarf_attr (die, DW_AT_byte_size);
@@ -1554,119 +2204,37 @@ read_structure_scope (die, objfile)
      type within the structure itself. */
   die->type = type;
 
-  num_fields = 0;
-  fields = NULL;
-  if (die->has_children)
+  if (die->has_children && ! die_is_declaration (die))
     {
+      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));
+
       child_die = die->next;
+
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_member)
            {
-             if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
-               {
-                 fields = (struct field *)
-                   xrealloc (fields,
-                             (num_fields + DW_FIELD_ALLOC_CHUNK)
-                              * sizeof (struct field));
-               }
-
-             /* Get bit offset of field */
-             attr = dwarf_attr (child_die, DW_AT_bit_offset);
-             if (attr)
-               {
-                 fields[num_fields].bitpos = DW_UNSND (attr);
-               }
-             else
-               {
-                 fields[num_fields].bitpos = 0;
-               }
-             attr = dwarf_attr (child_die, DW_AT_data_member_location);
-             if (attr)
-               {
-                 fields[num_fields].bitpos +=
-                   decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
-               }
-
-             /* Get bit size of field (zero if none). */
-             attr = dwarf_attr (child_die, DW_AT_bit_size);
-             if (attr)
-               {
-                 fields[num_fields].bitsize = DW_UNSND (attr);
-               }
-             else
-               {
-                 fields[num_fields].bitsize = 0;
-               }
-
-             /* Get type of member. */
-             fields[num_fields].type = die_type (child_die, objfile);
-
-             /* Get name of member. */
-             attr = dwarf_attr (child_die, DW_AT_name);
-             if (attr)
-               {
-                 fields[num_fields].name =
-                   obsavestring (DW_STRING (attr),
-                                 strlen (DW_STRING (attr)),
-                                 &objfile->type_obstack);
-               }
-             num_fields++;
+             dwarf2_add_field (&fi, child_die, objfile);
            }
          else if (child_die->tag == DW_TAG_variable)
            {
-             char *physname = NULL;
-             char *fieldname = NULL;
-
-             /* C++ static member.
-                Get physical name, extract field name from physical name.  */
-             attr = dwarf_attr (child_die, DW_AT_name);
-             if (attr)
-               {
-                 char *cp;
-
-                 physname = DW_STRING (attr);
-
-                 cp = physname;
-                 while (*cp && !is_cplus_marker (*cp))
-                   cp++;
-                 if (*cp)
-                   fieldname = cp + 1;
-               }
-
-             if (physname && fieldname)
-               {
-                 if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
-                   {
-                     fields = (struct field *)
-                       xrealloc (fields,
-                                 (num_fields + DW_FIELD_ALLOC_CHUNK)
-                                  * sizeof (struct field));
-                   }
-                 fields[num_fields].bitpos = -1;
-                 fields[num_fields].bitsize = (long)
-                   obsavestring (physname, strlen (physname),
-                                 &objfile->type_obstack);
-                 fields[num_fields].type = die_type (child_die, objfile);
-                 fields[num_fields].name =
-                   obsavestring (fieldname, strlen (fieldname),
-                                 &objfile->type_obstack);
-                 num_fields++;
-               }
-             else
-               {
-                 complain (&dwarf2_bad_static_member_name,
-                           physname ? physname : "<NULL>");
-               }
+             /* C++ static member.  */
+             dwarf2_add_field (&fi, child_die, objfile);
            }
          else if (child_die->tag == DW_TAG_subprogram)
            {
-             /* FIXME: C++ member function. */
+             /* C++ member function. */
              process_die (child_die, objfile);
+             dwarf2_add_member_fn (&fi, child_die, type, objfile);
            }
          else if (child_die->tag == DW_TAG_inheritance)
            {
-             /* FIXME: C++ inheritance information. */
+             /* C++ base class field.  */
+             dwarf2_add_field (&fi, child_die, objfile);
            }
          else
            {
@@ -1674,17 +2242,59 @@ read_structure_scope (die, objfile)
            }
          child_die = sibling_die (child_die);
        }
-      if (num_fields)
+
+      /* Attach fields and member functions to the type.  */
+      if (fi.nfields)
+       dwarf2_attach_fields_to_type (&fi, type, objfile);
+      if (fi.nfnfields)
        {
-         TYPE_NFIELDS (type) = num_fields;
-         TYPE_FIELDS (type) = (struct field *)
-           TYPE_ALLOC (type, sizeof (struct field) * num_fields);
-         memcpy (TYPE_FIELDS (type), fields,
-                 sizeof (struct field) * num_fields);
-         free (fields);
+         dwarf2_attach_fn_fields_to_type (&fi, type, objfile);
+
+         /* Get the type which refers to the base class (possibly this
+            class itself) which contains the vtable pointer for the current
+            class from the DW_AT_containing_type attribute.  */
+
+         if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+           {
+             struct type *t = die_containing_type (die, objfile);
+
+             TYPE_VPTR_BASETYPE (type) = t;
+             if (type == t)
+               {
+                 static const char vptr_name[] =
+                 {'_', 'v', 'p', 't', 'r', '\0'};
+                 int i;
+
+                 /* Our own class provides vtbl ptr.  */
+                 for (i = TYPE_NFIELDS (t) - 1;
+                      i >= TYPE_N_BASECLASSES (t);
+                      --i)
+                   {
+                     char *fieldname = TYPE_FIELD_NAME (t, i);
+
+                     if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1)
+                         && is_cplus_marker (fieldname[strlen (vptr_name)]))
+                       {
+                         TYPE_VPTR_FIELDNO (type) = i;
+                         break;
+                       }
+                   }
+
+                 /* Complain if virtual function table field not found.  */
+                 if (i < TYPE_N_BASECLASSES (t))
+                   complain (&dwarf2_vtbl_not_found_complaint,
+                         TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "");
+               }
+             else
+               {
+                 TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+               }
+           }
        }
 
-      sym = new_symbol (die, type, objfile);
+      new_symbol (die, type, objfile);
+
+      do_cleanups (back_to);
     }
   else
     {
@@ -1721,7 +2331,7 @@ read_enumeration (die, objfile)
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
+  if (attr && DW_STRING (attr))
     {
       TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
                                           strlen (DW_STRING (attr)),
@@ -1763,13 +2373,13 @@ read_enumeration (die, objfile)
                      fields = (struct field *)
                        xrealloc (fields,
                                  (num_fields + DW_FIELD_ALLOC_CHUNK)
-                                   * sizeof (struct field));
+                                 * sizeof (struct field));
                    }
 
-                 fields[num_fields].name = SYMBOL_NAME (sym);
-                 fields[num_fields].type = NULL;
-                 fields[num_fields].bitpos = SYMBOL_VALUE (sym);
-                 fields[num_fields].bitsize = 0;
+                 FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+                 FIELD_TYPE (fields[num_fields]) = NULL;
+                 FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+                 FIELD_BITSIZE (fields[num_fields]) = 0;
 
                  num_fields++;
                }
@@ -1791,7 +2401,7 @@ read_enumeration (die, objfile)
        TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
     }
   die->type = type;
-  sym = new_symbol (die, type, objfile);
+  new_symbol (die, type, objfile);
 }
 
 /* Extract all information from a DW_TAG_array_type DIE and put it in
@@ -1799,15 +2409,17 @@ read_enumeration (die, objfile)
    arrays.  */
 
 static void
-dwarf_read_array_type (die, objfile)
+read_array_type (die, objfile)
      struct die_info *die;
      struct objfile *objfile;
 {
   struct die_info *child_die;
   struct type *type = NULL;
   struct type *element_type, *range_type, *index_type;
+  struct type **range_types = NULL;
   struct attribute *attr;
-  unsigned int low, high;
+  int ndim = 0;
+  struct cleanup *back_to;
 
   /* Return if we've already decoded this type. */
   if (die->type)
@@ -1818,7 +2430,7 @@ dwarf_read_array_type (die, objfile)
   element_type = die_type (die, objfile);
 
   /* Irix 6.2 native cc creates array types without children for
-     variable length arrays.  */
+     arrays with unspecified length.  */
   if (die->has_children == 0)
     {
       index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
@@ -1827,19 +2439,23 @@ dwarf_read_array_type (die, objfile)
       return;
     }
 
-  low = 0;
-  high = 1;
-  if (cu_language == DW_LANG_Fortran77 || cu_language == DW_LANG_Fortran90)
-    {
-      /* FORTRAN implies a lower bound of 1, if not given.  */
-      low = 1;
-    }
-
+  back_to = make_cleanup (null_cleanup, NULL);
   child_die = die->next;
   while (child_die && child_die->tag)
     {
       if (child_die->tag == DW_TAG_subrange_type)
        {
+         unsigned int low, high;
+
+         /* Default bounds to an array with unspecified length.  */
+         low = 0;
+         high = -1;
+         if (cu_language == language_fortran)
+           {
+             /* FORTRAN implies a lower bound of 1, if not given.  */
+             low = 1;
+           }
+
          index_type = die_type (child_die, objfile);
          attr = dwarf_attr (child_die, DW_AT_lower_bound);
          if (attr)
@@ -1849,9 +2465,9 @@ dwarf_read_array_type (die, objfile)
                  low = DW_SND (attr);
                }
              else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4)
+                      || attr->form == DW_FORM_data1
+                      || attr->form == DW_FORM_data2
+                      || attr->form == DW_FORM_data4)
                {
                  low = DW_UNSND (attr);
                }
@@ -1875,9 +2491,9 @@ dwarf_read_array_type (die, objfile)
                  high = DW_SND (attr);
                }
              else if (attr->form == DW_FORM_udata
-                      || attr->form == DW_FORM_data1
-                      || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4)
+                      || attr->form == DW_FORM_data1
+                      || attr->form == DW_FORM_data2
+                      || attr->form == DW_FORM_data4)
                {
                  high = DW_UNSND (attr);
                }
@@ -1902,12 +2518,30 @@ dwarf_read_array_type (die, objfile)
 #endif
                }
            }
-         range_type = create_range_type (NULL, index_type, low, high);
-         type = create_array_type (NULL, element_type, range_type);
-         element_type = type;
+
+         /* Create a range type and save it for array type creation.  */
+         if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+           {
+             range_types = (struct type **)
+               xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                         * sizeof (struct type *));
+             if (ndim == 0)
+               make_cleanup ((make_cleanup_func) free_current_contents,
+                             &range_types);
+           }
+         range_types[ndim++] = create_range_type (NULL, index_type, low, high);
        }
       child_die = sibling_die (child_die);
     }
+
+  /* Dwarf2 dimensions are output from left to right, create the
+     necessary array types in backwards order.  */
+  type = element_type;
+  while (ndim-- > 0)
+    type = create_array_type (NULL, type, range_types[ndim]);
+
+  do_cleanups (back_to);
+
   /* Install the type in the die. */
   die->type = type;
 }
@@ -2096,13 +2730,13 @@ read_tag_string_type (die, objfile)
 /* Handle DIES due to C code like:
 
    struct foo
-     {
-       int (*funcp)(int a, long l);
-       int b;
-     };
+   {
+   int (*funcp)(int a, long l);
+   int b;
+   };
 
    ('funcp' generates a DW_TAG_subroutine_type DIE)
-*/
+ */
 
 static void
 read_subroutine_type (die, objfile)
@@ -2111,6 +2745,7 @@ read_subroutine_type (die, objfile)
 {
   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)
@@ -2120,6 +2755,12 @@ read_subroutine_type (die, objfile)
   type = die_type (die, objfile);
   ftype = lookup_function_type (type);
 
+  /* All functions in C++ have prototypes.  */
+  attr = dwarf_attr (die, DW_AT_prototyped);
+  if ((attr && (DW_UNSND (attr) != 0))
+      || cu_language == language_cplus)
+    TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+
   if (die->has_children)
     {
       struct die_info *child_die;
@@ -2127,13 +2768,15 @@ read_subroutine_type (die, objfile)
       int iparams = 0;
 
       /* Count the number of parameters.
-         FIXME: GDB currently has no way to deal with ellipsis,
-        represented by DW_TAG_unspecified_parameters.  */
+         FIXME: GDB currently ignores vararg functions, but knows about
+         vararg member functions.  */
       child_die = die->next;
       while (child_die && child_die->tag)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
            nparams++;
+         else if (child_die->tag == DW_TAG_unspecified_parameters)
+           TYPE_FLAGS (ftype) |= TYPE_FLAG_VARARGS;
          child_die = sibling_die (child_die);
        }
 
@@ -2147,6 +2790,16 @@ read_subroutine_type (die, objfile)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
            {
+             /* Dwarf2 has no clean way to discern C++ static and non-static
+                member functions. G++ helps GDB by marking the first
+                parameter for non-static member functions (which is the
+                this pointer) as artificial. We pass this information
+                to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
+             attr = dwarf_attr (child_die, DW_AT_artificial);
+             if (attr)
+               TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
+             else
+               TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
              TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile);
              iparams++;
            }
@@ -2176,7 +2829,7 @@ read_typedef (die, objfile)
       TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
       TYPE_TARGET_TYPE (type) = xtype;
       attr = dwarf_attr (die, DW_AT_name);
-      if (attr)
+      if (attr && DW_STRING (attr))
        TYPE_NAME (type) = obsavestring (DW_STRING (attr),
                                         strlen (DW_STRING (attr)),
                                         &objfile->type_obstack);
@@ -2214,7 +2867,7 @@ read_base_type (die, objfile)
       size = DW_UNSND (attr);
     }
   attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
+  if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
       int is_unsigned = 0;
@@ -2228,6 +2881,7 @@ read_base_type (die, objfile)
          break;
        case DW_ATE_boolean:
          code = TYPE_CODE_BOOL;
+         is_unsigned = 1;
          break;
        case DW_ATE_complex_float:
          code = TYPE_CODE_COMPLEX;
@@ -2253,7 +2907,7 @@ read_base_type (die, objfile)
     }
   else
     {
-      type = dwarf_base_type (encoding, size);
+      type = dwarf_base_type (encoding, size, objfile);
     }
   die->type = type;
 }
@@ -2262,8 +2916,8 @@ read_base_type (die, objfile)
 
 struct die_info *
 read_comp_unit (info_ptr, abfd)
-    char *info_ptr;
-    bfd *abfd;
+     char *info_ptr;
+     bfd *abfd;
 {
   struct die_info *first_die, *last_die, *die;
   char *cur_ptr;
@@ -2345,7 +2999,7 @@ dwarf2_read_section (objfile, offset, size)
     {
       buf = NULL;
       error ("Dwarf Error: Can't read DWARF data from '%s'",
-        bfd_get_filename (abfd));
+            bfd_get_filename (abfd));
     }
   return buf;
 }
@@ -2357,7 +3011,7 @@ dwarf2_read_section (objfile, offset, size)
 
 static void
 dwarf2_read_abbrevs (abfd, offset)
-     bfd * abfd;
+     bfd *abfd;
      unsigned int offset;
 {
   char *abbrev_ptr;
@@ -2396,7 +3050,7 @@ dwarf2_read_abbrevs (abfd, offset)
              cur_abbrev->attrs = (struct attr_abbrev *)
                xrealloc (cur_abbrev->attrs,
                          (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
-                           * sizeof (struct attr_abbrev));
+                         * sizeof (struct attr_abbrev));
            }
          cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
          cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
@@ -2412,13 +3066,13 @@ dwarf2_read_abbrevs (abfd, offset)
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
-        always properly terminated with an abbrev number of 0.
-        Exit loop if we encounter an abbreviation which we have
-        already read (which means we are about to read the abbreviations
-        for the next compile unit) or if the end of the abbreviation
-        table is reached.  */
+         always properly terminated with an abbrev number of 0.
+         Exit loop if we encounter an abbreviation which we have
+         already read (which means we are about to read the abbreviations
+         for the next compile unit) or if the end of the abbreviation
+         table is reached.  */
       if ((unsigned int) (abbrev_ptr - dwarf_abbrev_buffer)
-           >= dwarf_abbrev_size)
+         >= dwarf_abbrev_size)
        break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
@@ -2479,14 +3133,16 @@ dwarf2_lookup_abbrev (number)
 static char *
 read_partial_die (part_die, abfd, info_ptr, has_pc_info)
      struct partial_die_info *part_die;
-     bfd * abfd;
+     bfd *abfd;
      char *info_ptr;
      int *has_pc_info;
 {
   unsigned int abbrev_number, bytes_read, i;
   struct abbrev_info *abbrev;
-  char ebuf[256];
-  int has_low_pc_attr  = 0;
+  struct attribute attr;
+  struct attribute spec_attr;
+  int found_spec_attr = 0;
+  int has_low_pc_attr = 0;
   int has_high_pc_attr = 0;
 
   *part_die = zeroed_partial_die;
@@ -2506,141 +3162,99 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info)
   part_die->has_children = abbrev->has_children;
   part_die->abbrev = abbrev_number;
 
-  {
-    char *str = "";
-    struct dwarf_block *blk = 0;
-    CORE_ADDR addr = ((CORE_ADDR) -1);
-    unsigned int unsnd = ((unsigned int) -1);
-    int snd = -1;
+  for (i = 0; i < abbrev->num_attrs; ++i)
+    {
+      info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr);
 
-    for (i = 0; i < abbrev->num_attrs; ++i)
-      {
-       /* read the correct type of data */
-       switch (abbrev->attrs[i].form)
-         {
-         case DW_FORM_addr:
-           addr = read_address (abfd, info_ptr);
-           info_ptr += address_size;
-           break;
-         case DW_FORM_ref_addr:
-           addr = read_address (abfd, info_ptr);
-           info_ptr += address_size;
-           break;
-         case DW_FORM_block2:
-           blk = dwarf_alloc_block ();
-           blk->size = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           break;
-         case DW_FORM_block4:
-           blk = dwarf_alloc_block ();
-           blk->size = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           break;
-         case DW_FORM_data2:
-           unsnd = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           break;
-         case DW_FORM_data4:
-           unsnd = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           break;
-         case DW_FORM_data8:
-           unsnd = read_8_bytes (abfd, info_ptr);
-           info_ptr += 8;
-           break;
-         case DW_FORM_string:
-           str = read_string (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_block:
-           blk = dwarf_alloc_block ();
-           blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           break;
-         case DW_FORM_block1:
-           blk = dwarf_alloc_block ();
-           blk->size = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           break;
-         case DW_FORM_data1:
-           unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_ref1:
-           unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_ref2:
-           unsnd = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           break;
-         case DW_FORM_ref4:
-           unsnd = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           break;
-         case DW_FORM_ref_udata:
-           unsnd = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_flag:
-           unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_sdata:
-           snd = read_signed_leb128 (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_udata:
-           unsnd = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_indirect:
-         default:
-           sprintf (ebuf,
-                    "Dwarf Error: Cannot handle %s in DWARF reader.",
-                    dwarf_form_name (abbrev->attrs[i].form));
-           error (ebuf);
-         }
+      /* Store the data if it is of an attribute we want to keep in a
+         partial symbol table.  */
+      switch (attr.name)
+       {
+       case DW_AT_name:
 
-       /* store the data if it is of an attribute we want to keep in a
-          partial symbol table */
-       switch (abbrev->attrs[i].name)
-         {
-         case DW_AT_name:
-           part_die->name = str;
-           break;
-         case DW_AT_low_pc:
-           has_low_pc_attr = 1;
-           part_die->lowpc = addr;
-           break;
-         case DW_AT_high_pc:
-           has_high_pc_attr = 1;
-           part_die->highpc = addr;
-           break;
-         case DW_AT_location:
-           part_die->locdesc = blk;
-           break;
-         case DW_AT_language:
-           part_die->language = unsnd;
-           break;
-         case DW_AT_external:
-           part_die->is_external = unsnd;
-           break;
-         case DW_AT_declaration:
-           part_die->is_declaration = unsnd;
-           break;
-         }
-      }
-  }
-  *has_pc_info = has_low_pc_attr && has_high_pc_attr;
+         /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name.  */
+         if (part_die->name == NULL)
+           part_die->name = DW_STRING (&attr);
+         break;
+       case DW_AT_MIPS_linkage_name:
+         part_die->name = DW_STRING (&attr);
+         break;
+       case DW_AT_low_pc:
+         has_low_pc_attr = 1;
+         part_die->lowpc = DW_ADDR (&attr);
+         break;
+       case DW_AT_high_pc:
+         has_high_pc_attr = 1;
+         part_die->highpc = DW_ADDR (&attr);
+         break;
+       case DW_AT_location:
+         part_die->locdesc = DW_BLOCK (&attr);
+         break;
+       case DW_AT_language:
+         part_die->language = DW_UNSND (&attr);
+         break;
+       case DW_AT_external:
+         part_die->is_external = DW_UNSND (&attr);
+         break;
+       case DW_AT_declaration:
+         part_die->is_declaration = DW_UNSND (&attr);
+         break;
+       case DW_AT_type:
+         part_die->has_type = 1;
+         break;
+       case DW_AT_abstract_origin:
+       case DW_AT_specification:
+         found_spec_attr = 1;
+         spec_attr = attr;
+         break;
+       case DW_AT_sibling:
+         /* Ignore absolute siblings, they might point outside of
+            the current compile unit.  */
+         if (attr.form == DW_FORM_ref_addr)
+           complain (&dwarf2_absolute_sibling_complaint);
+         else
+           part_die->sibling =
+             dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+         break;
+       default:
+         break;
+       }
+    }
+
+  /* If we found a reference attribute and the die has no name, try
+     to find a name in the referred to die.  */
+
+  if (found_spec_attr && part_die->name == NULL)
+    {
+      struct partial_die_info spec_die;
+      char *spec_ptr;
+      int dummy;
+
+      spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+      read_partial_die (&spec_die, abfd, spec_ptr, &dummy);
+      if (spec_die.name)
+       {
+         part_die->name = spec_die.name;
+
+         /* Copy DW_AT_external attribute if it is set.  */
+         if (spec_die.is_external)
+           part_die->is_external = spec_die.is_external;
+       }
+    }
+
+  /* When using the GNU linker, .gnu.linkonce. sections are used to
+     eliminate duplicate copies of functions and vtables and such.
+     The linker will arbitrarily choose one and discard the others.
+     The AT_*_pc values for such functions refer to local labels in
+     these sections.  If the section from that file was discarded, the
+     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 (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)))
+    *has_pc_info = 1;
   return info_ptr;
 }
 
@@ -2656,7 +3270,6 @@ read_full_die (diep, abfd, info_ptr)
   unsigned int abbrev_number, bytes_read, i, offset;
   struct abbrev_info *abbrev;
   struct die_info *die;
-  char ebuf[256];
 
   offset = info_ptr - dwarf_info_buffer;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
@@ -2687,120 +3300,123 @@ read_full_die (diep, abfd, info_ptr)
   die->attrs = (struct attribute *)
     xmalloc (die->num_attrs * sizeof (struct attribute));
 
-  {
-    struct dwarf_block *blk;
+  for (i = 0; i < abbrev->num_attrs; ++i)
+    {
+      info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+                                abfd, info_ptr);
+    }
 
-    for (i = 0; i < abbrev->num_attrs; ++i)
-      {
-       /* read the correct type of data */
+  *diep = die;
+  return info_ptr;
+}
 
-       die->attrs[i].name = abbrev->attrs[i].name;
-       die->attrs[i].form = abbrev->attrs[i].form;
+/* Read an attribute described by an abbreviated attribute.  */
 
-       switch (abbrev->attrs[i].form)
-         {
-         case DW_FORM_addr:
-         case DW_FORM_ref_addr:
-           die->attrs[i].u.addr = read_address (abfd, info_ptr);
-           info_ptr += address_size;
-           break;
-         case DW_FORM_block2:
-           blk = dwarf_alloc_block ();
-           blk->size = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           die->attrs[i].u.blk = blk;
-           break;
-         case DW_FORM_block4:
-           blk = dwarf_alloc_block ();
-           blk->size = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           die->attrs[i].u.blk = blk;
-           break;
-         case DW_FORM_data2:
-           die->attrs[i].u.unsnd = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           break;
-         case DW_FORM_data4:
-           die->attrs[i].u.unsnd = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           break;
-         case DW_FORM_data8:
-           die->attrs[i].u.unsnd = read_8_bytes (abfd, info_ptr);
-           info_ptr += 8;
-           break;
-         case DW_FORM_string:
-           die->attrs[i].u.str = read_string (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_block:
-           blk = dwarf_alloc_block ();
-           blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-           info_ptr += bytes_read;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           die->attrs[i].u.blk = blk;
-           break;
-         case DW_FORM_block1:
-           blk = dwarf_alloc_block ();
-           blk->size = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           blk->data = read_n_bytes (abfd, info_ptr, blk->size);
-           info_ptr += blk->size;
-           die->attrs[i].u.blk = blk;
-           break;
-         case DW_FORM_data1:
-           die->attrs[i].u.unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_ref1:
-           die->attrs[i].u.unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_ref2:
-           die->attrs[i].u.unsnd = read_2_bytes (abfd, info_ptr);
-           info_ptr += 2;
-           break;
-         case DW_FORM_ref4:
-           die->attrs[i].u.unsnd = read_4_bytes (abfd, info_ptr);
-           info_ptr += 4;
-           break;
-         case DW_FORM_ref_udata:
-           die->attrs[i].u.unsnd = read_unsigned_leb128 (abfd,
-                                                         info_ptr,
-                                                         &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_flag:
-           die->attrs[i].u.unsnd = read_1_byte (abfd, info_ptr);
-           info_ptr += 1;
-           break;
-         case DW_FORM_sdata:
-           die->attrs[i].u.snd = read_signed_leb128 (abfd,
-                                                     info_ptr,
-                                                     &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_udata:
-           die->attrs[i].u.unsnd = read_unsigned_leb128 (abfd,
-                                                         info_ptr,
-                                                         &bytes_read);
-           info_ptr += bytes_read;
-           break;
-         case DW_FORM_indirect:
-         default:
-           sprintf (ebuf,
-                    "Dwarf Error: Cannot handle %s in DWARF reader.",
-                    dwarf_form_name (abbrev->attrs[i].form));
-           error (ebuf);
-         }
+static char *
+read_attribute (attr, abbrev, abfd, info_ptr)
+     struct attribute *attr;
+     struct attr_abbrev *abbrev;
+     bfd *abfd;
+     char *info_ptr;
+{
+  unsigned int bytes_read;
+  struct dwarf_block *blk;
 
-      }
-  }
-  *diep = die;
+  attr->name = abbrev->name;
+  attr->form = abbrev->form;
+  switch (abbrev->form)
+    {
+    case DW_FORM_addr:
+    case DW_FORM_ref_addr:
+      DW_ADDR (attr) = read_address (abfd, info_ptr);
+      info_ptr += address_size;
+      break;
+    case DW_FORM_block2:
+      blk = dwarf_alloc_block ();
+      blk->size = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_block4:
+      blk = dwarf_alloc_block ();
+      blk->size = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_data2:
+      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      break;
+    case DW_FORM_data4:
+      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      break;
+    case DW_FORM_data8:
+      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      info_ptr += 8;
+      break;
+    case DW_FORM_string:
+      DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_block:
+      blk = dwarf_alloc_block ();
+      blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_block1:
+      blk = dwarf_alloc_block ();
+      blk->size = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+      info_ptr += blk->size;
+      DW_BLOCK (attr) = blk;
+      break;
+    case DW_FORM_data1:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_flag:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_sdata:
+      DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_udata:
+      DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_ref1:
+      DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+      break;
+    case DW_FORM_ref2:
+      DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+      info_ptr += 2;
+      break;
+    case DW_FORM_ref4:
+      DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+      info_ptr += 4;
+      break;
+    case DW_FORM_ref_udata:
+      DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      break;
+    case DW_FORM_strp:
+    case DW_FORM_indirect:
+    default:
+      error ("Dwarf Error: Cannot handle %s in DWARF reader.",
+            dwarf_form_name (abbrev->form));
+    }
   return info_ptr;
 }
 
@@ -2869,18 +3485,34 @@ read_address (abfd, buf)
 {
   CORE_ADDR retval = 0;
 
-  if (address_size == 4)
+  switch (address_size)
     {
+    case 4:
       retval = bfd_get_32 (abfd, (bfd_byte *) buf);
-    } else {                   /* *THE* alternative is 8, right? */
+      break;
+    case 8:
       retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      break;
+    default:
+      /* *THE* alternative is 8, right? */
+      abort ();
+    }
+  /* If the address being read is larger than the address that is
+     applicable for the object file format then mask it down to the
+     correct size.  Take care to avoid unnecessary shift or shift
+     overflow */
+  if (address_size > address_significant_size
+      && address_significant_size < sizeof (CORE_ADDR))
+    {
+      CORE_ADDR mask = ((CORE_ADDR) 0) - 1;
+      retval &= ~(mask << (address_significant_size * 8));
     }
   return retval;
 }
 
 static char *
 read_n_bytes (abfd, buf, size)
-     bfd * abfd;
+     bfd *abfd;
      char *buf;
      unsigned int size;
 {
@@ -3014,22 +3646,21 @@ set_cu_language (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
-    case DW_LANG_Fortran77:
       cu_language = language_c;
       break;
     case DW_LANG_C_plus_plus:
       cu_language = language_cplus;
       break;
+    case DW_LANG_Fortran77:
+    case DW_LANG_Fortran90:
+      cu_language = language_fortran;
+      break;
     case DW_LANG_Mips_Assembler:
       cu_language = language_asm;
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Cobol74:
     case DW_LANG_Cobol85:
-#if 0
-    case DW_LANG_Fortran77:    /* moved up top for now */
-#endif
-    case DW_LANG_Fortran90:
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
@@ -3062,15 +3693,22 @@ dwarf_attr (die, name)
   if (spec)
     {
       struct die_info *ref_die =
-       follow_die_ref (dwarf2_get_ref_die_offset (spec));
+      follow_die_ref (dwarf2_get_ref_die_offset (spec));
 
       if (ref_die)
        return dwarf_attr (ref_die, name);
     }
-    
+
   return NULL;
 }
 
+static int
+die_is_declaration (struct die_info *die)
+{
+  return (dwarf_attr (die, DW_AT_declaration)
+         && ! dwarf_attr (die, DW_AT_specification));
+}
+
 /* Decode the line number information for the compilation unit whose
    line number info is at OFFSET in the .debug_line section.
    The compilation directory of the file is passed in COMP_DIR.  */
@@ -3079,20 +3717,20 @@ struct filenames
 {
   unsigned int num_files;
   struct fileinfo
-  {
-    char *name;
-    unsigned int dir;
-    unsigned int time;
-    unsigned int size;
-  }
-  *files;
+    {
+      char *name;
+      unsigned int dir;
+      unsigned int time;
+      unsigned int size;
+    }
+   *files;
 };
 
 struct directories
-{
-  unsigned int num_dirs;
-  char **dirs;
-};
+  {
+    unsigned int num_dirs;
+    char **dirs;
+  };
 
 static void
 dwarf_decode_lines (offset, comp_dir, abfd)
@@ -3148,7 +3786,8 @@ dwarf_decode_lines (offset, comp_dir, abfd)
   line_ptr += 1;
   lh.standard_opcode_lengths = (unsigned char *)
     xmalloc (lh.opcode_base * sizeof (unsigned char));
-  back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths);
+  back_to = make_cleanup ((make_cleanup_func) free_current_contents,
+                         &lh.standard_opcode_lengths);
 
   lh.standard_opcode_lengths[0] = 1;
   for (i = 1; i < lh.opcode_base; ++i)
@@ -3167,7 +3806,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
            xrealloc (dirs.dirs,
                      (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
          if (dirs.num_dirs == 0)
-           make_cleanup (free_current_contents, &dirs.dirs);
+           make_cleanup ((make_cleanup_func) free_current_contents, &dirs.dirs);
        }
       dirs.dirs[dirs.num_dirs++] = cur_dir;
     }
@@ -3182,9 +3821,10 @@ dwarf_decode_lines (offset, comp_dir, abfd)
          files.files = (struct fileinfo *)
            xrealloc (files.files,
                      (files.num_files + FILE_ALLOC_CHUNK)
-                       * sizeof (struct fileinfo));
+                     * sizeof (struct fileinfo));
          if (files.num_files == 0)
-           make_cleanup (free_current_contents, &files.files);
+           make_cleanup ((make_cleanup_func) free_current_contents,
+                         &files.files);
        }
       files.files[files.num_files].name = cur_file;
       files.files[files.num_files].dir =
@@ -3204,7 +3844,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
   while (line_ptr < line_end)
     {
       /* state machine registers  */
-      unsigned int address = 0;
+      CORE_ADDR address = 0;
       unsigned int file = 1;
       unsigned int line = 1;
       unsigned int column = 0;
@@ -3224,7 +3864,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
        }
 
       /* Decode the table. */
-      while (! end_sequence)
+      while (!end_sequence)
        {
          op_code = read_1_byte (abfd, line_ptr);
          line_ptr += 1;
@@ -3238,7 +3878,12 @@ dwarf_decode_lines (offset, comp_dir, abfd)
                {
                case DW_LNE_end_sequence:
                  end_sequence = 1;
-                 record_line (current_subfile, line, address);
+                 /* Don't call record_line here.  The end_sequence
+                    instruction provides the address of the first byte
+                    *after* the last line in the sequence; it's not the
+                    address of any real source line.  However, the GDB
+                    linetable structure only records the starts of lines,
+                    not the ends.  This is a weakness of GDB.  */
                  break;
                case DW_LNE_set_address:
                  address = read_address (abfd, line_ptr) + baseaddr;
@@ -3252,9 +3897,10 @@ dwarf_decode_lines (offset, comp_dir, abfd)
                      files.files = (struct fileinfo *)
                        xrealloc (files.files,
                                  (files.num_files + FILE_ALLOC_CHUNK)
-                                   * sizeof (struct fileinfo));
+                                 * sizeof (struct fileinfo));
                      if (files.num_files == 0)
-                       make_cleanup (free_current_contents, &files.files);
+                       make_cleanup ((make_cleanup_func) free_current_contents,
+                                     &files.files);
                    }
                  files.files[files.num_files].name = cur_file;
                  files.files[files.num_files].dir =
@@ -3288,7 +3934,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
              break;
            case DW_LNS_set_file:
              /* The file and directory tables are 0 based, the references
-                are 1 based.  */
+                are 1 based.  */
              file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
              line_ptr += bytes_read;
              dwarf2_start_subfile
@@ -3307,8 +3953,14 @@ dwarf_decode_lines (offset, comp_dir, abfd)
            case DW_LNS_set_basic_block:
              basic_block = 1;
              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.  */
            case DW_LNS_const_add_pc:
-             address += (255 - lh.opcode_base) / lh.line_range;
+             address += (lh.minimum_instruction_length
+                         * ((255 - lh.opcode_base) / lh.line_range));
              break;
            case DW_LNS_fixed_advance_pc:
              address += read_2_bytes (abfd, line_ptr);
@@ -3339,12 +3991,12 @@ done:
    /srcdir and compiling it with Irix6.2 cc in /compdir using a filename
    of /srcdir/list0.c yields the following debugging information for list0.c:
 
-       DW_AT_name:             /srcdir/list0.c
-       DW_AT_comp_dir:         /compdir
-       files.files[0].name:    list0.h         
-       files.files[0].dir:     /srcdir
-       files.files[1].name:    list0.c         
-       files.files[1].dir:     /srcdir
+   DW_AT_name:          /srcdir/list0.c
+   DW_AT_comp_dir:              /compdir
+   files.files[0].name: list0.h         
+   files.files[0].dir:  /srcdir
+   files.files[1].name: list0.c         
+   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.  */
@@ -3380,8 +4032,7 @@ dwarf2_start_subfile (filename, dirname)
    to make a symbol table entry for it, and if so, create a new entry
    and return a pointer to it.
    If TYPE is NULL, determine symbol type from the die, otherwise
-   used the passed type.
-  */
+   used the passed type.  */
 
 static struct symbol *
 new_symbol (die, type, objfile)
@@ -3390,23 +4041,23 @@ new_symbol (die, type, objfile)
      struct objfile *objfile;
 {
   struct symbol *sym = NULL;
+  char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
   CORE_ADDR addr;
 
-  attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
+  name = dwarf2_linkage_name (die);
+  if (name)
     {
       sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (DW_STRING (attr),
-                                       strlen (DW_STRING (attr)),
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
                                        &objfile->symbol_obstack);
 
       /* Default assumptions.
-        Use the passed type or decode it from the die.  */
+         Use the passed type or decode it from the die.  */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_CLASS (sym) = LOC_STATIC;
       if (type != NULL)
@@ -3433,16 +4084,13 @@ new_symbol (die, type, objfile)
          attr = dwarf_attr (die, DW_AT_low_pc);
          if (attr)
            {
-             SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr);
+             SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
            }
          SYMBOL_CLASS (sym) = LOC_LABEL;
          break;
        case DW_TAG_subprogram:
-         attr = dwarf_attr (die, DW_AT_low_pc);
-         if (attr)
-           {
-             SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr);
-           }
+         /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+            finish_block.  */
          SYMBOL_CLASS (sym) = LOC_BLOCK;
          attr2 = dwarf_attr (die, DW_AT_external);
          if (attr2 && (DW_UNSND (attr2) != 0))
@@ -3463,6 +4111,17 @@ new_symbol (die, type, objfile)
                                           TARGET_INT_BIT / HOST_CHAR_BIT, 0,
                                           "<variable, no debug info>",
                                           objfile);
+         attr = dwarf_attr (die, DW_AT_const_value);
+         if (attr)
+           {
+             dwarf2_const_value (attr, sym, objfile);
+             attr2 = dwarf_attr (die, DW_AT_external);
+             if (attr2 && (DW_UNSND (attr2) != 0))
+               add_symbol_to_list (sym, &global_symbols);
+             else
+               add_symbol_to_list (sym, list_in_scope);
+             break;
+           }
          attr = dwarf_attr (die, DW_AT_location);
          if (attr)
            {
@@ -3472,8 +4131,21 @@ new_symbol (die, type, objfile)
                  SYMBOL_VALUE_ADDRESS (sym) =
                    decode_locdesc (DW_BLOCK (attr), objfile);
                  add_symbol_to_list (sym, &global_symbols);
-                 SYMBOL_CLASS (sym) = LOC_STATIC;
-                 SYMBOL_VALUE_ADDRESS (sym) += baseaddr;
+
+                 /* In shared libraries the address of the variable
+                    in the location descriptor might still be relocatable,
+                    so its value could be zero.
+                    Enter the symbol as a LOC_UNRESOLVED symbol, if its
+                    value is zero, the address of the variable will then
+                    be determined from the minimal symbol table whenever
+                    the variable is referenced.  */
+                 if (SYMBOL_VALUE_ADDRESS (sym))
+                   {
+                     SYMBOL_VALUE_ADDRESS (sym) += baseaddr;
+                     SYMBOL_CLASS (sym) = LOC_STATIC;
+                   }
+                 else
+                   SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
                }
              else
                {
@@ -3507,11 +4179,11 @@ new_symbol (die, type, objfile)
          else
            {
              /* We do not know the address of this symbol.
-                If it is an external symbol and we have type information
-                it, enter the symbol as a LOC_UNRESOLVED symbol.
-                The address of the variable will then be determined from
-                the minimal symbol table whenever the variable is
-                referenced.  */
+                If it is an external symbol and we have type information
+                for it, enter the symbol as a LOC_UNRESOLVED symbol.
+                The address of the variable will then be determined from
+                the minimal symbol table whenever the variable is
+                referenced.  */
              attr2 = dwarf_attr (die, DW_AT_external);
              if (attr2 && (DW_UNSND (attr2) != 0)
                  && dwarf_attr (die, DW_AT_type) != NULL)
@@ -3523,24 +4195,38 @@ new_symbol (die, type, objfile)
          break;
        case DW_TAG_formal_parameter:
          attr = dwarf_attr (die, DW_AT_location);
-         if (attr != NULL)
+         if (attr)
            {
              SYMBOL_VALUE (sym) = decode_locdesc (DW_BLOCK (attr), objfile);
+             if (isreg)
+               {
+                 SYMBOL_CLASS (sym) = LOC_REGPARM;
+               }
+             else if (offreg)
+               {
+                 if (isderef)
+                   {
+                     if (basereg != frame_base_reg)
+                       complain (&dwarf2_complex_location_expr);
+                     SYMBOL_CLASS (sym) = LOC_REF_ARG;
+                   }
+                 else
+                   {
+                     SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
+                     SYMBOL_BASEREG (sym) = basereg;
+                   }
+               }
+             else
+               {
+                 SYMBOL_CLASS (sym) = LOC_ARG;
+               }
            }
-         add_symbol_to_list (sym, list_in_scope);
-         if (isreg)
-           {
-             SYMBOL_CLASS (sym) = LOC_REGPARM;
-           }
-         else if (offreg)
-           {
-             SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
-             SYMBOL_BASEREG (sym) = basereg;
-           }
-         else
+         attr = dwarf_attr (die, DW_AT_const_value);
+         if (attr)
            {
-             SYMBOL_CLASS (sym) = LOC_ARG;
+             dwarf2_const_value (attr, sym, objfile);
            }
+         add_symbol_to_list (sym, list_in_scope);
          break;
        case DW_TAG_unspecified_parameters:
          /* From varargs functions; gdb doesn't seem to have any
@@ -3561,8 +4247,8 @@ new_symbol (die, type, objfile)
          if (cu_language == language_cplus)
            {
              struct symbol *typedef_sym = (struct symbol *)
-               obstack_alloc (&objfile->symbol_obstack,
-                              sizeof (struct symbol));
+             obstack_alloc (&objfile->symbol_obstack,
+                            sizeof (struct symbol));
              *typedef_sym = *sym;
              SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
              if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
@@ -3574,16 +4260,16 @@ new_symbol (die, type, objfile)
            }
          break;
        case DW_TAG_typedef:
+       case DW_TAG_base_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
          SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
          add_symbol_to_list (sym, list_in_scope);
          break;
        case DW_TAG_enumerator:
-         SYMBOL_CLASS (sym) = LOC_CONST;
          attr = dwarf_attr (die, DW_AT_const_value);
          if (attr)
            {
-             SYMBOL_VALUE (sym) = DW_UNSND (attr);
+             dwarf2_const_value (attr, sym, objfile);
            }
          add_symbol_to_list (sym, list_in_scope);
          break;
@@ -3599,6 +4285,101 @@ new_symbol (die, type, objfile)
   return (sym);
 }
 
+/* Copy constant value from an attribute to a symbol.  */
+
+static void
+dwarf2_const_value (attr, sym, objfile)
+     struct attribute *attr;
+     struct symbol *sym;
+     struct objfile *objfile;
+{
+  struct dwarf_block *blk;
+
+  switch (attr->form)
+    {
+    case DW_FORM_addr:
+      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != (unsigned int) address_size)
+       complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+                 address_size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+      SYMBOL_VALUE_BYTES (sym) = (char *)
+       obstack_alloc (&objfile->symbol_obstack, address_size);
+      store_address (SYMBOL_VALUE_BYTES (sym), address_size, DW_ADDR (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)
+       complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym),
+                 blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym)));
+      SYMBOL_VALUE_BYTES (sym) = (char *)
+       obstack_alloc (&objfile->symbol_obstack, blk->size);
+      memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
+      SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+      break;
+
+      /* The DW_AT_const_value attributes are supposed to carry the
+        symbol's value "represented as it would be on the target
+        architecture."  By the time we get here, it's already been
+        converted to host endianness, so we just need to sign- or
+        zero-extend it as appropriate.  */
+    case DW_FORM_data1:
+      dwarf2_const_value_data (attr, sym, 8);
+      break;
+    case DW_FORM_data2:
+      dwarf2_const_value_data (attr, sym, 16);
+      break;
+    case DW_FORM_data4:
+      dwarf2_const_value_data (attr, sym, 32);
+      break;
+    case DW_FORM_data8:
+      dwarf2_const_value_data (attr, sym, 64);
+      break;
+
+    case DW_FORM_sdata:
+      SYMBOL_VALUE (sym) = DW_SND (attr);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+
+    case DW_FORM_udata:
+      SYMBOL_VALUE (sym) = DW_UNSND (attr);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+
+    default:
+      complain (&dwarf2_unsupported_const_value_attr,
+               dwarf_form_name (attr->form));
+      SYMBOL_VALUE (sym) = 0;
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      break;
+    }
+}
+
+
+/* Given an attr with a DW_FORM_dataN value in host byte order, sign-
+   or zero-extend it as appropriate for the symbol's type.  */
+static void
+dwarf2_const_value_data (struct attribute *attr,
+                        struct symbol *sym,
+                        int bits)
+{
+  LONGEST l = DW_UNSND (attr);
+
+  if (bits < sizeof (l) * 8)
+    {
+      if (TYPE_UNSIGNED (SYMBOL_TYPE (sym)))
+       l &= ((LONGEST) 1 << bits) - 1;
+      else
+       l = (l << (sizeof (l) - bits)) >> (sizeof (l) - bits);
+    }
+
+  SYMBOL_VALUE (sym) = l;
+  SYMBOL_CLASS (sym) = LOC_CONST;
+}
+
+
 /* Return the type of the die in question using its DW_AT_type attribute.  */
 
 static struct type *
@@ -3731,7 +4512,7 @@ read_type_die (die, objfile)
       read_subroutine_type (die, objfile);
       break;
     case DW_TAG_array_type:
-      dwarf_read_array_type (die, objfile);
+      read_array_type (die, objfile);
       break;
     case DW_TAG_pointer_type:
       read_tag_pointer_type (die, objfile);
@@ -3757,18 +4538,17 @@ read_type_die (die, objfile)
     case DW_TAG_base_type:
       read_base_type (die, objfile);
       break;
-    case DW_TAG_padding:
-    case DW_TAG_compile_unit:
-    case DW_TAG_lexical_block:
     default:
+      complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
       break;
     }
 }
 
 static struct type *
-dwarf_base_type (encoding, size)
+dwarf_base_type (encoding, size, objfile)
      int encoding;
      int size;
+     struct objfile *objfile;
 {
   /* FIXME - this should not produce a new (struct type *)
      every time.  It should cache base types.  */
@@ -3776,69 +4556,69 @@ dwarf_base_type (encoding, size)
   switch (encoding)
     {
     case DW_ATE_address:
-      type = dwarf2_fundamental_type (current_objfile, FT_VOID);
+      type = dwarf2_fundamental_type (objfile, FT_VOID);
       return type;
     case DW_ATE_boolean:
-      type = dwarf2_fundamental_type (current_objfile, FT_BOOLEAN);
+      type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
       return type;
     case DW_ATE_complex_float:
       if (size == 16)
        {
-         type = dwarf2_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
        }
       else
        {
-         type = dwarf2_fundamental_type (current_objfile, FT_COMPLEX);
+         type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
        }
       return type;
     case DW_ATE_float:
       if (size == 8)
        {
-         type = dwarf2_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
        }
       else
        {
-         type = dwarf2_fundamental_type (current_objfile, FT_FLOAT);
+         type = dwarf2_fundamental_type (objfile, FT_FLOAT);
        }
       return type;
     case DW_ATE_signed:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
          break;
        case 2:
-         type = dwarf2_fundamental_type (current_objfile, FT_SIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
          break;
        }
       return type;
     case DW_ATE_signed_char:
-      type = dwarf2_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
       return type;
     case DW_ATE_unsigned:
       switch (size)
        {
        case 1:
-         type = dwarf2_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
          break;
        case 2:
-         type = dwarf2_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
          break;
        default:
        case 4:
-         type = dwarf2_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+         type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
          break;
        }
       return type;
     case DW_ATE_unsigned_char:
-      type = dwarf2_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+      type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
       return type;
     default:
-      type = dwarf2_fundamental_type (current_objfile, FT_SIGNED_INTEGER);
+      type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
       return type;
     }
 }
@@ -3922,6 +4702,23 @@ sibling_die (die)
     }
 }
 
+/* Get linkage name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_linkage_name (die)
+     struct die_info *die;
+{
+  struct attribute *attr;
+
+  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  return NULL;
+}
+
 /* Convert a DIE tag into its string name.  */
 
 static char *
@@ -4565,10 +5362,10 @@ dwarf_stack_op_name (op)
 }
 
 static char *
-dwarf_bool_name (bool)
-     unsigned bool;
+dwarf_bool_name (mybool)
+     unsigned mybool;
 {
-  if (bool)
+  if (mybool)
     return "TRUE";
   else
     return "FALSE";
@@ -4679,14 +5476,13 @@ dump_die (die)
        case DW_FORM_ref_addr:
        case DW_FORM_addr:
          fprintf (stderr, "address: ");
-         print_address_numeric (die->attrs[i].u.addr, 1, stderr);
+         print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
          break;
        case DW_FORM_block2:
        case DW_FORM_block4:
        case DW_FORM_block:
        case DW_FORM_block1:
-         fprintf (stderr, "block: size %d",
-                  die->attrs[i].u.blk->size);
+         fprintf (stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
          break;
        case DW_FORM_data1:
        case DW_FORM_data2:
@@ -4696,13 +5492,15 @@ dump_die (die)
        case DW_FORM_ref4:
        case DW_FORM_udata:
        case DW_FORM_sdata:
-         fprintf (stderr, "constant: %d", die->attrs[i].u.unsnd);
+         fprintf (stderr, "constant: %d", DW_UNSND (&die->attrs[i]));
          break;
        case DW_FORM_string:
-         fprintf (stderr, "string: \"%s\"", die->attrs[i].u.str);
+         fprintf (stderr, "string: \"%s\"",
+                  DW_STRING (&die->attrs[i])
+                  ? DW_STRING (&die->attrs[i]) : "");
          break;
        case DW_FORM_flag:
-         if (die->attrs[i].u.unsnd)
+         if (DW_UNSND (&die->attrs[i]))
            fprintf (stderr, "flag: TRUE");
          else
            fprintf (stderr, "flag: FALSE");
@@ -4713,7 +5511,7 @@ dump_die (die)
        case DW_FORM_data8:     /* we do not have 64 bit quantities */
        default:
          fprintf (stderr, "unsupported attribute form: %d.",
-                          die->attrs[i].form);
+                  die->attrs[i].form);
        }
       fprintf (stderr, "\n");
     }
@@ -4841,7 +5639,7 @@ dwarf2_fundamental_type (objfile, typeid)
    DW_AT_frame_base attribute, the global islocal flag is set.
    Hopefully the machine dependent code knows how to set up a virtual
    frame pointer for the local references.
+
    Note that stack[0] is unused except as a default error return.
    Note that stack overflow is not yet handled.  */
 
@@ -4863,6 +5661,7 @@ decode_locdesc (blk, objfile)
   stack[stacki] = 0;
   isreg = 0;
   offreg = 0;
+  isderef = 0;
   islocal = 0;
   optimized_out = 1;
 
@@ -4959,6 +5758,14 @@ decode_locdesc (blk, objfile)
          i += bytes_read;
          break;
 
+       case DW_OP_bregx:
+         offreg = 1;
+         basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
        case DW_OP_fbreg:
          stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
          i += bytes_read;
@@ -5012,7 +5819,7 @@ decode_locdesc (blk, objfile)
 
        case DW_OP_constu:
          stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
-                                                        &bytes_read);
+                                                 &bytes_read);
          i += bytes_read;
          break;
 
@@ -5026,13 +5833,26 @@ decode_locdesc (blk, objfile)
          stacki--;
          break;
 
+       case DW_OP_plus_uconst:
+         stack[stacki] += read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+         i += bytes_read;
+         break;
+
        case DW_OP_minus:
          stack[stacki - 1] = stack[stacki] - stack[stacki - 1];
          stacki--;
          break;
 
+       case DW_OP_deref:
+         isderef = 1;
+         /* If we're not the last op, then we definitely can't encode
+            this using GDB's address_class enum.  */
+         if (i < size)
+           complain (&dwarf2_complex_location_expr);
+         break;
+
        default:
-         complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name(op));
+         complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op));
          return (stack[stacki]);
        }
     }
This page took 0.065875 seconds and 4 git commands to generate.