OSDN Git Service

* configure.in (all_headers, all_lib2funcs): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 740df26..2cbe716 100644 (file)
@@ -5,25 +5,24 @@
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
    Extensively modified by Jason Merrill (jason@cygnus.com).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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, or (at your option)
-any later version.
+GCC 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, or (at your option) any later
+version.
 
-GNU CC 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.
+GCC 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
-/* TODO: Implement .debug_str handling, and share entries somehow.
-        Emit .debug_line header even when there are no functions, since
+/* TODO: Emit .debug_line header even when there are no functions, since
           the file numbers are used by .debug_info.  Alternately, leave
           out locations for types and decls.
         Avoid talking about ctors and op= for PODs.
@@ -47,6 +46,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "output.h"
 #include "expr.h"
+#include "libfuncs.h"
 #include "except.h"
 #include "dwarf2.h"
 #include "dwarf2out.h"
@@ -58,6 +58,9 @@ Boston, MA 02111-1307, USA.  */
 #include "tm_p.h"
 #include "diagnostic.h"
 #include "debug.h"
+#include "target.h"
+#include "langhooks.h"
+#include "hashtable.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
 static void dwarf2out_source_line      PARAMS ((unsigned int, const char *));
@@ -88,6 +91,7 @@ int
 dwarf2out_do_frame ()
 {
   return (write_symbols == DWARF2_DEBUG
+         || write_symbols == VMS_AND_DWARF2_DEBUG
 #ifdef DWARF2_FRAME_INFO
          || DWARF2_FRAME_INFO
 #endif
@@ -105,6 +109,30 @@ dwarf2out_do_frame ()
    unique to each function definition.  */
 unsigned current_funcdef_number = 0;
 
+/* The size of the target's pointer type.  */
+#ifndef PTR_SIZE
+#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
+#endif
+
+/* Default version of targetm.eh_frame_section.  Note this must appear
+   outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro
+   guards.  */
+
+void
+default_eh_frame_section ()
+{
+#ifdef EH_FRAME_SECTION_NAME
+  named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE);
+#else
+  tree label = get_file_function_name ('F');
+
+  data_section ();
+  ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
+  ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
+  ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
+#endif
+}
+
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
 /* How to start an assembler comment.  */
@@ -154,7 +182,7 @@ typedef struct cfa_loc
 
 /* All call frame descriptions (FDE's) in the GCC generated DWARF
    refer to a single Common Information Entry (CIE), defined at
-   the beginning of the .debug_frame section.  This used of a single
+   the beginning of the .debug_frame section.  This use of a single
    CIE obviates the need to keep track of multiple CIE's
    in the DWARF generation routines below.  */
 
@@ -170,14 +198,9 @@ typedef struct dw_fde_struct
 }
 dw_fde_node;
 
-/* Maximum size (in bytes) of an artificially generated label.   */
+/* Maximum size (in bytes) of an artificially generated label.  */
 #define MAX_ARTIFICIAL_LABEL_BYTES     30
 
-/* The size of the target's pointer type.  */
-#ifndef PTR_SIZE
-#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
-#endif
-
 /* The size of addresses as they appear in the Dwarf 2 data.
    Some architectures use word addresses to refer to code locations,
    but Dwarf 2 info always uses byte addresses.  On such machines,
@@ -234,6 +257,16 @@ static dw_cfi_ref cie_cfi_head;
    associated with the current function (body) definition.  */
 static unsigned current_funcdef_fde;
 
+struct ht *debug_str_hash;
+
+struct indirect_string_node
+{
+  struct ht_identifier id;
+  unsigned int refcount;
+  unsigned int form;
+  char *label;
+};
+
 /* Forward declarations for functions defined in this file.  */
 
 static char *stripattributes           PARAMS ((const char *));
@@ -263,6 +296,11 @@ static struct dw_loc_descr_struct *build_cfa_loc
                                        PARAMS ((dw_cfa_location *));
 static void def_cfa_1                  PARAMS ((const char *, dw_cfa_location *));
 
+/* .debug_str support.  */
+static hashnode indirect_string_alloc  PARAMS ((hash_table *));
+static int output_indirect_string      PARAMS ((struct cpp_reader *,
+                                                hashnode, const PTR));
+
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
 #define ASM_COMMENT_START ";#"
@@ -287,6 +325,7 @@ static void def_cfa_1                       PARAMS ((const char *, dw_cfa_location *));
 #ifndef FUNC_END_LABEL
 #define FUNC_END_LABEL         "LFE"
 #endif
+#define FRAME_BEGIN_LABEL      "Lframe"
 #define CIE_AFTER_SIZE_LABEL   "LSCIE"
 #define CIE_END_LABEL          "LECIE"
 #define CIE_LENGTH_LABEL       "LLCIE"
@@ -395,7 +434,7 @@ expand_builtin_init_dwarf_reg_sizes (address)
 
 static const char *
 dwarf_cfi_name (cfi_opc)
-     register unsigned cfi_opc;
+     unsigned cfi_opc;
 {
   switch (cfi_opc)
     {
@@ -460,7 +499,7 @@ dwarf_cfi_name (cfi_opc)
 static inline dw_cfi_ref
 new_cfi ()
 {
-  register dw_cfi_ref cfi = (dw_cfi_ref) xmalloc (sizeof (dw_cfi_node));
+  dw_cfi_ref cfi = (dw_cfi_ref) xmalloc (sizeof (dw_cfi_node));
 
   cfi->dw_cfi_next = NULL;
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
@@ -473,10 +512,10 @@ new_cfi ()
 
 static inline void
 add_cfi (list_head, cfi)
-     register dw_cfi_ref *list_head;
-     register dw_cfi_ref cfi;
+     dw_cfi_ref *list_head;
+     dw_cfi_ref cfi;
 {
-  register dw_cfi_ref *p;
+  dw_cfi_ref *p;
 
   /* Find the end of the chain.  */
   for (p = list_head; (*p) != NULL; p = &(*p)->dw_cfi_next)
@@ -504,12 +543,12 @@ dwarf2out_cfi_label ()
 
 static void
 add_fde_cfi (label, cfi)
-     register const char *label;
-     register dw_cfi_ref cfi;
+     const char *label;
+     dw_cfi_ref cfi;
 {
   if (label)
     {
-      register dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
+      dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
 
       if (*label == 0)
        label = dwarf2out_cfi_label ();
@@ -517,7 +556,7 @@ add_fde_cfi (label, cfi)
       if (fde->dw_fde_current_label == NULL
          || strcmp (label, fde->dw_fde_current_label) != 0)
        {
-         register dw_cfi_ref xcfi;
+         dw_cfi_ref xcfi;
 
          fde->dw_fde_current_label = label = xstrdup (label);
 
@@ -539,8 +578,8 @@ add_fde_cfi (label, cfi)
 
 static inline void
 lookup_cfa_1 (cfi, loc)
-     register dw_cfi_ref cfi;
-     register dw_cfa_location *loc;
+     dw_cfi_ref cfi;
+     dw_cfa_location *loc;
 {
   switch (cfi->dw_cfi_opc)
     {
@@ -566,9 +605,9 @@ lookup_cfa_1 (cfi, loc)
 
 static void
 lookup_cfa (loc)
-     register dw_cfa_location *loc;
+     dw_cfa_location *loc;
 {
-  register dw_cfi_ref cfi;
+  dw_cfi_ref cfi;
 
   loc->reg = (unsigned long) -1;
   loc->offset = 0;
@@ -580,7 +619,7 @@ lookup_cfa (loc)
 
   if (fde_table_in_use)
     {
-      register dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
+      dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
       for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
        lookup_cfa_1 (cfi, loc);
     }
@@ -605,7 +644,7 @@ static long old_args_size;
 
 void
 dwarf2out_def_cfa (label, reg, offset)
-     register const char *label;
+     const char *label;
      unsigned reg;
      long offset;
 {
@@ -621,10 +660,10 @@ dwarf2out_def_cfa (label, reg, offset)
    the dw_cfa_location structure.  */
 static void
 def_cfa_1 (label, loc_p)
-     register const char *label;
+     const char *label;
      dw_cfa_location *loc_p;
 {
-  register dw_cfi_ref cfi;
+  dw_cfi_ref cfi;
   dw_cfa_location old_cfa, loc;
 
   cfa = *loc_p;
@@ -699,12 +738,12 @@ def_cfa_1 (label, loc_p)
 
 static void
 reg_save (label, reg, sreg, offset)
-     register const char *label;
-     register unsigned reg;
-     register unsigned sreg;
-     register long offset;
+     const char *label;
+     unsigned reg;
+     unsigned sreg;
+     long offset;
 {
-  register dw_cfi_ref cfi = new_cfi ();
+  dw_cfi_ref cfi = new_cfi ();
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
 
@@ -760,9 +799,9 @@ reg_save (label, reg, sreg, offset)
 
 void
 dwarf2out_window_save (label)
-     register const char *label;
+     const char *label;
 {
-  register dw_cfi_ref cfi = new_cfi ();
+  dw_cfi_ref cfi = new_cfi ();
   cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
   add_fde_cfi (label, cfi);
 }
@@ -775,7 +814,7 @@ dwarf2out_args_size (label, size)
      const char *label;
      long size;
 {
-  register dw_cfi_ref cfi;
+  dw_cfi_ref cfi;
 
   if (size == old_args_size)
     return;
@@ -792,9 +831,9 @@ dwarf2out_args_size (label, size)
 
 void
 dwarf2out_reg_save (label, reg, offset)
-     register const char *label;
-     register unsigned reg;
-     register long offset;
+     const char *label;
+     unsigned reg;
+     long offset;
 {
   reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
 }
@@ -804,8 +843,8 @@ dwarf2out_reg_save (label, reg, offset)
 
 void
 dwarf2out_return_save (label, offset)
-     register const char *label;
-     register long offset;
+     const char *label;
+     long offset;
 {
   reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
 }
@@ -815,8 +854,8 @@ dwarf2out_return_save (label, offset)
 
 void
 dwarf2out_return_reg (label, sreg)
-     register const char *label;
-     register unsigned sreg;
+     const char *label;
+     unsigned sreg;
 {
   reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0);
 }
@@ -826,7 +865,7 @@ dwarf2out_return_reg (label, sreg)
 
 static void
 initial_return_save (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
   unsigned int reg = (unsigned int) -1;
   long offset = 0;
@@ -941,7 +980,8 @@ dwarf2out_stack_adjust (insn)
   long offset;
   const char *label;
 
-  if (! flag_non_call_exceptions && GET_CODE (insn) == CALL_INSN)
+  if (!flag_asynchronous_unwind_tables
+      && GET_CODE (insn) == CALL_INSN)
     {
       /* Extract the size of the args from the CALL rtx itself.  */
 
@@ -958,7 +998,7 @@ dwarf2out_stack_adjust (insn)
 
   /* If only calls can throw, and we have a frame pointer,
      save up adjustments until we see the CALL_INSN.  */
-  else if (! flag_non_call_exceptions
+  else if (!flag_asynchronous_unwind_tables
           && cfa.reg != STACK_POINTER_REGNUM)
     return;
 
@@ -1602,8 +1642,8 @@ dwarf2out_frame_debug (insn)
 
 static void
 output_cfi (cfi, fde, for_eh)
-     register dw_cfi_ref cfi;
-     register dw_fde_ref fde;
+     dw_cfi_ref cfi;
+     dw_fde_ref fde;
      int for_eh;
 {
   if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
@@ -1704,10 +1744,10 @@ static void
 output_call_frame_info (for_eh)
      int for_eh;
 {
-  register unsigned int i;
-  register dw_fde_ref fde;
-  register dw_cfi_ref cfi;
-  char l1[20], l2[20];
+  unsigned int i;
+  dw_fde_ref fde;
+  dw_cfi_ref cfi;
+  char l1[20], l2[20], section_start_label[20];
   int any_lsda_needed = 0;
   char augmentation[6];
   int augmentation_size;
@@ -1719,7 +1759,7 @@ output_call_frame_info (for_eh)
      emit any EH unwind information.  */
   if (for_eh)
     {
-      int any_eh_needed = 0;
+      int any_eh_needed = flag_asynchronous_unwind_tables;
       for (i = 0; i < fde_table_in_use; ++i)
        if (fde_table[i].uses_eh_lsda)
          any_eh_needed = any_lsda_needed = 1;
@@ -1735,22 +1775,12 @@ output_call_frame_info (for_eh)
     app_enable ();
 
   if (for_eh)
-    {
-#ifdef EH_FRAME_SECTION_NAME
-      named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE,
-                          DWARF_OFFSET_SIZE);
-#else
-      tree label = get_file_function_name ('F');
-
-      data_section ();
-      ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
-      ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
-      ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
-#endif
-      assemble_label ("__FRAME_BEGIN__");
-    }
+    (*targetm.asm_out.eh_frame_section) ();
   else
-    named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG, 1);
+    named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG);
+
+  ASM_GENERATE_INTERNAL_LABEL (section_start_label, FRAME_BEGIN_LABEL, for_eh);
+  ASM_OUTPUT_LABEL (asm_out_file, section_start_label);
 
   /* Output the CIE.  */
   ASM_GENERATE_INTERNAL_LABEL (l1, CIE_AFTER_SIZE_LABEL, for_eh);
@@ -1882,19 +1912,10 @@ output_call_frame_info (for_eh)
                            "FDE Length");
       ASM_OUTPUT_LABEL (asm_out_file, l1);
 
-      /* ??? This always emits a 4 byte offset when for_eh is true, but it
-        emits a target dependent sized offset when for_eh is not true.
-        This inconsistency may confuse gdb.  The only case where we need a
-        non-4 byte offset is for the Irix6 N64 ABI, so we may lose SGI
-        compatibility if we emit a 4 byte offset.  We need a 4 byte offset
-        though in order to be compatible with the dwarf_fde struct in frame.c.
-        If the for_eh case is changed, then the struct in frame.c has
-        to be adjusted appropriately.  */
       if (for_eh)
-       dw2_asm_output_delta (4, l1, "__FRAME_BEGIN__", "FDE CIE offset");
+       dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset");
       else
-       dw2_asm_output_offset (DWARF_OFFSET_SIZE,
-                              stripattributes (DEBUG_FRAME_SECTION),
+       dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label,
                               "FDE CIE offset");
 
       if (for_eh)
@@ -1992,7 +2013,7 @@ dwarf2out_begin_prologue (line, file)
      const char *file ATTRIBUTE_UNUSED;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
-  register dw_fde_ref fde;
+  dw_fde_ref fde;
 
   current_function_func_begin_label = 0;
 
@@ -2095,16 +2116,10 @@ void
 dwarf2out_frame_finish ()
 {
   /* Output call frame information.  */
-#ifdef MIPS_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
+  if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
     output_call_frame_info (0);
-  if (flag_unwind_tables || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS))
-    output_call_frame_info (1);
-#else
-  if (write_symbols == DWARF2_DEBUG
-      || flag_unwind_tables || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS))
+  if (! USING_SJLJ_EXCEPTIONS && (flag_unwind_tables || flag_exceptions))
     output_call_frame_info (1);
-#endif
 }
 \f
 /* And now, the subset of the debugging information support code necessary
@@ -2125,6 +2140,7 @@ typedef enum
   dw_val_class_offset,
   dw_val_class_loc,
   dw_val_class_loc_list,
+  dw_val_class_range_list,
   dw_val_class_const,
   dw_val_class_unsigned_const,
   dw_val_class_long_long,
@@ -2178,7 +2194,7 @@ typedef struct dw_val_struct
        int external;
       } val_die_ref;
       unsigned val_fde_index;
-      char *val_str;
+      struct indirect_string_node *val_str;
       char *val_lbl_id;
       unsigned char val_flag;
     }
@@ -2227,7 +2243,7 @@ static void output_loc_sequence           PARAMS ((dw_loc_descr_ref));
 
 static const char *
 dwarf_stack_op_name (op)
-     register unsigned op;
+     unsigned op;
 {
   switch (op)
     {
@@ -2532,13 +2548,13 @@ dwarf_stack_op_name (op)
 
 static inline dw_loc_descr_ref
 new_loc_descr (op, oprnd1, oprnd2)
-     register enum dwarf_location_atom op;
-     register unsigned long oprnd1;
-     register unsigned long oprnd2;
+     enum dwarf_location_atom op;
+     unsigned long oprnd1;
+     unsigned long oprnd2;
 {
   /* Use xcalloc here so we clear out all of the long_long constant in
      the union.  */
-  register dw_loc_descr_ref descr
+  dw_loc_descr_ref descr
     = (dw_loc_descr_ref) xcalloc (1, sizeof (dw_loc_descr_node));
 
   descr->dw_loc_opc = op;
@@ -2555,10 +2571,10 @@ new_loc_descr (op, oprnd1, oprnd2)
 
 static inline void
 add_loc_descr (list_head, descr)
-     register dw_loc_descr_ref *list_head;
-     register dw_loc_descr_ref descr;
+     dw_loc_descr_ref *list_head;
+     dw_loc_descr_ref descr;
 {
-  register dw_loc_descr_ref *d;
+  dw_loc_descr_ref *d;
 
   /* Find the end of the chain.  */
   for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
@@ -2571,9 +2587,9 @@ add_loc_descr (list_head, descr)
 
 static unsigned long
 size_of_loc_descr (loc)
-     register dw_loc_descr_ref loc;
+     dw_loc_descr_ref loc;
 {
-  register unsigned long size = 1;
+  unsigned long size = 1;
 
   switch (loc->dw_loc_opc)
     {
@@ -2674,9 +2690,9 @@ size_of_loc_descr (loc)
 
 static unsigned long
 size_of_locs (loc)
-     register dw_loc_descr_ref loc;
+     dw_loc_descr_ref loc;
 {
-  register unsigned long size = 0;
+  unsigned long size = 0;
 
   for (; loc != NULL; loc = loc->dw_loc_next)
     {
@@ -2691,10 +2707,10 @@ size_of_locs (loc)
 
 static void
 output_loc_operands (loc)
-     register dw_loc_descr_ref loc;
+     dw_loc_descr_ref loc;
 {
-  register dw_val_ref val1 = &loc->dw_loc_oprnd1;
-  register dw_val_ref val2 = &loc->dw_loc_oprnd2;
+  dw_val_ref val1 = &loc->dw_loc_oprnd1;
+  dw_val_ref val2 = &loc->dw_loc_oprnd2;
 
   switch (loc->dw_loc_opc)
     {
@@ -2990,7 +3006,7 @@ get_cfa_from_loc_descr (cfa, loc)
          cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned;
          break;
        default:
-         internal_error ("DW_LOC_OP %s not implememnted\n",
+         internal_error ("DW_LOC_OP %s not implemented\n",
                          dwarf_stack_op_name (ptr->dw_loc_opc));
        }
     }
@@ -3210,7 +3226,7 @@ extern int flag_traditional;
    This value was chosen to give a reasonable range of values.  */
 #define DWARF_LINE_BASE  -10
 
-/* First special line opcde - leave room for the standard opcodes.  */
+/* First special line opcode - leave room for the standard opcodes.  */
 #define DWARF_LINE_OPCODE_BASE  10
 
 /* Range of line offsets in a special line info. opcode.  */
@@ -3272,17 +3288,7 @@ static unsigned decl_die_table_in_use;
    of declaration scopes at the current scope and containing
    scopes.  This table is used to find the proper place to
    define type declaration DIE's.  */
-static tree *decl_scope_table;
-
-/* Number of elements currently allocated for the decl_scope_table.  */
-static int decl_scope_table_allocated;
-
-/* Current level of nesting of declaration scopes.  */
-static int decl_scope_depth;
-
-/* Size (in elements) of increments by which we may expand the
-   decl_scope_table.  */
-#define DECL_SCOPE_TABLE_INCREMENT 64
+varray_type decl_scope_table;
 
 /* A pointer to the base of a list of references to DIE's that
    are uniquely identified by their tag, presence/absence of
@@ -3367,20 +3373,11 @@ static unsigned ranges_table_in_use;
 static unsigned have_location_lists;
 
 /* A pointer to the base of a list of incomplete types which might be
-   completed at some later time.  */
-
-static tree *incomplete_types_list;
-
-/* Number of elements currently allocated for the incomplete_types_list.  */
-static unsigned incomplete_types_allocated;
-
-/* Number of elements of incomplete_types_list currently in use.  */
-static unsigned incomplete_types;
-
-/* Size (in elements) of increments by which we may expand the incomplete
-   types list.  Actually, a single hunk of space of this size should
-   be enough for most typical programs.         */
-#define INCOMPLETE_TYPES_INCREMENT 64
+   completed at some later time.  incomplete_types_list needs to be a VARRAY
+   because we want to tell the garbage collector about it.  If we don't tell
+   the garbage collector about it, we can garbage collect live data.
+   Bug 4215.*/
+varray_type incomplete_types;
 
 /* Record whether the function being analyzed contains inlined functions.  */
 static int current_function_has_inlines;
@@ -3451,6 +3448,9 @@ static void add_AT_lbl_offset             PARAMS ((dw_die_ref,
 static void add_AT_offset              PARAMS ((dw_die_ref,
                                                 enum dwarf_attribute,
                                                 unsigned long));
+static void add_AT_range_list          PARAMS ((dw_die_ref,
+                                                enum dwarf_attribute,
+                                                unsigned long));
 static dw_attr_ref get_AT              PARAMS ((dw_die_ref,
                                                 enum dwarf_attribute));
 static const char *get_AT_low_pc       PARAMS ((dw_die_ref));
@@ -3464,6 +3464,7 @@ static unsigned get_AT_unsigned           PARAMS ((dw_die_ref,
 static inline dw_die_ref get_AT_ref    PARAMS ((dw_die_ref,
                                                 enum dwarf_attribute));
 static int is_c_family                 PARAMS ((void));
+static int is_cxx                      PARAMS ((void));
 static int is_java                     PARAMS ((void));
 static int is_fortran                  PARAMS ((void));
 static void remove_AT                  PARAMS ((dw_die_ref,
@@ -3494,7 +3495,6 @@ static void break_out_includes            PARAMS ((dw_die_ref));
 static void add_sibling_attributes     PARAMS ((dw_die_ref));
 static void build_abbrev_table         PARAMS ((dw_die_ref));
 static void output_location_lists      PARAMS ((dw_die_ref));
-static unsigned long size_of_string    PARAMS ((const char *));
 static int constant_size               PARAMS ((long unsigned));
 static unsigned long size_of_die       PARAMS ((dw_die_ref));
 static void calc_die_sizes             PARAMS ((dw_die_ref));
@@ -3646,14 +3646,16 @@ static char *gen_internal_sym           PARAMS ((const char *));
 #endif
 
 /* Standard ELF section names for compiled code and data.  */
-#ifndef TEXT_SECTION
-#define TEXT_SECTION           ".text"
+#ifndef TEXT_SECTION_NAME
+#define TEXT_SECTION_NAME      ".text"
 #endif
-#ifndef DATA_SECTION
-#define DATA_SECTION           ".data"
-#endif
-#ifndef BSS_SECTION
-#define BSS_SECTION            ".bss"
+
+/* Section flags for .debug_str section.  */
+#ifdef HAVE_GAS_SHF_MERGE
+#define DEBUG_STR_SECTION_FLAGS \
+  (SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1)
+#else
+#define DEBUG_STR_SECTION_FLAGS        SECTION_DEBUG
 #endif
 
 /* Labels we insert at beginning sections we can reference instead of
@@ -3674,6 +3676,9 @@ static char *gen_internal_sym             PARAMS ((const char *));
 #ifndef DEBUG_LOC_SECTION_LABEL
 #define DEBUG_LOC_SECTION_LABEL                "Ldebug_loc"
 #endif
+#ifndef DEBUG_RANGES_SECTION_LABEL
+#define DEBUG_RANGES_SECTION_LABEL     "Ldebug_ranges"
+#endif
 #ifndef DEBUG_MACINFO_SECTION_LABEL
 #define DEBUG_MACINFO_SECTION_LABEL     "Ldebug_macinfo"
 #endif
@@ -3691,6 +3696,7 @@ static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
 static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
 static char macinfo_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
 static char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
 #ifndef TEXT_END_LABEL
 #define TEXT_END_LABEL         "Letext"
 #endif
@@ -3737,7 +3743,7 @@ dwarf2out_set_demangle_name_func (func)
 
 static rtx
 save_rtx (orig)
-     register rtx orig;
+     rtx orig;
 {
   VARRAY_PUSH_RTX (used_rtx_varray, orig);
 
@@ -3748,7 +3754,7 @@ save_rtx (orig)
 
 static inline int
 is_pseudo_reg (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
   return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
          || (GET_CODE (rtl) == SUBREG
@@ -3760,7 +3766,7 @@ is_pseudo_reg (rtl)
 
 static inline tree
 type_main_variant (type)
-     register tree type;
+     tree type;
 {
   type = TYPE_MAIN_VARIANT (type);
 
@@ -3780,9 +3786,9 @@ type_main_variant (type)
 
 static inline int
 is_tagged_type (type)
-     register tree type;
+     tree type;
 {
-  register enum tree_code code = TREE_CODE (type);
+  enum tree_code code = TREE_CODE (type);
 
   return (code == RECORD_TYPE || code == UNION_TYPE
          || code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE);
@@ -3792,7 +3798,7 @@ is_tagged_type (type)
 
 static const char *
 dwarf_tag_name (tag)
-     register unsigned tag;
+     unsigned tag;
 {
   switch (tag)
     {
@@ -3913,7 +3919,7 @@ dwarf_tag_name (tag)
 
 static const char *
 dwarf_attr_name (attr)
-     register unsigned attr;
+     unsigned attr;
 {
   switch (attr)
     {
@@ -4102,6 +4108,9 @@ dwarf_attr_name (attr)
       return "DW_AT_body_begin";
     case DW_AT_body_end:
       return "DW_AT_body_end";
+    case DW_AT_VMS_rtnbeg_pd_address:
+      return "DW_AT_VMS_rtnbeg_pd_address";
+
     default:
       return "DW_AT_<unknown>";
     }
@@ -4111,7 +4120,7 @@ dwarf_attr_name (attr)
 
 static const char *
 dwarf_form_name (form)
-     register unsigned form;
+     unsigned form;
 {
   switch (form)
     {
@@ -4167,7 +4176,7 @@ dwarf_form_name (form)
 #if 0
 static const char *
 dwarf_type_encoding_name (enc)
-     register unsigned enc;
+     unsigned enc;
 {
   switch (enc)
     {
@@ -4201,7 +4210,7 @@ dwarf_type_encoding_name (enc)
 
 static tree
 decl_ultimate_origin (decl)
-     register tree decl;
+     tree decl;
 {
   /* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
      nodes in the function to point to themselves; ignore that if
@@ -4227,9 +4236,9 @@ decl_ultimate_origin (decl)
 
 static tree
 block_ultimate_origin (block)
-     register tree block;
+     tree block;
 {
-  register tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
+  tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
 
   /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the
      nodes in the function to point to themselves; ignore that if
@@ -4241,8 +4250,8 @@ block_ultimate_origin (block)
     return NULL_TREE;
   else
     {
-      register tree ret_val;
-      register tree lookahead = immediate_origin;
+      tree ret_val;
+      tree lookahead = immediate_origin;
 
       do
        {
@@ -4284,8 +4293,8 @@ decl_class_context (decl)
 
 static inline void
 add_dwarf_attr (die, attr)
-     register dw_die_ref die;
-     register dw_attr_ref attr;
+     dw_die_ref die;
+     dw_attr_ref attr;
 {
   if (die != NULL && attr != NULL)
     {
@@ -4306,11 +4315,11 @@ AT_class (a)
 
 static inline void
 add_AT_flag (die, attr_kind, flag)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned flag;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned flag;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4322,7 +4331,7 @@ add_AT_flag (die, attr_kind, flag)
 static inline unsigned AT_flag PARAMS ((dw_attr_ref));
 static inline unsigned
 AT_flag (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_flag)
     return a->dw_attr_val.v.val_flag;
@@ -4334,11 +4343,11 @@ AT_flag (a)
 
 static inline void
 add_AT_int (die, attr_kind, int_val)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register long int int_val;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     long int int_val;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4350,7 +4359,7 @@ add_AT_int (die, attr_kind, int_val)
 static inline long int AT_int PARAMS ((dw_attr_ref));
 static inline long int
 AT_int (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_const)
     return a->dw_attr_val.v.val_int;
@@ -4362,11 +4371,11 @@ AT_int (a)
 
 static inline void
 add_AT_unsigned (die, attr_kind, unsigned_val)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned long unsigned_val;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned long unsigned_val;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4378,7 +4387,7 @@ add_AT_unsigned (die, attr_kind, unsigned_val)
 static inline unsigned long AT_unsigned PARAMS ((dw_attr_ref));
 static inline unsigned long
 AT_unsigned (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_unsigned_const)
     return a->dw_attr_val.v.val_unsigned;
@@ -4390,12 +4399,12 @@ AT_unsigned (a)
 
 static inline void
 add_AT_long_long (die, attr_kind, val_hi, val_low)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned long val_hi;
-     register unsigned long val_low;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned long val_hi;
+     unsigned long val_low;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4409,12 +4418,12 @@ add_AT_long_long (die, attr_kind, val_hi, val_low)
 
 static inline void
 add_AT_float (die, attr_kind, length, array)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned length;
-     register long *array;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned length;
+     long *array;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4428,26 +4437,83 @@ add_AT_float (die, attr_kind, length, array)
 
 static inline void
 add_AT_string (die, attr_kind, str)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register const char *str;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     const char *str;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  struct indirect_string_node *node;
+  
+  if (! debug_str_hash)
+    {
+      debug_str_hash = ht_create (10);
+      debug_str_hash->alloc_node = indirect_string_alloc;
+    }
+
+  node = (struct indirect_string_node *)
+        ht_lookup (debug_str_hash, (const unsigned char *) str,
+                   strlen (str), HT_ALLOC);
+  node->refcount++;
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
   attr->dw_attr_val.val_class = dw_val_class_str;
-  attr->dw_attr_val.v.val_str = xstrdup (str);
+  attr->dw_attr_val.v.val_str = node;
   add_dwarf_attr (die, attr);
 }
 
 static inline const char *AT_string PARAMS ((dw_attr_ref));
 static inline const char *
 AT_string (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
+{
+  if (a && AT_class (a) == dw_val_class_str)
+    return (const char *) HT_STR (&a->dw_attr_val.v.val_str->id);
+
+  abort ();
+}
+
+/* Find out whether a string should be output inline in DIE
+   or out-of-line in .debug_str section.  */
+
+static int AT_string_form PARAMS ((dw_attr_ref));
+static int
+AT_string_form (a)
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_str)
-    return a->dw_attr_val.v.val_str;
+    {
+      struct indirect_string_node *node;
+      unsigned int len;
+      extern int const_labelno;
+      char label[32];
+
+      node = a->dw_attr_val.v.val_str;
+      if (node->form)
+       return node->form;
+
+      len = HT_LEN (&node->id) + 1;
+
+      /* If the string is shorter or equal to the size
+        of the reference, it is always better to put it
+        inline.  */
+      if (len <= DWARF_OFFSET_SIZE || node->refcount == 0)
+       return node->form = DW_FORM_string;
+
+      if ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) == 0)
+       {
+         /* If we cannot expect the linker to merge strings
+            in .debug_str section, only put it into .debug_str
+            if it is worth even in this single module.  */
+         if ((len - DWARF_OFFSET_SIZE) * node->refcount <= len)
+           return node->form = DW_FORM_string;
+       }
+
+      ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
+      ++const_labelno;
+      node->label = xstrdup (label);
+      return node->form = DW_FORM_strp;
+    }
 
   abort ();
 }
@@ -4456,11 +4522,11 @@ AT_string (a)
 
 static inline void
 add_AT_die_ref (die, attr_kind, targ_die)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register dw_die_ref targ_die;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     dw_die_ref targ_die;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4473,7 +4539,7 @@ add_AT_die_ref (die, attr_kind, targ_die)
 static inline dw_die_ref AT_ref PARAMS ((dw_attr_ref));
 static inline dw_die_ref
 AT_ref (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
     return a->dw_attr_val.v.val_die_ref.die;
@@ -4484,7 +4550,7 @@ AT_ref (a)
 static inline int AT_ref_external PARAMS ((dw_attr_ref));
 static inline int
 AT_ref_external (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
     return a->dw_attr_val.v.val_die_ref.external;
@@ -4495,7 +4561,7 @@ AT_ref_external (a)
 static inline void set_AT_ref_external PARAMS ((dw_attr_ref, int));
 static inline void
 set_AT_ref_external (a, i)
-     register dw_attr_ref a;
+     dw_attr_ref a;
      int i;
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
@@ -4508,11 +4574,11 @@ set_AT_ref_external (a, i)
 
 static inline void
 add_AT_fde_ref (die, attr_kind, targ_fde)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned targ_fde;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned targ_fde;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4525,11 +4591,11 @@ add_AT_fde_ref (die, attr_kind, targ_fde)
 
 static inline void
 add_AT_loc (die, attr_kind, loc)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register dw_loc_descr_ref loc;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     dw_loc_descr_ref loc;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4541,7 +4607,7 @@ add_AT_loc (die, attr_kind, loc)
 static inline dw_loc_descr_ref AT_loc PARAMS ((dw_attr_ref));
 static inline dw_loc_descr_ref
 AT_loc (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_loc)
     return a->dw_attr_val.v.val_loc;
@@ -4551,11 +4617,11 @@ AT_loc (a)
 
 static inline void
 add_AT_loc_list (die, attr_kind, loc_list)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register dw_loc_list_ref loc_list;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     dw_loc_list_ref loc_list;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4569,7 +4635,7 @@ static inline dw_loc_list_ref AT_loc_list PARAMS ((dw_attr_ref));
 
 static inline dw_loc_list_ref
 AT_loc_list (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_loc_list)
     return a->dw_attr_val.v.val_loc_list;
@@ -4581,11 +4647,11 @@ AT_loc_list (a)
 
 static inline void
 add_AT_addr (die, attr_kind, addr)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
      rtx addr;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4597,7 +4663,7 @@ add_AT_addr (die, attr_kind, addr)
 static inline rtx AT_addr PARAMS ((dw_attr_ref));
 static inline rtx
 AT_addr (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && AT_class (a) == dw_val_class_addr)
     return a->dw_attr_val.v.val_addr;
@@ -4609,11 +4675,11 @@ AT_addr (a)
 
 static inline void
 add_AT_lbl_id (die, attr_kind, lbl_id)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register const char *lbl_id;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     const char *lbl_id;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4626,11 +4692,11 @@ add_AT_lbl_id (die, attr_kind, lbl_id)
 
 static inline void
 add_AT_lbl_offset (die, attr_kind, label)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register const char *label;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     const char *label;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4641,13 +4707,13 @@ add_AT_lbl_offset (die, attr_kind, label)
 
 /* Add an offset attribute value to a DIE.  */
 
-static void
+static inline void
 add_AT_offset (die, attr_kind, offset)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
-     register unsigned long offset;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned long offset;
 {
-  register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4656,10 +4722,27 @@ add_AT_offset (die, attr_kind, offset)
   add_dwarf_attr (die, attr);
 }
 
+/* Add an range_list attribute value to a DIE.  */
+
+static void
+add_AT_range_list (die, attr_kind, offset)
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
+     unsigned long offset;
+{
+  dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+
+  attr->dw_attr_next = NULL;
+  attr->dw_attr = attr_kind;
+  attr->dw_attr_val.val_class = dw_val_class_range_list;
+  attr->dw_attr_val.v.val_offset = offset;
+  add_dwarf_attr (die, attr);
+}
+
 static inline const char *AT_lbl PARAMS ((dw_attr_ref));
 static inline const char *
 AT_lbl (a)
-     register dw_attr_ref a;
+     dw_attr_ref a;
 {
   if (a && (AT_class (a) == dw_val_class_lbl_id
            || AT_class (a) == dw_val_class_lbl_offset))
@@ -4672,11 +4755,11 @@ AT_lbl (a)
 
 static inline dw_attr_ref
 get_AT (die, attr_kind)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref a;
-  register dw_die_ref spec = NULL;
+  dw_attr_ref a;
+  dw_die_ref spec = NULL;
 
   if (die != NULL)
     {
@@ -4699,27 +4782,27 @@ get_AT (die, attr_kind)
 
 /* Return the "low pc" attribute value, typically associated with
    a subprogram DIE.  Return null if the "low pc" attribute is
-   either not prsent, or if it cannot be represented as an
+   either not present, or if it cannot be represented as an
    assembler label identifier.  */
 
 static inline const char *
 get_AT_low_pc (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_attr_ref a = get_AT (die, DW_AT_low_pc);
+  dw_attr_ref a = get_AT (die, DW_AT_low_pc);
   return a ? AT_lbl (a) : NULL;
 }
 
 /* Return the "high pc" attribute value, typically associated with
    a subprogram DIE.  Return null if the "high pc" attribute is
-   either not prsent, or if it cannot be represented as an
+   either not present, or if it cannot be represented as an
    assembler label identifier.  */
 
 static inline const char *
 get_AT_hi_pc (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_attr_ref a = get_AT (die, DW_AT_high_pc);
+  dw_attr_ref a = get_AT (die, DW_AT_high_pc);
   return a ? AT_lbl (a) : NULL;
 }
 
@@ -4728,10 +4811,10 @@ get_AT_hi_pc (die)
 
 static inline const char *
 get_AT_string (die, attr_kind)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref a = get_AT (die, attr_kind);
+  dw_attr_ref a = get_AT (die, attr_kind);
   return a ? AT_string (a) : NULL;
 }
 
@@ -4740,10 +4823,10 @@ get_AT_string (die, attr_kind)
 
 static inline int
 get_AT_flag (die, attr_kind)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref a = get_AT (die, attr_kind);
+  dw_attr_ref a = get_AT (die, attr_kind);
   return a ? AT_flag (a) : 0;
 }
 
@@ -4752,35 +4835,42 @@ get_AT_flag (die, attr_kind)
 
 static inline unsigned
 get_AT_unsigned (die, attr_kind)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref a = get_AT (die, attr_kind);
+  dw_attr_ref a = get_AT (die, attr_kind);
   return a ? AT_unsigned (a) : 0;
 }
 
 static inline dw_die_ref
 get_AT_ref (die, attr_kind)
      dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref a = get_AT (die, attr_kind);
+  dw_attr_ref a = get_AT (die, attr_kind);
   return a ? AT_ref (a) : NULL;
 }
 
 static inline int
 is_c_family ()
 {
-  register unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
 
   return (lang == DW_LANG_C || lang == DW_LANG_C89
          || lang == DW_LANG_C_plus_plus);
 }
 
 static inline int
+is_cxx ()
+{
+  return (get_AT_unsigned (comp_unit_die, DW_AT_language)
+         == DW_LANG_C_plus_plus);
+}  
+
+static inline int
 is_fortran ()
 {
-  register unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
 
   return (lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90);
 }
@@ -4788,7 +4878,7 @@ is_fortran ()
 static inline int
 is_java ()
 {
-  register unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
 
   return (lang == DW_LANG_Java);
 }
@@ -4803,9 +4893,13 @@ free_AT (a)
   switch (AT_class (a))
     {
     case dw_val_class_str:
+      if (a->dw_attr_val.v.val_str->refcount)
+       a->dw_attr_val.v.val_str->refcount--;
+      break;
+
     case dw_val_class_lbl_id:
     case dw_val_class_lbl_offset:
-      free (a->dw_attr_val.v.val_str);
+      free (a->dw_attr_val.v.val_lbl_id);
       break;
 
     case dw_val_class_float:
@@ -4823,11 +4917,11 @@ free_AT (a)
 
 static void
 remove_AT (die, attr_kind)
-     register dw_die_ref die;
-     register enum dwarf_attribute attr_kind;
+     dw_die_ref die;
+     enum dwarf_attribute attr_kind;
 {
-  register dw_attr_ref *p;
-  register dw_attr_ref removed = NULL;
+  dw_attr_ref *p;
+  dw_attr_ref removed = NULL;
 
   if (die != NULL)
     {
@@ -4859,22 +4953,22 @@ free_die (die)
 
 static void
 remove_children (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_die_ref child_die = die->die_child;
+  dw_die_ref child_die = die->die_child;
 
   die->die_child = NULL;
 
   while (child_die != NULL)
     {
-      register dw_die_ref tmp_die = child_die;
-      register dw_attr_ref a;
+      dw_die_ref tmp_die = child_die;
+      dw_attr_ref a;
 
       child_die = child_die->die_sib;
 
       for (a = tmp_die->die_attr; a != NULL;)
        {
-         register dw_attr_ref tmp_a = a;
+         dw_attr_ref tmp_a = a;
 
          a = a->dw_attr_next;
          free_AT (tmp_a);
@@ -4889,8 +4983,8 @@ remove_children (die)
 
 static inline void
 add_child_die (die, child_die)
-     register dw_die_ref die;
-     register dw_die_ref child_die;
+     dw_die_ref die;
+     dw_die_ref child_die;
 {
   if (die != NULL && child_die != NULL)
     {
@@ -4939,10 +5033,10 @@ splice_child_die (parent, child)
 
 static inline dw_die_ref
 new_die (tag_value, parent_die)
-     register enum dwarf_tag tag_value;
-     register dw_die_ref parent_die;
+     enum dwarf_tag tag_value;
+     dw_die_ref parent_die;
 {
-  register dw_die_ref die = (dw_die_ref) xcalloc (1, sizeof (die_node));
+  dw_die_ref die = (dw_die_ref) xcalloc (1, sizeof (die_node));
 
   die->die_tag = tag_value;
 
@@ -4965,7 +5059,7 @@ new_die (tag_value, parent_die)
 
 static inline dw_die_ref
 lookup_type_die (type)
-     register tree type;
+     tree type;
 {
   if (TREE_CODE (type) == VECTOR_TYPE)
     type = TYPE_DEBUG_REPRESENTATION_TYPE (type);
@@ -4976,8 +5070,8 @@ lookup_type_die (type)
 
 static inline void
 equate_type_number_to_die (type, type_die)
-     register tree type;
-     register dw_die_ref type_die;
+     tree type;
+     dw_die_ref type_die;
 {
   TYPE_SYMTAB_POINTER (type) = (char *) type_die;
 }
@@ -4986,9 +5080,9 @@ equate_type_number_to_die (type, type_die)
 
 static inline dw_die_ref
 lookup_decl_die (decl)
-     register tree decl;
+     tree decl;
 {
-  register unsigned decl_id = DECL_UID (decl);
+  unsigned decl_id = DECL_UID (decl);
 
   return (decl_id < decl_die_table_in_use
          ? decl_die_table[decl_id] : NULL);
@@ -4998,11 +5092,11 @@ lookup_decl_die (decl)
 
 static void
 equate_decl_number_to_die (decl, decl_die)
-     register tree decl;
-     register dw_die_ref decl_die;
+     tree decl;
+     dw_die_ref decl_die;
 {
-  register unsigned decl_id = DECL_UID (decl);
-  register unsigned num_allocated;
+  unsigned decl_id = DECL_UID (decl);
+  unsigned num_allocated;
 
   if (decl_id >= decl_die_table_allocated)
     {
@@ -5048,8 +5142,8 @@ print_die (die, outfile)
      dw_die_ref die;
      FILE *outfile;
 {
-  register dw_attr_ref a;
-  register dw_die_ref c;
+  dw_attr_ref a;
+  dw_die_ref c;
 
   print_spaces (outfile);
   fprintf (outfile, "DIE %4lu: %s\n",
@@ -5078,6 +5172,9 @@ print_die (die, outfile)
          fprintf (outfile, "location list -> label:%s",
                   AT_loc_list (a)->ll_symbol);
          break;
+       case dw_val_class_range_list:
+         fprintf (outfile, "range list");
+         break;
        case dw_val_class_const:
          fprintf (outfile, "%ld", AT_int (a));
          break;
@@ -5142,8 +5239,8 @@ static void
 print_dwarf_line_table (outfile)
      FILE *outfile;
 {
-  register unsigned i;
-  register dw_line_info_ref line_info;
+  unsigned i;
+  dw_line_info_ref line_info;
 
   fprintf (outfile, "\n\nDWARF source line information\n");
   for (i = 1; i < line_info_table_in_use; ++i)
@@ -5185,10 +5282,10 @@ debug_dwarf ()
 
 static void
 reverse_die_lists (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_die_ref c, cp, cn;
-  register dw_attr_ref a, ap, an;
+  dw_die_ref c, cp, cn;
+  dw_attr_ref a, ap, an;
 
   for (a = die->die_attr, ap = 0; a; a = an)
     {
@@ -5216,9 +5313,9 @@ reverse_die_lists (die)
 
 static void
 reverse_all_dies (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
 
   reverse_die_lists (die);
 
@@ -5502,9 +5599,9 @@ gen_internal_sym (prefix)
 
 static void
 assign_symbol_names (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
 
   if (is_symbol_die (die))
     {
@@ -5529,15 +5626,15 @@ assign_symbol_names (die)
 
 static void
 break_out_includes (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
   dw_die_ref *ptr;
-  register dw_die_ref unit = NULL;
+  dw_die_ref unit = NULL;
   limbo_die_node *node;
 
   for (ptr = &(die->die_child); *ptr; )
     {
-      register dw_die_ref c = *ptr;
+      dw_die_ref c = *ptr;
 
       if (c->die_tag == DW_TAG_GNU_BINCL
          || c->die_tag == DW_TAG_GNU_EINCL
@@ -5588,9 +5685,9 @@ break_out_includes (die)
 
 static void
 add_sibling_attributes (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
 
   if (die->die_tag != DW_TAG_compile_unit
       && die->die_sib && die->die_child != NULL)
@@ -5604,7 +5701,7 @@ add_sibling_attributes (die)
 /* Output all location lists for the DIE and it's children */
 static void
 output_location_lists (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
   dw_die_ref c;
   dw_attr_ref d_attr;
@@ -5627,12 +5724,12 @@ output_location_lists (die)
 
 static void
 build_abbrev_table (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register unsigned long abbrev_id;
-  register unsigned int n_alloc;
-  register dw_die_ref c;
-  register dw_attr_ref d_attr, a_attr;
+  unsigned long abbrev_id;
+  unsigned int n_alloc;
+  dw_die_ref c;
+  dw_attr_ref d_attr, a_attr;
 
   /* Scan the DIE references, and mark as external any that refer to
      DIEs from other CUs (i.e. those which are not marked).  */
@@ -5649,7 +5746,7 @@ build_abbrev_table (die)
 
   for (abbrev_id = 1; abbrev_id < abbrev_die_table_in_use; ++abbrev_id)
     {
-      register dw_die_ref abbrev = abbrev_die_table[abbrev_id];
+      dw_die_ref abbrev = abbrev_die_table[abbrev_id];
 
       if (abbrev->die_tag == die->die_tag)
        {
@@ -5697,20 +5794,6 @@ build_abbrev_table (die)
     build_abbrev_table (c);
 }
 \f
-/* Return the size of a string, including the null byte.
-
-   This used to treat backslashes as escapes, and hence they were not included
-   in the count.  However, that conflicts with what ASM_OUTPUT_ASCII does,
-   which treats a backslash as a backslash, escaping it if necessary, and hence
-   we must include them in the count.  */
-
-static unsigned long
-size_of_string (str)
-     register const char *str;
-{
-  return strlen (str) + 1;
-}
-
 /* Return the power-of-two number of bytes necessary to represent VALUE.  */
 
 static int
@@ -5735,10 +5818,10 @@ constant_size (value)
 
 static unsigned long
 size_of_die (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register unsigned long size = 0;
-  register dw_attr_ref a;
+  unsigned long size = 0;
+  dw_attr_ref a;
 
   size += size_of_uleb128 (die->die_abbrev);
   for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
@@ -5753,7 +5836,7 @@ size_of_die (die)
          break;
        case dw_val_class_loc:
          {
-           register unsigned long lsize = size_of_locs (AT_loc (a));
+           unsigned long lsize = size_of_locs (AT_loc (a));
 
            /* Block length.  */
            size += constant_size (lsize);
@@ -5763,6 +5846,9 @@ size_of_die (die)
        case dw_val_class_loc_list:
          size += DWARF_OFFSET_SIZE;
          break;
+       case dw_val_class_range_list:
+         size += DWARF_OFFSET_SIZE;
+         break;
        case dw_val_class_const:
          size += size_of_sleb128 (AT_int (a));
          break;
@@ -5791,7 +5877,10 @@ size_of_die (die)
          size += DWARF_OFFSET_SIZE;
          break;
        case dw_val_class_str:
-         size += size_of_string (AT_string (a));
+         if (AT_string_form (a) == DW_FORM_strp)
+           size += DWARF_OFFSET_SIZE;
+         else
+           size += HT_LEN (&a->dw_attr_val.v.val_str->id) + 1;
          break;
        default:
          abort ();
@@ -5811,7 +5900,7 @@ static void
 calc_die_sizes (die)
      dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
   die->die_offset = next_die_offset;
   next_die_offset += size_of_die (die);
 
@@ -5832,7 +5921,7 @@ static void
 mark_dies (die)
      dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
   die->die_mark = 1;
   for (c = die->die_child; c; c = c->die_sib)
     mark_dies (c);
@@ -5844,7 +5933,7 @@ static void
 unmark_dies (die)
      dw_die_ref die;
 {
-  register dw_die_ref c;
+  dw_die_ref c;
   die->die_mark = 0;
   for (c = die->die_child; c; c = c->die_sib)
     unmark_dies (c);
@@ -5856,14 +5945,14 @@ unmark_dies (die)
 static unsigned long
 size_of_pubnames ()
 {
-  register unsigned long size;
-  register unsigned i;
+  unsigned long size;
+  unsigned i;
 
   size = DWARF_PUBNAMES_HEADER_SIZE;
   for (i = 0; i < pubname_table_in_use; ++i)
     {
-      register pubname_ref p = &pubname_table[i];
-      size += DWARF_OFFSET_SIZE + size_of_string (p->name);
+      pubname_ref p = &pubname_table[i];
+      size += DWARF_OFFSET_SIZE + strlen (p->name) + 1;
     }
 
   size += DWARF_OFFSET_SIZE;
@@ -5875,7 +5964,7 @@ size_of_pubnames ()
 static unsigned long
 size_of_aranges ()
 {
-  register unsigned long size;
+  unsigned long size;
 
   size = DWARF_ARANGES_HEADER_SIZE;
 
@@ -5898,6 +5987,7 @@ value_format (a)
     {
     case dw_val_class_addr:
       return DW_FORM_addr;
+    case dw_val_class_range_list:
     case dw_val_class_offset:
       if (DWARF_OFFSET_SIZE == 4)
        return DW_FORM_data4;
@@ -5952,7 +6042,7 @@ value_format (a)
     case dw_val_class_lbl_offset:
       return DW_FORM_data;
     case dw_val_class_str:
-      return DW_FORM_string;
+      return AT_string_form (a);
 
     default:
       abort ();
@@ -5980,7 +6070,7 @@ output_abbrev_section ()
   dw_attr_ref a_attr;
   for (abbrev_id = 1; abbrev_id < abbrev_die_table_in_use; ++abbrev_id)
     {
-      register dw_die_ref abbrev = abbrev_die_table[abbrev_id];
+      dw_die_ref abbrev = abbrev_die_table[abbrev_id];
 
       dw2_asm_output_data_uleb128 (abbrev_id, "(abbrev code)");
 
@@ -6012,7 +6102,7 @@ output_abbrev_section ()
 
 static inline void
 output_die_symbol (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
   char *sym = die->die_symbol;
 
@@ -6033,13 +6123,13 @@ output_die_symbol (die)
    the list only.  */ 
 static inline dw_loc_list_ref
 new_loc_list (expr, begin, end, section, gensym)
-     register dw_loc_descr_ref expr;
-     register const char *begin;
-     register const char *end;
-     register const char *section;
-     register unsigned gensym;
+     dw_loc_descr_ref expr;
+     const char *begin;
+     const char *end;
+     const char *section;
+     unsigned gensym;
 {
-  register dw_loc_list_ref retlist
+  dw_loc_list_ref retlist
     = (dw_loc_list_ref) xcalloc (1, sizeof (dw_loc_list_node));
   retlist->begin = begin;
   retlist->end = end;
@@ -6053,13 +6143,13 @@ new_loc_list (expr, begin, end, section, gensym)
 /* Add a location description expression to a location list */
 static inline void
 add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
-     register dw_loc_list_ref *list_head;
-     register dw_loc_descr_ref descr;
-     register const char *begin;
-     register const char *end;
-     register const char *section;
+     dw_loc_list_ref *list_head;
+     dw_loc_descr_ref descr;
+     const char *begin;
+     const char *end;
+     const char *section;
 {
-  register dw_loc_list_ref *d;
+  dw_loc_list_ref *d;
   
   /* Find the end of the chain.  */
   for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
@@ -6071,9 +6161,9 @@ add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
 /* Output the location list given to us */
 static void
 output_loc_list (list_head)
-     register dw_loc_list_ref list_head;
+     dw_loc_list_ref list_head;
 {
-  register dw_loc_list_ref curr=list_head;
+  dw_loc_list_ref curr=list_head;
   ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol);
 
   /* ??? This shouldn't be needed now that we've forced the
@@ -6089,7 +6179,7 @@ output_loc_list (list_head)
     }
   for (curr = list_head; curr != NULL; curr=curr->dw_loc_next)
     {
-      int size;
+      unsigned long size;
       dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
                            "Location list begin address (%s)",
                            list_head->ll_symbol);
@@ -6099,9 +6189,10 @@ output_loc_list (list_head)
       size = size_of_locs (curr->expr);
       
       /* Output the block length for this list of location operations.  */
-      dw2_asm_output_data (constant_size (size), size, "%s",
-                          "Location expression size");
-      
+      if (size > 0xffff)
+       abort ();
+      dw2_asm_output_data (2, size, "%s", "Location expression size");
+
       output_loc_sequence (curr->expr);
     }
   dw2_asm_output_data (DWARF_OFFSET_SIZE, 0,
@@ -6111,16 +6202,17 @@ output_loc_list (list_head)
                       "Location list terminator end (%s)",
                       list_head->ll_symbol);
 }
+
 /* Output the DIE and its attributes.  Called recursively to generate
    the definitions of each child DIE.  */
 
 static void
 output_die (die)
-     register dw_die_ref die;
+     dw_die_ref die;
 {
-  register dw_attr_ref a;
-  register dw_die_ref c;
-  register unsigned long size;
+  dw_attr_ref a;
+  dw_die_ref c;
+  unsigned long size;
 
   /* If someone in another CU might refer to us, set up a symbol for
      them to point to.  */
@@ -6145,6 +6237,17 @@ output_die (die)
                               "%s", name);
          break;
 
+       case dw_val_class_range_list:
+         {
+           char *p = strchr (ranges_section_label, '\0');
+
+           sprintf (p, "+0x%lx", a->dw_attr_val.v.val_offset);
+           dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label,
+                                  "%s", name);
+           *p = '\0';
+         }
+         break;
+
        case dw_val_class_loc:
          size = size_of_locs (AT_loc (a));
 
@@ -6192,7 +6295,7 @@ output_die (die)
 
        case dw_val_class_float:
          {
-           register unsigned int i;
+           unsigned int i;
 
            dw2_asm_output_data (1, a->dw_attr_val.v.val_float.length * 4,
                                 "%s", name);
@@ -6250,7 +6353,12 @@ output_die (die)
          break;
 
        case dw_val_class_str:
-         dw2_asm_output_nstring (AT_string (a), -1, "%s", name);
+         if (AT_string_form (a) == DW_FORM_strp)
+           dw2_asm_output_offset (DWARF_OFFSET_SIZE,
+                                  a->dw_attr_val.v.val_str->label,
+                                  "%s: \"%s\"", name, AT_string (a));
+         else
+           dw2_asm_output_nstring (AT_string (a), -1, "%s", name);
          break;
 
        default:
@@ -6305,7 +6413,7 @@ output_comp_unit (die)
 
   build_abbrev_table (die);
 
-  /* Initialize the beginning DIE offset - and calculate sizes/offsets.   */
+  /* Initialize the beginning DIE offset - and calculate sizes/offsets.  */
   next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
   calc_die_sizes (die);
 
@@ -6320,7 +6428,7 @@ output_comp_unit (die)
     secname = (const char *) DEBUG_INFO_SECTION;
 
   /* Output debugging information.  */
-  named_section_flags (secname, SECTION_DEBUG, 1);
+  named_section_flags (secname, SECTION_DEBUG);
   output_compilation_unit_header ();
   output_die (die);
 
@@ -6374,8 +6482,8 @@ add_pubname (decl, die)
 static void
 output_pubnames ()
 {
-  register unsigned i;
-  register unsigned long pubnames_length = size_of_pubnames ();
+  unsigned i;
+  unsigned long pubnames_length = size_of_pubnames ();
 
   dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
                       "Length of Public Names Info");
@@ -6390,7 +6498,7 @@ output_pubnames ()
 
   for (i = 0; i < pubname_table_in_use; ++i)
     {
-      register pubname_ref pub = &pubname_table[i];
+      pubname_ref pub = &pubname_table[i];
 
       /* We shouldn't see pubnames for DIEs outside of the main CU.  */
       if (pub->die->die_mark == 0)
@@ -6432,8 +6540,8 @@ add_arange (decl, die)
 static void
 output_aranges ()
 {
-  register unsigned i;
-  register unsigned long aranges_length = size_of_aranges ();
+  unsigned i;
+  unsigned long aranges_length = size_of_aranges ();
 
   dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length,
                       "Length of Address Ranges Info");
@@ -6531,8 +6639,8 @@ add_ranges (block)
 static void
 output_ranges ()
 {
-  register unsigned i;
-  const char *start_fmt = "Offset 0x%x";
+  unsigned i;
+  static const char *const start_fmt = "Offset 0x%x";
   const char *fmt = start_fmt;
 
   for (i = 0; i < ranges_table_in_use; ++i)
@@ -6604,6 +6712,7 @@ struct dir_info
 
 /* Callback function for file_info comparison.  We sort by looking at
    the directories in the path.  */
+
 static int
 file_info_cmp (p1, p2)
      const void *p1;
@@ -6614,11 +6723,13 @@ file_info_cmp (p1, p2)
   unsigned char *cp1;
   unsigned char *cp2;
 
-  /* Take care of file names without directories.  */
-  if (s1->path == s1->fname)
-    return -1;
-  else if (s2->path == s2->fname)
-    return 1;
+  /* Take care of file names without directories.  We need to make sure that
+     we return consistent values to qsort since some will get confused if
+     we return the same value when identical operands are passed in opposite
+     orders.  So if neither has a directory, return 0 and otherwise return
+     1 or -1 depending on which one has the directory.  */
+  if ((s1->path == s1->fname || s2->path == s2->fname))
+    return (s2->path == s2->fname) - (s1->path == s1->fname);
 
   cp1 = (unsigned char *) s1->path;
   cp2 = (unsigned char *) s2->path;
@@ -6627,17 +6738,14 @@ file_info_cmp (p1, p2)
     {
       ++cp1;
       ++cp2;
-      /* Reached the end of the first path?  */
-      if (cp1 == (unsigned char *) s1->fname)
-       /* It doesn't really matter in which order files from the
-          same directory are sorted in.  Therefore don't test for
-          the second path reaching the end.  */
-       return -1;
-      else if (cp2 == (unsigned char *) s2->fname)
-       return 1;
+      /* Reached the end of the first path?  If so, handle like above.  */
+      if ((cp1 == (unsigned char *) s1->fname)
+         || (cp2 == (unsigned char *) s2->fname))
+       return ((cp2 == (unsigned char *) s2->fname)
+               - (cp1 == (unsigned char *) s1->fname));
 
       /* Character of current path component the same?  */
-      if (*cp1 != *cp2)
+      else if (*cp1 != *cp2)
        return *cp1 - *cp2;
     }
 }
@@ -6858,14 +6966,14 @@ output_line_info ()
   char l1[20], l2[20], p1[20], p2[20];
   char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
   char prev_line_label[MAX_ARTIFICIAL_LABEL_BYTES];
-  register unsigned opc;
-  register unsigned n_op_args;
-  register unsigned long lt_index;
-  register unsigned long current_line;
-  register long line_offset;
-  register long line_delta;
-  register unsigned long current_file;
-  register unsigned long function;
+  unsigned opc;
+  unsigned n_op_args;
+  unsigned long lt_index;
+  unsigned long current_line;
+  long line_offset;
+  long line_delta;
+  unsigned long current_file;
+  unsigned long function;
 
   ASM_GENERATE_INTERNAL_LABEL (l1, LINE_NUMBER_BEGIN_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (l2, LINE_NUMBER_END_LABEL, 0);
@@ -6931,7 +7039,7 @@ output_line_info ()
   strcpy (prev_line_label, text_section_label);
   for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
     {
-      register dw_line_info_ref line_info = &line_info_table[lt_index];
+      dw_line_info_ref line_info = &line_info_table[lt_index];
 
 #if 0
       /* Disable this optimization for now; GDB wants to see two line notes
@@ -7040,7 +7148,7 @@ output_line_info ()
   current_line = 1;
   for (lt_index = 0; lt_index < separate_line_info_table_in_use;)
     {
-      register dw_separate_line_info_ref line_info
+      dw_separate_line_info_ref line_info
        = &separate_line_info_table[lt_index];
 
 #if 0
@@ -7163,12 +7271,12 @@ output_line_info ()
 
 static dw_die_ref
 base_type_die (type)
-     register tree type;
+     tree type;
 {
-  register dw_die_ref base_type_result;
-  register const char *type_name;
-  register enum dwarf_type encoding;
-  register tree name = TYPE_NAME (type);
+  dw_die_ref base_type_result;
+  const char *type_name;
+  enum dwarf_type encoding;
+  tree name = TYPE_NAME (type);
 
   if (TREE_CODE (type) == ERROR_MARK
       || TREE_CODE (type) == VOID_TYPE)
@@ -7257,7 +7365,7 @@ base_type_die (type)
 
 static tree
 root_type (type)
-     register tree type;
+     tree type;
 {
   if (TREE_CODE (type) == ERROR_MARK)
     return error_mark_node;
@@ -7281,7 +7389,7 @@ root_type (type)
 
 static inline int
 is_base_type (type)
-     register tree type;
+     tree type;
 {
   switch (TREE_CODE (type))
     {
@@ -7322,15 +7430,15 @@ is_base_type (type)
 
 static dw_die_ref
 modified_type_die (type, is_const_type, is_volatile_type, context_die)
-     register tree type;
-     register int is_const_type;
-     register int is_volatile_type;
-     register dw_die_ref context_die;
+     tree type;
+     int is_const_type;
+     int is_volatile_type;
+     dw_die_ref context_die;
 {
-  register enum tree_code code = TREE_CODE (type);
-  register dw_die_ref mod_type_die = NULL;
-  register dw_die_ref sub_die = NULL;
-  register tree item_type = NULL;
+  enum tree_code code = TREE_CODE (type);
+  dw_die_ref mod_type_die = NULL;
+  dw_die_ref sub_die = NULL;
+  tree item_type = NULL;
 
   if (code != ERROR_MARK)
     {
@@ -7447,11 +7555,11 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
 }
 
 /* Given a pointer to an arbitrary ..._TYPE tree node, return true if it is
-   an enumerated type.   */
+   an enumerated type.  */
 
 static inline int
 type_is_enum (type)
-     register tree type;
+     tree type;
 {
   return TREE_CODE (type) == ENUMERAL_TYPE;
 }
@@ -7460,29 +7568,30 @@ type_is_enum (type)
 
 static unsigned int
 reg_number (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
-  register unsigned regno = REGNO (rtl);
+  unsigned regno = REGNO (rtl);
 
   if (regno >= FIRST_PSEUDO_REGISTER)
-    {
-      warning ("internal regno botch: regno = %d\n", regno);
-      regno = 0;
-    }
+    abort ();
 
-  regno = DBX_REGISTER_NUMBER (regno);
-  return regno;
+  return DBX_REGISTER_NUMBER (regno);
 }
 
-/* Return a location descriptor that designates a machine register.  */
+/* Return a location descriptor that designates a machine register or
+   zero if there is no such.  */
 
 static dw_loc_descr_ref
 reg_loc_descriptor (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
-  register dw_loc_descr_ref loc_result = NULL;
-  register unsigned reg = reg_number (rtl);
+  dw_loc_descr_ref loc_result = NULL;
+  unsigned reg;
 
+  if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
+    return 0;
+
+  reg = reg_number (rtl);
   if (reg <= 31)
     loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
   else
@@ -7538,13 +7647,13 @@ based_loc_descr (reg, offset)
      unsigned reg;
      long int offset;
 {
-  register dw_loc_descr_ref loc_result;
+  dw_loc_descr_ref loc_result;
   /* For the "frame base", we use the frame pointer or stack pointer
      registers, since the RTL for local variables is relative to one of
      them.  */
-  register unsigned fp_reg = DBX_REGISTER_NUMBER (frame_pointer_needed
-                                                 ? HARD_FRAME_POINTER_REGNUM
-                                                 : STACK_POINTER_REGNUM);
+  unsigned fp_reg = DBX_REGISTER_NUMBER (frame_pointer_needed
+                                        ? HARD_FRAME_POINTER_REGNUM
+                                        : STACK_POINTER_REGNUM);
 
   if (reg == fp_reg)
     loc_result = new_loc_descr (DW_OP_fbreg, offset, 0);
@@ -7560,10 +7669,11 @@ based_loc_descr (reg, offset)
 
 static inline int
 is_based_loc (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
     return (GET_CODE (rtl) == PLUS
            && ((GET_CODE (XEXP (rtl, 0)) == REG
+                && REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER
                 && GET_CODE (XEXP (rtl, 1)) == CONST_INT)));
 }
 
@@ -7578,14 +7688,17 @@ is_based_loc (rtl)
    it into Dwarf postfix code as it goes.
 
    MODE is the mode of the memory reference, needed to handle some
-   autoincrement addressing modes.  */
+   autoincrement addressing modes.
+
+   Return 0 if we can't represent the location.  */
 
 static dw_loc_descr_ref
 mem_loc_descriptor (rtl, mode)
-     register rtx rtl;
+     rtx rtl;
      enum machine_mode mode;
 {
   dw_loc_descr_ref mem_loc_result = NULL;
+
   /* Note that for a dynamically sized array, the location we will generate a
      description of here will be the lowest numbered location which is
      actually within the array.  That's *not* necessarily the same as the
@@ -7629,12 +7742,14 @@ mem_loc_descriptor (rtl, mode)
          the object in question was allocated to a register (rather than in
          memory) so DWARF consumers need to be aware of the subtle
          distinction between OP_REG and OP_BASEREG.  */
-      mem_loc_result = based_loc_descr (reg_number (rtl), 0);
+      if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
+       mem_loc_result = based_loc_descr (reg_number (rtl), 0);
       break;
 
     case MEM:
       mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
-      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
+      if (mem_loc_result != 0)
+       add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
       break;
 
     case LABEL_REF:
@@ -7683,14 +7798,14 @@ mem_loc_descriptor (rtl, mode)
       else
        {
          mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
+         if (mem_loc_result == 0)
+           break;
 
          if (GET_CODE (XEXP (rtl, 1)) == CONST_INT
              && INTVAL (XEXP (rtl, 1)) >= 0)
-           {
-             add_loc_descr (&mem_loc_result,
-                            new_loc_descr (DW_OP_plus_uconst,
-                                           INTVAL (XEXP (rtl, 1)), 0));
-           }
+           add_loc_descr (&mem_loc_result,
+                          new_loc_descr (DW_OP_plus_uconst,
+                                         INTVAL (XEXP (rtl, 1)), 0));
          else
            {
              add_loc_descr (&mem_loc_result,
@@ -7702,14 +7817,20 @@ mem_loc_descriptor (rtl, mode)
       break;
 
     case MULT:
-      /* If a pseudo-reg is optimized away, it is possible for it to
-        be replaced with a MEM containing a multiply.  */
-      add_loc_descr (&mem_loc_result,
-                    mem_loc_descriptor (XEXP (rtl, 0), mode));
-      add_loc_descr (&mem_loc_result,
-                    mem_loc_descriptor (XEXP (rtl, 1), mode));
-      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
-      break;
+      {
+       /* If a pseudo-reg is optimized away, it is possible for it to
+          be replaced with a MEM containing a multiply.  */
+       dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
+       dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
+
+       if (op0 == 0 || op1 == 0)
+         break;
+
+       mem_loc_result = op0;
+       add_loc_descr (&mem_loc_result, op1);
+       add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
+       break;
+      }
 
     case CONST_INT:
       mem_loc_result = int_loc_descriptor (INTVAL (rtl));
@@ -7727,21 +7848,24 @@ mem_loc_descriptor (rtl, mode)
 
 static dw_loc_descr_ref
 concat_loc_descriptor (x0, x1)
-     register rtx x0, x1;
+     rtx x0, x1;
 {
   dw_loc_descr_ref cc_loc_result = NULL;
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0);
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1);
+
+  if (x0_ref == 0 || x1_ref == 0)
+    return 0;
 
-  if (!is_pseudo_reg (x0)
-      && (GET_CODE (x0) != MEM || !is_pseudo_reg (XEXP (x0, 0))))
-    add_loc_descr (&cc_loc_result, loc_descriptor (x0));
+  cc_loc_result = x0_ref;
   add_loc_descr (&cc_loc_result,
-                new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x0)), 0));
+                new_loc_descr (DW_OP_piece,
+                               GET_MODE_SIZE (GET_MODE (x0)), 0));
 
-  if (!is_pseudo_reg (x1)
-      && (GET_CODE (x1) != MEM || !is_pseudo_reg (XEXP (x1, 0))))
-    add_loc_descr (&cc_loc_result, loc_descriptor (x1));
+  add_loc_descr (&cc_loc_result, x1_ref);
   add_loc_descr (&cc_loc_result,
-                new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x1)), 0));
+                new_loc_descr (DW_OP_piece,
+                               GET_MODE_SIZE (GET_MODE (x1)), 0));
 
   return cc_loc_result;
 }
@@ -7750,13 +7874,16 @@ concat_loc_descriptor (x0, x1)
    which is either allocated in a register or in a memory location.  For a
    register, we just generate an OP_REG and the register number.  For a
    memory location we provide a Dwarf postfix expression describing how to
-   generate the (dynamic) address of the object onto the address stack.  */
+   generate the (dynamic) address of the object onto the address stack.
+
+   If we don't know how to describe it, return 0.  */
 
 static dw_loc_descr_ref
 loc_descriptor (rtl)
-     register rtx rtl;
+     rtx rtl;
 {
   dw_loc_descr_ref loc_result = NULL;
+
   switch (GET_CODE (rtl))
     {
     case SUBREG:
@@ -7789,15 +7916,17 @@ loc_descriptor (rtl)
 }
 
 /* Similar, but generate the descriptor from trees instead of rtl.
-   This comes up particularly with variable length arrays.  */
+   This comes up particularly with variable length arrays.  If ADDRESSP
+   is nonzero, we are looking for an address.  Otherwise, we return a
+   value.  If we can't find a value, return 0.  */
 
 static dw_loc_descr_ref
 loc_descriptor_from_tree (loc, addressp)
      tree loc;
      int addressp;
 {
-  dw_loc_descr_ref ret = NULL;
-  int indirect_size = 0;
+  dw_loc_descr_ref ret, ret1;
+  int indirect_p = 0;
   int unsignedp = TREE_UNSIGNED (TREE_TYPE (loc));
   enum dwarf_location_atom op;
 
@@ -7808,35 +7937,36 @@ loc_descriptor_from_tree (loc, addressp)
   switch (TREE_CODE (loc))
     {
     case ERROR_MARK:
-      break;
+      return 0;
 
     case WITH_RECORD_EXPR:
+    case PLACEHOLDER_EXPR:
       /* This case involves extracting fields from an object to determine the
         position of other fields.  We don't try to encode this here.  The
         only user of this is Ada, which encodes the needed information using
         the names of types.  */
-      return ret;
+      return 0;
 
     case VAR_DECL:
     case PARM_DECL:
       {
        rtx rtl = rtl_for_decl_location (loc);
-       enum machine_mode mode = DECL_MODE (loc);
+       enum machine_mode mode = GET_MODE (rtl);
 
        if (rtl == NULL_RTX)
-         break;
+         return 0;
        else if (CONSTANT_P (rtl))
          {
            ret = new_loc_descr (DW_OP_addr, 0, 0);
            ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
            ret->dw_loc_oprnd1.v.val_addr = rtl;
-           indirect_size = GET_MODE_SIZE (mode);
+           indirect_p = 1;
          }
        else
          {
            if (GET_CODE (rtl) == MEM)
              {
-               indirect_size = GET_MODE_SIZE (mode);
+               indirect_p = 1;
                rtl = XEXP (rtl, 0);
              }
            ret = mem_loc_descriptor (rtl, mode);
@@ -7846,12 +7976,16 @@ loc_descriptor_from_tree (loc, addressp)
 
     case INDIRECT_REF:
       ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
-      indirect_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (loc)));
+      indirect_p = 1;
       break;
 
+    case COMPOUND_EXPR:
+      return loc_descriptor_from_tree (TREE_OPERAND (loc, 1), addressp);
+
     case NOP_EXPR:
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
     case SAVE_EXPR:
       return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
 
@@ -7864,11 +7998,18 @@ loc_descriptor_from_tree (loc, addressp)
        HOST_WIDE_INT bitsize, bitpos, bytepos;
        enum machine_mode mode;
        int volatilep;
-       unsigned int alignment;
 
        obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
-                                  &unsignedp, &volatilep, &alignment);
+                                  &unsignedp, &volatilep);
+
+       if (obj == loc)
+         return 0;
+
        ret = loc_descriptor_from_tree (obj, 1);
+       if (ret == 0
+           || bitpos % BITS_PER_UNIT != 0
+           || bitsize % BITS_PER_UNIT != 0)
+         return 0;
 
        if (offset != NULL_TREE)
          {
@@ -7877,24 +8018,8 @@ loc_descriptor_from_tree (loc, addressp)
            add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
          }
 
-       if (addressp)
-         {
-           /* We cannot address anything not on a unit boundary.  */
-           if (bitpos % BITS_PER_UNIT != 0)
-             abort ();
-         }
-       else
-         {
-           if (bitpos % BITS_PER_UNIT != 0
-               || bitsize % BITS_PER_UNIT != 0)
-             {
-               /* ??? We could handle this by loading and shifting etc.
-                  Wait until someone needs it before expending the effort.  */
-               abort ();
-             }
-
-           indirect_size = bitsize / BITS_PER_UNIT;
-         }
+       if (!addressp)
+         indirect_p = 1;
 
        bytepos = bitpos / BITS_PER_UNIT;
        if (bytepos > 0)
@@ -7910,40 +8035,54 @@ loc_descriptor_from_tree (loc, addressp)
     case INTEGER_CST:
       if (host_integerp (loc, 0))
        ret = int_loc_descriptor (tree_low_cst (loc, 0));
+      else
+       return 0;
       break;
 
     case BIT_AND_EXPR:
       op = DW_OP_and;
       goto do_binop;
+
     case BIT_XOR_EXPR:
       op = DW_OP_xor;
       goto do_binop;
+
     case BIT_IOR_EXPR:
       op = DW_OP_or;
       goto do_binop;
+
     case TRUNC_DIV_EXPR:
       op = DW_OP_div;
       goto do_binop;
+
     case MINUS_EXPR:
       op = DW_OP_minus;
       goto do_binop;
+
     case TRUNC_MOD_EXPR:
       op = DW_OP_mod;
       goto do_binop;
+
     case MULT_EXPR:
       op = DW_OP_mul;
       goto do_binop;
+
     case LSHIFT_EXPR:
       op = DW_OP_shl;
       goto do_binop;
+
     case RSHIFT_EXPR:
       op = (unsignedp ? DW_OP_shr : DW_OP_shra);
       goto do_binop;
+
     case PLUS_EXPR:
       if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST
          && host_integerp (TREE_OPERAND (loc, 1), 0))
        {
          ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+         if (ret == 0)
+           return 0;
+
          add_loc_descr (&ret,
                         new_loc_descr (DW_OP_plus_uconst,
                                        tree_low_cst (TREE_OPERAND (loc, 1),
@@ -7951,53 +8090,72 @@ loc_descriptor_from_tree (loc, addressp)
                                        0));
          break;
        }
+
       op = DW_OP_plus;
       goto do_binop;
     case LE_EXPR:
       if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
-       break;
+       return 0;
+
       op = DW_OP_le;
       goto do_binop;
+
     case GE_EXPR:
       if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
-       break;
+       return 0;
+
       op = DW_OP_ge;
       goto do_binop;
+
     case LT_EXPR:
       if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
-       break;
+       return 0;
+
       op = DW_OP_lt;
       goto do_binop;
+
     case GT_EXPR:
       if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
-       break;
+       return 0;
+
       op = DW_OP_gt;
       goto do_binop;
+
     case EQ_EXPR:
       op = DW_OP_eq;
       goto do_binop;
+
     case NE_EXPR:
       op = DW_OP_ne;
       goto do_binop;
 
     do_binop:
       ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
-      add_loc_descr (&ret, loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0));
+      ret1 = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
+      if (ret == 0 || ret1 == 0)
+       return 0;
+
+      add_loc_descr (&ret, ret1);
       add_loc_descr (&ret, new_loc_descr (op, 0, 0));
       break;
 
     case BIT_NOT_EXPR:
       op = DW_OP_not;
       goto do_unop;
+
     case ABS_EXPR:
       op = DW_OP_abs;
       goto do_unop;
+
     case NEGATE_EXPR:
       op = DW_OP_neg;
       goto do_unop;
 
     do_unop:
       ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+      if (ret == 0)
+       return 0;
+
       add_loc_descr (&ret, new_loc_descr (op, 0, 0));
       break;
 
@@ -8010,21 +8168,26 @@ loc_descriptor_from_tree (loc, addressp)
 
     case COND_EXPR:
       {
+       dw_loc_descr_ref lhs
+         = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
+       dw_loc_descr_ref rhs
+         = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0);
        dw_loc_descr_ref bra_node, jump_node, tmp;
 
        ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+       if (ret == 0 || lhs == 0 || rhs == 0)
+         return 0;
+
        bra_node = new_loc_descr (DW_OP_bra, 0, 0);
        add_loc_descr (&ret, bra_node);
 
-       tmp = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0);
-       add_loc_descr (&ret, tmp);
+       add_loc_descr (&ret, rhs);
        jump_node = new_loc_descr (DW_OP_skip, 0, 0);
        add_loc_descr (&ret, jump_node);
 
-       tmp = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
-       add_loc_descr (&ret, tmp);
+       add_loc_descr (&ret, lhs);
        bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
-       bra_node->dw_loc_oprnd1.v.val_loc = tmp;
+       bra_node->dw_loc_oprnd1.v.val_loc = lhs;
 
        /* ??? Need a node to point the skip at.  Use a nop.  */
        tmp = new_loc_descr (DW_OP_nop, 0, 0);
@@ -8038,20 +8201,23 @@ loc_descriptor_from_tree (loc, addressp)
       abort ();
     }
 
-  /* If we can't fill the request for an address, die.  */
-  if (addressp && indirect_size == 0)
-    abort ();
+  /* Show if we can't fill the request for an address.  */
+  if (addressp && indirect_p == 0)
+    return 0;
 
   /* If we've got an address and don't want one, dereference.  */
-  if (!addressp && indirect_size > 0)
+  if (!addressp && indirect_p > 0)
     {
-      if (indirect_size > DWARF2_ADDR_SIZE)
-       abort ();
-      if (indirect_size == DWARF2_ADDR_SIZE)
+      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
+
+      if (size > DWARF2_ADDR_SIZE || size == -1)
+       return 0;
+      if (size == DWARF2_ADDR_SIZE)
        op = DW_OP_deref;
       else
        op = DW_OP_deref_size;
-      add_loc_descr (&ret, new_loc_descr (op, indirect_size, 0));
+
+      add_loc_descr (&ret, new_loc_descr (op, size, 0));
     }
 
   return ret;
@@ -8075,9 +8241,9 @@ ceiling (value, boundary)
 
 static inline tree
 field_type (decl)
-     register tree decl;
+     tree decl;
 {
-  register tree type;
+  tree type;
 
   if (TREE_CODE (decl) == ERROR_MARK)
     return integer_type_node;
@@ -8095,14 +8261,14 @@ field_type (decl)
 
 static inline unsigned
 simple_type_align_in_bits (type)
-     register tree type;
+     tree type;
 {
   return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
 }
 
 static inline unsigned
 simple_decl_align_in_bits (decl)
-     register tree decl;
+     tree decl;
 {
   return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
 }
@@ -8115,7 +8281,7 @@ simple_decl_align_in_bits (decl)
 
 static inline unsigned HOST_WIDE_INT
 simple_type_size_in_bits (type)
-     register tree type;
+     tree type;
 {
   tree type_size_tree;
 
@@ -8139,7 +8305,7 @@ simple_type_size_in_bits (type)
 
 static HOST_WIDE_INT
 field_byte_offset (decl)
-     register tree decl;
+     tree decl;
 {
   unsigned int type_align_in_bits;
   unsigned int decl_align_in_bits;
@@ -8265,33 +8431,12 @@ static void
 add_AT_location_description (die, attr_kind, rtl)
      dw_die_ref die;
      enum dwarf_attribute attr_kind;
-     register rtx rtl;
-{
-  /* Handle a special case.  If we are about to output a location descriptor
-     for a variable or parameter which has been optimized out of existence,
-     don't do that.  A variable which has been optimized out
-     of existence will have a DECL_RTL value which denotes a pseudo-reg.
-     Currently, in some rare cases, variables can have DECL_RTL values which
-     look like (MEM (REG pseudo-reg#)).  These cases are due to bugs
-     elsewhere in the compiler.  We treat such cases as if the variable(s) in
-     question had been optimized out of existence.  */
-
-  if (is_pseudo_reg (rtl)
-      || (GET_CODE (rtl) == MEM
-         && is_pseudo_reg (XEXP (rtl, 0)))
-      /* This can happen for a PARM_DECL with a DECL_INCOMING_RTL which
-        references the internal argument pointer (a pseudo) in a function
-        where all references to the internal argument pointer were
-        eliminated via the optimizers.  */
-      || (GET_CODE (rtl) == MEM
-         && GET_CODE (XEXP (rtl, 0)) == PLUS
-         && is_pseudo_reg (XEXP (XEXP (rtl, 0), 0)))
-      || (GET_CODE (rtl) == CONCAT
-         && is_pseudo_reg (XEXP (rtl, 0))
-         && is_pseudo_reg (XEXP (rtl, 1))))
-    return;
+     rtx rtl;
+{
+  dw_loc_descr_ref descr = loc_descriptor (rtl);
 
-  add_AT_loc (die, attr_kind, loc_descriptor (rtl));
+  if (descr != 0)
+    add_AT_loc (die, attr_kind, descr);
 }
 
 /* Attach the specialized form of location attribute used for data
@@ -8315,31 +8460,73 @@ add_AT_location_description (die, attr_kind, rtl)
 
 static void
 add_data_member_location_attribute (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
-  register unsigned long offset;
-  register dw_loc_descr_ref loc_descr;
-  register enum dwarf_location_atom op;
+  long offset;
+  dw_loc_descr_ref loc_descr = 0;
 
   if (TREE_CODE (decl) == TREE_VEC)
-    offset = tree_low_cst (BINFO_OFFSET (decl), 0);
+    {
+      /* We're working on the TAG_inheritance for a base class.  */
+
+      if (TREE_VIA_VIRTUAL (decl) && is_cxx ())
+       {
+         /* For C++ virtual bases we can't just use BINFO_OFFSET, as they
+            aren't at a fixed offset from all (sub)objects of the same
+            type.  We need to extract the appropriate offset from our
+            vtable.  The following dwarf expression means
+
+              BaseAddr = ObAddr + *((*ObAddr) - Offset)
+
+            This is specific to the V3 ABI, of course.  */
+
+         dw_loc_descr_ref tmp;
+         /* Make a copy of the object address.  */
+         tmp = new_loc_descr (DW_OP_dup, 0, 0);
+         add_loc_descr (&loc_descr, tmp);
+         /* Extract the vtable address.  */
+         tmp = new_loc_descr (DW_OP_deref, 0, 0);
+         add_loc_descr (&loc_descr, tmp);
+         /* Calculate the address of the offset.  */
+         offset = tree_low_cst (BINFO_VPTR_FIELD (decl), 0);
+         if (offset >= 0)
+           abort ();
+         tmp = int_loc_descriptor (-offset);
+         add_loc_descr (&loc_descr, tmp);
+         tmp = new_loc_descr (DW_OP_minus, 0, 0);
+         add_loc_descr (&loc_descr, tmp);
+         /* Extract the offset.  */
+         tmp = new_loc_descr (DW_OP_deref, 0, 0);
+         add_loc_descr (&loc_descr, tmp);
+         /* Add it to the object address.  */
+         tmp = new_loc_descr (DW_OP_plus, 0, 0);
+         add_loc_descr (&loc_descr, tmp);
+       }
+      else
+       offset = tree_low_cst (BINFO_OFFSET (decl), 0);
+    }
   else
     offset = field_byte_offset (decl);
 
-  /* The DWARF2 standard says that we should assume that the structure address
-     is already on the stack, so we can specify a structure field address
-     by using DW_OP_plus_uconst.  */
+  if (! loc_descr)
+    {
+      enum dwarf_location_atom op;
+
+      /* The DWARF2 standard says that we should assume that the structure address
+        is already on the stack, so we can specify a structure field address
+        by using DW_OP_plus_uconst.  */
 
 #ifdef MIPS_DEBUGGING_INFO
-  /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst operator
-     correctly.  It works only if we leave the offset on the stack.  */
-  op = DW_OP_constu;
+      /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst operator
+        correctly.  It works only if we leave the offset on the stack.  */
+      op = DW_OP_constu;
 #else
-  op = DW_OP_plus_uconst;
+      op = DW_OP_plus_uconst;
 #endif
 
-  loc_descr = new_loc_descr (op, offset, 0);
+      loc_descr = new_loc_descr (op, offset, 0);
+    }
   add_AT_loc (die, DW_AT_data_member_location, loc_descr);
 }
 
@@ -8351,8 +8538,8 @@ add_data_member_location_attribute (die, decl)
 
 static void
 add_const_value_attribute (die, rtl)
-     register dw_die_ref die;
-     register rtx rtl;
+     dw_die_ref die;
+     rtx rtl;
 {
   switch (GET_CODE (rtl))
     {
@@ -8366,17 +8553,18 @@ add_const_value_attribute (die, rtl)
        HOST_WIDE_INT val = INTVAL (rtl);
        
        /* ??? We really should be using HOST_WIDE_INT throughout.  */
-       if (val < 0)
-         {
-           if ((long) val != val)
-             abort ();
-           add_AT_int (die, DW_AT_const_value, (long) val);
-         }
+       if (val < 0 && (long) val == val)
+         add_AT_int (die, DW_AT_const_value, (long) val);
+       else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val)
+         add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
        else
          {
-           if ((unsigned long) val != (unsigned HOST_WIDE_INT) val)
-             abort ();
-           add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
+#if HOST_BITS_PER_LONG * 2 == HOST_BITS_PER_WIDE_INT
+           add_AT_long_long (die, DW_AT_const_value,
+                             val >> HOST_BITS_PER_LONG, val);
+#else
+           abort ();
+#endif
          }
       }
       break;
@@ -8387,11 +8575,11 @@ add_const_value_attribute (die, rtl)
          constant requires more than one word in order to be adequately
          represented.  We output CONST_DOUBLEs as blocks.  */
       {
-       register enum machine_mode mode = GET_MODE (rtl);
+       enum machine_mode mode = GET_MODE (rtl);
 
        if (GET_MODE_CLASS (mode) == MODE_FLOAT)
          {
-           register unsigned length = GET_MODE_SIZE (mode) / 4;
+           unsigned length = GET_MODE_SIZE (mode) / 4;
            long *array = (long *) xmalloc (sizeof (long) * length);
            REAL_VALUE_TYPE rv;
 
@@ -8463,7 +8651,7 @@ static rtx
 rtl_for_decl_location (decl)
      tree decl;
 {
-  register rtx rtl;
+  rtx rtl;
 
   /* Here we have to decide where we are going to say the parameter "lives"
      (as far as the debugger is concerned).  We only have a couple of
@@ -8604,6 +8792,16 @@ rtl_for_decl_location (decl)
 #endif
     }
 
+  /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time
+     constant, and will have been substituted directly into all 
+     expressions that use it.  C does not have such a concept, but
+     C++ and other languages do.  */
+  else if (DECL_INITIAL (decl))
+    {
+      rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
+                        EXPAND_INITIALIZER);
+    }
+
   return rtl;
 }
 
@@ -8620,10 +8818,10 @@ rtl_for_decl_location (decl)
 
 static void
 add_location_or_const_value_attribute (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
-  register rtx rtl;
+  rtx rtl;
 
   if (TREE_CODE (decl) == ERROR_MARK)
     return;
@@ -8709,8 +8907,8 @@ tree_add_const_value_attribute (var_die, decl)
 
 static inline void
 add_name_attribute (die, name_string)
-     register dw_die_ref die;
-     register const char *name_string;
+     dw_die_ref die;
+     const char *name_string;
 {
   if (name_string != NULL && *name_string != 0)
     {
@@ -8726,16 +8924,10 @@ add_name_attribute (die, name_string)
 
 static void
 add_bound_info (subrange_die, bound_attr, bound)
-     register dw_die_ref subrange_die;
-     register enum dwarf_attribute bound_attr;
-     register tree bound;
-{
-  /* If this is an Ada unconstrained array type, then don't emit any debug
-     info because the array bounds are unknown.  They are parameterized when
-     the type is instantiated.  */
-  if (contains_placeholder_p (bound))
-    return;
-
+     dw_die_ref subrange_die;
+     enum dwarf_attribute bound_attr;
+     tree bound;
+{
   switch (TREE_CODE (bound))
     {
     case ERROR_MARK:
@@ -8756,6 +8948,7 @@ add_bound_info (subrange_die, bound_attr, bound)
     case CONVERT_EXPR:
     case NOP_EXPR:
     case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
       add_bound_info (subrange_die, bound_attr, TREE_OPERAND (bound, 0));
       break;
 
@@ -8774,7 +8967,7 @@ add_bound_info (subrange_die, bound_attr, bound)
          they have to deal with empty upper bounds location descriptions
          anyway in order to be able to deal with incomplete array types.
          Of course an intelligent debugger (GDB?)  should be able to
-         comprehend that a missing upper bound specification in a array
+         comprehend that a missing upper bound specification in an array
          type used for a storage class `auto' local array variable
          indicates that the upper bound is both unknown (at compile- time)
          and unknowable (at run-time) due to optimization.
@@ -8785,9 +8978,9 @@ add_bound_info (subrange_die, bound_attr, bound)
       if (SAVE_EXPR_RTL (bound)
          && (! optimize || GET_CODE (SAVE_EXPR_RTL (bound)) == MEM))
        {
-         register dw_die_ref ctx = lookup_decl_die (current_function_decl);
-         register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
-         register rtx loc = SAVE_EXPR_RTL (bound);
+         dw_die_ref ctx = lookup_decl_die (current_function_decl);
+         dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
+         rtx loc = SAVE_EXPR_RTL (bound);
 
          /* If the RTL for the SAVE_EXPR is memory, handle the case where
             it references an outer function's frame.  */
@@ -8836,7 +9029,10 @@ add_bound_info (subrange_die, bound_attr, bound)
        if (loc == NULL)
          break;
 
-       ctx = lookup_decl_die (current_function_decl);
+       if (current_function_decl == 0)
+         ctx = comp_unit_die;
+       else
+         ctx = lookup_decl_die (current_function_decl);
 
        decl_die = new_die (DW_TAG_variable, ctx);
        add_AT_flag (decl_die, DW_AT_artificial, 1);
@@ -8854,14 +9050,14 @@ add_bound_info (subrange_die, bound_attr, bound)
 
 static void
 add_subscript_info (type_die, type)
-     register dw_die_ref type_die;
-     register tree type;
+     dw_die_ref type_die;
+     tree type;
 {
 #ifndef MIPS_DEBUGGING_INFO
-  register unsigned dimension_number;
+  unsigned dimension_number;
 #endif
-  register tree lower, upper;
-  register dw_die_ref subrange_die;
+  tree lower, upper;
+  dw_die_ref subrange_die;
 
   /* The GNU compilers represent multidimensional array types as sequences of
      one dimensional array types whose element types are themselves array
@@ -8882,7 +9078,7 @@ add_subscript_info (type_die, type)
        type = TREE_TYPE (type), dimension_number++)
     {
 #endif
-      register tree domain = TYPE_DOMAIN (type);
+      tree domain = TYPE_DOMAIN (type);
 
       /* Arrays come in three flavors: Unspecified bounds, fixed bounds,
         and (in GNU C only) variable bounds.  Handle all three forms
@@ -8935,9 +9131,9 @@ add_subscript_info (type_die, type)
 static void
 add_byte_size_attribute (die, tree_node)
      dw_die_ref die;
-     register tree tree_node;
+     tree tree_node;
 {
-  register unsigned size;
+  unsigned size;
 
   switch (TREE_CODE (tree_node))
     {
@@ -8988,8 +9184,8 @@ add_byte_size_attribute (die, tree_node)
 
 static inline void
 add_bit_offset_attribute (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
   HOST_WIDE_INT object_offset_in_bytes = field_byte_offset (decl);
   tree type = DECL_BIT_FIELD_TYPE (decl);
@@ -9039,8 +9235,8 @@ add_bit_offset_attribute (die, decl)
 
 static inline void
 add_bit_size_attribute (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
   /* Must be a field and a bit field.  */
   if (TREE_CODE (decl) != FIELD_DECL
@@ -9056,8 +9252,8 @@ add_bit_size_attribute (die, decl)
 
 static inline void
 add_prototyped_attribute (die, func_type)
-     register dw_die_ref die;
-     register tree func_type;
+     dw_die_ref die;
+     tree func_type;
 {
   if (get_AT_unsigned (comp_unit_die, DW_AT_language) == DW_LANG_C89
       && TYPE_ARG_TYPES (func_type) != NULL)
@@ -9070,8 +9266,8 @@ add_prototyped_attribute (die, func_type)
 
 static inline void
 add_abstract_origin_attribute (die, origin)
-     register dw_die_ref die;
-     register tree origin;
+     dw_die_ref die;
+     tree origin;
 {
   dw_die_ref origin_die = NULL;
 
@@ -9106,8 +9302,8 @@ add_abstract_origin_attribute (die, origin)
 
 static inline void
 add_pure_or_virtual_attribute (die, func_decl)
-     register dw_die_ref die;
-     register tree func_decl;
+     dw_die_ref die;
+     tree func_decl;
 {
   if (DECL_VINDEX (func_decl))
     {
@@ -9130,10 +9326,10 @@ add_pure_or_virtual_attribute (die, func_decl)
 
 static void
 add_src_coords_attributes (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
-  register unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
+  unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
 
   add_AT_unsigned (die, DW_AT_decl_file, file_index);
   add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
@@ -9144,10 +9340,10 @@ add_src_coords_attributes (die, decl)
 
 static void
 add_name_and_src_coords_attributes (die, decl)
-     register dw_die_ref die;
-     register tree decl;
+     dw_die_ref die;
+     tree decl;
 {
-  register tree decl_name;
+  tree decl_name;
 
   decl_name = DECL_NAME (decl);
   if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL)
@@ -9163,6 +9359,15 @@ add_name_and_src_coords_attributes (die, decl)
        add_AT_string (die, DW_AT_MIPS_linkage_name,
                       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
     }
+
+#ifdef VMS_DEBUGGING_INFO
+
+  /* Get the function's name, as described by its RTL.  This may be different
+     from the DECL_NAME name used in the source file.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
+    add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address,
+                save_rtx (XEXP (DECL_RTL (decl), 0)));
+#endif
 }
 
 /* Push a new declaration scope.  */
@@ -9171,26 +9376,16 @@ static void
 push_decl_scope (scope)
      tree scope;
 {
-  /* Make room in the decl_scope_table, if necessary.  */
-  if (decl_scope_table_allocated == decl_scope_depth)
-    {
-      decl_scope_table_allocated += DECL_SCOPE_TABLE_INCREMENT;
-      decl_scope_table
-       = (tree *) xrealloc (decl_scope_table,
-                            decl_scope_table_allocated * sizeof (tree));
-    }
-
-  decl_scope_table[decl_scope_depth] = scope;
-  decl_scope_depth++;
+  VARRAY_PUSH_TREE (decl_scope_table, scope);
 }
 
 /* Pop a declaration scope.  */
 static inline void
 pop_decl_scope ()
 {
-  if (decl_scope_depth <= 0)
+  if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0)
     abort ();
-  --decl_scope_depth;
+  VARRAY_POP (decl_scope_table);
 }
 
 /* Return the DIE for the scope that immediately contains this type.
@@ -9201,12 +9396,12 @@ pop_decl_scope ()
 
 static dw_die_ref
 scope_die_for (t, context_die)
-     register tree t;
-     register dw_die_ref context_die;
+     tree t;
+     dw_die_ref context_die;
 {
-  register dw_die_ref scope_die = NULL;
-  register tree containing_scope;
-  register int i;
+  dw_die_ref scope_die = NULL;
+  tree containing_scope;
+  int i;
 
   /* Non-types always go in the current scope.  */
   if (! TYPE_P (t))
@@ -9232,8 +9427,8 @@ scope_die_for (t, context_die)
         first we check to see if we're in the middle of emitting it
         so we know where the new DIE should go.  */
 
-      for (i = decl_scope_depth - 1; i >= 0; --i)
-       if (decl_scope_table[i] == containing_scope)
+      for (i = VARRAY_ACTIVE_SIZE (decl_scope_table) - 1; i >= 0; --i)
+       if (VARRAY_TREE (decl_scope_table, i) == containing_scope)
          break;
 
       if (i < 0)
@@ -9286,14 +9481,14 @@ class_scope_p (context_die)
 
 static void
 add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
-     register dw_die_ref object_die;
-     register tree type;
-     register int decl_const;
-     register int decl_volatile;
-     register dw_die_ref context_die;
+     dw_die_ref object_die;
+     tree type;
+     int decl_const;
+     int decl_volatile;
+     dw_die_ref context_die;
 {
-  register enum tree_code code  = TREE_CODE (type);
-  register dw_die_ref type_die  = NULL;
+  enum tree_code code  = TREE_CODE (type);
+  dw_die_ref type_die  = NULL;
 
   /* ??? If this type is an unnamed subrange type of an integral or
      floating-point type, use the inner type.  This is because we have no
@@ -9326,13 +9521,13 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
 
 static const char *
 type_tag (type)
-     register tree type;
+     tree type;
 {
-  register const char *name = 0;
+  const char *name = 0;
 
   if (TYPE_NAME (type) != 0)
     {
-      register tree t = 0;
+      tree t = 0;
 
       /* Find the IDENTIFIER_NODE for the type name.  */
       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
@@ -9358,7 +9553,7 @@ type_tag (type)
 
 static inline tree
 member_declared_type (member)
-     register tree member;
+     tree member;
 {
   return (DECL_BIT_FIELD_TYPE (member)
          ? DECL_BIT_FIELD_TYPE (member)
@@ -9371,7 +9566,7 @@ member_declared_type (member)
 #if 0
 static const char *
 decl_start_label (decl)
-     register tree decl;
+     tree decl;
 {
   rtx x;
   const char *fnname;
@@ -9394,12 +9589,12 @@ decl_start_label (decl)
 
 static void
 gen_array_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref scope_die = scope_die_for (type, context_die);
-  register dw_die_ref array_die;
-  register tree element_type;
+  dw_die_ref scope_die = scope_die_for (type, context_die);
+  dw_die_ref array_die;
+  tree element_type;
 
   /* ??? The SGI dwarf reader fails for array of array of enum types unless
      the inner array type comes before the outer array type.  Thus we must
@@ -9452,10 +9647,10 @@ gen_array_type_die (type, context_die)
 
 static void
 gen_set_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die
+  dw_die_ref type_die
     = new_die (DW_TAG_set_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, type_die);
@@ -9465,11 +9660,11 @@ gen_set_type_die (type, context_die)
 #if 0
 static void
 gen_entry_point_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register tree origin = decl_ultimate_origin (decl);
-  register dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die);
+  tree origin = decl_ultimate_origin (decl);
+  dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die);
   if (origin != NULL)
     add_abstract_origin_attribute (decl_die, origin);
   else
@@ -9487,20 +9682,11 @@ gen_entry_point_die (decl, context_die)
 #endif
 
 /* Remember a type in the incomplete_types_list.  */
-
 static void
 add_incomplete_type (type)
      tree type;
 {
-  if (incomplete_types == incomplete_types_allocated)
-    {
-      incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT;
-      incomplete_types_list
-       = (tree *) xrealloc (incomplete_types_list,
-                            sizeof (tree) * incomplete_types_allocated);
-    }
-
-  incomplete_types_list[incomplete_types++] = type;
+  VARRAY_PUSH_TREE (incomplete_types, type);
 }
 
 /* Walk through the list of incomplete types again, trying once more to
@@ -9509,13 +9695,10 @@ add_incomplete_type (type)
 static void
 retry_incomplete_types ()
 {
-  register tree type;
-
-  while (incomplete_types)
+  int i;
+  for (i = VARRAY_ACTIVE_SIZE (incomplete_types) - 1; i >= 0; i--)
     {
-      --incomplete_types;
-      type = incomplete_types_list[incomplete_types];
-      gen_type_die (type, comp_unit_die);
+      gen_type_die (VARRAY_TREE (incomplete_types, i), comp_unit_die);
     }
 }
 
@@ -9523,11 +9706,10 @@ retry_incomplete_types ()
 
 static void
 gen_inlined_enumeration_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die = new_die (DW_TAG_enumeration_type,
-                                         context_die);
+  dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die);
   /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
      be incomplete and such types are not marked.  */
   add_abstract_origin_attribute (type_die, type);
@@ -9537,10 +9719,10 @@ gen_inlined_enumeration_type_die (type, context_die)
 
 static void
 gen_inlined_structure_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die);
+  dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die);
 
   /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
      be incomplete and such types are not marked.  */
@@ -9551,10 +9733,10 @@ gen_inlined_structure_type_die (type, context_die)
 
 static void
 gen_inlined_union_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die = new_die (DW_TAG_union_type, context_die);
+  dw_die_ref type_die = new_die (DW_TAG_union_type, context_die);
 
   /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may
      be incomplete and such types are not marked.  */
@@ -9568,10 +9750,10 @@ gen_inlined_union_type_die (type, context_die)
 
 static void
 gen_enumeration_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die = lookup_type_die (type);
+  dw_die_ref type_die = lookup_type_die (type);
 
   if (type_die == NULL)
     {
@@ -9590,7 +9772,7 @@ gen_enumeration_type_die (type, context_die)
      attribute or the DW_AT_element_list attribute.  */
   if (TYPE_SIZE (type))
     {
-      register tree link;
+      tree link;
 
       TREE_ASM_WRITTEN (type) = 1;
       add_byte_size_attribute (type_die, type);
@@ -9605,7 +9787,7 @@ gen_enumeration_type_die (type, context_die)
       for (link = TYPE_FIELDS (type);
           link != NULL; link = TREE_CHAIN (link))
        {
-         register dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die);
+         dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die);
 
          add_name_attribute (enum_die,
                              IDENTIFIER_POINTER (TREE_PURPOSE (link)));
@@ -9640,12 +9822,12 @@ gen_enumeration_type_die (type, context_die)
 
 static dw_die_ref
 gen_formal_parameter_die (node, context_die)
-     register tree node;
-     register dw_die_ref context_die;
+     tree node;
+     dw_die_ref context_die;
 {
-  register dw_die_ref parm_die
+  dw_die_ref parm_die
     = new_die (DW_TAG_formal_parameter, context_die);
-  register tree origin;
+  tree origin;
 
   switch (TREE_CODE_CLASS (TREE_CODE (node)))
     {
@@ -9687,8 +9869,8 @@ gen_formal_parameter_die (node, context_die)
 
 static void
 gen_unspecified_parameters_die (decl_or_type, context_die)
-     register tree decl_or_type ATTRIBUTE_UNUSED;
-     register dw_die_ref context_die;
+     tree decl_or_type ATTRIBUTE_UNUSED;
+     dw_die_ref context_die;
 {
   new_die (DW_TAG_unspecified_parameters, context_die);
 }
@@ -9700,12 +9882,12 @@ gen_unspecified_parameters_die (decl_or_type, context_die)
 
 static void
 gen_formal_types_die (function_or_method_type, context_die)
-     register tree function_or_method_type;
-     register dw_die_ref context_die;
+     tree function_or_method_type;
+     dw_die_ref context_die;
 {
-  register tree link;
-  register tree formal_type = NULL;
-  register tree first_parm_type;
+  tree link;
+  tree formal_type = NULL;
+  tree first_parm_type;
   tree arg;
 
   if (TREE_CODE (function_or_method_type) == FUNCTION_DECL)
@@ -9722,7 +9904,7 @@ gen_formal_types_die (function_or_method_type, context_die)
      DW_TAG_formal_parameter DIE for each one.  */
   for (link = first_parm_type; link; )
     {
-      register dw_die_ref parm_die;
+      dw_die_ref parm_die;
 
       formal_type = TREE_VALUE (link);
       if (formal_type == void_type_node)
@@ -9797,7 +9979,7 @@ static void
 dwarf2out_abstract_function (decl)
      tree decl;
 {
-  register dw_die_ref old_die;
+  dw_die_ref old_die;
   tree save_fn;
   tree context;
   int was_abstract = DECL_ABSTRACT (decl);
@@ -9837,18 +10019,18 @@ dwarf2out_abstract_function (decl)
 
 static void
 gen_subprogram_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
   char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
-  register tree origin = decl_ultimate_origin (decl);
-  register dw_die_ref subr_die;
-  register rtx fp_reg;
-  register tree fn_arg_types;
-  register tree outer_scope;
-  register dw_die_ref old_die = lookup_decl_die (decl);
-  register int declaration = (current_function_decl != decl
-                             || class_scope_p (context_die));
+  tree origin = decl_ultimate_origin (decl);
+  dw_die_ref subr_die;
+  rtx fp_reg;
+  tree fn_arg_types;
+  tree outer_scope;
+  dw_die_ref old_die = lookup_decl_die (decl);
+  int declaration = (current_function_decl != decl
+                    || class_scope_p (context_die));
 
   /* Note that it is possible to have both DECL_ABSTRACT and `declaration'
      be true, if we started to generate the abstract instance of an inline,
@@ -9892,7 +10074,7 @@ gen_subprogram_die (decl, context_die)
             instance, if it has duplicate function definitions.  Ideally,
             we should detect this case and ignore it.  For now, if we have
             already reported an error, any error at all, then assume that
-            we got here because of a input error, not a dwarf2 bug.  */
+            we got here because of an input error, not a dwarf2 bug.  */
          if (errorcount)
            return;
          abort ();
@@ -9939,7 +10121,7 @@ gen_subprogram_die (decl, context_die)
       add_name_and_src_coords_attributes (subr_die, decl);
       if (debug_info_level > DINFO_LEVEL_TERSE)
        {
-         register tree type = TREE_TYPE (decl);
+         tree type = TREE_TYPE (decl);
 
          add_prototyped_attribute (subr_die, type);
          add_type_attribute (subr_die, TREE_TYPE (type), 0, 0, context_die);
@@ -10043,8 +10225,8 @@ gen_subprogram_die (decl, context_die)
   else
     {
       /* Generate DIEs to represent all known formal parameters */
-      register tree arg_decls = DECL_ARGUMENTS (decl);
-      register tree parm;
+      tree arg_decls = DECL_ARGUMENTS (decl);
+      tree parm;
 
       /* When generating DIEs, generate the unspecified_parameters DIE
          instead if we come across the arg "__builtin_va_alist" */
@@ -10059,7 +10241,7 @@ gen_subprogram_die (decl, context_die)
              gen_decl_die (parm, subr_die);
          }
 
-      /* Decide whether we need a unspecified_parameters DIE at the end.
+      /* Decide whether we need an unspecified_parameters DIE at the end.
          There are 2 more cases to do this for: 1) the ansi ... declaration -
          this is detectable when the end of the arg list is not a
          void_type_node 2) an unprototyped function declaration (not a
@@ -10117,11 +10299,11 @@ gen_subprogram_die (decl, context_die)
 
 static void
 gen_variable_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register tree origin = decl_ultimate_origin (decl);
-  register dw_die_ref var_die = new_die (DW_TAG_variable, context_die);
+  tree origin = decl_ultimate_origin (decl);
+  dw_die_ref var_die = new_die (DW_TAG_variable, context_die);
 
   dw_die_ref old_die = lookup_decl_die (decl);
   int declaration = (DECL_EXTERNAL (decl)
@@ -10193,12 +10375,12 @@ gen_variable_die (decl, context_die)
 
 static void
 gen_label_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register tree origin = decl_ultimate_origin (decl);
-  register dw_die_ref lbl_die = new_die (DW_TAG_label, context_die);
-  register rtx insn;
+  tree origin = decl_ultimate_origin (decl);
+  dw_die_ref lbl_die = new_die (DW_TAG_label, context_die);
+  rtx insn;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   if (origin != NULL)
@@ -10237,11 +10419,11 @@ gen_label_die (decl, context_die)
 
 static void
 gen_lexical_block_die (stmt, context_die, depth)
-     register tree stmt;
-     register dw_die_ref context_die;
+     tree stmt;
+     dw_die_ref context_die;
      int depth;
 {
-  register dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die);
+  dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die);
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   if (! BLOCK_ABSTRACT (stmt))
@@ -10250,7 +10432,7 @@ gen_lexical_block_die (stmt, context_die, depth)
        {
          tree chain;
 
-         add_AT_offset (stmt_die, DW_AT_ranges, add_ranges (stmt));
+         add_AT_range_list (stmt_die, DW_AT_ranges, add_ranges (stmt));
 
          chain = BLOCK_FRAGMENT_CHAIN (stmt);
          do
@@ -10279,15 +10461,15 @@ gen_lexical_block_die (stmt, context_die, depth)
 
 static void
 gen_inlined_subroutine_die (stmt, context_die, depth)
-     register tree stmt;
-     register dw_die_ref context_die;
+     tree stmt;
+     dw_die_ref context_die;
      int depth;
 {
   if (! BLOCK_ABSTRACT (stmt))
     {
-      register dw_die_ref subr_die
+      dw_die_ref subr_die
        = new_die (DW_TAG_inlined_subroutine, context_die);
-      register tree decl = block_ultimate_origin (stmt);
+      tree decl = block_ultimate_origin (stmt);
       char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
       /* Emit info for the abstract instance first, if we haven't yet.  */
@@ -10309,10 +10491,10 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
 
 static void
 gen_field_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register dw_die_ref decl_die = new_die (DW_TAG_member, context_die);
+  dw_die_ref decl_die = new_die (DW_TAG_member, context_die);
 
   add_name_and_src_coords_attributes (decl_die, decl);
   add_type_attribute (decl_die, member_declared_type (decl),
@@ -10347,10 +10529,10 @@ gen_field_die (decl, context_die)
    represent certain things in other languages (e.g. Pascal) someday.  */
 static void
 gen_pointer_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref ptr_die
+  dw_die_ref ptr_die
     = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, ptr_die);
@@ -10364,10 +10546,10 @@ gen_pointer_type_die (type, context_die)
    represent certain things in other languages (e.g. Pascal) someday.  */
 static void
 gen_reference_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref ref_die
+  dw_die_ref ref_die
     = new_die (DW_TAG_reference_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, ref_die);
@@ -10379,10 +10561,10 @@ gen_reference_type_die (type, context_die)
 /* Generate a DIE for a pointer to a member type.  */
 static void
 gen_ptr_to_mbr_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref ptr_die
+  dw_die_ref ptr_die
     = new_die (DW_TAG_ptr_to_member_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, ptr_die);
@@ -10395,11 +10577,12 @@ gen_ptr_to_mbr_type_die (type, context_die)
 
 static dw_die_ref
 gen_compile_unit_die (filename)
-     register const char *filename;
+     const char *filename;
 {
-  register dw_die_ref die;
+  dw_die_ref die;
   char producer[250];
   const char *wd = getpwd ();
+  const char *language_string = lang_hooks.name;
   int language;
 
   die = new_die (DW_TAG_compile_unit, NULL);
@@ -10447,10 +10630,10 @@ gen_compile_unit_die (filename)
 
 static void
 gen_string_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die
+  dw_die_ref type_die
     = new_die (DW_TAG_string_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, type_die);
@@ -10466,8 +10649,8 @@ gen_string_type_die (type, context_die)
 
 static void
 gen_inheritance_die (binfo, context_die)
-     register tree binfo;
-     register dw_die_ref context_die;
+     tree binfo;
+     dw_die_ref context_die;
 {
   dw_die_ref die = new_die (DW_TAG_inheritance, context_die);
 
@@ -10486,10 +10669,10 @@ gen_inheritance_die (binfo, context_die)
 
 static void
 gen_member_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register tree member;
+  tree member;
   dw_die_ref child;
 
   /* If this is not an incomplete type, output descriptions of each of its
@@ -10497,7 +10680,7 @@ gen_member_die (type, context_die)
      members of this record or union type, we will also be trying to output
      DIEs to represent the *types* of those members. However the `type'
      function (above) will specifically avoid generating type DIEs for member
-     types *within* the list of member DIEs for this (containing) type execpt
+     types *within* the list of member DIEs for this (containing) type except
      for those types (of members) which are explicitly marked as also being
      members of this (containing) type themselves.  The g++ front- end can
      force any given type to be treated as a member of some other
@@ -10508,9 +10691,9 @@ gen_member_die (type, context_die)
   /* First output info about the base classes.  */
   if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
     {
-      register tree bases = TYPE_BINFO_BASETYPES (type);
-      register int n_bases = TREE_VEC_LENGTH (bases);
-      register int i;
+      tree bases = TYPE_BINFO_BASETYPES (type);
+      int n_bases = TREE_VEC_LENGTH (bases);
+      int i;
 
       for (i = 0; i < n_bases; i++)
        gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die);
@@ -10552,12 +10735,12 @@ gen_member_die (type, context_die)
 
 static void
 gen_struct_or_union_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die = lookup_type_die (type);
-  register dw_die_ref scope_die = 0;
-  register int nested = 0;
+  dw_die_ref type_die = lookup_type_die (type);
+  dw_die_ref scope_die = 0;
+  int nested = 0;
   int complete = (TYPE_SIZE (type)
                  && (! TYPE_STUB_DECL (type)
                      || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
@@ -10574,7 +10757,7 @@ gen_struct_or_union_type_die (type, context_die)
   if (! type_die || (nested && scope_die == comp_unit_die))
     /* First occurrence of type or toplevel definition of nested class.  */
     {
-      register dw_die_ref old_die = type_die;
+      dw_die_ref old_die = type_die;
 
       type_die = new_die (TREE_CODE (type) == RECORD_TYPE
                          ? DW_TAG_structure_type : DW_TAG_union_type,
@@ -10632,11 +10815,11 @@ gen_struct_or_union_type_die (type, context_die)
 
 static void
 gen_subroutine_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
-  register tree return_type = TREE_TYPE (type);
-  register dw_die_ref subr_die
+  tree return_type = TREE_TYPE (type);
+  dw_die_ref subr_die
     = new_die (DW_TAG_subroutine_type, scope_die_for (type, context_die));
 
   equate_type_number_to_die (type, subr_die);
@@ -10649,11 +10832,11 @@ gen_subroutine_type_die (type, context_die)
 
 static void
 gen_typedef_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register dw_die_ref type_die;
-  register tree origin;
+  dw_die_ref type_die;
+  tree origin;
 
   if (TREE_ASM_WRITTEN (decl))
     return;
@@ -10665,7 +10848,7 @@ gen_typedef_die (decl, context_die)
     add_abstract_origin_attribute (type_die, origin);
   else
     {
-      register tree type;
+      tree type;
       add_name_and_src_coords_attributes (type_die, decl);
       if (DECL_ORIGINAL_TYPE (decl))
        {
@@ -10690,8 +10873,8 @@ gen_typedef_die (decl, context_die)
 
 static void
 gen_type_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
   int need_pop;
 
@@ -10847,8 +11030,8 @@ gen_type_die (type, context_die)
 
 static void
 gen_tagged_type_instantiation_die (type, context_die)
-     register tree type;
-     register dw_die_ref context_die;
+     tree type;
+     dw_die_ref context_die;
 {
   if (type == NULL_TREE || type == error_mark_node)
     return;
@@ -10891,14 +11074,14 @@ gen_tagged_type_instantiation_die (type, context_die)
 
 static void
 gen_block_die (stmt, context_die, depth)
-     register tree stmt;
-     register dw_die_ref context_die;
+     tree stmt;
+     dw_die_ref context_die;
      int depth;
 {
-  register int must_output_die = 0;
-  register tree origin;
-  register tree decl;
-  register enum tree_code origin_code;
+  int must_output_die = 0;
+  tree origin;
+  tree decl;
+  enum tree_code origin_code;
 
   /* Ignore blocks never really used to make RTL.  */
   if (stmt == NULL_TREE || !TREE_USED (stmt)
@@ -10986,12 +11169,12 @@ gen_block_die (stmt, context_die, depth)
 
 static void
 decls_for_scope (stmt, context_die, depth)
-     register tree stmt;
-     register dw_die_ref context_die;
+     tree stmt;
+     dw_die_ref context_die;
      int depth;
 {
-  register tree decl;
-  register tree subblocks;
+  tree decl;
+  tree subblocks;
 
   /* Ignore blocks never really used to make RTL.  */
   if (stmt == NULL_TREE || ! TREE_USED (stmt))
@@ -11004,7 +11187,7 @@ decls_for_scope (stmt, context_die, depth)
   for (decl = BLOCK_VARS (stmt);
        decl != NULL; decl = TREE_CHAIN (decl))
     {
-      register dw_die_ref die;
+      dw_die_ref die;
 
       if (TREE_CODE (decl) == FUNCTION_DECL)
        die = lookup_decl_die (decl);
@@ -11031,7 +11214,7 @@ decls_for_scope (stmt, context_die, depth)
 
 static inline int
 is_redundant_typedef (decl)
-     register tree decl;
+     tree decl;
 {
   if (TYPE_DECL_IS_STUB (decl))
     return 1;
@@ -11051,10 +11234,10 @@ is_redundant_typedef (decl)
 
 static void
 gen_decl_die (decl, context_die)
-     register tree decl;
-     register dw_die_ref context_die;
+     tree decl;
+     dw_die_ref context_die;
 {
-  register tree origin;
+  tree origin;
 
   if (TREE_CODE (decl) == ERROR_MARK)
     return;
@@ -11238,9 +11421,9 @@ dwarf2out_global_decl (decl)
 
 void
 dwarf2out_decl (decl)
-     register tree decl;
+     tree decl;
 {
-  register dw_die_ref context_die = comp_unit_die;
+  dw_die_ref context_die = comp_unit_die;
 
   if (TREE_CODE (decl) == ERROR_MARK)
     return;
@@ -11407,7 +11590,7 @@ static unsigned
 lookup_filename (file_name)
      const char *file_name;
 {
-  register unsigned i;
+  unsigned i;
 
   /* ??? Why isn't DECL_SOURCE_FILE left null instead.  */
   if (strcmp (file_name, "<internal>") == 0
@@ -11467,7 +11650,7 @@ init_file_table ()
 static void
 dwarf2out_source_line (line, filename)
      unsigned int line;
-     register const char *filename;
+     const char *filename;
 {
   if (debug_info_level >= DINFO_LEVEL_NORMAL)
     {
@@ -11494,7 +11677,7 @@ dwarf2out_source_line (line, filename)
        }
       else if (DECL_SECTION_NAME (current_function_decl))
        {
-         register dw_separate_line_info_ref line_info;
+         dw_separate_line_info_ref line_info;
          ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
                                     separate_line_info_table_in_use);
 
@@ -11519,7 +11702,7 @@ dwarf2out_source_line (line, filename)
        }
       else
        {
-         register dw_line_info_ref line_info;
+         dw_line_info_ref line_info;
 
          ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
                                     line_info_table_in_use);
@@ -11547,8 +11730,8 @@ dwarf2out_source_line (line, filename)
 
 static void
 dwarf2out_start_source_file (lineno, filename)
-     register unsigned int lineno;
-     register const char *filename;
+     unsigned int lineno;
+     const char *filename;
 {
   if (flag_eliminate_dwarf2_dups)
     {
@@ -11558,7 +11741,7 @@ dwarf2out_start_source_file (lineno, filename)
     }
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
       dw2_asm_output_data_uleb128 (lineno, "Included from line number %d",
                                   lineno);
@@ -11580,7 +11763,7 @@ dwarf2out_end_source_file (lineno)
     }
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       dw2_asm_output_data (1, DW_MACINFO_end_file, "End file");
     }
 }
@@ -11591,8 +11774,8 @@ dwarf2out_end_source_file (lineno)
 
 static void
 dwarf2out_define (lineno, buffer)
-     register unsigned lineno ATTRIBUTE_UNUSED;
-     register const char *buffer ATTRIBUTE_UNUSED;
+     unsigned lineno ATTRIBUTE_UNUSED;
+     const char *buffer ATTRIBUTE_UNUSED;
 {
   static int initialized = 0;
   if (!initialized)
@@ -11602,7 +11785,7 @@ dwarf2out_define (lineno, buffer)
     }
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       dw2_asm_output_data (1, DW_MACINFO_define, "Define macro");
       dw2_asm_output_data_uleb128 (lineno, "At line number %d", lineno);
       dw2_asm_output_nstring (buffer, -1, "The macro");
@@ -11615,12 +11798,12 @@ dwarf2out_define (lineno, buffer)
 
 static void
 dwarf2out_undef (lineno, buffer)
-     register unsigned lineno ATTRIBUTE_UNUSED;
-     register const char *buffer ATTRIBUTE_UNUSED;
+     unsigned lineno ATTRIBUTE_UNUSED;
+     const char *buffer ATTRIBUTE_UNUSED;
 {
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       dw2_asm_output_data (1, DW_MACINFO_undef, "Undefine macro");
       dw2_asm_output_data_uleb128 (lineno, "At line number %d", lineno);
       dw2_asm_output_nstring (buffer, -1, "The macro");
@@ -11631,7 +11814,7 @@ dwarf2out_undef (lineno, buffer)
 
 static void
 dwarf2out_init (main_input_filename)
-     register const char *main_input_filename;
+     const char *main_input_filename;
 {
   init_file_table ();
 
@@ -11650,10 +11833,8 @@ dwarf2out_init (main_input_filename)
   decl_die_table_in_use = 0;
 
   /* Allocate the initial hunk of the decl_scope_table.  */
-  decl_scope_table
-    = (tree *) xcalloc (DECL_SCOPE_TABLE_INCREMENT, sizeof (tree));
-  decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
-  decl_scope_depth = 0;
+  VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
+  ggc_add_tree_varray_root (&decl_scope_table, 1);
 
   /* Allocate the initial hunk of the abbrev_die_table.  */
   abbrev_die_table
@@ -11678,6 +11859,9 @@ dwarf2out_init (main_input_filename)
      invoked when the given (base) source file was compiled.  */
   comp_unit_die = gen_compile_unit_die (main_input_filename);
 
+  VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
+  ggc_add_tree_varray_root (&incomplete_types, 1);
+
   VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
   ggc_add_rtx_varray_root (&used_rtx_varray, 1);
 
@@ -11687,23 +11871,22 @@ dwarf2out_init (main_input_filename)
   if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
     ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
   else
-    strcpy (text_section_label, stripattributes (TEXT_SECTION));
+    strcpy (text_section_label, stripattributes (TEXT_SECTION_NAME));
   ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
                               DEBUG_INFO_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
                               DEBUG_LINE_SECTION_LABEL, 0);
-  ASM_GENERATE_INTERNAL_LABEL (loc_section_label, DEBUG_LOC_SECTION_LABEL, 0);
-  named_section_flags (DEBUG_LOC_SECTION, SECTION_DEBUG, 1);
-  ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
-  named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG, 1);
+  ASM_GENERATE_INTERNAL_LABEL (ranges_section_label,
+                              DEBUG_RANGES_SECTION_LABEL, 0);
+  named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG);
   ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
-  named_section_flags (DEBUG_INFO_SECTION, SECTION_DEBUG, 1);
+  named_section_flags (DEBUG_INFO_SECTION, SECTION_DEBUG);
   ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
-  named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG, 1);
+  named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG);
   ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label,
                                   DEBUG_MACINFO_SECTION_LABEL, 0);
       ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
@@ -11716,12 +11899,49 @@ dwarf2out_init (main_input_filename)
     }
 }
 
+/* Allocate a string in .debug_str hash table.  */
+
+static hashnode
+indirect_string_alloc (tab)
+     hash_table *tab ATTRIBUTE_UNUSED;
+{
+  struct indirect_string_node *node;
+
+  node = xmalloc (sizeof (struct indirect_string_node));
+  node->refcount = 0;
+  node->form = 0;
+  node->label = NULL;
+  return (hashnode) node;
+}
+
+/* A helper function for dwarf2out_finish called through
+   ht_forall.  Emit one queued .debug_str string.  */
+
+static int
+output_indirect_string (pfile, h, v)
+     struct cpp_reader *pfile ATTRIBUTE_UNUSED;
+     hashnode h;
+     const PTR v ATTRIBUTE_UNUSED;
+{
+  struct indirect_string_node *node;
+
+  node = (struct indirect_string_node *) h;
+  if (node->form == DW_FORM_strp)
+    {
+      named_section_flags (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS);
+      ASM_OUTPUT_LABEL (asm_out_file, node->label);
+      assemble_string ((const char *) HT_STR (&node->id),
+                      HT_LEN (&node->id) + 1);
+    }
+  return 1;
+}
+
 /* Output stuff that dwarf requires at the end of every file,
    and generate the DWARF-2 debugging info.  */
 
 static void
 dwarf2out_finish (input_filename)
-     register const char *input_filename ATTRIBUTE_UNUSED;
+     const char *input_filename ATTRIBUTE_UNUSED;
 {
   limbo_die_node *node, *next_node;
   dw_die_ref die = 0;
@@ -11743,6 +11963,9 @@ dwarf2out_finish (input_filename)
            add_child_die (origin->die_parent, die);
          else if (die == comp_unit_die)
            ;
+         else if (errorcount > 0 || sorrycount > 0)
+           /* It's OK to be confused by errors in the input.  */
+           add_child_die (comp_unit_die, die);
          else
            abort ();
        }
@@ -11780,10 +12003,22 @@ dwarf2out_finish (input_filename)
      examining the file.  */
   if (! DWARF2_ASM_LINE_DEBUG_INFO)
     {
-      named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG);
       output_line_info ();
     }
 
+  /* Output location list section if necessary.  */
+  if (have_location_lists)
+    {
+      /* Output the location lists info.  */
+      named_section_flags (DEBUG_LOC_SECTION, SECTION_DEBUG);
+      ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
+                                  DEBUG_LOC_SECTION_LABEL, 0);
+      ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
+      output_location_lists (die);
+      have_location_lists = 0;
+    }
+
   /* We can only use the low/high_pc attributes if all of the code was
      in .text.  */
   if (separate_line_info_table_in_use == 0)
@@ -11811,13 +12046,13 @@ dwarf2out_finish (input_filename)
   output_comp_unit (comp_unit_die);
 
   /* Output the abbreviation table.  */
-  named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG, 1);
+  named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG);
   output_abbrev_section ();
 
   if (pubname_table_in_use)
     {
       /* Output public names table.  */
-      named_section_flags (DEBUG_PUBNAMES_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_PUBNAMES_SECTION, SECTION_DEBUG);
       output_pubnames ();
     }
 
@@ -11826,31 +12061,28 @@ dwarf2out_finish (input_filename)
   if (fde_table_in_use)
     {
       /* Output the address range information.  */
-      named_section_flags (DEBUG_ARANGES_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_ARANGES_SECTION, SECTION_DEBUG);
       output_aranges ();
     }
 
-  /* Output location list section if necessary.  */
-  if (have_location_lists)
-    {
-      /* Output the location lists info.  */
-      named_section_flags (DEBUG_LOC_SECTION, SECTION_DEBUG, 1);
-      output_location_lists (die);
-      have_location_lists = 0;
-    }
-
   /* Output ranges section if necessary.  */
   if (ranges_table_in_use)
     {
-      named_section_flags (DEBUG_RANGES_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_RANGES_SECTION, SECTION_DEBUG);
+      ASM_OUTPUT_LABEL (asm_out_file, ranges_section_label);
       output_ranges ();
     }
 
   /* Have to end the primary source file.  */
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     { 
-      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG, 1);
+      named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
       dw2_asm_output_data (1, DW_MACINFO_end_file, "End file");
     }
+
+  /* If we emitted any DW_FORM_strp form attribute, output string
+     table too.  */
+  if (debug_str_hash)
+    ht_forall (debug_str_hash, output_indirect_string, NULL);
 }
-#endif /* DWARF2_DEBUGGING_INFO */
+#endif /* DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO */