OSDN Git Service

* config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Add
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 38d3400..5fa730e 100644 (file)
@@ -1,6 +1,6 @@
-/* Output Dwarf2 format symbol table information from the GNU C compiler.
-   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+/* Output Dwarf2 format symbol table information from GCC.
+   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
    Contributed by Gary Funck (gary@intrepid.com).
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
    Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -66,7 +66,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "hashtab.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
-static void dwarf2out_source_line      PARAMS ((unsigned int, const char *));
+static void dwarf2out_source_line (unsigned int, const char *);
 #endif
 
 /* DWARF2 Abbreviation Glossary:
@@ -91,7 +91,7 @@ static void dwarf2out_source_line     PARAMS ((unsigned int, const char *));
    translation unit.  */
 
 int
-dwarf2out_do_frame ()
+dwarf2out_do_frame (void)
 {
   return (write_symbols == DWARF2_DEBUG
          || write_symbols == VMS_AND_DWARF2_DEBUG
@@ -115,7 +115,7 @@ dwarf2out_do_frame ()
    guards.  */
 
 void
-default_eh_frame_section ()
+default_eh_frame_section (void)
 {
 #ifdef EH_FRAME_SECTION_NAME
 #ifdef HAVE_LD_RO_RW_SECTION_MIXING
@@ -197,9 +197,9 @@ typedef struct dw_cfi_struct GTY(())
 {
   dw_cfi_ref dw_cfi_next;
   enum dwarf_call_frame_info dw_cfi_opc;
-  dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)"))) 
+  dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)")))
     dw_cfi_oprnd1;
-  dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)"))) 
+  dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)")))
     dw_cfi_oprnd2;
 }
 dw_cfi_node;
@@ -257,6 +257,18 @@ dw_fde_node;
 #define DWARF_OFFSET_SIZE 4
 #endif
 
+/* According to the (draft) DWARF 3 specification, the initial length
+   should either be 4 or 12 bytes.  When it's 12 bytes, the first 4
+   bytes are 0xffffffff, followed by the length stored in the next 8
+   bytes.
+
+   However, the SGI/MIPS ABI uses an initial length which is equal to
+   DWARF_OFFSET_SIZE.  It is defined (elsewhere) accordingly.  */
+
+#ifndef DWARF_INITIAL_LENGTH_SIZE
+#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12)
+#endif
+
 #define DWARF_VERSION 2
 
 /* Round SIZE up to the nearest BOUNDARY.  */
@@ -277,10 +289,10 @@ dw_fde_node;
 static GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table;
 
 /* Number of elements currently allocated for fde_table.  */
-static unsigned fde_table_allocated;
+static GTY(()) unsigned fde_table_allocated;
 
 /* Number of elements in fde_table currently in use.  */
-static unsigned fde_table_in_use;
+static GTY(()) unsigned fde_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    fde_table.  */
@@ -289,11 +301,13 @@ static unsigned fde_table_in_use;
 /* A list of call frame insns for the CIE.  */
 static GTY(()) dw_cfi_ref cie_cfi_head;
 
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 /* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram
    attribute that accelerates the lookup of the FDE associated
    with the subprogram.  This variable holds the table index of the FDE
    associated with the current function (body) definition.  */
 static unsigned current_funcdef_fde;
+#endif
 
 struct indirect_string_node GTY(())
 {
@@ -306,43 +320,37 @@ struct indirect_string_node GTY(())
 static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
 
 static GTY(()) int dw2_string_counter;
+static GTY(()) unsigned long dwarf2out_cfi_label_num;
 
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
 /* Forward declarations for functions defined in this file.  */
 
-static char *stripattributes           PARAMS ((const char *));
-static const char *dwarf_cfi_name      PARAMS ((unsigned));
-static dw_cfi_ref new_cfi              PARAMS ((void));
-static void add_cfi                    PARAMS ((dw_cfi_ref *, dw_cfi_ref));
-static void add_fde_cfi                        PARAMS ((const char *, dw_cfi_ref));
-static void lookup_cfa_1               PARAMS ((dw_cfi_ref,
-                                                dw_cfa_location *));
-static void lookup_cfa                 PARAMS ((dw_cfa_location *));
-static void reg_save                   PARAMS ((const char *, unsigned,
-                                                unsigned, long));
-static void initial_return_save                PARAMS ((rtx));
-static long stack_adjust_offset                PARAMS ((rtx));
-static void output_cfi                 PARAMS ((dw_cfi_ref, dw_fde_ref, int));
-static enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc 
-   PARAMS ((enum dwarf_call_frame_info cfi));
-static enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc 
-   PARAMS ((enum dwarf_call_frame_info cfi));
-static void output_call_frame_info     PARAMS ((int));
-static void dwarf2out_stack_adjust     PARAMS ((rtx));
-static void queue_reg_save             PARAMS ((const char *, rtx, long));
-static void flush_queued_reg_saves     PARAMS ((void));
-static bool clobbers_queued_reg_save   PARAMS ((rtx));
-static void dwarf2out_frame_debug_expr PARAMS ((rtx, const char *));
+static char *stripattributes (const char *);
+static const char *dwarf_cfi_name (unsigned);
+static dw_cfi_ref new_cfi (void);
+static void add_cfi (dw_cfi_ref *, dw_cfi_ref);
+static void add_fde_cfi (const char *, dw_cfi_ref);
+static void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *);
+static void lookup_cfa (dw_cfa_location *);
+static void reg_save (const char *, unsigned, unsigned, long);
+static void initial_return_save (rtx);
+static long stack_adjust_offset (rtx);
+static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
+static void output_call_frame_info (int);
+static void dwarf2out_stack_adjust (rtx);
+static void queue_reg_save (const char *, rtx, long);
+static void flush_queued_reg_saves (void);
+static bool clobbers_queued_reg_save (rtx);
+static void dwarf2out_frame_debug_expr (rtx, const char *);
 
 /* Support for complex CFA locations.  */
-static void output_cfa_loc             PARAMS ((dw_cfi_ref));
-static void get_cfa_from_loc_descr     PARAMS ((dw_cfa_location *,
-                                               struct dw_loc_descr_struct *));
+static void output_cfa_loc (dw_cfi_ref);
+static void get_cfa_from_loc_descr (dw_cfa_location *,
+                                   struct dw_loc_descr_struct *);
 static struct dw_loc_descr_struct *build_cfa_loc
-                                       PARAMS ((dw_cfa_location *));
-static void def_cfa_1                  PARAMS ((const char *,
-                                                dw_cfa_location *));
+ (dw_cfa_location *);
+static void def_cfa_1 (const char *, dw_cfa_location *);
 
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
@@ -382,9 +390,9 @@ static void def_cfa_1                       PARAMS ((const char *,
    registers.  */
 #ifndef DWARF_FRAME_RETURN_COLUMN
 #ifdef PC_REGNUM
-#define DWARF_FRAME_RETURN_COLUMN      DWARF_FRAME_REGNUM (PC_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN      DWARF_FRAME_REGNUM (PC_REGNUM)
 #else
-#define DWARF_FRAME_RETURN_COLUMN      DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_RETURN_COLUMN      DWARF_FRAME_REGISTERS
 #endif
 #endif
 
@@ -403,17 +411,16 @@ static void def_cfa_1                     PARAMS ((const char *,
 /* Hook used by __throw.  */
 
 rtx
-expand_builtin_dwarf_fp_regnum ()
+expand_builtin_dwarf_sp_column (void)
 {
-  return GEN_INT (DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM));
+  return GEN_INT (DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM));
 }
 
 /* Return a pointer to a copy of the section string name S with all
    attributes stripped off, and an asterisk prepended (for assemble_name).  */
 
 static inline char *
-stripattributes (s)
-     const char *s;
+stripattributes (const char *s)
 {
   char *stripped = xmalloc (strlen (s) + 2);
   char *p = stripped;
@@ -430,32 +437,48 @@ stripattributes (s)
 /* Generate code to initialize the register size table.  */
 
 void
-expand_builtin_init_dwarf_reg_sizes (address)
-     tree address;
+expand_builtin_init_dwarf_reg_sizes (tree address)
 {
   int i;
   enum machine_mode mode = TYPE_MODE (char_type_node);
   rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
   rtx mem = gen_rtx_MEM (BLKmode, addr);
+  bool wrote_return_column = false;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS)
       {
        HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
-       HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
+       enum machine_mode save_mode = reg_raw_mode[i];
+       HOST_WIDE_INT size;
 
+       if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
+         save_mode = choose_hard_reg_mode (i, 1, true);
+       if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
+         {
+           if (save_mode == VOIDmode)
+             continue;
+           wrote_return_column = true;
+         }
+       size = GET_MODE_SIZE (save_mode);
        if (offset < 0)
          continue;
 
        emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
       }
+  if (! wrote_return_column)
+    {
+      enum machine_mode save_mode = Pmode;
+      HOST_WIDE_INT offset = DWARF_FRAME_RETURN_COLUMN * GET_MODE_SIZE (mode);
+      HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
+      emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+    }
 }
 
 /* Convert a DWARF call frame info. operation to its string name */
 
 static const char *
-dwarf_cfi_name (cfi_opc)
-     unsigned cfi_opc;
+dwarf_cfi_name (unsigned int cfi_opc)
 {
   switch (cfi_opc)
     {
@@ -528,9 +551,9 @@ dwarf_cfi_name (cfi_opc)
 /* Return a pointer to a newly allocated Call Frame Instruction.  */
 
 static inline dw_cfi_ref
-new_cfi ()
+new_cfi (void)
 {
-  dw_cfi_ref cfi = (dw_cfi_ref) ggc_alloc (sizeof (dw_cfi_node));
+  dw_cfi_ref cfi = ggc_alloc (sizeof (dw_cfi_node));
 
   cfi->dw_cfi_next = NULL;
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
@@ -542,9 +565,7 @@ new_cfi ()
 /* Add a Call Frame Instruction to list of instructions.  */
 
 static inline void
-add_cfi (list_head, cfi)
-     dw_cfi_ref *list_head;
-     dw_cfi_ref cfi;
+add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
 {
   dw_cfi_ref *p;
 
@@ -558,12 +579,11 @@ add_cfi (list_head, cfi)
 /* Generate a new label for the CFI info to refer to.  */
 
 char *
-dwarf2out_cfi_label ()
+dwarf2out_cfi_label (void)
 {
   static char label[20];
-  static unsigned long label_num = 0;
 
-  ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", label_num++);
+  ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", dwarf2out_cfi_label_num++);
   ASM_OUTPUT_LABEL (asm_out_file, label);
   return label;
 }
@@ -572,9 +592,7 @@ dwarf2out_cfi_label ()
    or to the CIE if LABEL is NULL.  */
 
 static void
-add_fde_cfi (label, cfi)
-     const char *label;
-     dw_cfi_ref cfi;
+add_fde_cfi (const char *label, dw_cfi_ref cfi)
 {
   if (label)
     {
@@ -607,9 +625,7 @@ add_fde_cfi (label, cfi)
 /* Subroutine of lookup_cfa.  */
 
 static inline void
-lookup_cfa_1 (cfi, loc)
-     dw_cfi_ref cfi;
-     dw_cfa_location *loc;
+lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
 {
   switch (cfi->dw_cfi_opc)
     {
@@ -634,8 +650,7 @@ lookup_cfa_1 (cfi, loc)
 /* Find the previous value for the CFA.  */
 
 static void
-lookup_cfa (loc)
-     dw_cfa_location *loc;
+lookup_cfa (dw_cfa_location *loc)
 {
   dw_cfi_ref cfi;
 
@@ -673,10 +688,7 @@ static long old_args_size;
    calculated from REG+OFFSET.  */
 
 void
-dwarf2out_def_cfa (label, reg, offset)
-     const char *label;
-     unsigned reg;
-     long offset;
+dwarf2out_def_cfa (const char *label, unsigned int reg, long int offset)
 {
   dw_cfa_location loc;
   loc.indirect = 0;
@@ -690,9 +702,7 @@ dwarf2out_def_cfa (label, reg, offset)
    the dw_cfa_location structure.  */
 
 static void
-def_cfa_1 (label, loc_p)
-     const char *label;
-     dw_cfa_location *loc_p;
+def_cfa_1 (const char *label, dw_cfa_location *loc_p)
 {
   dw_cfi_ref cfi;
   dw_cfa_location old_cfa, loc;
@@ -765,11 +775,7 @@ def_cfa_1 (label, loc_p)
    otherwise it is saved in SREG.  */
 
 static void
-reg_save (label, reg, sreg, offset)
-     const char *label;
-     unsigned reg;
-     unsigned sreg;
-     long offset;
+reg_save (const char *label, unsigned int reg, unsigned int sreg, long int offset)
 {
   dw_cfi_ref cfi = new_cfi ();
 
@@ -824,8 +830,7 @@ reg_save (label, reg, sreg, offset)
    assuming 0(cfa)) and what registers are in the window.  */
 
 void
-dwarf2out_window_save (label)
-     const char *label;
+dwarf2out_window_save (const char *label)
 {
   dw_cfi_ref cfi = new_cfi ();
 
@@ -837,9 +842,7 @@ dwarf2out_window_save (label)
    pushed onto the stack.  */
 
 void
-dwarf2out_args_size (label, size)
-     const char *label;
-     long size;
+dwarf2out_args_size (const char *label, long int size)
 {
   dw_cfi_ref cfi;
 
@@ -858,10 +861,7 @@ dwarf2out_args_size (label, size)
    number.  LABEL and OFFSET are passed to reg_save.  */
 
 void
-dwarf2out_reg_save (label, reg, offset)
-     const char *label;
-     unsigned reg;
-     long offset;
+dwarf2out_reg_save (const char *label, unsigned int reg, long int offset)
 {
   reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
 }
@@ -870,9 +870,7 @@ dwarf2out_reg_save (label, reg, offset)
    LABEL and OFFSET are passed to reg_save.  */
 
 void
-dwarf2out_return_save (label, offset)
-     const char *label;
-     long offset;
+dwarf2out_return_save (const char *label, long int offset)
 {
   reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
 }
@@ -881,9 +879,7 @@ dwarf2out_return_save (label, offset)
    LABEL and SREG are passed to reg_save.  */
 
 void
-dwarf2out_return_reg (label, sreg)
-     const char *label;
-     unsigned sreg;
+dwarf2out_return_reg (const char *label, unsigned int sreg)
 {
   reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0);
 }
@@ -892,8 +888,7 @@ dwarf2out_return_reg (label, sreg)
    INCOMING_RETURN_ADDR_RTX.  */
 
 static void
-initial_return_save (rtl)
-     rtx rtl;
+initial_return_save (rtx rtl)
 {
   unsigned int reg = (unsigned int) -1;
   HOST_WIDE_INT offset = 0;
@@ -954,8 +949,7 @@ initial_return_save (rtl)
    contains.  */
 
 static long
-stack_adjust_offset (pattern)
-     rtx pattern;
+stack_adjust_offset (rtx pattern)
 {
   rtx src = SET_SRC (pattern);
   rtx dest = SET_DEST (pattern);
@@ -1030,8 +1024,7 @@ stack_adjust_offset (pattern)
    much extra space it needs to pop off the stack.  */
 
 static void
-dwarf2out_stack_adjust (insn)
-     rtx insn;
+dwarf2out_stack_adjust (rtx insn)
 {
   HOST_WIDE_INT offset;
   const char *label;
@@ -1120,10 +1113,7 @@ static GTY(()) struct queued_reg_save *queued_reg_saves;
 static const char *last_reg_save_label;
 
 static void
-queue_reg_save (label, reg, offset)
-     const char *label;
-     rtx reg;
-     long offset;
+queue_reg_save (const char *label, rtx reg, long int offset)
 {
   struct queued_reg_save *q = ggc_alloc (sizeof (*q));
 
@@ -1136,7 +1126,7 @@ queue_reg_save (label, reg, offset)
 }
 
 static void
-flush_queued_reg_saves ()
+flush_queued_reg_saves (void)
 {
   struct queued_reg_save *q, *next;
 
@@ -1151,8 +1141,7 @@ flush_queued_reg_saves ()
 }
 
 static bool
-clobbers_queued_reg_save (insn)
-     rtx insn;
+clobbers_queued_reg_save (rtx insn)
 {
   struct queued_reg_save *q;
 
@@ -1215,7 +1204,7 @@ static dw_cfa_location cfa_temp;
               to track stores to the stack via fp or a temp reg.
 
   Rules  1- 4: Setting a register's value to cfa.reg or an expression
-              with cfa.reg as the first operand changes the cfa.reg and its
+              with cfa.reg as the first operand changes the cfa.reg and its
               cfa.offset.  Rule 1 and 4 also set cfa_temp.reg and
               cfa_temp.offset.
 
@@ -1238,7 +1227,7 @@ static dw_cfa_location cfa_temp;
   Rule 1:
   (set <reg1> <reg2>:cfa.reg)
   effects: cfa.reg = <reg1>
-           cfa.offset unchanged
+          cfa.offset unchanged
           cfa_temp.reg = <reg1>
           cfa_temp.offset = cfa.offset
 
@@ -1246,19 +1235,19 @@ static dw_cfa_location cfa_temp;
   (set sp ({minus,plus,losum} {sp,fp}:cfa.reg
                              {<const_int>,<reg>:cfa_temp.reg}))
   effects: cfa.reg = sp if fp used
-          cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
+          cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
           cfa_store.offset += {+/- <const_int>, cfa_temp.offset}
             if cfa_store.reg==sp
 
   Rule 3:
   (set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>))
   effects: cfa.reg = fp
-          cfa_offset += +/- <const_int>
+          cfa_offset += +/- <const_int>
 
   Rule 4:
   (set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>))
   constraints: <reg1> != fp
-              <reg1> != sp
+              <reg1> != sp
   effects: cfa.reg = <reg1>
           cfa_temp.reg = <reg1>
           cfa_temp.offset = cfa.offset
@@ -1266,14 +1255,14 @@ static dw_cfa_location cfa_temp;
   Rule 5:
   (set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg))
   constraints: <reg1> != fp
-              <reg1> != sp
+              <reg1> != sp
   effects: cfa_store.reg = <reg1>
-          cfa_store.offset = cfa.offset - cfa_temp.offset
+          cfa_store.offset = cfa.offset - cfa_temp.offset
 
   Rule 6:
   (set <reg> <const_int>)
   effects: cfa_temp.reg = <reg>
-          cfa_temp.offset = <const_int>
+          cfa_temp.offset = <const_int>
 
   Rule 7:
   (set <reg1>:cfa_temp.reg (ior <reg2>:cfa_temp.reg <const_int>))
@@ -1287,7 +1276,7 @@ static dw_cfa_location cfa_temp;
   Rule 9:
   (set <reg> (lo_sum <exp> <const_int>))
   effects: cfa_temp.reg = <reg>
-          cfa_temp.offset = <const_int>
+          cfa_temp.offset = <const_int>
 
   Rule 10:
   (set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>)
@@ -1322,9 +1311,7 @@ static dw_cfa_location cfa_temp;
           cfa_temp.offset -= mode_size(mem)  */
 
 static void
-dwarf2out_frame_debug_expr (expr, label)
-     rtx expr;
-     const char *label;
+dwarf2out_frame_debug_expr (rtx expr, const char *label)
 {
   rtx src, dest;
   HOST_WIDE_INT offset;
@@ -1359,7 +1346,7 @@ dwarf2out_frame_debug_expr (expr, label)
     case REG:
       /* Rule 1 */
       /* Update the CFA rule wrt SP or FP.  Make sure src is
-         relative to the current CFA register.  */
+        relative to the current CFA register.  */
       switch (GET_CODE (src))
        {
          /* Setting FP from SP.  */
@@ -1622,7 +1609,7 @@ dwarf2out_frame_debug_expr (expr, label)
          else
            {
              /* Otherwise, we'll need to look in the stack to
-                 calculate the CFA.  */
+                calculate the CFA.  */
              rtx x = XEXP (dest, 0);
 
              if (GET_CODE (x) != REG)
@@ -1652,8 +1639,7 @@ dwarf2out_frame_debug_expr (expr, label)
    register to the stack.  If INSN is NULL_RTX, initialize our state.  */
 
 void
-dwarf2out_frame_debug (insn)
-     rtx insn;
+dwarf2out_frame_debug (rtx insn)
 {
   const char *label;
   rtx src;
@@ -1699,10 +1685,11 @@ dwarf2out_frame_debug (insn)
 #endif
 
 /* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used.  */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc
+ (enum dwarf_call_frame_info cfi);
 
 static enum dw_cfi_oprnd_type
-dw_cfi_oprnd1_desc (cfi)
-     enum dwarf_call_frame_info cfi;
+dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
 {
   switch (cfi)
     {
@@ -1733,7 +1720,7 @@ dw_cfi_oprnd1_desc (cfi)
     case DW_CFA_GNU_args_size:
     case DW_CFA_def_cfa_offset_sf:
       return dw_cfi_oprnd_offset;
-      
+
     case DW_CFA_def_cfa_expression:
     case DW_CFA_expression:
       return dw_cfi_oprnd_loc;
@@ -1744,10 +1731,11 @@ dw_cfi_oprnd1_desc (cfi)
 }
 
 /* Describe for the GTY machinery what parts of dw_cfi_oprnd2 are used.  */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc
+ (enum dwarf_call_frame_info cfi);
 
 static enum dw_cfi_oprnd_type
-dw_cfi_oprnd2_desc (cfi)
-     enum dwarf_call_frame_info cfi;
+dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
 {
   switch (cfi)
     {
@@ -1771,10 +1759,7 @@ dw_cfi_oprnd2_desc (cfi)
 /* Output a Call Frame Information opcode and its operand(s).  */
 
 static void
-output_cfi (cfi, fde, for_eh)
-     dw_cfi_ref cfi;
-     dw_fde_ref fde;
-     int for_eh;
+output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 {
   if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
     dw2_asm_output_data (1, (cfi->dw_cfi_opc
@@ -1897,14 +1882,13 @@ output_cfi (cfi, fde, for_eh)
    location of saved registers.  */
 
 static void
-output_call_frame_info (for_eh)
-     int for_eh;
+output_call_frame_info (int for_eh)
 {
   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;
+  bool any_lsda_needed = false;
   char augmentation[6];
   int augmentation_size;
   int fde_encoding = DW_EH_PE_absptr;
@@ -1915,17 +1899,20 @@ output_call_frame_info (for_eh)
   if (fde_table_in_use == 0)
     return;
 
-  /* If we don't have any functions we'll want to unwind out of, don't emit any
-     EH unwind information.  */
+  /* If we don't have any functions we'll want to unwind out of, don't
+     emit any EH unwind information.  Note that if exceptions aren't
+     enabled, we won't have collected nothrow information, and if we
+     asked for asynchronous tables, we always want this info.  */
   if (for_eh)
     {
-      int any_eh_needed = flag_asynchronous_unwind_tables;
+      bool any_eh_needed = !flag_exceptions || 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;
-       else if (! fde_table[i].nothrow)
-         any_eh_needed = 1;
+         any_eh_needed = any_lsda_needed = true;
+       else if (! fde_table[i].nothrow
+                && ! fde_table[i].all_throwers_are_sibcalls)
+         any_eh_needed = true;
 
       if (! any_eh_needed)
        return;
@@ -1966,7 +1953,7 @@ output_call_frame_info (for_eh)
 
       /* Augmentation:
         z      Indicates that a uleb128 is present to size the
-               augmentation section.
+               augmentation section.
         L      Indicates the encoding (and thus presence) of
                an LSDA pointer in the FDE augmentation.
         R      Indicates a non-default pointer encoding for
@@ -2063,7 +2050,7 @@ output_call_frame_info (for_eh)
       fde = &fde_table[i];
 
       /* Don't emit EH unwind info for leaf functions that don't need it.  */
-      if (!flag_asynchronous_unwind_tables && for_eh
+      if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions
          && (fde->nothrow || fde->all_throwers_are_sibcalls)
          && !fde->uses_eh_lsda)
        continue;
@@ -2121,13 +2108,13 @@ output_call_frame_info (for_eh)
              dw2_asm_output_data_uleb128 (size, "Augmentation size");
 
              if (fde->uses_eh_lsda)
-               {
-                 ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
+               {
+                 ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
                                               fde->funcdef_number);
-                 dw2_asm_output_encoded_addr_rtx (
+                 dw2_asm_output_encoded_addr_rtx (
                        lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1),
-                       "Language Specific Data Area");
-               }
+                       "Language Specific Data Area");
+               }
              else
                {
                  if (lsda_encoding == DW_EH_PE_aligned)
@@ -2149,7 +2136,7 @@ output_call_frame_info (for_eh)
 
       /* Pad the FDE out to an address sized boundary.  */
       ASM_OUTPUT_ALIGN (asm_out_file,
-                       floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
+                       floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
       ASM_OUTPUT_LABEL (asm_out_file, l2);
     }
 
@@ -2170,9 +2157,8 @@ output_call_frame_info (for_eh)
    the prologue.  */
 
 void
-dwarf2out_begin_prologue (line, file)
-     unsigned int line ATTRIBUTE_UNUSED;
-     const char *file ATTRIBUTE_UNUSED;
+dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
+                         const char *file ATTRIBUTE_UNUSED)
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
   dw_fde_ref fde;
@@ -2243,9 +2229,8 @@ dwarf2out_begin_prologue (line, file)
    been generated.  */
 
 void
-dwarf2out_end_epilogue (line, file)
-     unsigned int line ATTRIBUTE_UNUSED;
-     const char *file ATTRIBUTE_UNUSED;
+dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+                       const char *file ATTRIBUTE_UNUSED)
 {
   dw_fde_ref fde;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -2260,11 +2245,10 @@ dwarf2out_end_epilogue (line, file)
 }
 
 void
-dwarf2out_frame_init ()
+dwarf2out_frame_init (void)
 {
   /* Allocate the initial hunk of the fde_table.  */
-  fde_table = (dw_fde_ref) ggc_alloc_cleared (FDE_TABLE_INCREMENT
-                                             * sizeof (dw_fde_node));
+  fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
   fde_table_allocated = FDE_TABLE_INCREMENT;
   fde_table_in_use = 0;
 
@@ -2279,7 +2263,7 @@ dwarf2out_frame_init ()
 }
 
 void
-dwarf2out_frame_finish ()
+dwarf2out_frame_finish (void)
 {
   /* Output call frame information.  */
   if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
@@ -2404,22 +2388,19 @@ typedef struct dw_loc_list_struct GTY(())
 
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
-static const char *dwarf_stack_op_name PARAMS ((unsigned));
-static dw_loc_descr_ref new_loc_descr  PARAMS ((enum dwarf_location_atom,
-                                                unsigned long,
-                                                unsigned long));
-static void add_loc_descr              PARAMS ((dw_loc_descr_ref *,
-                                                dw_loc_descr_ref));
-static unsigned long size_of_loc_descr PARAMS ((dw_loc_descr_ref));
-static unsigned long size_of_locs      PARAMS ((dw_loc_descr_ref));
-static void output_loc_operands                PARAMS ((dw_loc_descr_ref));
-static void output_loc_sequence                PARAMS ((dw_loc_descr_ref));
+static const char *dwarf_stack_op_name (unsigned);
+static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
+                                      unsigned long, unsigned long);
+static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
+static unsigned long size_of_loc_descr (dw_loc_descr_ref);
+static unsigned long size_of_locs (dw_loc_descr_ref);
+static void output_loc_operands (dw_loc_descr_ref);
+static void output_loc_sequence (dw_loc_descr_ref);
 
 /* Convert a DWARF stack opcode into its string name.  */
 
 static const char *
-dwarf_stack_op_name (op)
-     unsigned op;
+dwarf_stack_op_name (unsigned int op)
 {
   switch (op)
     {
@@ -2734,13 +2715,10 @@ dwarf_stack_op_name (op)
    together to form more complicated location (address) descriptions.  */
 
 static inline dw_loc_descr_ref
-new_loc_descr (op, oprnd1, oprnd2)
-     enum dwarf_location_atom op;
-     unsigned long oprnd1;
-     unsigned long oprnd2;
+new_loc_descr (enum dwarf_location_atom op, long unsigned int oprnd1,
+              long unsigned int oprnd2)
 {
-  dw_loc_descr_ref descr
-    = (dw_loc_descr_ref) ggc_alloc_cleared (sizeof (dw_loc_descr_node));
+  dw_loc_descr_ref descr = ggc_alloc_cleared (sizeof (dw_loc_descr_node));
 
   descr->dw_loc_opc = op;
   descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
@@ -2755,9 +2733,7 @@ new_loc_descr (op, oprnd1, oprnd2)
 /* Add a location description term to a location description expression.  */
 
 static inline void
-add_loc_descr (list_head, descr)
-     dw_loc_descr_ref *list_head;
-     dw_loc_descr_ref descr;
+add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
 {
   dw_loc_descr_ref *d;
 
@@ -2771,8 +2747,7 @@ add_loc_descr (list_head, descr)
 /* Return the size of a location descriptor.  */
 
 static unsigned long
-size_of_loc_descr (loc)
-     dw_loc_descr_ref loc;
+size_of_loc_descr (dw_loc_descr_ref loc)
 {
   unsigned long size = 1;
 
@@ -2884,8 +2859,7 @@ size_of_loc_descr (loc)
 /* Return the size of a series of location descriptors.  */
 
 static unsigned long
-size_of_locs (loc)
-     dw_loc_descr_ref loc;
+size_of_locs (dw_loc_descr_ref loc)
 {
   unsigned long size;
 
@@ -2901,8 +2875,7 @@ size_of_locs (loc)
 /* Output location description stack opcode's operands (if any).  */
 
 static void
-output_loc_operands (loc)
-     dw_loc_descr_ref loc;
+output_loc_operands (dw_loc_descr_ref loc)
 {
   dw_val_ref val1 = &loc->dw_loc_oprnd1;
   dw_val_ref val2 = &loc->dw_loc_oprnd2;
@@ -2951,9 +2924,9 @@ output_loc_operands (loc)
     case DW_OP_skip:
     case DW_OP_bra:
       /* We currently don't make any attempt to make sure these are
-         aligned properly like we do for the main unwind info, so
-         don't support emitting things larger than a byte if we're
-         only doing unwinding.  */
+        aligned properly like we do for the main unwind info, so
+        don't support emitting things larger than a byte if we're
+        only doing unwinding.  */
       abort ();
 #endif
     case DW_OP_const1u:
@@ -3043,8 +3016,7 @@ output_loc_operands (loc)
 /* Output a sequence of location operations.  */
 
 static void
-output_loc_sequence (loc)
-     dw_loc_descr_ref loc;
+output_loc_sequence (dw_loc_descr_ref loc)
 {
   for (; loc != NULL; loc = loc->dw_loc_next)
     {
@@ -3061,8 +3033,7 @@ output_loc_sequence (loc)
    description based on a cfi entry with a complex address.  */
 
 static void
-output_cfa_loc (cfi)
-     dw_cfi_ref cfi;
+output_cfa_loc (dw_cfi_ref cfi)
 {
   dw_loc_descr_ref loc;
   unsigned long size;
@@ -3080,8 +3051,7 @@ output_cfa_loc (cfi)
    a dw_cfa_location.  */
 
 static struct dw_loc_descr_struct *
-build_cfa_loc (cfa)
-     dw_cfa_location *cfa;
+build_cfa_loc (dw_cfa_location *cfa)
 {
   struct dw_loc_descr_struct *head, *tmp;
 
@@ -3116,9 +3086,7 @@ build_cfa_loc (cfa)
    descriptor sequence.  */
 
 static void
-get_cfa_from_loc_descr (cfa, loc)
-     dw_cfa_location *cfa;
-     struct dw_loc_descr_struct *loc;
+get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc)
 {
   struct dw_loc_descr_struct *ptr;
   cfa->offset = 0;
@@ -3226,19 +3194,19 @@ get_cfa_from_loc_descr (cfa, loc)
 #ifdef DWARF2_DEBUGGING_INFO
 
 /* .debug_str support.  */
-static int output_indirect_string      PARAMS ((void **, void *));
-
-static void dwarf2out_init             PARAMS ((const char *));
-static void dwarf2out_finish           PARAMS ((const char *));
-static void dwarf2out_define           PARAMS ((unsigned int, const char *));
-static void dwarf2out_undef            PARAMS ((unsigned int, const char *));
-static void dwarf2out_start_source_file        PARAMS ((unsigned, const char *));
-static void dwarf2out_end_source_file  PARAMS ((unsigned));
-static void dwarf2out_begin_block      PARAMS ((unsigned, unsigned));
-static void dwarf2out_end_block                PARAMS ((unsigned, unsigned));
-static bool dwarf2out_ignore_block     PARAMS ((tree));
-static void dwarf2out_global_decl      PARAMS ((tree));
-static void dwarf2out_abstract_function PARAMS ((tree));
+static int output_indirect_string (void **, void *);
+
+static void dwarf2out_init (const char *);
+static void dwarf2out_finish (const char *);
+static void dwarf2out_define (unsigned int, const char *);
+static void dwarf2out_undef (unsigned int, const char *);
+static void dwarf2out_start_source_file (unsigned, const char *);
+static void dwarf2out_end_source_file (unsigned);
+static void dwarf2out_begin_block (unsigned, unsigned);
+static void dwarf2out_end_block (unsigned, unsigned);
+static bool dwarf2out_ignore_block (tree);
+static void dwarf2out_global_decl (tree);
+static void dwarf2out_abstract_function (tree);
 
 /* The debug hooks structure.  */
 
@@ -3266,7 +3234,8 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
      emitting the abstract description of inline functions until
      something tries to reference them.  */
   dwarf2out_abstract_function, /* outlining_inline_function */
-  debug_nothing_rtx            /* label */
+  debug_nothing_rtx,           /* label */
+  debug_nothing_int            /* handle_pch */
 };
 #endif
 \f
@@ -3395,21 +3364,24 @@ limbo_die_node;
    language, and compiler version.  */
 
 /* Fixed size portion of the DWARF compilation unit header.  */
-#define DWARF_COMPILE_UNIT_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 3)
+#define DWARF_COMPILE_UNIT_HEADER_SIZE \
+  (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 3)
 
 /* Fixed size portion of public names info.  */
 #define DWARF_PUBNAMES_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 2)
 
 /* Fixed size portion of the address range info.  */
 #define DWARF_ARANGES_HEADER_SIZE                                      \
-  (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2)       \
-   - DWARF_OFFSET_SIZE)
+  (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4,     \
+                DWARF2_ADDR_SIZE * 2)                                  \
+   - DWARF_INITIAL_LENGTH_SIZE)
 
 /* Size of padding portion in the address range info.  It must be
    aligned to twice the pointer size.  */
 #define DWARF_ARANGES_PAD_SIZE \
-  (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
-   - (2 * DWARF_OFFSET_SIZE + 4))
+  (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \
+                DWARF2_ADDR_SIZE * 2) \
+   - (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4))
 
 /* Use assembler line directives if available.  */
 #ifndef DWARF2_ASM_LINE_DEBUG_INFO
@@ -3436,35 +3408,28 @@ limbo_die_node;
    is not made available by the GCC front-end.  */
 #define        DWARF_LINE_DEFAULT_IS_STMT_START 1
 
+#ifdef DWARF2_DEBUGGING_INFO
 /* This location is used by calc_die_sizes() to keep track
    the offset of each DIE within the .debug_info section.  */
 static unsigned long next_die_offset;
+#endif
 
 /* Record the root of the DIE's built for the current compilation unit.  */
 static GTY(()) dw_die_ref comp_unit_die;
 
+#ifdef DWARF2_DEBUGGING_INFO
 /* We need special handling in dwarf2out_start_source_file if it is
    first one.  */
 static int is_main_source;
+#endif
 
 /* A list of DIEs with a NULL parent waiting to be relocated.  */
 static GTY(()) limbo_die_node *limbo_die_list;
 
-/* Structure used by lookup_filename to manage sets of filenames.  */
-struct file_table
-{
-  char **table;
-  unsigned allocated;
-  unsigned in_use;
-  unsigned last_lookup_index;
-};
-
-/* Size (in elements) of increments by which we may expand the filename
-   table.  */
-#define FILE_TABLE_INCREMENT 64
-
 /* Filenames referenced by this compilation unit.  */
-static struct file_table file_table;
+static GTY(()) varray_type file_table;
+static GTY(()) varray_type file_table_emitted;
+static GTY(()) size_t file_table_last_lookup_index;
 
 /* A pointer to the base of a table of references to DIE's that describe
    declarations.  The table is indexed by DECL_UID() which is a unique
@@ -3472,10 +3437,10 @@ static struct file_table file_table;
 static GTY((length ("decl_die_table_allocated"))) dw_die_ref *decl_die_table;
 
 /* Number of elements currently allocated for the decl_die_table.  */
-static unsigned decl_die_table_allocated;
+static GTY(()) unsigned decl_die_table_allocated;
 
 /* Number of elements in decl_die_table currently in use.  */
-static unsigned decl_die_table_in_use;
+static GTY(()) unsigned decl_die_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    decl_die_table.  */
@@ -3484,14 +3449,14 @@ static unsigned decl_die_table_in_use;
 /* A pointer to the base of a list of references to DIE's that
    are uniquely identified by their tag, presence/absence of
    children DIE's, and list of attribute/value pairs.  */
-static GTY((length ("abbrev_die_table_allocated"))) 
+static GTY((length ("abbrev_die_table_allocated")))
   dw_die_ref *abbrev_die_table;
 
 /* Number of elements currently allocated for abbrev_die_table.  */
-static unsigned abbrev_die_table_allocated;
+static GTY(()) unsigned abbrev_die_table_allocated;
 
 /* Number of elements in type_die_table currently in use.  */
-static unsigned abbrev_die_table_in_use;
+static GTY(()) unsigned abbrev_die_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    abbrev_die_table.  */
@@ -3499,14 +3464,14 @@ static unsigned abbrev_die_table_in_use;
 
 /* A pointer to the base of a table that contains line information
    for each source code line in .text in the compilation unit.  */
-static GTY((length ("line_info_table_allocated"))) 
+static GTY((length ("line_info_table_allocated")))
      dw_line_info_ref line_info_table;
 
 /* Number of elements currently allocated for line_info_table.  */
-static unsigned line_info_table_allocated;
+static GTY(()) unsigned line_info_table_allocated;
 
 /* Number of elements in line_info_table currently in use.  */
-static unsigned line_info_table_in_use;
+static GTY(()) unsigned line_info_table_in_use;
 
 /* A pointer to the base of a table that contains line information
    for each source code line outside of .text in the compilation unit.  */
@@ -3514,10 +3479,10 @@ static GTY ((length ("separate_line_info_table_allocated")))
      dw_separate_line_info_ref separate_line_info_table;
 
 /* Number of elements currently allocated for separate_line_info_table.  */
-static unsigned separate_line_info_table_allocated;
+static GTY(()) unsigned separate_line_info_table_allocated;
 
 /* Number of elements in separate_line_info_table currently in use.  */
-static unsigned separate_line_info_table_in_use;
+static GTY(()) unsigned separate_line_info_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    line_info_table.  */
@@ -3528,10 +3493,10 @@ static unsigned separate_line_info_table_in_use;
 static GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table;
 
 /* Number of elements currently allocated for pubname_table.  */
-static unsigned pubname_table_allocated;
+static GTY(()) unsigned pubname_table_allocated;
 
 /* Number of elements in pubname_table currently in use.  */
-static unsigned pubname_table_in_use;
+static GTY(()) unsigned pubname_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    pubname_table.  */
@@ -3541,10 +3506,10 @@ static unsigned pubname_table_in_use;
 static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table;
 
 /* Number of elements currently allocated for arange_table.  */
-static unsigned arange_table_allocated;
+static GTY(()) unsigned arange_table_allocated;
 
 /* Number of elements in arange_table currently in use.  */
-static unsigned arange_table_in_use;
+static GTY(()) unsigned arange_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    arange_table.  */
@@ -3554,286 +3519,263 @@ static unsigned arange_table_in_use;
 static GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table;
 
 /* Number of elements currently allocated for ranges_table.  */
-static unsigned ranges_table_allocated;
+static GTY(()) unsigned ranges_table_allocated;
 
 /* Number of elements in ranges_table currently in use.  */
-static unsigned ranges_table_in_use;
+static GTY(()) unsigned ranges_table_in_use;
 
 /* Size (in elements) of increments by which we may expand the
    ranges_table.  */
 #define RANGES_TABLE_INCREMENT 64
 
 /* Whether we have location lists that need outputting */
-static unsigned have_location_lists;
+static GTY(()) unsigned have_location_lists;
 
+#ifdef DWARF2_DEBUGGING_INFO
 /* Record whether the function being analyzed contains inlined functions.  */
 static int current_function_has_inlines;
+#endif
 #if 0 && defined (MIPS_DEBUGGING_INFO)
 static int comp_unit_has_inlines;
 #endif
 
+/* Number of file tables emitted in maybe_emit_file().  */
+static GTY(()) int emitcount = 0;
+
+/* Number of internal labels generated by gen_internal_sym().  */
+static GTY(()) int label_num;
+
 #ifdef DWARF2_DEBUGGING_INFO
 
 /* Forward declarations for functions defined in this file.  */
 
-static int is_pseudo_reg               PARAMS ((rtx));
-static tree type_main_variant          PARAMS ((tree));
-static int is_tagged_type              PARAMS ((tree));
-static const char *dwarf_tag_name      PARAMS ((unsigned));
-static const char *dwarf_attr_name     PARAMS ((unsigned));
-static const char *dwarf_form_name     PARAMS ((unsigned));
+static int is_pseudo_reg (rtx);
+static tree type_main_variant (tree);
+static int is_tagged_type (tree);
+static const char *dwarf_tag_name (unsigned);
+static const char *dwarf_attr_name (unsigned);
+static const char *dwarf_form_name (unsigned);
 #if 0
-static const char *dwarf_type_encoding_name PARAMS ((unsigned));
+static const char *dwarf_type_encoding_name (unsigned);
 #endif
-static tree decl_ultimate_origin       PARAMS ((tree));
-static tree block_ultimate_origin      PARAMS ((tree));
-static tree decl_class_context         PARAMS ((tree));
-static void add_dwarf_attr             PARAMS ((dw_die_ref, dw_attr_ref));
-static inline enum dw_val_class AT_class       PARAMS ((dw_attr_ref));
-static void add_AT_flag                        PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                unsigned));
-static inline unsigned AT_flag         PARAMS ((dw_attr_ref));
-static void add_AT_int                 PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute, long));
-static inline long int AT_int          PARAMS ((dw_attr_ref));
-static void add_AT_unsigned            PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                unsigned long));
-static inline unsigned long            AT_unsigned PARAMS ((dw_attr_ref));
-static void add_AT_long_long           PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                unsigned long,
-                                                unsigned long));
-static void add_AT_float               PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                unsigned, long *));
-static hashval_t debug_str_do_hash     PARAMS ((const void *));
-static int debug_str_eq                        PARAMS ((const void *, const void *));
-static void add_AT_string              PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                const char *));
-static inline const char *AT_string    PARAMS ((dw_attr_ref));
-static int AT_string_form              PARAMS ((dw_attr_ref));
-static void add_AT_die_ref             PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                dw_die_ref));
-static inline dw_die_ref AT_ref                PARAMS ((dw_attr_ref));
-static inline int AT_ref_external      PARAMS ((dw_attr_ref));
-static inline void set_AT_ref_external PARAMS ((dw_attr_ref, int));
-static void add_AT_fde_ref             PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                unsigned));
-static void add_AT_loc                 PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                dw_loc_descr_ref));
-static inline dw_loc_descr_ref AT_loc  PARAMS ((dw_attr_ref));
-static void add_AT_loc_list            PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                dw_loc_list_ref));
-static inline dw_loc_list_ref AT_loc_list PARAMS ((dw_attr_ref));
-static void add_AT_addr                        PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                rtx));
-static inline rtx AT_addr              PARAMS ((dw_attr_ref));
-static void add_AT_lbl_id              PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                const char *));
-static void add_AT_lbl_offset          PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                const char *));
-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 inline const char *AT_lbl       PARAMS ((dw_attr_ref));
-static dw_attr_ref get_AT              PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute));
-static const char *get_AT_low_pc       PARAMS ((dw_die_ref));
-static const char *get_AT_hi_pc                PARAMS ((dw_die_ref));
-static const char *get_AT_string       PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute));
-static int get_AT_flag                 PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute));
-static unsigned get_AT_unsigned                PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute));
-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,
-                                                enum dwarf_attribute));
-static inline void free_die            PARAMS ((dw_die_ref));
-static void remove_children            PARAMS ((dw_die_ref));
-static void add_child_die              PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref new_die              PARAMS ((enum dwarf_tag, dw_die_ref,
-                                                tree));
-static dw_die_ref lookup_type_die      PARAMS ((tree));
-static void equate_type_number_to_die  PARAMS ((tree, dw_die_ref));
-static dw_die_ref lookup_decl_die      PARAMS ((tree));
-static void equate_decl_number_to_die  PARAMS ((tree, dw_die_ref));
-static void print_spaces               PARAMS ((FILE *));
-static void print_die                  PARAMS ((dw_die_ref, FILE *));
-static void print_dwarf_line_table     PARAMS ((FILE *));
-static void reverse_die_lists          PARAMS ((dw_die_ref));
-static void reverse_all_dies           PARAMS ((dw_die_ref));
-static dw_die_ref push_new_compile_unit PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref pop_compile_unit     PARAMS ((dw_die_ref));
-static void loc_checksum               PARAMS ((dw_loc_descr_ref,
-                                                struct md5_ctx *));
-static void attr_checksum              PARAMS ((dw_attr_ref,
-                                                struct md5_ctx *,
-                                                int *));
-static void die_checksum               PARAMS ((dw_die_ref,
-                                                struct md5_ctx *,
-                                                int *));
-static int same_loc_p                  PARAMS ((dw_loc_descr_ref,
-                                                dw_loc_descr_ref, int *));
-static int same_dw_val_p               PARAMS ((dw_val_node *, dw_val_node *,
-                                                int *));
-static int same_attr_p                 PARAMS ((dw_attr_ref, dw_attr_ref, int *));
-static int same_die_p                  PARAMS ((dw_die_ref, dw_die_ref, int *));
-static int same_die_p_wrap             PARAMS ((dw_die_ref, dw_die_ref));
-static void compute_section_prefix     PARAMS ((dw_die_ref));
-static int is_type_die                 PARAMS ((dw_die_ref));
-static int is_comdat_die               PARAMS ((dw_die_ref));
-static int is_symbol_die               PARAMS ((dw_die_ref));
-static void assign_symbol_names                PARAMS ((dw_die_ref));
-static void break_out_includes         PARAMS ((dw_die_ref));
-static hashval_t htab_cu_hash          PARAMS ((const void *));
-static int htab_cu_eq                  PARAMS ((const void *, const void *));
-static void htab_cu_del                        PARAMS ((void *));
-static int check_duplicate_cu          PARAMS ((dw_die_ref, htab_t, unsigned *));
-static void record_comdat_symbol_number        PARAMS ((dw_die_ref, htab_t, unsigned));
-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 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));
-static void mark_dies                  PARAMS ((dw_die_ref));
-static void unmark_dies                        PARAMS ((dw_die_ref));
-static void unmark_all_dies             PARAMS ((dw_die_ref));
-static unsigned long size_of_pubnames  PARAMS ((void));
-static unsigned long size_of_aranges   PARAMS ((void));
-static enum dwarf_form value_format    PARAMS ((dw_attr_ref));
-static void output_value_format                PARAMS ((dw_attr_ref));
-static void output_abbrev_section      PARAMS ((void));
-static void output_die_symbol          PARAMS ((dw_die_ref));
-static void output_die                 PARAMS ((dw_die_ref));
-static void output_compilation_unit_header PARAMS ((void));
-static void output_comp_unit           PARAMS ((dw_die_ref, int));
-static const char *dwarf2_name         PARAMS ((tree, int));
-static void add_pubname                        PARAMS ((tree, dw_die_ref));
-static void output_pubnames            PARAMS ((void));
-static void add_arange                 PARAMS ((tree, dw_die_ref));
-static void output_aranges             PARAMS ((void));
-static unsigned int add_ranges         PARAMS ((tree));
-static void output_ranges              PARAMS ((void));
-static void output_line_info           PARAMS ((void));
-static void output_file_names           PARAMS ((void));
-static dw_die_ref base_type_die                PARAMS ((tree));
-static tree root_type                  PARAMS ((tree));
-static int is_base_type                        PARAMS ((tree));
-static dw_die_ref modified_type_die    PARAMS ((tree, int, int, dw_die_ref));
-static int type_is_enum                        PARAMS ((tree));
-static unsigned int reg_number         PARAMS ((rtx));
-static dw_loc_descr_ref reg_loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref int_loc_descriptor PARAMS ((HOST_WIDE_INT));
-static dw_loc_descr_ref based_loc_descr        PARAMS ((unsigned, long));
-static int is_based_loc                        PARAMS ((rtx));
-static dw_loc_descr_ref mem_loc_descriptor PARAMS ((rtx, enum machine_mode mode));
-static dw_loc_descr_ref concat_loc_descriptor PARAMS ((rtx, rtx));
-static dw_loc_descr_ref loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref loc_descriptor_from_tree PARAMS ((tree, int));
-static HOST_WIDE_INT ceiling           PARAMS ((HOST_WIDE_INT, unsigned int));
-static tree field_type                 PARAMS ((tree));
-static unsigned int simple_type_align_in_bits PARAMS ((tree));
-static unsigned int simple_decl_align_in_bits PARAMS ((tree));
-static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
-static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
-static void add_AT_location_description        PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute,
-                                                dw_loc_descr_ref));
-static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
-static void add_const_value_attribute  PARAMS ((dw_die_ref, rtx));
-static rtx rtl_for_decl_location       PARAMS ((tree));
-static void add_location_or_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void tree_add_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void add_name_attribute         PARAMS ((dw_die_ref, const char *));
-static void add_bound_info             PARAMS ((dw_die_ref,
-                                                enum dwarf_attribute, tree));
-static void add_subscript_info         PARAMS ((dw_die_ref, tree));
-static void add_byte_size_attribute    PARAMS ((dw_die_ref, tree));
-static void add_bit_offset_attribute   PARAMS ((dw_die_ref, tree));
-static void add_bit_size_attribute     PARAMS ((dw_die_ref, tree));
-static void add_prototyped_attribute   PARAMS ((dw_die_ref, tree));
-static void add_abstract_origin_attribute PARAMS ((dw_die_ref, tree));
-static void add_pure_or_virtual_attribute PARAMS ((dw_die_ref, tree));
-static void add_src_coords_attributes  PARAMS ((dw_die_ref, tree));
-static void add_name_and_src_coords_attributes PARAMS ((dw_die_ref, tree));
-static void push_decl_scope            PARAMS ((tree));
-static void pop_decl_scope             PARAMS ((void));
-static dw_die_ref scope_die_for                PARAMS ((tree, dw_die_ref));
-static inline int local_scope_p                PARAMS ((dw_die_ref));
-static inline int class_scope_p                PARAMS ((dw_die_ref));
-static void add_type_attribute         PARAMS ((dw_die_ref, tree, int, int,
-                                                dw_die_ref));
-static const char *type_tag            PARAMS ((tree));
-static tree member_declared_type       PARAMS ((tree));
+static tree decl_ultimate_origin (tree);
+static tree block_ultimate_origin (tree);
+static tree decl_class_context (tree);
+static void add_dwarf_attr (dw_die_ref, dw_attr_ref);
+static inline enum dw_val_class AT_class (dw_attr_ref);
+static void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned);
+static inline unsigned AT_flag (dw_attr_ref);
+static void add_AT_int (dw_die_ref, enum dwarf_attribute, long);
+static inline long int AT_int (dw_attr_ref);
+static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned long);
+static inline unsigned long AT_unsigned (dw_attr_ref);
+static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
+                             unsigned long);
+static void add_AT_float (dw_die_ref, enum dwarf_attribute, unsigned, long *);
+static hashval_t debug_str_do_hash (const void *);
+static int debug_str_eq (const void *, const void *);
+static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
+static inline const char *AT_string (dw_attr_ref);
+static int AT_string_form (dw_attr_ref);
+static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref);
+static inline dw_die_ref AT_ref (dw_attr_ref);
+static inline int AT_ref_external (dw_attr_ref);
+static inline void set_AT_ref_external (dw_attr_ref, int);
+static void add_AT_fde_ref (dw_die_ref, enum dwarf_attribute, unsigned);
+static void add_AT_loc (dw_die_ref, enum dwarf_attribute, dw_loc_descr_ref);
+static inline dw_loc_descr_ref AT_loc (dw_attr_ref);
+static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute,
+                            dw_loc_list_ref);
+static inline dw_loc_list_ref AT_loc_list (dw_attr_ref);
+static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
+static inline rtx AT_addr (dw_attr_ref);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_offset (dw_die_ref, enum dwarf_attribute, unsigned long);
+static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
+                              unsigned long);
+static inline const char *AT_lbl (dw_attr_ref);
+static dw_attr_ref get_AT (dw_die_ref, enum dwarf_attribute);
+static const char *get_AT_low_pc (dw_die_ref);
+static const char *get_AT_hi_pc (dw_die_ref);
+static const char *get_AT_string (dw_die_ref, enum dwarf_attribute);
+static int get_AT_flag (dw_die_ref, enum dwarf_attribute);
+static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute);
+static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute);
+static bool is_c_family (void);
+static bool is_cxx (void);
+static bool is_java (void);
+static bool is_fortran (void);
+static bool is_ada (void);
+static void remove_AT (dw_die_ref, enum dwarf_attribute);
+static inline void free_die (dw_die_ref);
+static void remove_children (dw_die_ref);
+static void add_child_die (dw_die_ref, dw_die_ref);
+static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
+static dw_die_ref lookup_type_die (tree);
+static void equate_type_number_to_die (tree, dw_die_ref);
+static dw_die_ref lookup_decl_die (tree);
+static void equate_decl_number_to_die (tree, dw_die_ref);
+static void print_spaces (FILE *);
+static void print_die (dw_die_ref, FILE *);
+static void print_dwarf_line_table (FILE *);
+static void reverse_die_lists (dw_die_ref);
+static void reverse_all_dies (dw_die_ref);
+static dw_die_ref push_new_compile_unit (dw_die_ref, dw_die_ref);
+static dw_die_ref pop_compile_unit (dw_die_ref);
+static void loc_checksum (dw_loc_descr_ref, struct md5_ctx *);
+static void attr_checksum (dw_attr_ref, struct md5_ctx *, int *);
+static void die_checksum (dw_die_ref, struct md5_ctx *, int *);
+static int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *);
+static int same_dw_val_p (dw_val_node *, dw_val_node *, int *);
+static int same_attr_p (dw_attr_ref, dw_attr_ref, int *);
+static int same_die_p (dw_die_ref, dw_die_ref, int *);
+static int same_die_p_wrap (dw_die_ref, dw_die_ref);
+static void compute_section_prefix (dw_die_ref);
+static int is_type_die (dw_die_ref);
+static int is_comdat_die (dw_die_ref);
+static int is_symbol_die (dw_die_ref);
+static void assign_symbol_names (dw_die_ref);
+static void break_out_includes (dw_die_ref);
+static hashval_t htab_cu_hash (const void *);
+static int htab_cu_eq (const void *, const void *);
+static void htab_cu_del (void *);
+static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *);
+static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned);
+static void add_sibling_attributes (dw_die_ref);
+static void build_abbrev_table (dw_die_ref);
+static void output_location_lists (dw_die_ref);
+static int constant_size (long unsigned);
+static unsigned long size_of_die (dw_die_ref);
+static void calc_die_sizes (dw_die_ref);
+static void mark_dies (dw_die_ref);
+static void unmark_dies (dw_die_ref);
+static void unmark_all_dies (dw_die_ref);
+static unsigned long size_of_pubnames (void);
+static unsigned long size_of_aranges (void);
+static enum dwarf_form value_format (dw_attr_ref);
+static void output_value_format (dw_attr_ref);
+static void output_abbrev_section (void);
+static void output_die_symbol (dw_die_ref);
+static void output_die (dw_die_ref);
+static void output_compilation_unit_header (void);
+static void output_comp_unit (dw_die_ref, int);
+static const char *dwarf2_name (tree, int);
+static void add_pubname (tree, dw_die_ref);
+static void output_pubnames (void);
+static void add_arange (tree, dw_die_ref);
+static void output_aranges (void);
+static unsigned int add_ranges (tree);
+static void output_ranges (void);
+static void output_line_info (void);
+static void output_file_names (void);
+static dw_die_ref base_type_die (tree);
+static tree root_type (tree);
+static int is_base_type (tree);
+static bool is_ada_subrange_type (tree);
+static dw_die_ref subrange_type_die (tree);
+static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
+static int type_is_enum (tree);
+static unsigned int reg_number (rtx);
+static dw_loc_descr_ref reg_loc_descriptor (rtx);
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
+static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
+static dw_loc_descr_ref based_loc_descr (unsigned, long);
+static int is_based_loc (rtx);
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref loc_descriptor (rtx);
+static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
+static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
+static tree field_type (tree);
+static unsigned int simple_type_align_in_bits (tree);
+static unsigned int simple_decl_align_in_bits (tree);
+static unsigned HOST_WIDE_INT simple_type_size_in_bits (tree);
+static HOST_WIDE_INT field_byte_offset (tree);
+static void add_AT_location_description        (dw_die_ref, enum dwarf_attribute,
+                                        dw_loc_descr_ref);
+static void add_data_member_location_attribute (dw_die_ref, tree);
+static void add_const_value_attribute (dw_die_ref, rtx);
+static rtx rtl_for_decl_location (tree);
+static void add_location_or_const_value_attribute (dw_die_ref, tree);
+static void tree_add_const_value_attribute (dw_die_ref, tree);
+static void add_name_attribute (dw_die_ref, const char *);
+static void add_comp_dir_attribute (dw_die_ref);
+static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
+static void add_subscript_info (dw_die_ref, tree);
+static void add_byte_size_attribute (dw_die_ref, tree);
+static void add_bit_offset_attribute (dw_die_ref, tree);
+static void add_bit_size_attribute (dw_die_ref, tree);
+static void add_prototyped_attribute (dw_die_ref, tree);
+static void add_abstract_origin_attribute (dw_die_ref, tree);
+static void add_pure_or_virtual_attribute (dw_die_ref, tree);
+static void add_src_coords_attributes (dw_die_ref, tree);
+static void add_name_and_src_coords_attributes (dw_die_ref, tree);
+static void push_decl_scope (tree);
+static void pop_decl_scope (void);
+static dw_die_ref scope_die_for (tree, dw_die_ref);
+static inline int local_scope_p (dw_die_ref);
+static inline int class_scope_p (dw_die_ref);
+static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
+static const char *type_tag (tree);
+static tree member_declared_type (tree);
 #if 0
-static const char *decl_start_label    PARAMS ((tree));
+static const char *decl_start_label (tree);
 #endif
-static void gen_array_type_die         PARAMS ((tree, dw_die_ref));
-static void gen_set_type_die           PARAMS ((tree, dw_die_ref));
+static void gen_array_type_die (tree, dw_die_ref);
+static void gen_set_type_die (tree, dw_die_ref);
 #if 0
-static void gen_entry_point_die                PARAMS ((tree, dw_die_ref));
+static void gen_entry_point_die (tree, dw_die_ref);
 #endif
-static void gen_inlined_enumeration_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_structure_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_enumeration_type_die   PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_formal_parameter_die PARAMS ((tree, dw_die_ref));
-static void gen_unspecified_parameters_die PARAMS ((tree, dw_die_ref));
-static void gen_formal_types_die       PARAMS ((tree, dw_die_ref));
-static void gen_subprogram_die         PARAMS ((tree, dw_die_ref));
-static void gen_variable_die           PARAMS ((tree, dw_die_ref));
-static void gen_label_die              PARAMS ((tree, dw_die_ref));
-static void gen_lexical_block_die      PARAMS ((tree, dw_die_ref, int));
-static void gen_inlined_subroutine_die PARAMS ((tree, dw_die_ref, int));
-static void gen_field_die              PARAMS ((tree, dw_die_ref));
-static void gen_ptr_to_mbr_type_die    PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_compile_unit_die PARAMS ((const char *));
-static void gen_string_type_die                PARAMS ((tree, dw_die_ref));
-static void gen_inheritance_die                PARAMS ((tree, dw_die_ref));
-static void gen_member_die             PARAMS ((tree, dw_die_ref));
-static void gen_struct_or_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_subroutine_type_die    PARAMS ((tree, dw_die_ref));
-static void gen_typedef_die            PARAMS ((tree, dw_die_ref));
-static void gen_type_die               PARAMS ((tree, dw_die_ref));
-static void gen_tagged_type_instantiation_die PARAMS ((tree, dw_die_ref));
-static void gen_block_die              PARAMS ((tree, dw_die_ref, int));
-static void decls_for_scope            PARAMS ((tree, dw_die_ref, int));
-static int is_redundant_typedef                PARAMS ((tree));
-static void gen_decl_die               PARAMS ((tree, dw_die_ref));
-static unsigned lookup_filename                PARAMS ((const char *));
-static void init_file_table            PARAMS ((void));
-static void retry_incomplete_types     PARAMS ((void));
-static void gen_type_die_for_member    PARAMS ((tree, tree, dw_die_ref));
-static void splice_child_die           PARAMS ((dw_die_ref, dw_die_ref));
-static int file_info_cmp               PARAMS ((const void *, const void *));
-static dw_loc_list_ref new_loc_list     PARAMS ((dw_loc_descr_ref,
-                                                const char *, const char *,
-                                                const char *, unsigned));
-static void add_loc_descr_to_loc_list   PARAMS ((dw_loc_list_ref *,
-                                                dw_loc_descr_ref,
-                                                const char *, const char *, const char *));
-static void output_loc_list            PARAMS ((dw_loc_list_ref));
-static char *gen_internal_sym          PARAMS ((const char *));
+static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
+static void gen_inlined_structure_type_die (tree, dw_die_ref);
+static void gen_inlined_union_type_die (tree, dw_die_ref);
+static void gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
+static void gen_unspecified_parameters_die (tree, dw_die_ref);
+static void gen_formal_types_die (tree, dw_die_ref);
+static void gen_subprogram_die (tree, dw_die_ref);
+static void gen_variable_die (tree, dw_die_ref);
+static void gen_label_die (tree, dw_die_ref);
+static void gen_lexical_block_die (tree, dw_die_ref, int);
+static void gen_inlined_subroutine_die (tree, dw_die_ref, int);
+static void gen_field_die (tree, dw_die_ref);
+static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
+static dw_die_ref gen_compile_unit_die (const char *);
+static void gen_string_type_die (tree, dw_die_ref);
+static void gen_inheritance_die (tree, tree, dw_die_ref);
+static void gen_member_die (tree, dw_die_ref);
+static void gen_struct_or_union_type_die (tree, dw_die_ref);
+static void gen_subroutine_type_die (tree, dw_die_ref);
+static void gen_typedef_die (tree, dw_die_ref);
+static void gen_type_die (tree, dw_die_ref);
+static void gen_tagged_type_instantiation_die (tree, dw_die_ref);
+static void gen_block_die (tree, dw_die_ref, int);
+static void decls_for_scope (tree, dw_die_ref, int);
+static int is_redundant_typedef (tree);
+static void gen_decl_die (tree, dw_die_ref);
+static unsigned lookup_filename (const char *);
+static void init_file_table (void);
+static void retry_incomplete_types (void);
+static void gen_type_die_for_member (tree, tree, dw_die_ref);
+static void splice_child_die (dw_die_ref, dw_die_ref);
+static int file_info_cmp (const void *, const void *);
+static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
+                                    const char *, const char *, unsigned);
+static void add_loc_descr_to_loc_list (dw_loc_list_ref *, dw_loc_descr_ref,
+                                      const char *, const char *,
+                                      const char *);
+static void output_loc_list (dw_loc_list_ref);
+static char *gen_internal_sym (const char *);
+
+static void prune_unmark_dies (dw_die_ref);
+static void prune_unused_types_mark (dw_die_ref, int);
+static void prune_unused_types_walk (dw_die_ref);
+static void prune_unused_types_walk_attribs (dw_die_ref);
+static void prune_unused_types_prune (dw_die_ref);
+static void prune_unused_types (void);
+static int maybe_emit_file (int);
 
 /* Section names used to hold DWARF debugging information.  */
 #ifndef DEBUG_INFO_SECTION
@@ -3872,7 +3814,9 @@ static char *gen_internal_sym             PARAMS ((const char *));
 /* Section flags for .debug_str section.  */
 #ifdef HAVE_GAS_SHF_MERGE
 #define DEBUG_STR_SECTION_FLAGS \
-  (SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1)
+  (flag_merge_constants                                                \
+   ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1       \
+   : SECTION_DEBUG)
 #else
 #define DEBUG_STR_SECTION_FLAGS        SECTION_DEBUG
 #endif
@@ -3936,11 +3880,10 @@ static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
 /* We allow a language front-end to designate a function that is to be
    called to "demangle" any name before it it put into a DIE.  */
 
-static const char *(*demangle_name_func) PARAMS ((const char *));
+static const char *(*demangle_name_func) (const char *);
 
 void
-dwarf2out_set_demangle_name_func (func)
-     const char *(*func) PARAMS ((const char *));
+dwarf2out_set_demangle_name_func (const char *(*func) (const char *))
 {
   demangle_name_func = func;
 }
@@ -3948,8 +3891,7 @@ dwarf2out_set_demangle_name_func (func)
 /* Test if rtl node points to a pseudo register.  */
 
 static inline int
-is_pseudo_reg (rtl)
-     rtx rtl;
+is_pseudo_reg (rtx rtl)
 {
   return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
          || (GET_CODE (rtl) == SUBREG
@@ -3960,8 +3902,7 @@ is_pseudo_reg (rtl)
    removed.  */
 
 static inline tree
-type_main_variant (type)
-     tree type;
+type_main_variant (tree type)
 {
   type = TYPE_MAIN_VARIANT (type);
 
@@ -3980,8 +3921,7 @@ type_main_variant (type)
 /* Return nonzero if the given type node represents a tagged type.  */
 
 static inline int
-is_tagged_type (type)
-     tree type;
+is_tagged_type (tree type)
 {
   enum tree_code code = TREE_CODE (type);
 
@@ -3992,8 +3932,7 @@ is_tagged_type (type)
 /* Convert a DIE tag into its string name.  */
 
 static const char *
-dwarf_tag_name (tag)
-     unsigned tag;
+dwarf_tag_name (unsigned int tag)
 {
   switch (tag)
     {
@@ -4113,8 +4052,7 @@ dwarf_tag_name (tag)
 /* Convert a DWARF attribute code into its string name.  */
 
 static const char *
-dwarf_attr_name (attr)
-     unsigned attr;
+dwarf_attr_name (unsigned int attr)
 {
   switch (attr)
     {
@@ -4317,8 +4255,7 @@ dwarf_attr_name (attr)
 /* Convert a DWARF value form code into its string name.  */
 
 static const char *
-dwarf_form_name (form)
-     unsigned form;
+dwarf_form_name (unsigned int form)
 {
   switch (form)
     {
@@ -4373,8 +4310,7 @@ dwarf_form_name (form)
 
 #if 0
 static const char *
-dwarf_type_encoding_name (enc)
-     unsigned enc;
+dwarf_type_encoding_name (unsigned enc)
 {
   switch (enc)
     {
@@ -4407,8 +4343,7 @@ dwarf_type_encoding_name (enc)
    given block.  */
 
 static tree
-decl_ultimate_origin (decl)
-     tree decl;
+decl_ultimate_origin (tree decl)
 {
   /* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
      nodes in the function to point to themselves; ignore that if
@@ -4433,8 +4368,7 @@ decl_ultimate_origin (decl)
    given block.  */
 
 static tree
-block_ultimate_origin (block)
-     tree block;
+block_ultimate_origin (tree block)
 {
   tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
 
@@ -4468,8 +4402,7 @@ block_ultimate_origin (block)
    parameter.  */
 
 static tree
-decl_class_context (decl)
-     tree decl;
+decl_class_context (tree decl)
 {
   tree context = NULL_TREE;
 
@@ -4489,9 +4422,7 @@ decl_class_context (decl)
    addition order, and correct that in reverse_all_dies.  */
 
 static inline void
-add_dwarf_attr (die, attr)
-     dw_die_ref die;
-     dw_attr_ref attr;
+add_dwarf_attr (dw_die_ref die, dw_attr_ref attr)
 {
   if (die != NULL && attr != NULL)
     {
@@ -4501,8 +4432,7 @@ add_dwarf_attr (die, attr)
 }
 
 static inline enum dw_val_class
-AT_class (a)
-     dw_attr_ref a;
+AT_class (dw_attr_ref a)
 {
   return a->dw_attr_val.val_class;
 }
@@ -4510,12 +4440,9 @@ AT_class (a)
 /* Add a flag value attribute to a DIE.  */
 
 static inline void
-add_AT_flag (die, attr_kind, flag)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned flag;
+add_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int flag)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4525,8 +4452,7 @@ add_AT_flag (die, attr_kind, flag)
 }
 
 static inline unsigned
-AT_flag (a)
-     dw_attr_ref a;
+AT_flag (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_flag)
     return a->dw_attr_val.v.val_flag;
@@ -4537,12 +4463,9 @@ AT_flag (a)
 /* Add a signed integer attribute value to a DIE.  */
 
 static inline void
-add_AT_int (die, attr_kind, int_val)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     long int int_val;
+add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, long int int_val)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4552,8 +4475,7 @@ add_AT_int (die, attr_kind, int_val)
 }
 
 static inline long int
-AT_int (a)
-     dw_attr_ref a;
+AT_int (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_const)
     return a->dw_attr_val.v.val_int;
@@ -4564,12 +4486,10 @@ AT_int (a)
 /* Add an unsigned integer attribute value to a DIE.  */
 
 static inline void
-add_AT_unsigned (die, attr_kind, unsigned_val)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned long unsigned_val;
+add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
+                long unsigned int unsigned_val)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4579,8 +4499,7 @@ add_AT_unsigned (die, attr_kind, unsigned_val)
 }
 
 static inline unsigned long
-AT_unsigned (a)
-     dw_attr_ref a;
+AT_unsigned (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_unsigned_const)
     return a->dw_attr_val.v.val_unsigned;
@@ -4591,13 +4510,10 @@ AT_unsigned (a)
 /* Add an unsigned double integer attribute value to a DIE.  */
 
 static inline void
-add_AT_long_long (die, attr_kind, val_hi, val_low)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned long val_hi;
-     unsigned long val_low;
+add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind,
+                 long unsigned int val_hi, long unsigned int val_low)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4610,13 +4526,10 @@ add_AT_long_long (die, attr_kind, val_hi, val_low)
 /* Add a floating point attribute value to a DIE and return it.  */
 
 static inline void
-add_AT_float (die, attr_kind, length, array)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned length;
-     long *array;
+add_AT_float (dw_die_ref die, enum dwarf_attribute attr_kind,
+             unsigned int length, long int *array)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4629,16 +4542,13 @@ add_AT_float (die, attr_kind, length, array)
 /* Hash and equality functions for debug_str_hash.  */
 
 static hashval_t
-debug_str_do_hash (x)
-     const void * x;
+debug_str_do_hash (const void *x)
 {
   return htab_hash_string (((const struct indirect_string_node *)x)->str);
 }
 
 static int
-debug_str_eq (x1, x2)
-     const void * x1;
-     const void * x2;
+debug_str_eq (const void *x1, const void *x2)
 {
   return strcmp ((((const struct indirect_string_node *)x1)->str),
                 (const char *)x2) == 0;
@@ -4647,17 +4557,14 @@ debug_str_eq (x1, x2)
 /* Add a string attribute value to a DIE.  */
 
 static inline void
-add_AT_string (die, attr_kind, str)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     const char *str;
+add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
   struct indirect_string_node *node;
-  PTR *slot;
+  void **slot;
 
   if (! debug_str_hash)
-    debug_str_hash = htab_create_ggc (10, debug_str_do_hash, 
+    debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
                                      debug_str_eq, NULL);
 
   slot = htab_find_slot_with_hash (debug_str_hash, str,
@@ -4665,7 +4572,7 @@ add_AT_string (die, attr_kind, str)
   if (*slot == NULL)
     *slot = ggc_alloc_cleared (sizeof (struct indirect_string_node));
   node = (struct indirect_string_node *) *slot;
-  node->str = ggc_alloc_string (str, -1);
+  node->str = ggc_strdup (str);
   node->refcount++;
 
   attr->dw_attr_next = NULL;
@@ -4676,8 +4583,7 @@ add_AT_string (die, attr_kind, str)
 }
 
 static inline const char *
-AT_string (a)
-     dw_attr_ref a;
+AT_string (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_str)
     return a->dw_attr_val.v.val_str->str;
@@ -4689,8 +4595,7 @@ AT_string (a)
    or out-of-line in .debug_str section.  */
 
 static int
-AT_string_form (a)
-     dw_attr_ref a;
+AT_string_form (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_str)
     {
@@ -4729,12 +4634,9 @@ AT_string_form (a)
 /* Add a DIE reference attribute value to a DIE.  */
 
 static inline void
-add_AT_die_ref (die, attr_kind, targ_die)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     dw_die_ref targ_die;
+add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_die)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4745,8 +4647,7 @@ add_AT_die_ref (die, attr_kind, targ_die)
 }
 
 static inline dw_die_ref
-AT_ref (a)
-     dw_attr_ref a;
+AT_ref (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
     return a->dw_attr_val.v.val_die_ref.die;
@@ -4755,8 +4656,7 @@ AT_ref (a)
 }
 
 static inline int
-AT_ref_external (a)
-     dw_attr_ref a;
+AT_ref_external (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
     return a->dw_attr_val.v.val_die_ref.external;
@@ -4765,9 +4665,7 @@ AT_ref_external (a)
 }
 
 static inline void
-set_AT_ref_external (a, i)
-     dw_attr_ref a;
-     int i;
+set_AT_ref_external (dw_attr_ref a, int i)
 {
   if (a && AT_class (a) == dw_val_class_die_ref)
     a->dw_attr_val.v.val_die_ref.external = i;
@@ -4778,12 +4676,9 @@ set_AT_ref_external (a, i)
 /* Add an FDE reference attribute value to a DIE.  */
 
 static inline void
-add_AT_fde_ref (die, attr_kind, targ_fde)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned targ_fde;
+add_AT_fde_ref (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int targ_fde)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4795,12 +4690,9 @@ add_AT_fde_ref (die, attr_kind, targ_fde)
 /* Add a location description attribute value to a DIE.  */
 
 static inline void
-add_AT_loc (die, attr_kind, loc)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     dw_loc_descr_ref loc;
+add_AT_loc (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_descr_ref loc)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4810,8 +4702,7 @@ add_AT_loc (die, attr_kind, loc)
 }
 
 static inline dw_loc_descr_ref
-AT_loc (a)
-     dw_attr_ref a;
+AT_loc (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_loc)
     return a->dw_attr_val.v.val_loc;
@@ -4820,12 +4711,9 @@ AT_loc (a)
 }
 
 static inline void
-add_AT_loc_list (die, attr_kind, loc_list)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     dw_loc_list_ref loc_list;
+add_AT_loc_list (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref loc_list)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4836,8 +4724,7 @@ add_AT_loc_list (die, attr_kind, loc_list)
 }
 
 static inline dw_loc_list_ref
-AT_loc_list (a)
-     dw_attr_ref a;
+AT_loc_list (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_loc_list)
     return a->dw_attr_val.v.val_loc_list;
@@ -4848,12 +4735,9 @@ AT_loc_list (a)
 /* Add an address constant attribute value to a DIE.  */
 
 static inline void
-add_AT_addr (die, attr_kind, addr)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     rtx addr;
+add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4863,8 +4747,7 @@ add_AT_addr (die, attr_kind, addr)
 }
 
 static inline rtx
-AT_addr (a)
-     dw_attr_ref a;
+AT_addr (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_addr)
     return a->dw_attr_val.v.val_addr;
@@ -4875,12 +4758,9 @@ AT_addr (a)
 /* Add a label identifier attribute value to a DIE.  */
 
 static inline void
-add_AT_lbl_id (die, attr_kind, lbl_id)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     const char *lbl_id;
+add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, const char *lbl_id)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4892,12 +4772,9 @@ add_AT_lbl_id (die, attr_kind, lbl_id)
 /* Add a section offset attribute value to a DIE.  */
 
 static inline void
-add_AT_lbl_offset (die, attr_kind, label)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     const char *label;
+add_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *label)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4909,12 +4786,9 @@ add_AT_lbl_offset (die, attr_kind, label)
 /* Add an offset attribute value to a DIE.  */
 
 static inline void
-add_AT_offset (die, attr_kind, offset)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     unsigned long offset;
+add_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind, long unsigned int offset)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4926,12 +4800,10 @@ add_AT_offset (die, attr_kind, offset)
 /* 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;
+add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind,
+                  long unsigned int offset)
 {
-  dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
@@ -4941,8 +4813,7 @@ add_AT_range_list (die, attr_kind, offset)
 }
 
 static inline const char *
-AT_lbl (a)
-     dw_attr_ref a;
+AT_lbl (dw_attr_ref a)
 {
   if (a && (AT_class (a) == dw_val_class_lbl_id
            || AT_class (a) == dw_val_class_lbl_offset))
@@ -4954,9 +4825,7 @@ AT_lbl (a)
 /* Get the attribute of type attr_kind.  */
 
 static inline dw_attr_ref
-get_AT (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a;
   dw_die_ref spec = NULL;
@@ -4982,8 +4851,7 @@ get_AT (die, attr_kind)
    cannot be represented as an assembler label identifier.  */
 
 static inline const char *
-get_AT_low_pc (die)
-     dw_die_ref die;
+get_AT_low_pc (dw_die_ref die)
 {
   dw_attr_ref a = get_AT (die, DW_AT_low_pc);
 
@@ -4995,8 +4863,7 @@ get_AT_low_pc (die)
    cannot be represented as an assembler label identifier.  */
 
 static inline const char *
-get_AT_hi_pc (die)
-     dw_die_ref die;
+get_AT_hi_pc (dw_die_ref die)
 {
   dw_attr_ref a = get_AT (die, DW_AT_high_pc);
 
@@ -5007,9 +4874,7 @@ get_AT_hi_pc (die)
    NULL if it is not present.  */
 
 static inline const char *
-get_AT_string (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+get_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a = get_AT (die, attr_kind);
 
@@ -5020,9 +4885,7 @@ get_AT_string (die, attr_kind)
    if it is not present.  */
 
 static inline int
-get_AT_flag (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+get_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a = get_AT (die, attr_kind);
 
@@ -5033,9 +4896,7 @@ get_AT_flag (die, attr_kind)
    if it is not present.  */
 
 static inline unsigned
-get_AT_unsigned (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+get_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a = get_AT (die, attr_kind);
 
@@ -5043,53 +4904,68 @@ get_AT_unsigned (die, attr_kind)
 }
 
 static inline dw_die_ref
-get_AT_ref (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+get_AT_ref (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a = get_AT (die, attr_kind);
 
   return a ? AT_ref (a) : NULL;
 }
 
-static inline int
-is_c_family ()
+/* Return TRUE if the language is C or C++.  */
+
+static inline bool
+is_c_family (void)
 {
-  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned int 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 TRUE if the language is C++.  */
+
+static inline bool
+is_cxx (void)
 {
   return (get_AT_unsigned (comp_unit_die, DW_AT_language)
          == DW_LANG_C_plus_plus);
 }
 
-static inline int
-is_fortran ()
+/* Return TRUE if the language is Fortran.  */
+
+static inline bool
+is_fortran (void)
 {
-  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
 
-  return (lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90);
+  return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90;
 }
 
-static inline int
-is_java ()
+/* Return TRUE if the language is Java.  */
+
+static inline bool
+is_java (void)
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+
+  return lang == DW_LANG_Java;
+}
+
+/* Return TRUE if the language is Ada.  */
+
+static inline bool
+is_ada (void)
 {
-  unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+  unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
 
-  return (lang == DW_LANG_Java);
+  return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
 }
 
 /* Free up the memory used by A.  */
 
-static inline void free_AT PARAMS ((dw_attr_ref));
+static inline void free_AT (dw_attr_ref);
 static inline void
-free_AT (a)
-     dw_attr_ref a;
+free_AT (dw_attr_ref a)
 {
   if (AT_class (a) == dw_val_class_str)
     if (a->dw_attr_val.v.val_str->refcount)
@@ -5099,9 +4975,7 @@ free_AT (a)
 /* Remove the specified attribute if present.  */
 
 static void
-remove_AT (die, attr_kind)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
+remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref *p;
   dw_attr_ref removed = NULL;
@@ -5124,8 +4998,7 @@ remove_AT (die, attr_kind)
 /* Free up the memory used by DIE.  */
 
 static inline void
-free_die (die)
-     dw_die_ref die;
+free_die (dw_die_ref die)
 {
   remove_children (die);
 }
@@ -5133,8 +5006,7 @@ free_die (die)
 /* Discard the children of this DIE.  */
 
 static void
-remove_children (die)
-     dw_die_ref die;
+remove_children (dw_die_ref die)
 {
   dw_die_ref child_die = die->die_child;
 
@@ -5163,9 +5035,7 @@ remove_children (die)
    addition order, and correct that in reverse_all_dies.  */
 
 static inline void
-add_child_die (die, child_die)
-     dw_die_ref die;
-     dw_die_ref child_die;
+add_child_die (dw_die_ref die, dw_die_ref child_die)
 {
   if (die != NULL && child_die != NULL)
     {
@@ -5182,8 +5052,7 @@ add_child_die (die, child_die)
    is the specification, to the front of PARENT's list of children.  */
 
 static void
-splice_child_die (parent, child)
-     dw_die_ref parent, child;
+splice_child_die (dw_die_ref parent, dw_die_ref child)
 {
   dw_die_ref *p;
 
@@ -5208,6 +5077,7 @@ splice_child_die (parent, child)
        break;
       }
 
+  child->die_parent = parent;
   child->die_sib = parent->die_child;
   parent->die_child = child;
 }
@@ -5215,12 +5085,9 @@ splice_child_die (parent, child)
 /* Return a pointer to a newly created DIE node.  */
 
 static inline dw_die_ref
-new_die (tag_value, parent_die, t)
-     enum dwarf_tag tag_value;
-     dw_die_ref parent_die;
-     tree t;
+new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
 {
-  dw_die_ref die = (dw_die_ref) ggc_alloc_cleared (sizeof (die_node));
+  dw_die_ref die = ggc_alloc_cleared (sizeof (die_node));
 
   die->die_tag = tag_value;
 
@@ -5243,8 +5110,7 @@ new_die (tag_value, parent_die, t)
 /* Return the DIE associated with the given type specifier.  */
 
 static inline dw_die_ref
-lookup_type_die (type)
-     tree type;
+lookup_type_die (tree type)
 {
   return TYPE_SYMTAB_DIE (type);
 }
@@ -5252,9 +5118,7 @@ lookup_type_die (type)
 /* Equate a DIE to a given type specifier.  */
 
 static inline void
-equate_type_number_to_die (type, type_die)
-     tree type;
-     dw_die_ref type_die;
+equate_type_number_to_die (tree type, dw_die_ref type_die)
 {
   TYPE_SYMTAB_DIE (type) = type_die;
 }
@@ -5262,8 +5126,7 @@ equate_type_number_to_die (type, type_die)
 /* Return the DIE associated with a given declaration.  */
 
 static inline dw_die_ref
-lookup_decl_die (decl)
-     tree decl;
+lookup_decl_die (tree decl)
 {
   unsigned decl_id = DECL_UID (decl);
 
@@ -5273,9 +5136,7 @@ lookup_decl_die (decl)
 /* Equate a DIE to a particular declaration.  */
 
 static void
-equate_decl_number_to_die (decl, decl_die)
-     tree decl;
-     dw_die_ref decl_die;
+equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
 {
   unsigned int decl_id = DECL_UID (decl);
   unsigned int num_allocated;
@@ -5290,7 +5151,7 @@ equate_decl_number_to_die (decl, decl_die)
       decl_die_table = ggc_realloc (decl_die_table,
                                    sizeof (dw_die_ref) * num_allocated);
 
-      memset ((char *) &decl_die_table[decl_die_table_allocated], 0,
+      memset (&decl_die_table[decl_die_table_allocated], 0,
             (num_allocated - decl_die_table_allocated) * sizeof (dw_die_ref));
       decl_die_table_allocated = num_allocated;
     }
@@ -5309,8 +5170,7 @@ static int print_indent;
 /* Indent the line the number of spaces given by print_indent.  */
 
 static inline void
-print_spaces (outfile)
-     FILE *outfile;
+print_spaces (FILE *outfile)
 {
   fprintf (outfile, "%*s", print_indent, "");
 }
@@ -5319,9 +5179,7 @@ print_spaces (outfile)
    This routine is a debugging aid only.  */
 
 static void
-print_die (die, outfile)
-     dw_die_ref die;
-     FILE *outfile;
+print_die (dw_die_ref die, FILE *outfile)
 {
   dw_attr_ref a;
   dw_die_ref c;
@@ -5417,8 +5275,7 @@ print_die (die, outfile)
    This routine is a debugging aid only.  */
 
 static void
-print_dwarf_line_table (outfile)
-     FILE *outfile;
+print_dwarf_line_table (FILE *outfile)
 {
   unsigned i;
   dw_line_info_ref line_info;
@@ -5428,7 +5285,8 @@ print_dwarf_line_table (outfile)
     {
       line_info = &line_info_table[i];
       fprintf (outfile, "%5d: ", i);
-      fprintf (outfile, "%-20s", file_table.table[line_info->dw_file_num]);
+      fprintf (outfile, "%-20s",
+              VARRAY_CHAR_PTR (file_table, line_info->dw_file_num));
       fprintf (outfile, "%6ld", line_info->dw_line_num);
       fprintf (outfile, "\n");
     }
@@ -5439,8 +5297,7 @@ print_dwarf_line_table (outfile)
 /* Print the information collected for a given DIE.  */
 
 void
-debug_dwarf_die (die)
-     dw_die_ref die;
+debug_dwarf_die (dw_die_ref die)
 {
   print_die (die, stderr);
 }
@@ -5449,7 +5306,7 @@ debug_dwarf_die (die)
    This routine is a debugging aid only.  */
 
 void
-debug_dwarf ()
+debug_dwarf (void)
 {
   print_indent = 0;
   print_die (comp_unit_die, stderr);
@@ -5462,8 +5319,7 @@ debug_dwarf ()
    they are in order of addition.  */
 
 static void
-reverse_die_lists (die)
-     dw_die_ref die;
+reverse_die_lists (dw_die_ref die)
 {
   dw_die_ref c, cp, cn;
   dw_attr_ref a, ap, an;
@@ -5494,8 +5350,7 @@ reverse_die_lists (die)
    recursively reverse all the dies. This is that routine.  */
 
 static void
-reverse_all_dies (die)
-     dw_die_ref die;
+reverse_all_dies (dw_die_ref die)
 {
   dw_die_ref c;
 
@@ -5510,8 +5365,7 @@ reverse_all_dies (die)
    DIE that marks the start of the DIEs for this include file.  */
 
 static dw_die_ref
-push_new_compile_unit (old_unit, bincl_die)
-     dw_die_ref old_unit, bincl_die;
+push_new_compile_unit (dw_die_ref old_unit, dw_die_ref bincl_die)
 {
   const char *filename = get_AT_string (bincl_die, DW_AT_name);
   dw_die_ref new_unit = gen_compile_unit_die (filename);
@@ -5523,8 +5377,7 @@ push_new_compile_unit (old_unit, bincl_die)
 /* Close an include-file CU and reopen the enclosing one.  */
 
 static dw_die_ref
-pop_compile_unit (old_unit)
-     dw_die_ref old_unit;
+pop_compile_unit (dw_die_ref old_unit)
 {
   dw_die_ref new_unit = old_unit->die_sib;
 
@@ -5538,9 +5391,7 @@ pop_compile_unit (old_unit)
 /* Calculate the checksum of a location expression.  */
 
 static inline void
-loc_checksum (loc, ctx)
-     dw_loc_descr_ref loc;
-     struct md5_ctx *ctx;
+loc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx)
 {
   CHECKSUM (loc->dw_loc_opc);
   CHECKSUM (loc->dw_loc_oprnd1);
@@ -5550,10 +5401,7 @@ loc_checksum (loc, ctx)
 /* Calculate the checksum of an attribute.  */
 
 static void
-attr_checksum (at, ctx, mark)
-     dw_attr_ref at;
-     struct md5_ctx *ctx;
-     int *mark;
+attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
 {
   dw_loc_descr_ref loc;
   rtx r;
@@ -5627,10 +5475,7 @@ attr_checksum (at, ctx, mark)
 /* Calculate the checksum of a DIE.  */
 
 static void
-die_checksum (die, ctx, mark)
-     dw_die_ref die;
-     struct md5_ctx *ctx;
-     int *mark;
+die_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark)
 {
   dw_die_ref c;
   dw_attr_ref a;
@@ -5657,10 +5502,7 @@ die_checksum (die, ctx, mark)
 
 /* Do the location expressions look same?  */
 static inline int
-same_loc_p (loc1, loc2, mark)
-     dw_loc_descr_ref loc1;
-     dw_loc_descr_ref loc2;
-     int *mark;
+same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark)
 {
   return loc1->dw_loc_opc == loc2->dw_loc_opc
         && same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
@@ -5669,10 +5511,7 @@ same_loc_p (loc1, loc2, mark)
 
 /* Do the values look the same?  */
 static int
-same_dw_val_p (v1, v2, mark)
-     dw_val_node *v1;
-     dw_val_node *v2;
-     int *mark;
+same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark)
 {
   dw_loc_descr_ref loc1, loc2;
   rtx r1, r2;
@@ -5689,12 +5528,12 @@ same_dw_val_p (v1, v2, mark)
       return v1->v.val_unsigned == v2->v.val_unsigned;
     case dw_val_class_long_long:
       return v1->v.val_long_long.hi == v2->v.val_long_long.hi
-             && v1->v.val_long_long.low == v2->v.val_long_long.low;
+            && v1->v.val_long_long.low == v2->v.val_long_long.low;
     case dw_val_class_float:
       if (v1->v.val_float.length != v2->v.val_float.length)
        return 0;
       for (i = 0; i < v1->v.val_float.length; i++)
-        if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
+       if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
          return 0;
       return 1;
     case dw_val_class_flag:
@@ -5743,10 +5582,7 @@ same_dw_val_p (v1, v2, mark)
 /* Do the attributes look the same?  */
 
 static int
-same_attr_p (at1, at2, mark)
-     dw_attr_ref at1;
-     dw_attr_ref at2;
-     int *mark;
+same_attr_p (dw_attr_ref at1, dw_attr_ref at2, int *mark)
 {
   if (at1->dw_attr != at2->dw_attr)
     return 0;
@@ -5764,10 +5600,7 @@ same_attr_p (at1, at2, mark)
 /* Do the dies look the same?  */
 
 static int
-same_die_p (die1, die2, mark)
-     dw_die_ref die1;
-     dw_die_ref die2;
-     int *mark;
+same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark)
 {
   dw_die_ref c1, c2;
   dw_attr_ref a1, a2;
@@ -5802,9 +5635,7 @@ same_die_p (die1, die2, mark)
 /* Do the dies look the same?  Wrapper around same_die_p.  */
 
 static int
-same_die_p_wrap (die1, die2)
-     dw_die_ref die1;
-     dw_die_ref die2;
+same_die_p_wrap (dw_die_ref die1, dw_die_ref die2)
 {
   int mark = 0;
   int ret = same_die_p (die1, die2, &mark);
@@ -5826,12 +5657,11 @@ static unsigned int comdat_symbol_number;
    children, and set comdat_symbol_id accordingly.  */
 
 static void
-compute_section_prefix (unit_die)
-     dw_die_ref unit_die;
+compute_section_prefix (dw_die_ref unit_die)
 {
   const char *die_name = get_AT_string (unit_die, DW_AT_name);
   const char *base = die_name ? lbasename (die_name) : "anonymous";
-  char *name = (char *) alloca (strlen (base) + 64);
+  char *name = alloca (strlen (base) + 64);
   char *p;
   int i, mark;
   unsigned char checksum[16];
@@ -5863,8 +5693,7 @@ compute_section_prefix (unit_die)
 /* Returns nonzero if DIE represents a type, in the sense of TYPE_P.  */
 
 static int
-is_type_die (die)
-     dw_die_ref die;
+is_type_die (dw_die_ref die)
 {
   switch (die->die_tag)
     {
@@ -5898,8 +5727,7 @@ is_type_die (die)
    compilations (functions).  */
 
 static int
-is_comdat_die (c)
-     dw_die_ref c;
+is_comdat_die (dw_die_ref c)
 {
   /* I think we want to leave base types and __vtbl_ptr_type in the main CU, as
      we do for stabs.  The advantage is a greater likelihood of sharing between
@@ -5926,8 +5754,7 @@ is_comdat_die (c)
    compilation unit.  */
 
 static int
-is_symbol_die (c)
-     dw_die_ref c;
+is_symbol_die (dw_die_ref c)
 {
   return (is_type_die (c)
          || (get_AT (c, DW_AT_declaration)
@@ -5935,11 +5762,9 @@ is_symbol_die (c)
 }
 
 static char *
-gen_internal_sym (prefix)
-     const char *prefix;
+gen_internal_sym (const char *prefix)
 {
   char buf[256];
-  static int label_num;
 
   ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
   return xstrdup (buf);
@@ -5948,8 +5773,7 @@ gen_internal_sym (prefix)
 /* Assign symbols to all worthy DIEs under DIE.  */
 
 static void
-assign_symbol_names (die)
-     dw_die_ref die;
+assign_symbol_names (dw_die_ref die)
 {
   dw_die_ref c;
 
@@ -5980,8 +5804,7 @@ struct cu_hash_table_entry
 
 /* Routines to manipulate hash table of CUs.  */
 static hashval_t
-htab_cu_hash (of)
-     const void *of;
+htab_cu_hash (const void *of)
 {
   const struct cu_hash_table_entry *entry = of;
 
@@ -5989,9 +5812,7 @@ htab_cu_hash (of)
 }
 
 static int
-htab_cu_eq (of1, of2)
-     const void *of1;
-     const void *of2;
+htab_cu_eq (const void *of1, const void *of2)
 {
   const struct cu_hash_table_entry *entry1 = of1;
   const struct die_struct *entry2 = of2;
@@ -6000,8 +5821,7 @@ htab_cu_eq (of1, of2)
 }
 
 static void
-htab_cu_del (what)
-     void *what;
+htab_cu_del (void *what)
 {
   struct cu_hash_table_entry *next, *entry = what;
 
@@ -6016,10 +5836,7 @@ htab_cu_del (what)
 /* Check whether we have already seen this CU and set up SYM_NUM
    accordingly.  */
 static int
-check_duplicate_cu (cu, htable, sym_num)
-     dw_die_ref cu;
-     htab_t htable;
-     unsigned *sym_num;
+check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
 {
   struct cu_hash_table_entry dummy;
   struct cu_hash_table_entry **slot, *entry, *last = &dummy;
@@ -6054,10 +5871,7 @@ check_duplicate_cu (cu, htable, sym_num)
 
 /* Record SYM_NUM to record of CU in HTABLE.  */
 static void
-record_comdat_symbol_number (cu, htable, sym_num)
-     dw_die_ref cu;
-     htab_t htable;
-     unsigned sym_num;
+record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num)
 {
   struct cu_hash_table_entry **slot, *entry;
 
@@ -6074,8 +5888,7 @@ record_comdat_symbol_number (cu, htable, sym_num)
    bracketed by BINCL/EINCL.  */
 
 static void
-break_out_includes (die)
-     dw_die_ref die;
+break_out_includes (dw_die_ref die)
 {
   dw_die_ref *ptr;
   dw_die_ref unit = NULL;
@@ -6135,7 +5948,7 @@ break_out_includes (die)
       if (is_dupl)
        *pnode = node->next;
       else
-        {
+       {
          pnode = &node->next;
          record_comdat_symbol_number (node->die, cu_hash_table,
                comdat_symbol_number);
@@ -6149,8 +5962,7 @@ break_out_includes (die)
    avoid generating sibling attributes for DIE's without children.  */
 
 static void
-add_sibling_attributes (die)
-     dw_die_ref die;
+add_sibling_attributes (dw_die_ref die)
 {
   dw_die_ref c;
 
@@ -6166,8 +5978,7 @@ add_sibling_attributes (die)
 /* Output all location lists for the DIE and its children.  */
 
 static void
-output_location_lists (die)
-     dw_die_ref die;
+output_location_lists (dw_die_ref die)
 {
   dw_die_ref c;
   dw_attr_ref d_attr;
@@ -6187,8 +5998,7 @@ output_location_lists (die)
    die are visited recursively.  */
 
 static void
-build_abbrev_table (die)
-     dw_die_ref die;
+build_abbrev_table (dw_die_ref die)
 {
   unsigned long abbrev_id;
   unsigned int n_alloc;
@@ -6242,7 +6052,7 @@ build_abbrev_table (die)
          abbrev_die_table = ggc_realloc (abbrev_die_table,
                                          sizeof (dw_die_ref) * n_alloc);
 
-         memset ((char *) &abbrev_die_table[abbrev_die_table_allocated], 0,
+         memset (&abbrev_die_table[abbrev_die_table_allocated], 0,
                 (n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref));
          abbrev_die_table_allocated = n_alloc;
        }
@@ -6259,8 +6069,7 @@ build_abbrev_table (die)
 /* Return the power-of-two number of bytes necessary to represent VALUE.  */
 
 static int
-constant_size (value)
-     long unsigned value;
+constant_size (long unsigned int value)
 {
   int log;
 
@@ -6279,8 +6088,7 @@ constant_size (value)
    .debug_info section.  */
 
 static unsigned long
-size_of_die (die)
-     dw_die_ref die;
+size_of_die (dw_die_ref die)
 {
   unsigned long size = 0;
   dw_attr_ref a;
@@ -6327,7 +6135,10 @@ size_of_die (die)
          size += 1;
          break;
        case dw_val_class_die_ref:
-         size += DWARF_OFFSET_SIZE;
+         if (AT_ref_external (a))
+           size += DWARF2_ADDR_SIZE;
+         else
+           size += DWARF_OFFSET_SIZE;
          break;
        case dw_val_class_fde_ref:
          size += DWARF_OFFSET_SIZE;
@@ -6358,8 +6169,7 @@ size_of_die (die)
    die_offset field in each DIE.  */
 
 static void
-calc_die_sizes (die)
-     dw_die_ref die;
+calc_die_sizes (dw_die_ref die)
 {
   dw_die_ref c;
 
@@ -6380,14 +6190,13 @@ calc_die_sizes (die)
    and use that as the flag, but ran into ordering problems.  */
 
 static void
-mark_dies (die)
-     dw_die_ref die;
+mark_dies (dw_die_ref die)
 {
   dw_die_ref c;
 
   if (die->die_mark)
     abort ();
-  
+
   die->die_mark = 1;
   for (c = die->die_child; c; c = c->die_sib)
     mark_dies (c);
@@ -6396,14 +6205,13 @@ mark_dies (die)
 /* Clear the marks for a die and its children.  */
 
 static void
-unmark_dies (die)
-     dw_die_ref die;
+unmark_dies (dw_die_ref die)
 {
   dw_die_ref c;
 
   if (!die->die_mark)
     abort ();
-  
+
   die->die_mark = 0;
   for (c = die->die_child; c; c = c->die_sib)
     unmark_dies (c);
@@ -6412,8 +6220,7 @@ unmark_dies (die)
 /* Clear the marks for a die, its children and referred dies.  */
 
 static void
-unmark_all_dies (die)
-     dw_die_ref die;
+unmark_all_dies (dw_die_ref die)
 {
   dw_die_ref c;
   dw_attr_ref a;
@@ -6434,7 +6241,7 @@ unmark_all_dies (die)
    compilation unit.  */
 
 static unsigned long
-size_of_pubnames ()
+size_of_pubnames (void)
 {
   unsigned long size;
   unsigned i;
@@ -6453,7 +6260,7 @@ size_of_pubnames ()
 /* Return the size of the information in the .debug_aranges section.  */
 
 static unsigned long
-size_of_aranges ()
+size_of_aranges (void)
 {
   unsigned long size;
 
@@ -6471,8 +6278,7 @@ size_of_aranges ()
 /* Select the encoding of an attribute value.  */
 
 static enum dwarf_form
-value_format (a)
-     dw_attr_ref a;
+value_format (dw_attr_ref a)
 {
   switch (a->dw_attr_val.val_class)
     {
@@ -6543,8 +6349,7 @@ value_format (a)
 /* Output the encoding of an attribute value.  */
 
 static void
-output_value_format (a)
-     dw_attr_ref a;
+output_value_format (dw_attr_ref a)
 {
   enum dwarf_form form = value_format (a);
 
@@ -6555,7 +6360,7 @@ output_value_format (a)
    table.  */
 
 static void
-output_abbrev_section ()
+output_abbrev_section (void)
 {
   unsigned long abbrev_id;
 
@@ -6593,8 +6398,7 @@ output_abbrev_section ()
 /* Output a symbol we can use to refer to this DIE from another CU.  */
 
 static inline void
-output_die_symbol (die)
-     dw_die_ref die;
+output_die_symbol (dw_die_ref die)
 {
   char *sym = die->die_symbol;
 
@@ -6615,12 +6419,8 @@ output_die_symbol (die)
    this location list node, which is done for the head of the list only.  */
 
 static inline dw_loc_list_ref
-new_loc_list (expr, begin, end, section, gensym)
-     dw_loc_descr_ref expr;
-     const char *begin;
-     const char *end;
-     const char *section;
-     unsigned gensym;
+new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
+             const char *section, unsigned int gensym)
 {
   dw_loc_list_ref retlist = ggc_alloc_cleared (sizeof (dw_loc_list_node));
 
@@ -6634,15 +6434,12 @@ new_loc_list (expr, begin, end, section, gensym)
   return retlist;
 }
 
-/* Add a location description expression to a location list */
+/* Add a location description expression to a location list */
 
 static inline void
-add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
-     dw_loc_list_ref *list_head;
-     dw_loc_descr_ref descr;
-     const char *begin;
-     const char *end;
-     const char *section;
+add_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr,
+                          const char *begin, const char *end,
+                          const char *section)
 {
   dw_loc_list_ref *d;
 
@@ -6650,15 +6447,14 @@ add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
   for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
     ;
 
-  /* Add a new location list node to the list */
+  /* Add a new location list node to the list */
   *d = new_loc_list (descr, begin, end, section, 0);
 }
 
-/* Output the location list given to us */
+/* Output the location list given to us */
 
 static void
-output_loc_list (list_head)
-     dw_loc_list_ref list_head;
+output_loc_list (dw_loc_list_ref list_head)
 {
   dw_loc_list_ref curr = list_head;
 
@@ -6708,8 +6504,7 @@ output_loc_list (list_head)
    the definitions of each child DIE.  */
 
 static void
-output_die (die)
-     dw_die_ref die;
+output_die (dw_die_ref die)
 {
   dw_attr_ref a;
   dw_die_ref c;
@@ -6885,9 +6680,13 @@ output_die (die)
    .debug_info section, and precedes the DIE descriptions.  */
 
 static void
-output_compilation_unit_header ()
+output_compilation_unit_header (void)
 {
-  dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset - DWARF_OFFSET_SIZE,
+  if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+    dw2_asm_output_data (4, 0xffffffff,
+      "Initial length escape value indicating 64-bit DWARF extension");
+  dw2_asm_output_data (DWARF_OFFSET_SIZE,
+                       next_die_offset - DWARF_INITIAL_LENGTH_SIZE,
                       "Length of Compilation Unit Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF version number");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
@@ -6898,9 +6697,7 @@ output_compilation_unit_header ()
 /* Output the compilation unit DIE and its children.  */
 
 static void
-output_comp_unit (die, output_if_empty)
-     dw_die_ref die;
-     int output_if_empty;
+output_comp_unit (dw_die_ref die, int output_if_empty)
 {
   const char *secname;
   char *oldsym, *tmp;
@@ -6925,7 +6722,7 @@ output_comp_unit (die, output_if_empty)
   oldsym = die->die_symbol;
   if (oldsym)
     {
-      tmp = (char *) alloca (strlen (oldsym) + 24);
+      tmp = alloca (strlen (oldsym) + 24);
 
       sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
       secname = tmp;
@@ -6953,9 +6750,7 @@ output_comp_unit (die, output_if_empty)
    "A::f(int)".  Let's drop the argument list, and maybe the scope.  */
 
 static const char *
-dwarf2_name (decl, scope)
-     tree decl;
-     int scope;
+dwarf2_name (tree decl, int scope)
 {
   return (*lang_hooks.decl_printable_name) (decl, scope ? 1 : 0);
 }
@@ -6963,9 +6758,7 @@ dwarf2_name (decl, scope)
 /* Add a new entry to .debug_pubnames if appropriate.  */
 
 static void
-add_pubname (decl, die)
-     tree decl;
-     dw_die_ref die;
+add_pubname (tree decl, dw_die_ref die)
 {
   pubname_ref p;
 
@@ -6976,9 +6769,8 @@ add_pubname (decl, die)
     {
       pubname_table_allocated += PUBNAME_TABLE_INCREMENT;
       pubname_table
-       = (pubname_ref) ggc_realloc (pubname_table,
-                                    (pubname_table_allocated
-                                     * sizeof (pubname_entry)));
+       = ggc_realloc (pubname_table,
+                      (pubname_table_allocated * sizeof (pubname_entry)));
       memset (pubname_table + pubname_table_in_use, 0,
              PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry));
     }
@@ -6993,11 +6785,14 @@ add_pubname (decl, die)
    visible procedures.  */
 
 static void
-output_pubnames ()
+output_pubnames (void)
 {
   unsigned i;
   unsigned long pubnames_length = size_of_pubnames ();
 
+  if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+    dw2_asm_output_data (4, 0xffffffff,
+      "Initial length escape value indicating 64-bit DWARF extension");
   dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
                       "Length of Public Names Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
@@ -7026,9 +6821,7 @@ output_pubnames ()
 /* Add a new entry to .debug_aranges if appropriate.  */
 
 static void
-add_arange (decl, die)
-     tree decl;
-     dw_die_ref die;
+add_arange (tree decl, dw_die_ref die)
 {
   if (! DECL_SECTION_NAME (decl))
     return;
@@ -7036,8 +6829,8 @@ add_arange (decl, die)
   if (arange_table_in_use == arange_table_allocated)
     {
       arange_table_allocated += ARANGE_TABLE_INCREMENT;
-      arange_table = ggc_realloc (arange_table, 
-                                 (arange_table_allocated 
+      arange_table = ggc_realloc (arange_table,
+                                 (arange_table_allocated
                                   * sizeof (dw_die_ref)));
       memset (arange_table + arange_table_in_use, 0,
              ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
@@ -7051,11 +6844,14 @@ add_arange (decl, die)
    text section generated for this compilation unit.  */
 
 static void
-output_aranges ()
+output_aranges (void)
 {
   unsigned i;
   unsigned long aranges_length = size_of_aranges ();
 
+  if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+    dw2_asm_output_data (4, 0xffffffff,
+      "Initial length escape value indicating 64-bit DWARF extension");
   dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length,
                       "Length of Address Ranges Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
@@ -7068,7 +6864,7 @@ output_aranges ()
   if (DWARF_ARANGES_PAD_SIZE)
     {
       /* Pad using a 2 byte words so that padding is correct for any
-         pointer size.  */
+        pointer size.  */
       dw2_asm_output_data (2, 0, "Pad to %d byte boundary",
                           2 * DWARF2_ADDR_SIZE);
       for (i = 2; i < (unsigned) DWARF_ARANGES_PAD_SIZE; i += 2)
@@ -7126,17 +6922,16 @@ output_aranges ()
    was placed.  */
 
 static unsigned int
-add_ranges (block)
-     tree block;
+add_ranges (tree block)
 {
   unsigned int in_use = ranges_table_in_use;
 
   if (in_use == ranges_table_allocated)
     {
       ranges_table_allocated += RANGES_TABLE_INCREMENT;
-      ranges_table = (dw_ranges_ref)
-       ggc_realloc (ranges_table, (ranges_table_allocated
-                                   * sizeof (struct dw_ranges_struct)));
+      ranges_table
+       ggc_realloc (ranges_table, (ranges_table_allocated
+                                     * sizeof (struct dw_ranges_struct)));
       memset (ranges_table + ranges_table_in_use, 0,
              RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
     }
@@ -7148,7 +6943,7 @@ add_ranges (block)
 }
 
 static void
-output_ranges ()
+output_ranges (void)
 {
   unsigned i;
   static const char *const start_fmt = "Offset 0x%x";
@@ -7226,9 +7021,7 @@ struct dir_info
    the directories in the path.  */
 
 static int
-file_info_cmp (p1, p2)
-     const void *p1;
-     const void *p2;
+file_info_cmp (const void *p1, const void *p2)
 {
   const struct file_info *s1 = p1;
   const struct file_info *s2 = p2;
@@ -7267,31 +7060,37 @@ file_info_cmp (p1, p2)
    slowdowns with many input files.  */
 
 static void
-output_file_names ()
+output_file_names (void)
 {
   struct file_info *files;
   struct dir_info *dirs;
   int *saved;
   int *savehere;
   int *backmap;
-  int ndirs;
+  size_t ndirs;
   int idx_offset;
-  int i;
+  size_t i;
   int idx;
 
+  /* Handle the case where file_table is empty.  */
+  if (VARRAY_ACTIVE_SIZE (file_table) <= 1)
+    {
+      dw2_asm_output_data (1, 0, "End directory table");
+      dw2_asm_output_data (1, 0, "End file name table");
+      return;
+    }
+
   /* Allocate the various arrays we need.  */
-  files = (struct file_info *) alloca (file_table.in_use
-                                      * sizeof (struct file_info));
-  dirs = (struct dir_info *) alloca (file_table.in_use
-                                    * sizeof (struct dir_info));
+  files = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct file_info));
+  dirs = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct dir_info));
 
   /* Sort the file names.  */
-  for (i = 1; i < (int) file_table.in_use; i++)
+  for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
     {
       char *f;
 
       /* Skip all leading "./".  */
-      f = file_table.table[i];
+      f = VARRAY_CHAR_PTR (file_table, i);
       while (f[0] == '.' && f[1] == '/')
        f += 2;
 
@@ -7305,7 +7104,8 @@ output_file_names ()
       files[i].fname = f == NULL ? files[i].path : f + 1;
     }
 
-  qsort (files + 1, file_table.in_use - 1, sizeof (files[0]), file_info_cmp);
+  qsort (files + 1, VARRAY_ACTIVE_SIZE (file_table) - 1,
+        sizeof (files[0]), file_info_cmp);
 
   /* Find all the different directories used.  */
   dirs[0].path = files[1].path;
@@ -7317,7 +7117,7 @@ output_file_names ()
   files[1].dir_idx = 0;
   ndirs = 1;
 
-  for (i = 2; i < (int) file_table.in_use; i++)
+  for (i = 2; i < VARRAY_ACTIVE_SIZE (file_table); i++)
     if (files[i].fname - files[i].path == dirs[ndirs - 1].length
        && memcmp (dirs[ndirs - 1].path, files[i].path,
                   dirs[ndirs - 1].length) == 0)
@@ -7328,7 +7128,7 @@ output_file_names ()
       }
     else
       {
-       int j;
+       size_t j;
 
        /* This is a new directory.  */
        dirs[ndirs].path = files[i].path;
@@ -7357,13 +7157,13 @@ output_file_names ()
      where we would have to check out every combination of every single
      possible prefix.  Instead we use a heuristic which provides nearly optimal
      results in most cases and never is much off.  */
-  saved = (int *) alloca (ndirs * sizeof (int));
-  savehere = (int *) alloca (ndirs * sizeof (int));
+  saved = alloca (ndirs * sizeof (int));
+  savehere = alloca (ndirs * sizeof (int));
 
   memset (saved, '\0', ndirs * sizeof (saved[0]));
   for (i = 0; i < ndirs; i++)
     {
-      int j;
+      size_t j;
       int total;
 
       /* We can always save some space for the current directory.  But this
@@ -7381,10 +7181,10 @@ output_file_names ()
              int k;
 
              k = dirs[j].prefix;
-             while (k != -1 && k != i)
+             while (k != -1 && k != (int) i)
                k = dirs[k].prefix;
 
-             if (k == i)
+             if (k == (int) i)
                {
                  /* Yes it is.  We can possibly safe some memory but
                     writing the filenames in dirs[j] relative to
@@ -7415,8 +7215,8 @@ output_file_names ()
   /* We have to emit them in the order they appear in the file_table array
      since the index is used in the debug info generation.  To do this
      efficiently we generate a back-mapping of the indices first.  */
-  backmap = (int *) alloca (file_table.in_use * sizeof (int));
-  for (i = 1; i < (int) file_table.in_use; i++)
+  backmap = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (int));
+  for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
     {
       backmap[files[i].file_idx] = i;
 
@@ -7447,13 +7247,13 @@ output_file_names ()
     dirs[0].used = 0;
 
   /* Now write all the file names.  */
-  for (i = 1; i < (int) file_table.in_use; i++)
+  for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
     {
       int file_idx = backmap[i];
       int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
 
       dw2_asm_output_nstring (files[file_idx].path + dirs[dir_idx].length, -1,
-                             "File Entry: 0x%x", i);
+                             "File Entry: 0x%lx", (unsigned long) i);
 
       /* Include directory index.  */
       dw2_asm_output_data_uleb128 (dirs[dir_idx].used, NULL);
@@ -7473,7 +7273,7 @@ output_file_names ()
    information goes into the .debug_line section.  */
 
 static void
-output_line_info ()
+output_line_info (void)
 {
   char l1[20], l2[20], p1[20], p2[20];
   char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -7492,6 +7292,9 @@ output_line_info ()
   ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL, 0);
 
+  if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+    dw2_asm_output_data (4, 0xffffffff,
+      "Initial length escape value indicating 64-bit DWARF extension");
   dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1,
                        "Length of Source Line Info");
   ASM_OUTPUT_LABEL (asm_out_file, l1);
@@ -7563,8 +7366,8 @@ output_line_info ()
         prologue.  */
 
       /* Don't emit anything for redundant notes.  Just updating the
-         address doesn't accomplish anything, because we already assume
-         that anything after the last address is this line.  */
+        address doesn't accomplish anything, because we already assume
+        that anything after the last address is this line.  */
       if (line_info->dw_line_num == current_line
          && line_info->dw_file_num == current_file)
        continue;
@@ -7590,7 +7393,7 @@ output_line_info ()
       else
        {
          /* This can handle any delta.  This takes
-             4+DWARF2_ADDR_SIZE bytes.  */
+            4+DWARF2_ADDR_SIZE bytes.  */
          dw2_asm_output_data (1, 0, "DW_LNE_set_address");
          dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
          dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7606,7 +7409,8 @@ output_line_info ()
          current_file = line_info->dw_file_num;
          dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
          dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
-                                      file_table.table[current_file]);
+                                      VARRAY_CHAR_PTR (file_table,
+                                                       current_file));
        }
 
       /* Emit debug info for the current line number, choosing the encoding
@@ -7681,7 +7485,7 @@ output_line_info ()
        {
          function = line_info->function;
 
-         /* Set the address register to the first line in the function */
+         /* Set the address register to the first line in the function */
          dw2_asm_output_data (1, 0, "DW_LNE_set_address");
          dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
          dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7714,7 +7518,8 @@ output_line_info ()
          current_file = line_info->dw_file_num;
          dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
          dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
-                                      file_table.table[current_file]);
+                                      VARRAY_CHAR_PTR (file_table,
+                                                       current_file));
        }
 
       /* Emit debug info for the current line number, choosing the encoding
@@ -7785,8 +7590,7 @@ output_line_info ()
    Dwarf base (fundamental) types.  */
 
 static dw_die_ref
-base_type_die (type)
-     tree type;
+base_type_die (tree type)
 {
   dw_die_ref base_type_result;
   const char *type_name;
@@ -7810,9 +7614,9 @@ base_type_die (type)
     {
     case INTEGER_TYPE:
       /* Carefully distinguish the C character types, without messing
-         up if the language is not C. Note that we check only for the names
-         that contain spaces; other names might occur by coincidence in other
-         languages.  */
+        up if the language is not C. Note that we check only for the names
+        that contain spaces; other names might occur by coincidence in other
+        languages.  */
       if (! (TYPE_PRECISION (type) == CHAR_TYPE_SIZE
             && (type == char_type_node
                 || ! strcmp (type_name, "signed char")
@@ -7879,8 +7683,7 @@ base_type_die (type)
    root type of the given type without the qualifiers.  */
 
 static tree
-root_type (type)
-     tree type;
+root_type (tree type)
 {
   if (TREE_CODE (type) == ERROR_MARK)
     return error_mark_node;
@@ -7903,8 +7706,7 @@ root_type (type)
    given input type is a Dwarf "fundamental" type.  Otherwise return null.  */
 
 static inline int
-is_base_type (type)
-     tree type;
+is_base_type (tree type)
 {
   switch (TREE_CODE (type))
     {
@@ -7947,10 +7749,8 @@ is_base_type (type)
    ERROR_MARK node.  */
 
 static inline unsigned HOST_WIDE_INT
-simple_type_size_in_bits (type)
-     tree type;
+simple_type_size_in_bits (tree type)
 {
-
   if (TREE_CODE (type) == ERROR_MARK)
     return BITS_PER_WORD;
   else if (TYPE_SIZE (type) == NULL_TREE)
@@ -7961,15 +7761,54 @@ simple_type_size_in_bits (type)
     return TYPE_ALIGN (type);
 }
 
+/* Return true if the debug information for the given type should be
+   emitted as a subrange type.  */
+
+static inline bool
+is_ada_subrange_type (tree type)
+{
+  /* We do this for INTEGER_TYPEs that have names, parent types, and when
+     we are compiling Ada code.  */
+  return (TREE_CODE (type) == INTEGER_TYPE
+         && TYPE_NAME (type) != 0 && TREE_TYPE (type) != 0
+         && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
+         && TREE_UNSIGNED (TREE_TYPE (type)) && is_ada ());
+}
+
+/*  Given a pointer to a tree node for a subrange type, return a pointer
+    to a DIE that describes the given type.  */
+
+static dw_die_ref
+subrange_type_die (tree type)
+{
+  dw_die_ref subtype_die;
+  dw_die_ref subrange_die;
+  tree name = TYPE_NAME (type);
+
+  subtype_die = base_type_die (TREE_TYPE (type));
+
+  if (TREE_CODE (name) == TYPE_DECL)
+    name = DECL_NAME (name);
+
+  subrange_die = new_die (DW_TAG_subrange_type, comp_unit_die, type);
+  add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
+  if (TYPE_MIN_VALUE (type) != NULL)
+    add_bound_info (subrange_die, DW_AT_lower_bound,
+                    TYPE_MIN_VALUE (type));
+  if (TYPE_MAX_VALUE (type) != NULL)
+    add_bound_info (subrange_die, DW_AT_upper_bound,
+                    TYPE_MAX_VALUE (type));
+  add_AT_die_ref (subrange_die, DW_AT_type, subtype_die);
+
+  return subrange_die;
+}
+
 /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
    entry that chains various modifiers in front of the given type.  */
 
 static dw_die_ref
-modified_type_die (type, is_const_type, is_volatile_type, context_die)
-     tree type;
-     int is_const_type;
-     int is_volatile_type;
-     dw_die_ref context_die;
+modified_type_die (tree type, int is_const_type, int is_volatile_type,
+                  dw_die_ref context_die)
 {
   enum tree_code code = TREE_CODE (type);
   dw_die_ref mod_type_die = NULL;
@@ -8055,6 +7894,8 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
 #endif
          item_type = TREE_TYPE (type);
        }
+      else if (is_ada_subrange_type (type))
+        mod_type_die = subrange_type_die (type);
       else if (is_base_type (type))
        mod_type_die = base_type_die (type);
       else
@@ -8103,8 +7944,7 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
    an enumerated type.  */
 
 static inline int
-type_is_enum (type)
-     tree type;
+type_is_enum (tree type)
 {
   return TREE_CODE (type) == ENUMERAL_TYPE;
 }
@@ -8112,8 +7952,7 @@ type_is_enum (type)
 /* Return the register number described by a given RTL node.  */
 
 static unsigned int
-reg_number (rtl)
-     rtx rtl;
+reg_number (rtx rtl)
 {
   unsigned regno = REGNO (rtl);
 
@@ -8124,32 +7963,94 @@ reg_number (rtl)
 }
 
 /* Return a location descriptor that designates a machine register or
-   zero if there is no such.  */
+   zero if there is none.  */
 
 static dw_loc_descr_ref
-reg_loc_descriptor (rtl)
-     rtx rtl;
+reg_loc_descriptor (rtx rtl)
 {
-  dw_loc_descr_ref loc_result = NULL;
   unsigned reg;
+  rtx regs;
 
   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);
+  regs = (*targetm.dwarf_register_span) (rtl);
+
+  if (HARD_REGNO_NREGS (reg, GET_MODE (rtl)) > 1
+      || regs)
+    return multiple_reg_loc_descriptor (rtl, regs);
   else
-    loc_result = new_loc_descr (DW_OP_regx, reg, 0);
+    return one_reg_loc_descriptor (reg);
+}
 
+/* Return a location descriptor that designates a machine register for
+   a given hard register number.  */
+
+static dw_loc_descr_ref
+one_reg_loc_descriptor (unsigned int regno)
+{
+  if (regno <= 31)
+    return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
+  else
+    return new_loc_descr (DW_OP_regx, regno, 0);
+}
+
+/* Given an RTL of a register, return a location descriptor that
+   designates a value that spans more than one register.  */
+
+static dw_loc_descr_ref
+multiple_reg_loc_descriptor (rtx rtl, rtx regs)
+{
+  int nregs, size, i;
+  unsigned reg;
+  dw_loc_descr_ref loc_result = NULL;
+
+  reg = reg_number (rtl);
+  nregs = HARD_REGNO_NREGS (reg, GET_MODE (rtl));
+
+  /* Simple, contiguous registers.  */
+  if (regs == NULL_RTX)
+    {
+      size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+
+      loc_result = NULL;
+      while (nregs--)
+       {
+         dw_loc_descr_ref t;
+
+         t = one_reg_loc_descriptor (reg);
+         add_loc_descr (&loc_result, t);
+         add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+         ++reg;
+       }
+      return loc_result;
+    }
+
+  /* Now onto stupid register sets in non contiguous locations.  */
+
+  if (GET_CODE (regs) != PARALLEL)
+    abort ();
+
+  size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+  loc_result = NULL;
+
+  for (i = 0; i < XVECLEN (regs, 0); ++i)
+    {
+      dw_loc_descr_ref t;
+
+      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+      add_loc_descr (&loc_result, t);
+      size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+      add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+    }
   return loc_result;
 }
 
 /* Return a location descriptor that designates a constant.  */
 
 static dw_loc_descr_ref
-int_loc_descriptor (i)
-     HOST_WIDE_INT i;
+int_loc_descriptor (HOST_WIDE_INT i)
 {
   enum dwarf_location_atom op;
 
@@ -8188,9 +8089,7 @@ int_loc_descriptor (i)
 /* Return a location descriptor that designates a base+offset location.  */
 
 static dw_loc_descr_ref
-based_loc_descr (reg, offset)
-     unsigned reg;
-     long int offset;
+based_loc_descr (unsigned int reg, long int offset)
 {
   dw_loc_descr_ref loc_result;
   /* For the "frame base", we use the frame pointer or stack pointer
@@ -8213,8 +8112,7 @@ based_loc_descr (reg, offset)
 /* Return true if this RTL expression describes a base+offset calculation.  */
 
 static inline int
-is_based_loc (rtl)
-     rtx rtl;
+is_based_loc (rtx rtl)
 {
   return (GET_CODE (rtl) == PLUS
          && ((GET_CODE (XEXP (rtl, 0)) == REG
@@ -8238,9 +8136,7 @@ is_based_loc (rtl)
    Return 0 if we can't represent the location.  */
 
 static dw_loc_descr_ref
-mem_loc_descriptor (rtl, mode)
-     rtx rtl;
-     enum machine_mode mode;
+mem_loc_descriptor (rtx rtl, enum machine_mode mode)
 {
   dw_loc_descr_ref mem_loc_result = NULL;
 
@@ -8249,9 +8145,7 @@ mem_loc_descriptor (rtl, mode)
      actually within the array.  That's *not* necessarily the same as the
      zeroth element of the array.  */
 
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
-  rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+  rtl = (*targetm.delegitimize_address) (rtl);
 
   switch (GET_CODE (rtl))
     {
@@ -8265,28 +8159,28 @@ mem_loc_descriptor (rtl, mode)
 
     case SUBREG:
       /* The case of a subreg may arise when we have a local (register)
-         variable or a formal (register) parameter which doesn't quite fill
-         up an entire register.  For now, just assume that it is
-         legitimate to make the Dwarf info refer to the whole register which
-         contains the given subreg.  */
+        variable or a formal (register) parameter which doesn't quite fill
+        up an entire register.  For now, just assume that it is
+        legitimate to make the Dwarf info refer to the whole register which
+        contains the given subreg.  */
       rtl = SUBREG_REG (rtl);
 
       /* ... fall through ...  */
 
     case REG:
       /* Whenever a register number forms a part of the description of the
-         method for calculating the (dynamic) address of a memory resident
-         object, DWARF rules require the register number be referred to as
-         a "base register".  This distinction is not based in any way upon
-         what category of register the hardware believes the given register
-         belongs to.  This is strictly DWARF terminology we're dealing with
-         here. Note that in cases where the location of a memory-resident
-         data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
-         OP_CONST (0)) the actual DWARF location descriptor that we generate
-         may just be OP_BASEREG (basereg).  This may look deceptively like
-         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.  */
+        method for calculating the (dynamic) address of a memory resident
+        object, DWARF rules require the register number be referred to as
+        a "base register".  This distinction is not based in any way upon
+        what category of register the hardware believes the given register
+        belongs to.  This is strictly DWARF terminology we're dealing with
+        here. Note that in cases where the location of a memory-resident
+        data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
+        OP_CONST (0)) the actual DWARF location descriptor that we generate
+        may just be OP_BASEREG (basereg).  This may look deceptively like
+        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.  */
       if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
        mem_loc_result = based_loc_descr (reg_number (rtl), 0);
       break;
@@ -8297,10 +8191,15 @@ mem_loc_descriptor (rtl, mode)
        add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
       break;
 
+    case LO_SUM:
+        rtl = XEXP (rtl, 1);
+
+      /* ... fall through ...  */
+
     case LABEL_REF:
       /* Some ports can transform a symbol ref into a label ref, because
-        the symbol ref is too far away and has to be dumped into a constant
-        pool.  */
+        the symbol ref is too far away and has to be dumped into a constant
+        pool.  */
     case CONST:
     case SYMBOL_REF:
       /* Alternatively, the symbol in the constant pool might be referenced
@@ -8335,7 +8234,7 @@ mem_loc_descriptor (rtl, mode)
 
     case PRE_MODIFY:
       /* Extract the PLUS expression nested inside and fall into
-         PLUS code below.  */
+        PLUS code below.  */
       rtl = XEXP (rtl, 1);
       goto plus;
 
@@ -8415,8 +8314,7 @@ mem_loc_descriptor (rtl, mode)
    This is typically a complex variable.  */
 
 static dw_loc_descr_ref
-concat_loc_descriptor (x0, x1)
-     rtx x0, x1;
+concat_loc_descriptor (rtx x0, rtx x1)
 {
   dw_loc_descr_ref cc_loc_result = NULL;
   dw_loc_descr_ref x0_ref = loc_descriptor (x0);
@@ -8447,8 +8345,7 @@ concat_loc_descriptor (x0, x1)
    If we don't know how to describe it, return 0.  */
 
 static dw_loc_descr_ref
-loc_descriptor (rtl)
-     rtx rtl;
+loc_descriptor (rtx rtl)
 {
   dw_loc_descr_ref loc_result = NULL;
 
@@ -8456,10 +8353,10 @@ loc_descriptor (rtl)
     {
     case SUBREG:
       /* The case of a subreg may arise when we have a local (register)
-         variable or a formal (register) parameter which doesn't quite fill
-         up an entire register.  For now, just assume that it is
-         legitimate to make the Dwarf info refer to the whole register which
-         contains the given subreg.  */
+        variable or a formal (register) parameter which doesn't quite fill
+        up an entire register.  For now, just assume that it is
+        legitimate to make the Dwarf info refer to the whole register which
+        contains the given subreg.  */
       rtl = SUBREG_REG (rtl);
 
       /* ... fall through ...  */
@@ -8489,9 +8386,7 @@ loc_descriptor (rtl)
    descriptor, return 0.  */
 
 static dw_loc_descr_ref
-loc_descriptor_from_tree (loc, addressp)
-     tree loc;
-     int addressp;
+loc_descriptor_from_tree (tree loc, int addressp)
 {
   dw_loc_descr_ref ret, ret1;
   int indirect_p = 0;
@@ -8611,6 +8506,7 @@ loc_descriptor_from_tree (loc, addressp)
     case NON_LVALUE_EXPR:
     case VIEW_CONVERT_EXPR:
     case SAVE_EXPR:
+    case MODIFY_EXPR:
       return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
 
     case COMPONENT_REF:
@@ -8662,6 +8558,24 @@ loc_descriptor_from_tree (loc, addressp)
        return 0;
       break;
 
+    case CONSTRUCTOR:
+      {
+       /* Get an RTL for this, if something has been emitted.  */
+       rtx rtl = lookup_constant_def (loc);
+       enum machine_mode mode;
+
+       if (GET_CODE (rtl) != MEM)
+         return 0;
+       mode = GET_MODE (rtl);
+       rtl = XEXP (rtl, 0);
+
+       rtl = (*targetm.delegitimize_address) (rtl);
+
+       indirect_p = 1;
+       ret = mem_loc_descriptor (rtl, mode);
+       break;
+      }
+
     case TRUTH_AND_EXPR:
     case TRUTH_ANDIF_EXPR:
     case BIT_AND_EXPR:
@@ -8679,6 +8593,9 @@ loc_descriptor_from_tree (loc, addressp)
       op = DW_OP_or;
       goto do_binop;
 
+    case FLOOR_DIV_EXPR:
+    case CEIL_DIV_EXPR:
+    case ROUND_DIV_EXPR:
     case TRUNC_DIV_EXPR:
       op = DW_OP_div;
       goto do_binop;
@@ -8687,6 +8604,9 @@ loc_descriptor_from_tree (loc, addressp)
       op = DW_OP_minus;
       goto do_binop;
 
+    case FLOOR_MOD_EXPR:
+    case CEIL_MOD_EXPR:
+    case ROUND_MOD_EXPR:
     case TRUNC_MOD_EXPR:
       op = DW_OP_mod;
       goto do_binop;
@@ -8829,6 +8749,14 @@ loc_descriptor_from_tree (loc, addressp)
       break;
 
     default:
+      /* Leave front-end specific codes as simply unknown.  This comes
+        up, for instance, with the C STMT_EXPR.  */
+      if ((unsigned int) TREE_CODE (loc)
+          >= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
+       return 0;
+
+      /* Otherwise this is a generic code; we should just lists all of
+        these explicitly.  Aborting means we forgot one.  */
       abort ();
     }
 
@@ -8858,9 +8786,7 @@ loc_descriptor_from_tree (loc, addressp)
    which is not less than the value itself.  */
 
 static inline HOST_WIDE_INT
-ceiling (value, boundary)
-     HOST_WIDE_INT value;
-     unsigned int boundary;
+ceiling (HOST_WIDE_INT value, unsigned int boundary)
 {
   return (((value + boundary - 1) / boundary) * boundary);
 }
@@ -8871,8 +8797,7 @@ ceiling (value, boundary)
    ERROR_MARK node.  */
 
 static inline tree
-field_type (decl)
-     tree decl;
+field_type (tree decl)
 {
   tree type;
 
@@ -8891,15 +8816,13 @@ field_type (decl)
    be an ERROR_MARK node.  */
 
 static inline unsigned
-simple_type_align_in_bits (type)
-     tree type;
+simple_type_align_in_bits (tree type)
 {
   return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
 }
 
 static inline unsigned
-simple_decl_align_in_bits (decl)
-     tree decl;
+simple_decl_align_in_bits (tree decl)
 {
   return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
 }
@@ -8912,8 +8835,7 @@ simple_decl_align_in_bits (decl)
    just yet).  */
 
 static HOST_WIDE_INT
-field_byte_offset (decl)
-     tree decl;
+field_byte_offset (tree decl)
 {
   unsigned int type_align_in_bits;
   unsigned int decl_align_in_bits;
@@ -9032,10 +8954,8 @@ field_byte_offset (decl)
    generated by the routine `data_member_location_attribute' below.  */
 
 static inline void
-add_AT_location_description (die, attr_kind, descr)
-     dw_die_ref die;
-     enum dwarf_attribute attr_kind;
-     dw_loc_descr_ref descr;
+add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
+                            dw_loc_descr_ref descr)
 {
   if (descr != 0)
     add_AT_loc (die, attr_kind, descr);
@@ -9061,9 +8981,7 @@ add_AT_location_description (die, attr_kind, descr)
    function below.)  */
 
 static void
-add_data_member_location_attribute (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_data_member_location_attribute (dw_die_ref die, tree decl)
 {
   long offset;
   dw_loc_descr_ref loc_descr = 0;
@@ -9139,16 +9057,14 @@ add_data_member_location_attribute (die, decl)
   add_AT_loc (die, DW_AT_data_member_location, loc_descr);
 }
 
-/* Attach an DW_AT_const_value attribute for a variable or a parameter which
+/* Attach a DW_AT_const_value attribute for a variable or a parameter which
    does not have a "location" either in memory or in a register.  These
    things can arise in GNU C when a constant is passed as an actual parameter
    to an inlined function.  They can also arise in C++ where declared
    constants do not necessarily get memory "homes".  */
 
 static void
-add_const_value_attribute (die, rtl)
-     dw_die_ref die;
-     rtx rtl;
+add_const_value_attribute (dw_die_ref die, rtx rtl)
 {
   switch (GET_CODE (rtl))
     {
@@ -9180,16 +9096,16 @@ add_const_value_attribute (die, rtl)
 
     case CONST_DOUBLE:
       /* Note that a CONST_DOUBLE rtx could represent either an integer or a
-         floating-point constant.  A CONST_DOUBLE is used whenever the
-         constant requires more than one word in order to be adequately
-         represented.  We output CONST_DOUBLEs as blocks.  */
+        floating-point constant.  A CONST_DOUBLE is used whenever the
+        constant requires more than one word in order to be adequately
+        represented.  We output CONST_DOUBLEs as blocks.  */
       {
        enum machine_mode mode = GET_MODE (rtl);
 
        if (GET_MODE_CLASS (mode) == MODE_FLOAT)
          {
            unsigned length = GET_MODE_SIZE (mode) / 4;
-           long *array = (long *) ggc_alloc (sizeof (long) * length);
+           long *array = ggc_alloc (sizeof (long) * length);
            REAL_VALUE_TYPE rv;
 
            REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
@@ -9239,16 +9155,16 @@ add_const_value_attribute (die, rtl)
 
     case PLUS:
       /* In cases where an inlined instance of an inline function is passed
-         the address of an `auto' variable (which is local to the caller) we
-         can get a situation where the DECL_RTL of the artificial local
-         variable (for the inlining) which acts as a stand-in for the
-         corresponding formal parameter (of the inline function) will look
-         like (plus:SI (reg:SI FRAME_PTR) (const_int ...)).  This is not
-         exactly a compile-time constant expression, but it isn't the address
-         of the (artificial) local variable either.  Rather, it represents the
-         *value* which the artificial local variable always has during its
-         lifetime.  We currently have no way to represent such quasi-constant
-         values in Dwarf, so for now we just punt and generate nothing.  */
+        the address of an `auto' variable (which is local to the caller) we
+        can get a situation where the DECL_RTL of the artificial local
+        variable (for the inlining) which acts as a stand-in for the
+        corresponding formal parameter (of the inline function) will look
+        like (plus:SI (reg:SI FRAME_PTR) (const_int ...)).  This is not
+        exactly a compile-time constant expression, but it isn't the address
+        of the (artificial) local variable either.  Rather, it represents the
+        *value* which the artificial local variable always has during its
+        lifetime.  We currently have no way to represent such quasi-constant
+        values in Dwarf, so for now we just punt and generate nothing.  */
       break;
 
     default:
@@ -9259,8 +9175,7 @@ add_const_value_attribute (die, rtl)
 }
 
 static rtx
-rtl_for_decl_location (decl)
-     tree decl;
+rtl_for_decl_location (tree decl)
 {
   rtx rtl;
 
@@ -9341,17 +9256,19 @@ rtl_for_decl_location (decl)
   rtl = DECL_RTL_IF_SET (decl);
 
   /* When generating abstract instances, ignore everything except
-     constants and symbols living in memory.  */
+     constants, symbols living in memory, and symbols living in
+     fixed registers.  */
   if (! reload_completed)
     {
       if (rtl
          && (CONSTANT_P (rtl)
              || (GET_CODE (rtl) == MEM
-                 && CONSTANT_P (XEXP (rtl, 0)))))
+                 && CONSTANT_P (XEXP (rtl, 0)))
+             || (GET_CODE (rtl) == REG
+                 && TREE_CODE (decl) == VAR_DECL
+                 && TREE_STATIC (decl))))
        {
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
-         rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+         rtl = (*targetm.delegitimize_address) (rtl);
          return rtl;
        }
       rtl = NULL_RTX;
@@ -9457,10 +9374,8 @@ rtl_for_decl_location (decl)
        }
     }
 
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
   if (rtl)
-    rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+    rtl = (*targetm.delegitimize_address) (rtl);
 
   /* If we don't look past the constant pool, we risk emitting a
      reference to a constant pool entry that isn't referenced from
@@ -9471,7 +9386,7 @@ rtl_for_decl_location (decl)
   return rtl;
 }
 
-/* Generate *either* an DW_AT_location attribute or else an DW_AT_const_value
+/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
    data attribute for a variable or a parameter.  We generate the
    DW_AT_const_value attribute only in those cases where the given variable
    or parameter does not have a true "location" either in memory or in a
@@ -9483,9 +9398,7 @@ rtl_for_decl_location (decl)
    function call evaluates to a compile-time constant address.  */
 
 static void
-add_location_or_const_value_attribute (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_location_or_const_value_attribute (dw_die_ref die, tree decl)
 {
   rtx rtl;
   dw_loc_descr_ref descr;
@@ -9535,7 +9448,7 @@ add_location_or_const_value_attribute (die, decl)
        }
       add_AT_location_description (die, DW_AT_location, descr);
       break;
-       
+
     default:
       abort ();
     }
@@ -9546,9 +9459,7 @@ add_location_or_const_value_attribute (die, decl)
    we should tell the debugger about the constant value.  */
 
 static void
-tree_add_const_value_attribute (var_die, decl)
-     dw_die_ref var_die;
-     tree decl;
+tree_add_const_value_attribute (dw_die_ref var_die, tree decl)
 {
   tree init = DECL_INITIAL (decl);
   tree type = TREE_TYPE (decl);
@@ -9575,13 +9486,11 @@ tree_add_const_value_attribute (var_die, decl)
     }
 }
 
-/* Generate an DW_AT_name attribute given some string value to be included as
+/* Generate a DW_AT_name attribute given some string value to be included as
    the value of the attribute.  */
 
-static inline void
-add_name_attribute (die, name_string)
-     dw_die_ref die;
-     const char *name_string;
+static void
+add_name_attribute (dw_die_ref die, const char *name_string)
 {
   if (name_string != NULL && *name_string != 0)
     {
@@ -9592,14 +9501,21 @@ add_name_attribute (die, name_string)
     }
 }
 
+/* Generate a DW_AT_comp_dir attribute for DIE.  */
+
+static void
+add_comp_dir_attribute (dw_die_ref die)
+{
+  const char *wd = get_src_pwd ();
+  if (wd != NULL)
+    add_AT_string (die, DW_AT_comp_dir, wd);
+}
+
 /* Given a tree node describing an array bound (either lower or upper) output
    a representation for that bound.  */
 
 static void
-add_bound_info (subrange_die, bound_attr, bound)
-     dw_die_ref subrange_die;
-     enum dwarf_attribute bound_attr;
-     tree bound;
+add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree bound)
 {
   switch (TREE_CODE (bound))
     {
@@ -9627,23 +9543,23 @@ add_bound_info (subrange_die, bound_attr, bound)
 
     case SAVE_EXPR:
       /* If optimization is turned on, the SAVE_EXPRs that describe how to
-         access the upper bound values may be bogus.  If they refer to a
-         register, they may only describe how to get at these values at the
-         points in the generated code right after they have just been
-         computed.  Worse yet, in the typical case, the upper bound values
-         will not even *be* computed in the optimized code (though the
-         number of elements will), so these SAVE_EXPRs are entirely
-         bogus. In order to compensate for this fact, we check here to see
-         if optimization is enabled, and if so, we don't add an attribute
-         for the (unknown and unknowable) upper bound.  This should not
-         cause too much trouble for existing (stupid?)  debuggers because
-         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 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.
+        access the upper bound values may be bogus.  If they refer to a
+        register, they may only describe how to get at these values at the
+        points in the generated code right after they have just been
+        computed.  Worse yet, in the typical case, the upper bound values
+        will not even *be* computed in the optimized code (though the
+        number of elements will), so these SAVE_EXPRs are entirely
+        bogus. In order to compensate for this fact, we check here to see
+        if optimization is enabled, and if so, we don't add an attribute
+        for the (unknown and unknowable) upper bound.  This should not
+        cause too much trouble for existing (stupid?)  debuggers because
+        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 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.
 
         We assume that a MEM rtx is safe because gcc wouldn't put the
         value there unless it was going to be used repeatedly in the
@@ -9731,9 +9647,7 @@ add_bound_info (subrange_die, bound_attr, bound)
    includes information about the element type of type given array type.  */
 
 static void
-add_subscript_info (type_die, type)
-     dw_die_ref type_die;
-     tree type;
+add_subscript_info (dw_die_ref type_die, tree type)
 {
 #ifndef MIPS_DEBUGGING_INFO
   unsigned dimension_number;
@@ -9764,7 +9678,7 @@ add_subscript_info (type_die, type)
 
       /* Arrays come in three flavors: Unspecified bounds, fixed bounds,
         and (in GNU C only) variable bounds.  Handle all three forms
-         here.  */
+        here.  */
       subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL);
       if (domain)
        {
@@ -9772,7 +9686,7 @@ add_subscript_info (type_die, type)
          lower = TYPE_MIN_VALUE (domain);
          upper = TYPE_MAX_VALUE (domain);
 
-         /* define the index type.  */
+         /* Define the index type.  */
          if (TREE_TYPE (domain))
            {
              /* ??? This is probably an Ada unnamed subrange type.  Ignore the
@@ -9791,7 +9705,7 @@ add_subscript_info (type_die, type)
          /* ??? If upper is NULL, the array has unspecified length,
             but it does have a lower bound.  This happens with Fortran
               dimension arr(N:*)
-                    Since the debugger is definitely going to need to know N
+            Since the debugger is definitely going to need to know N
             to produce useful results, go ahead and output the lower
             bound solo, and hope the debugger can cope.  */
 
@@ -9807,9 +9721,7 @@ add_subscript_info (type_die, type)
 }
 
 static void
-add_byte_size_attribute (die, tree_node)
-     dw_die_ref die;
-     tree tree_node;
+add_byte_size_attribute (dw_die_ref die, tree tree_node)
 {
   unsigned size;
 
@@ -9826,9 +9738,9 @@ add_byte_size_attribute (die, tree_node)
       break;
     case FIELD_DECL:
       /* For a data member of a struct or union, the DW_AT_byte_size is
-         generally given as the number of bytes normally allocated for an
-         object of the *declared* type of the member itself.  This is true
-         even for bit-fields.  */
+        generally given as the number of bytes normally allocated for an
+        object of the *declared* type of the member itself.  This is true
+        even for bit-fields.  */
       size = simple_type_size_in_bits (field_type (tree_node)) / BITS_PER_UNIT;
       break;
     default:
@@ -9859,9 +9771,7 @@ add_byte_size_attribute (die, tree_node)
    (See `byte_size_attribute' above).  */
 
 static inline void
-add_bit_offset_attribute (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_bit_offset_attribute (dw_die_ref die, tree decl)
 {
   HOST_WIDE_INT object_offset_in_bytes = field_byte_offset (decl);
   tree type = DECL_BIT_FIELD_TYPE (decl);
@@ -9910,9 +9820,7 @@ add_bit_offset_attribute (die, decl)
    which specifies the length in bits of the given field.  */
 
 static inline void
-add_bit_size_attribute (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_bit_size_attribute (dw_die_ref die, tree decl)
 {
   /* Must be a field and a bit field.  */
   if (TREE_CODE (decl) != FIELD_DECL
@@ -9927,9 +9835,7 @@ add_bit_size_attribute (die, decl)
    attribute, if arg types are given for the parameters of a function.  */
 
 static inline void
-add_prototyped_attribute (die, func_type)
-     dw_die_ref die;
-     tree func_type;
+add_prototyped_attribute (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)
@@ -9941,9 +9847,7 @@ add_prototyped_attribute (die, func_type)
    equate table.  */
 
 static inline void
-add_abstract_origin_attribute (die, origin)
-     dw_die_ref die;
-     tree origin;
+add_abstract_origin_attribute (dw_die_ref die, tree origin)
 {
   dw_die_ref origin_die = NULL;
 
@@ -9953,7 +9857,7 @@ add_abstract_origin_attribute (die, origin)
         function, if we're in an exception handler or some such; make
         sure that the abstract function has been written out.
 
-         Doing this for nested functions is wrong, however; functions are
+        Doing this for nested functions is wrong, however; functions are
         distinct units, and our context might not even be inline.  */
       tree fn = origin;
 
@@ -9979,9 +9883,7 @@ add_abstract_origin_attribute (die, origin)
 /* We do not currently support the pure_virtual attribute.  */
 
 static inline void
-add_pure_or_virtual_attribute (die, func_decl)
-     dw_die_ref die;
-     tree func_decl;
+add_pure_or_virtual_attribute (dw_die_ref die, tree func_decl)
 {
   if (DECL_VINDEX (func_decl))
     {
@@ -10003,9 +9905,7 @@ add_pure_or_virtual_attribute (die, func_decl)
 /* Add source coordinate attributes for the given decl.  */
 
 static void
-add_src_coords_attributes (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_src_coords_attributes (dw_die_ref die, tree decl)
 {
   unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
 
@@ -10013,13 +9913,11 @@ add_src_coords_attributes (die, decl)
   add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
 }
 
-/* Add an DW_AT_name attribute and source coordinate attribute for the
+/* Add a DW_AT_name attribute and source coordinate attribute for the
    given decl, but only if it actually has a name.  */
 
 static void
-add_name_and_src_coords_attributes (die, decl)
-     dw_die_ref die;
-     tree decl;
+add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
 {
   tree decl_name;
 
@@ -10053,8 +9951,7 @@ add_name_and_src_coords_attributes (die, decl)
 /* Push a new declaration scope.  */
 
 static void
-push_decl_scope (scope)
-     tree scope;
+push_decl_scope (tree scope)
 {
   VARRAY_PUSH_TREE (decl_scope_table, scope);
 }
@@ -10062,7 +9959,7 @@ push_decl_scope (scope)
 /* Pop a declaration scope.  */
 
 static inline void
-pop_decl_scope ()
+pop_decl_scope (void)
 {
   if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0)
     abort ();
@@ -10077,9 +9974,7 @@ pop_decl_scope ()
    the current active scope.  */
 
 static dw_die_ref
-scope_die_for (t, context_die)
-     tree t;
-     dw_die_ref context_die;
+scope_die_for (tree t, dw_die_ref context_die)
 {
   dw_die_ref scope_die = NULL;
   tree containing_scope;
@@ -10133,8 +10028,7 @@ scope_die_for (t, context_die)
 /* Returns nonzero if CONTEXT_DIE is internal to a function.  */
 
 static inline int
-local_scope_p (context_die)
-     dw_die_ref context_die;
+local_scope_p (dw_die_ref context_die)
 {
   for (; context_die; context_die = context_die->die_parent)
     if (context_die->die_tag == DW_TAG_inlined_subroutine
@@ -10147,8 +10041,7 @@ local_scope_p (context_die)
 /* Returns nonzero if CONTEXT_DIE is a class.  */
 
 static inline int
-class_scope_p (context_die)
-     dw_die_ref context_die;
+class_scope_p (dw_die_ref context_die)
 {
   return (context_die
          && (context_die->die_tag == DW_TAG_structure_type
@@ -10157,15 +10050,11 @@ class_scope_p (context_die)
 
 /* Many forms of DIEs require a "type description" attribute.  This
    routine locates the proper "type descriptor" die for the type given
-   by 'type', and adds an DW_AT_type attribute below the given die.  */
+   by 'type', and adds a DW_AT_type attribute below the given die.  */
 
 static void
-add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
-     dw_die_ref object_die;
-     tree type;
-     int decl_const;
-     int decl_volatile;
-     dw_die_ref context_die;
+add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
+                   int decl_volatile, dw_die_ref context_die)
 {
   enum tree_code code  = TREE_CODE (type);
   dw_die_ref type_die  = NULL;
@@ -10199,8 +10088,7 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
    was declared without a tag.  */
 
 static const char *
-type_tag (type)
-     tree type;
+type_tag (tree type)
 {
   const char *name = 0;
 
@@ -10213,8 +10101,8 @@ type_tag (type)
        t = TYPE_NAME (type);
 
       /* The g++ front end makes the TYPE_NAME of *each* tagged type point to
-         a TYPE_DECL node, regardless of whether or not a `typedef' was
-         involved.  */
+        a TYPE_DECL node, regardless of whether or not a `typedef' was
+        involved.  */
       else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
               && ! DECL_IGNORED_P (TYPE_NAME (type)))
        t = DECL_NAME (TYPE_NAME (type));
@@ -10231,8 +10119,7 @@ type_tag (type)
    for bit field types.  */
 
 static inline tree
-member_declared_type (member)
-     tree member;
+member_declared_type (tree member)
 {
   return (DECL_BIT_FIELD_TYPE (member)
          ? DECL_BIT_FIELD_TYPE (member) : TREE_TYPE (member));
@@ -10243,8 +10130,7 @@ member_declared_type (member)
 
 #if 0
 static const char *
-decl_start_label (decl)
-     tree decl;
+decl_start_label (tree decl)
 {
   rtx x;
   const char *fnname;
@@ -10267,9 +10153,7 @@ decl_start_label (decl)
    the declaration trees passed in from dwarf2out_decl().  */
 
 static void
-gen_array_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_array_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref scope_die = scope_die_for (type, context_die);
   dw_die_ref array_die;
@@ -10332,9 +10216,7 @@ gen_array_type_die (type, context_die)
 }
 
 static void
-gen_set_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_set_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die
     = new_die (DW_TAG_set_type, scope_die_for (type, context_die), type);
@@ -10345,9 +10227,7 @@ gen_set_type_die (type, context_die)
 
 #if 0
 static void
-gen_entry_point_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_entry_point_die (tree decl, dw_die_ref context_die)
 {
   tree origin = decl_ultimate_origin (decl);
   dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl);
@@ -10372,7 +10252,7 @@ gen_entry_point_die (decl, context_die)
    emit full debugging info for them.  */
 
 static void
-retry_incomplete_types ()
+retry_incomplete_types (void)
 {
   int i;
 
@@ -10383,9 +10263,7 @@ retry_incomplete_types ()
 /* Generate a DIE to represent an inlined instance of an enumeration type.  */
 
 static void
-gen_inlined_enumeration_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_inlined_enumeration_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die, type);
 
@@ -10397,9 +10275,7 @@ gen_inlined_enumeration_type_die (type, context_die)
 /* Generate a DIE to represent an inlined instance of a structure type.  */
 
 static void
-gen_inlined_structure_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_inlined_structure_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die, type);
 
@@ -10411,9 +10287,7 @@ gen_inlined_structure_type_die (type, context_die)
 /* Generate a DIE to represent an inlined instance of a union type.  */
 
 static void
-gen_inlined_union_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_inlined_union_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = new_die (DW_TAG_union_type, context_die, type);
 
@@ -10428,9 +10302,7 @@ gen_inlined_union_type_die (type, context_die)
    DIE.  */
 
 static void
-gen_enumeration_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_enumeration_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = lookup_type_die (type);
 
@@ -10471,14 +10343,15 @@ gen_enumeration_type_die (type, context_die)
          add_name_attribute (enum_die,
                              IDENTIFIER_POINTER (TREE_PURPOSE (link)));
 
-         if (host_integerp (TREE_VALUE (link), 0))
+         if (host_integerp (TREE_VALUE (link), 
+                            TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (link)))))
            {
              if (tree_int_cst_sgn (TREE_VALUE (link)) < 0)
                add_AT_int (enum_die, DW_AT_const_value,
                            tree_low_cst (TREE_VALUE (link), 0));
              else
                add_AT_unsigned (enum_die, DW_AT_const_value,
-                                tree_low_cst (TREE_VALUE (link), 0));
+                                tree_low_cst (TREE_VALUE (link), 1));
            }
        }
     }
@@ -10500,9 +10373,7 @@ gen_enumeration_type_die (type, context_die)
    argument type of some subprogram type.  */
 
 static dw_die_ref
-gen_formal_parameter_die (node, context_die)
-     tree node;
-     dw_die_ref context_die;
+gen_formal_parameter_die (tree node, dw_die_ref context_die)
 {
   dw_die_ref parm_die
     = new_die (DW_TAG_formal_parameter, context_die, node);
@@ -10547,9 +10418,7 @@ gen_formal_parameter_die (node, context_die)
    at the end of an (ANSI prototyped) formal parameters list.  */
 
 static void
-gen_unspecified_parameters_die (decl_or_type, context_die)
-     tree decl_or_type;
-     dw_die_ref context_die;
+gen_unspecified_parameters_die (tree decl_or_type, dw_die_ref context_die)
 {
   new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type);
 }
@@ -10560,9 +10429,7 @@ gen_unspecified_parameters_die (decl_or_type, context_die)
    those which appear as part of a function *definition*).  */
 
 static void
-gen_formal_types_die (function_or_method_type, context_die)
-     tree function_or_method_type;
-     dw_die_ref context_die;
+gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
 {
   tree link;
   tree formal_type = NULL;
@@ -10621,9 +10488,7 @@ gen_formal_types_die (function_or_method_type, context_die)
    trick; we need to attach the member declaration by hand.  */
 
 static void
-gen_type_die_for_member (type, member, context_die)
-     tree type, member;
-     dw_die_ref context_die;
+gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
 {
   gen_type_die (type, context_die);
 
@@ -10649,8 +10514,7 @@ gen_type_die_for_member (type, member, context_die)
    may later generate inlined and/or out-of-line instances of.  */
 
 static void
-dwarf2out_abstract_function (decl)
-     tree decl;
+dwarf2out_abstract_function (tree decl)
 {
   dw_die_ref old_die;
   tree save_fn;
@@ -10691,9 +10555,7 @@ dwarf2out_abstract_function (decl)
    block-local).  */
 
 static void
-gen_subprogram_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_subprogram_die (tree decl, dw_die_ref context_die)
 {
   char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
   tree origin = decl_ultimate_origin (decl);
@@ -10862,8 +10724,8 @@ gen_subprogram_die (decl, context_die)
 #endif
 
       /* Define the "frame base" location for this routine.  We use the
-         frame pointer or stack pointer registers, since the RTL for local
-         variables is relative to one of them.  */
+        frame pointer or stack pointer registers, since the RTL for local
+        variables is relative to one of them.  */
       fp_reg
        = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
       add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
@@ -10896,12 +10758,12 @@ gen_subprogram_die (decl, context_die)
     gen_formal_types_die (decl, subr_die);
   else
     {
-      /* Generate DIEs to represent all known formal parameters */
+      /* Generate DIEs to represent all known formal parameters */
       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" */
+        instead if we come across the arg "__builtin_va_alist" */
       for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
        if (TREE_CODE (parm) == PARM_DECL)
          {
@@ -10914,15 +10776,15 @@ gen_subprogram_die (decl, context_die)
          }
 
       /* 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
-         definition).  This just means that we have no info about the
-         parameters at all.  */
+        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
+        definition).  This just means that we have no info about the
+        parameters at all.  */
       fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
       if (fn_arg_types != NULL)
        {
-         /* this is the prototyped case, check for ...  */
+         /* This is the prototyped case, check for....  */
          if (TREE_VALUE (tree_last (fn_arg_types)) != void_type_node)
            gen_unspecified_parameters_die (decl, subr_die);
        }
@@ -10970,9 +10832,7 @@ gen_subprogram_die (decl, context_die)
 /* Generate a DIE to represent a declared data object.  */
 
 static void
-gen_variable_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_variable_die (tree decl, dw_die_ref context_die)
 {
   tree origin = decl_ultimate_origin (decl);
   dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl);
@@ -11047,9 +10907,7 @@ gen_variable_die (decl, context_die)
 /* Generate a DIE to represent a label identifier.  */
 
 static void
-gen_label_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_label_die (tree decl, dw_die_ref context_die)
 {
   tree origin = decl_ultimate_origin (decl);
   dw_die_ref lbl_die = new_die (DW_TAG_label, context_die, decl);
@@ -11068,7 +10926,7 @@ gen_label_die (decl, context_die)
       insn = DECL_RTL (decl);
 
       /* Deleted labels are programmer specified labels which have been
-        eliminated because of various optimisations.  We still emit them
+        eliminated because of various optimizations.  We still emit them
         here so that it is possible to put breakpoints on them.  */
       if (GET_CODE (insn) == CODE_LABEL
          || ((GET_CODE (insn) == NOTE
@@ -11091,10 +10949,7 @@ gen_label_die (decl, context_die)
 /* Generate a DIE for a lexical block.  */
 
 static void
-gen_lexical_block_die (stmt, context_die, depth)
-     tree stmt;
-     dw_die_ref context_die;
-     int depth;
+gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
 {
   dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -11133,21 +10988,22 @@ gen_lexical_block_die (stmt, context_die, depth)
 /* Generate a DIE for an inlined subprogram.  */
 
 static void
-gen_inlined_subroutine_die (stmt, context_die, depth)
-     tree stmt;
-     dw_die_ref context_die;
-     int depth;
+gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
 {
+  tree decl = block_ultimate_origin (stmt);
+
+  /* Emit info for the abstract instance first, if we haven't yet.  We
+     must emit this even if the block is abstract, otherwise when we
+     emit the block below (or elsewhere), we may end up trying to emit
+     a die whose origin die hasn't been emitted, and crashing.  */
+  dwarf2out_abstract_function (decl);
+
   if (! BLOCK_ABSTRACT (stmt))
     {
       dw_die_ref subr_die
        = new_die (DW_TAG_inlined_subroutine, context_die, 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.  */
-      dwarf2out_abstract_function (decl);
-
       add_abstract_origin_attribute (subr_die, decl);
       ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
                                   BLOCK_NUMBER (stmt));
@@ -11177,12 +11033,14 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
 /* Generate a DIE for a field in a record, or structure.  */
 
 static void
-gen_field_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_field_die (tree decl, dw_die_ref context_die)
 {
-  dw_die_ref decl_die = new_die (DW_TAG_member, context_die, decl);
+  dw_die_ref decl_die;
+
+  if (TREE_TYPE (decl) == error_mark_node)
+    return;
 
+  decl_die = new_die (DW_TAG_member, context_die, decl);
   add_name_and_src_coords_attributes (decl_die, decl);
   add_type_attribute (decl_die, member_declared_type (decl),
                      TREE_READONLY (decl), TREE_THIS_VOLATILE (decl),
@@ -11214,9 +11072,7 @@ 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)
-     tree type;
-     dw_die_ref context_die;
+gen_pointer_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref ptr_die
     = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type);
@@ -11232,9 +11088,7 @@ 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)
-     tree type;
-     dw_die_ref context_die;
+gen_reference_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref ref_die
     = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type);
@@ -11248,9 +11102,7 @@ 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)
-     tree type;
-     dw_die_ref context_die;
+gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref ptr_die
     = new_die (DW_TAG_ptr_to_member_type,
@@ -11265,20 +11117,22 @@ gen_ptr_to_mbr_type_die (type, context_die)
 /* Generate the DIE for the compilation unit.  */
 
 static dw_die_ref
-gen_compile_unit_die (filename)
-     const char *filename;
+gen_compile_unit_die (const char *filename)
 {
   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, NULL);
-  add_name_attribute (die, filename);
 
-  if (wd != NULL && filename[0] != DIR_SEPARATOR)
-    add_AT_string (die, DW_AT_comp_dir, wd);
+  if (filename)
+    {
+      add_name_attribute (die, filename);
+      /* Don't add cwd for <built-in>.  */
+      if (filename[0] != DIR_SEPARATOR && filename[0] != '<')
+       add_comp_dir_attribute (die);
+    }
 
   sprintf (producer, "%s %s", language_string, version_string);
 
@@ -11298,7 +11152,7 @@ gen_compile_unit_die (filename)
   if (strcmp (language_string, "GNU C++") == 0)
     language = DW_LANG_C_plus_plus;
   else if (strcmp (language_string, "GNU Ada") == 0)
-    language = DW_LANG_Ada83;
+    language = DW_LANG_Ada95;
   else if (strcmp (language_string, "GNU F77") == 0)
     language = DW_LANG_Fortran77;
   else if (strcmp (language_string, "GNU Pascal") == 0)
@@ -11315,9 +11169,7 @@ gen_compile_unit_die (filename)
 /* Generate a DIE for a string type.  */
 
 static void
-gen_string_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_string_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die
     = new_die (DW_TAG_string_type, scope_die_for (type, context_die), type);
@@ -11335,9 +11187,7 @@ gen_string_type_die (type, context_die)
 /* Generate the DIE for a base class.  */
 
 static void
-gen_inheritance_die (binfo, context_die)
-     tree binfo;
-     dw_die_ref context_die;
+gen_inheritance_die (tree binfo, tree access, dw_die_ref context_die)
 {
   dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo);
 
@@ -11347,20 +11197,19 @@ gen_inheritance_die (binfo, context_die)
   if (TREE_VIA_VIRTUAL (binfo))
     add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);
 
-  if (TREE_VIA_PUBLIC (binfo))
+  if (access == access_public_node)
     add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public);
-  else if (TREE_VIA_PROTECTED (binfo))
+  else if (access == access_protected_node)
     add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected);
 }
 
 /* Generate a DIE for a class member.  */
 
 static void
-gen_member_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_member_die (tree type, dw_die_ref context_die)
 {
   tree member;
+  tree binfo = TYPE_BINFO (type);
   dw_die_ref child;
 
   /* If this is not an incomplete type, output descriptions of each of its
@@ -11376,14 +11225,17 @@ gen_member_die (type, context_die)
      the TREE node representing the appropriate (containing) type.  */
 
   /* First output info about the base classes.  */
-  if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
+  if (binfo && BINFO_BASETYPES (binfo))
     {
-      tree bases = TYPE_BINFO_BASETYPES (type);
+      tree bases = BINFO_BASETYPES (binfo);
+      tree accesses = BINFO_BASEACCESSES (binfo);
       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);
+       gen_inheritance_die (TREE_VEC_ELT (bases, i),
+                            (accesses ? TREE_VEC_ELT (accesses, i)
+                             : access_public_node), context_die);
     }
 
   /* Now output info about the data members and type members.  */
@@ -11421,9 +11273,7 @@ gen_member_die (type, context_die)
    member DIEs needed by later specification DIEs.  */
 
 static void
-gen_struct_or_union_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = lookup_type_die (type);
   dw_die_ref scope_die = 0;
@@ -11463,7 +11313,7 @@ gen_struct_or_union_type_die (type, context_die)
   if (complete)
     {
       /* Prevent infinite recursion in cases where the type of some member of
-         this type is expressed in terms of this type itself.  */
+        this type is expressed in terms of this type itself.  */
       TREE_ASM_WRITTEN (type) = 1;
       add_byte_size_attribute (type_die, type);
       if (TYPE_STUB_DECL (type) != NULL_TREE)
@@ -11502,9 +11352,7 @@ gen_struct_or_union_type_die (type, context_die)
 /* Generate a DIE for a subroutine _type_.  */
 
 static void
-gen_subroutine_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_subroutine_type_die (tree type, dw_die_ref context_die)
 {
   tree return_type = TREE_TYPE (type);
   dw_die_ref subr_die
@@ -11517,12 +11365,10 @@ gen_subroutine_type_die (type, context_die)
   gen_formal_types_die (type, subr_die);
 }
 
-/* Generate a DIE for a type definition */
+/* Generate a DIE for a type definition */
 
 static void
-gen_typedef_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_typedef_die (tree decl, dw_die_ref context_die)
 {
   dw_die_ref type_die;
   tree origin;
@@ -11563,29 +11409,19 @@ gen_typedef_die (decl, context_die)
 /* Generate a type description DIE.  */
 
 static void
-gen_type_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_type_die (tree type, dw_die_ref context_die)
 {
   int need_pop;
 
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
-  /* We are going to output a DIE to represent the unqualified version
-     of this type (i.e. without any const or volatile qualifiers) so
-     get the main variant (i.e. the unqualified version) of this type
-     now.  (Vectors are special because the debugging info is in the
-     cloned type itself).  */
-  if (TREE_CODE (type) != VECTOR_TYPE)
-    type = type_main_variant (type);
-
-  if (TREE_ASM_WRITTEN (type))
-    return;
-
   if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
       && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
     {
+      if (TREE_ASM_WRITTEN (type))
+       return;
+
       /* Prevent broken recursion; we can't hand off to the same type.  */
       if (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) == type)
        abort ();
@@ -11595,6 +11431,17 @@ gen_type_die (type, context_die)
       return;
     }
 
+  /* We are going to output a DIE to represent the unqualified version
+     of this type (i.e. without any const or volatile qualifiers) so
+     get the main variant (i.e. the unqualified version) of this type
+     now.  (Vectors are special because the debugging info is in the
+     cloned type itself).  */
+  if (TREE_CODE (type) != VECTOR_TYPE)
+    type = type_main_variant (type);
+
+  if (TREE_ASM_WRITTEN (type))
+    return;
+
   switch (TREE_CODE (type))
     {
     case ERROR_MARK:
@@ -11610,7 +11457,7 @@ gen_type_die (type, context_die)
       TREE_ASM_WRITTEN (type) = 1;
 
       /* For these types, all that is required is that we output a DIE (or a
-         set of DIEs) to represent the "basis" type.  */
+        set of DIEs) to represent the "basis" type.  */
       gen_type_die (TREE_TYPE (type), context_die);
       break;
 
@@ -11623,7 +11470,7 @@ gen_type_die (type, context_die)
       gen_type_die (TREE_TYPE (type), context_die);
 
       /* Now output a DIE to represent this pointer-to-data-member type
-         itself.  */
+        itself.  */
       gen_ptr_to_mbr_type_die (type, context_die);
       break;
 
@@ -11668,11 +11515,11 @@ gen_type_die (type, context_die)
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
       /* If this is a nested type whose containing class hasn't been written
-         out yet, writing it out will cover this one, too.  This does not apply
-         to instantiations of member class templates; they need to be added to
-         the containing class as they are generated.  FIXME: This hurts the
-         idea of combining type decls from multiple TUs, since we can't predict
-         what set of template instantiations we'll get.  */
+        out yet, writing it out will cover this one, too.  This does not apply
+        to instantiations of member class templates; they need to be added to
+        the containing class as they are generated.  FIXME: This hurts the
+        idea of combining type decls from multiple TUs, since we can't predict
+        what set of template instantiations we'll get.  */
       if (TYPE_CONTEXT (type)
          && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
          && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
@@ -11726,9 +11573,7 @@ gen_type_die (type, context_die)
 /* Generate a DIE for a tagged type instantiation.  */
 
 static void
-gen_tagged_type_instantiation_die (type, context_die)
-     tree type;
-     dw_die_ref context_die;
+gen_tagged_type_instantiation_die (tree type, dw_die_ref context_die)
 {
   if (type == NULL_TREE || type == error_mark_node)
     return;
@@ -11770,10 +11615,7 @@ gen_tagged_type_instantiation_die (type, context_die)
    things which are local to the given block.  */
 
 static void
-gen_block_die (stmt, context_die, depth)
-     tree stmt;
-     dw_die_ref context_die;
-     int depth;
+gen_block_die (tree stmt, dw_die_ref context_die, int depth)
 {
   int must_output_die = 0;
   tree origin;
@@ -11815,12 +11657,12 @@ gen_block_die (stmt, context_die, depth)
   else
     {
       /* In the case where the current block represents an inlining of the
-         "body block" of an inline function, we must *NOT* output any DIE for
-         this block because we have already output a DIE to represent the whole
-         inlined function scope and the "body block" of any function doesn't
-         really represent a different scope according to ANSI C rules.  So we
-         check here to make sure that this block does not represent a "body
-         block inlining" before trying to set the MUST_OUTPUT_DIE flag.  */
+        "body block" of an inline function, we must *NOT* output any DIE for
+        this block because we have already output a DIE to represent the whole
+        inlined function scope and the "body block" of any function doesn't
+        really represent a different scope according to ANSI C rules.  So we
+        check here to make sure that this block does not represent a "body
+        block inlining" before trying to set the MUST_OUTPUT_DIE flag.  */
       if (! is_body_block (origin ? origin : stmt))
        {
          /* Determine if this block directly contains any "significant"
@@ -11865,10 +11707,7 @@ gen_block_die (stmt, context_die, depth)
    all of its sub-blocks.  */
 
 static void
-decls_for_scope (stmt, context_die, depth)
-     tree stmt;
-     dw_die_ref context_die;
-     int depth;
+decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
 {
   tree decl;
   tree subblocks;
@@ -11898,6 +11737,10 @@ decls_for_scope (stmt, context_die, depth)
        gen_decl_die (decl, context_die);
     }
 
+  /* If we're at -g1, we're not interested in subblocks.  */
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return;
+
   /* Output the DIEs to represent all sub-blocks (and the items declared
      therein) of this block.  */
   for (subblocks = BLOCK_SUBBLOCKS (stmt);
@@ -11909,8 +11752,7 @@ decls_for_scope (stmt, context_die, depth)
 /* Is this a typedef we can avoid emitting?  */
 
 static inline int
-is_redundant_typedef (decl)
-     tree decl;
+is_redundant_typedef (tree decl)
 {
   if (TYPE_DECL_IS_STUB (decl))
     return 1;
@@ -11929,9 +11771,7 @@ is_redundant_typedef (decl)
 /* Generate Dwarf debug information for a decl described by DECL.  */
 
 static void
-gen_decl_die (decl, context_die)
-     tree decl;
-     dw_die_ref context_die;
+gen_decl_die (tree decl, dw_die_ref context_die)
 {
   tree origin;
 
@@ -11945,7 +11785,7 @@ gen_decl_die (decl, context_die)
 
     case CONST_DECL:
       /* The individual enumerators of an enum type get output when we output
-         the Dwarf representation of the relevant enum type itself.  */
+        the Dwarf representation of the relevant enum type itself.  */
       break;
 
     case FUNCTION_DECL:
@@ -11995,16 +11835,16 @@ gen_decl_die (decl, context_die)
 
     case TYPE_DECL:
       /* If we are in terse mode, don't generate any DIEs to represent any
-         actual typedefs.  */
+        actual typedefs.  */
       if (debug_info_level <= DINFO_LEVEL_TERSE)
        break;
 
       /* In the special case of a TYPE_DECL node representing the declaration
-         of some type tag, if the given TYPE_DECL is marked as having been
-         instantiated from some other (original) TYPE_DECL node (e.g. one which
-         was generated within the original definition of an inline function) we
-         have to generate a special (abbreviated) DW_TAG_structure_type,
-         DW_TAG_union_type, or DW_TAG_enumeration_type DIE here.  */
+        of some type tag, if the given TYPE_DECL is marked as having been
+        instantiated from some other (original) TYPE_DECL node (e.g. one which
+        was generated within the original definition of an inline function) we
+        have to generate a special (abbreviated) DW_TAG_structure_type,
+        DW_TAG_union_type, or DW_TAG_enumeration_type DIE here.  */
       if (TYPE_DECL_IS_STUB (decl) && decl_ultimate_origin (decl) != NULL_TREE)
        {
          gen_tagged_type_instantiation_die (TREE_TYPE (decl), context_die);
@@ -12025,12 +11865,12 @@ gen_decl_die (decl, context_die)
 
     case VAR_DECL:
       /* If we are in terse mode, don't generate any DIEs to represent any
-         variable declarations or definitions.  */
+        variable declarations or definitions.  */
       if (debug_info_level <= DINFO_LEVEL_TERSE)
        break;
 
       /* Output any DIEs that are needed to specify the type of this data
-         object.  */
+        object.  */
       gen_type_die (TREE_TYPE (decl), context_die);
 
       /* And its containing type.  */
@@ -12039,9 +11879,9 @@ gen_decl_die (decl, context_die)
        gen_type_die_for_member (origin, decl, context_die);
 
       /* Now output the DIE to represent the data object itself.  This gets
-         complicated because of the possibility that the VAR_DECL really
-         represents an inlined instance of a formal parameter for an inline
-         function.  */
+        complicated because of the possibility that the VAR_DECL really
+        represents an inlined instance of a formal parameter for an inline
+        function.  */
       origin = decl_ultimate_origin (decl);
       if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
        gen_formal_parameter_die (decl, context_die);
@@ -12070,6 +11910,9 @@ gen_decl_die (decl, context_die)
       break;
 
     default:
+      if ((int)TREE_CODE (decl) > NUM_TREE_CODES)
+       /* Probably some frontend-internal decl.  Assume we don't care.  */
+       break;
       abort ();
     }
 }
@@ -12077,9 +11920,7 @@ gen_decl_die (decl, context_die)
 /* Add Ada "use" clause information for SGI Workshop debugger.  */
 
 void
-dwarf2out_add_library_unit_info (filename, context_list)
-     const char *filename;
-     const char *context_list;
+dwarf2out_add_library_unit_info (const char *filename, const char *context_list)
 {
   unsigned int file_index;
 
@@ -12102,8 +11943,7 @@ dwarf2out_add_library_unit_info (filename, context_list)
    compilation proper has finished.  */
 
 static void
-dwarf2out_global_decl (decl)
-     tree decl;
+dwarf2out_global_decl (tree decl)
 {
   /* Output DWARF2 information for file-scope tentative data object
      declarations, file-scope (extern) function declarations (which had no
@@ -12116,8 +11956,7 @@ dwarf2out_global_decl (decl)
 /* Write the debugging output for DECL.  */
 
 void
-dwarf2out_decl (decl)
-     tree decl;
+dwarf2out_decl (tree decl)
 {
   dw_die_ref context_die = comp_unit_die;
 
@@ -12128,32 +11967,32 @@ dwarf2out_decl (decl)
 
     case FUNCTION_DECL:
       /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of a
-         builtin function.  Explicit programmer-supplied declarations of
-         these same functions should NOT be ignored however.  */
+        builtin function.  Explicit programmer-supplied declarations of
+        these same functions should NOT be ignored however.  */
       if (DECL_EXTERNAL (decl) && DECL_BUILT_IN (decl))
        return;
 
       /* What we would really like to do here is to filter out all mere
-         file-scope declarations of file-scope functions which are never
-         referenced later within this translation unit (and keep all of ones
-         that *are* referenced later on) but we aren't clairvoyant, so we have
-         no idea which functions will be referenced in the future (i.e. later
-         on within the current translation unit). So here we just ignore all
-         file-scope function declarations which are not also definitions.  If
-         and when the debugger needs to know something about these functions,
-         it will have to hunt around and find the DWARF information associated
-         with the definition of the function.
+        file-scope declarations of file-scope functions which are never
+        referenced later within this translation unit (and keep all of ones
+        that *are* referenced later on) but we aren't clairvoyant, so we have
+        no idea which functions will be referenced in the future (i.e. later
+        on within the current translation unit). So here we just ignore all
+        file-scope function declarations which are not also definitions.  If
+        and when the debugger needs to know something about these functions,
+        it will have to hunt around and find the DWARF information associated
+        with the definition of the function.
 
         We can't just check DECL_EXTERNAL to find out which FUNCTION_DECL
-         nodes represent definitions and which ones represent mere
-         declarations.  We have to check DECL_INITIAL instead. That's because
-         the C front-end supports some weird semantics for "extern inline"
-         function definitions.  These can get inlined within the current
-         translation unit (an thus, we need to generate Dwarf info for their
-         abstract instances so that the Dwarf info for the concrete inlined
-         instances can have something to refer to) but the compiler never
-         generates any out-of-lines instances of such things (despite the fact
-         that they *are* definitions).
+        nodes represent definitions and which ones represent mere
+        declarations.  We have to check DECL_INITIAL instead. That's because
+        the C front-end supports some weird semantics for "extern inline"
+        function definitions.  These can get inlined within the current
+        translation unit (an thus, we need to generate Dwarf info for their
+        abstract instances so that the Dwarf info for the concrete inlined
+        instances can have something to refer to) but the compiler never
+        generates any out-of-lines instances of such things (despite the fact
+        that they *are* definitions).
 
         The important point is that the C front-end marks these "extern
         inline" functions as DECL_EXTERNAL, but we need to generate DWARF for
@@ -12166,24 +12005,26 @@ dwarf2out_decl (decl)
       /* If we're a nested function, initially use a parent of NULL; if we're
         a plain function, this will be fixed up in decls_for_scope.  If
         we're a method, it will be ignored, since we already have a DIE.  */
-      if (decl_function_context (decl))
+      if (decl_function_context (decl)
+         /* But if we're in terse mode, we don't care about scope.  */
+         && debug_info_level > DINFO_LEVEL_TERSE)
        context_die = NULL;
       break;
 
     case VAR_DECL:
       /* Ignore this VAR_DECL if it refers to a file-scope extern data object
-         declaration and if the declaration was never even referenced from
-         within this entire compilation unit.  We suppress these DIEs in
-         order to save space in the .debug section (by eliminating entries
-         which are probably useless).  Note that we must not suppress
-         block-local extern declarations (whether used or not) because that
-         would screw-up the debugger's name lookup mechanism and cause it to
-         miss things which really ought to be in scope at a given point.  */
+        declaration and if the declaration was never even referenced from
+        within this entire compilation unit.  We suppress these DIEs in
+        order to save space in the .debug section (by eliminating entries
+        which are probably useless).  Note that we must not suppress
+        block-local extern declarations (whether used or not) because that
+        would screw-up the debugger's name lookup mechanism and cause it to
+        miss things which really ought to be in scope at a given point.  */
       if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
        return;
 
       /* If we are in terse mode, don't generate any DIEs to represent any
-         variable declarations or definitions.  */
+        variable declarations or definitions.  */
       if (debug_info_level <= DINFO_LEVEL_TERSE)
        return;
       break;
@@ -12194,11 +12035,11 @@ dwarf2out_decl (decl)
        return;
 
       /* Don't bother trying to generate any DIEs to represent any of the
-         normal built-in types for the language we are compiling.  */
+        normal built-in types for the language we are compiling.  */
       if (DECL_SOURCE_LINE (decl) == 0)
        {
          /* OK, we need to generate one for `bool' so GDB knows what type
-             comparisons have.  */
+            comparisons have.  */
          if ((get_AT_unsigned (comp_unit_die, DW_AT_language)
               == DW_LANG_C_plus_plus)
              && TREE_CODE (TREE_TYPE (decl)) == BOOLEAN_TYPE
@@ -12230,9 +12071,8 @@ dwarf2out_decl (decl)
    a lexical block.  */
 
 static void
-dwarf2out_begin_block (line, blocknum)
-     unsigned int line ATTRIBUTE_UNUSED;
-     unsigned int blocknum;
+dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
+                      unsigned int blocknum)
 {
   function_section (current_function_decl);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
@@ -12242,9 +12082,7 @@ dwarf2out_begin_block (line, blocknum)
    lexical block.  */
 
 static void
-dwarf2out_end_block (line, blocknum)
-     unsigned int line ATTRIBUTE_UNUSED;
-     unsigned int blocknum;
+dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
 {
   function_section (current_function_decl);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
@@ -12258,8 +12096,7 @@ dwarf2out_end_block (line, blocknum)
    we may end up calling them anyway.  */
 
 static bool
-dwarf2out_ignore_block (block)
-     tree block;
+dwarf2out_ignore_block (tree block)
 {
   tree decl;
 
@@ -12283,67 +12120,70 @@ dwarf2out_ignore_block (block)
    all searches.  */
 
 static unsigned
-lookup_filename (file_name)
-     const char *file_name;
+lookup_filename (const char *file_name)
 {
-  unsigned i;
-
-  /* ??? Why isn't DECL_SOURCE_FILE left null instead.  */
-  if (strcmp (file_name, "<internal>") == 0
-      || strcmp (file_name, "<built-in>") == 0)
-    return 0;
+  size_t i, n;
+  char *save_file_name;
 
   /* Check to see if the file name that was searched on the previous
      call matches this file name.  If so, return the index.  */
-  if (file_table.last_lookup_index != 0)
-    if (0 == strcmp (file_name,
-                    file_table.table[file_table.last_lookup_index]))
-      return file_table.last_lookup_index;
+  if (file_table_last_lookup_index != 0)
+    {
+      const char *last
+       = VARRAY_CHAR_PTR (file_table, file_table_last_lookup_index);
+      if (strcmp (file_name, last) == 0)
+       return file_table_last_lookup_index;
+    }
 
   /* Didn't match the previous lookup, search the table */
-  for (i = 1; i < file_table.in_use; i++)
-    if (strcmp (file_name, file_table.table[i]) == 0)
+  n = VARRAY_ACTIVE_SIZE (file_table);
+  for (i = 1; i < n; i++)
+    if (strcmp (file_name, VARRAY_CHAR_PTR (file_table, i)) == 0)
       {
-       file_table.last_lookup_index = i;
+       file_table_last_lookup_index = i;
        return i;
       }
 
-  /* Prepare to add a new table entry by making sure there is enough space in
-     the table to do so.  If not, expand the current table.  */
-  if (i == file_table.allocated)
-    {
-      file_table.allocated = i + FILE_TABLE_INCREMENT;
-      file_table.table = (char **)
-       xrealloc (file_table.table, file_table.allocated * sizeof (char *));
-      memset (file_table.table + i, 0,
-             FILE_TABLE_INCREMENT * sizeof (char *));
-    }
-
   /* Add the new entry to the end of the filename table.  */
-  file_table.table[i] = xstrdup (file_name);
-  file_table.in_use = i + 1;
-  file_table.last_lookup_index = i;
+  file_table_last_lookup_index = n;
+  save_file_name = (char *) ggc_strdup (file_name);
+  VARRAY_PUSH_CHAR_PTR (file_table, save_file_name);
+  VARRAY_PUSH_UINT (file_table_emitted, 0);
+
+  return i;
+}
 
-  if (DWARF2_ASM_LINE_DEBUG_INFO)
+static int
+maybe_emit_file (int fileno)
+{
+  if (DWARF2_ASM_LINE_DEBUG_INFO && fileno > 0)
     {
-      fprintf (asm_out_file, "\t.file %u ", i);
-      output_quoted_string (asm_out_file, file_name);
-      fputc ('\n', asm_out_file);
+      if (!VARRAY_UINT (file_table_emitted, fileno))
+       {
+         VARRAY_UINT (file_table_emitted, fileno) = ++emitcount;
+         fprintf (asm_out_file, "\t.file %u ",
+                  VARRAY_UINT (file_table_emitted, fileno));
+         output_quoted_string (asm_out_file,
+                               VARRAY_CHAR_PTR (file_table, fileno));
+         fputc ('\n', asm_out_file);
+       }
+      return VARRAY_UINT (file_table_emitted, fileno);
     }
-
-  return i;
+  else
+    return fileno;
 }
 
 static void
-init_file_table ()
+init_file_table (void)
 {
   /* Allocate the initial hunk of the file_table.  */
-  file_table.table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
-  file_table.allocated = FILE_TABLE_INCREMENT;
+  VARRAY_CHAR_PTR_INIT (file_table, 64, "file_table");
+  VARRAY_UINT_INIT (file_table_emitted, 64, "file_table_emitted");
 
   /* Skip the first entry - file numbers begin at 1.  */
-  file_table.in_use = 1;
-  file_table.last_lookup_index = 0;
+  VARRAY_PUSH_CHAR_PTR (file_table, NULL);
+  VARRAY_PUSH_UINT (file_table_emitted, 0);
+  file_table_last_lookup_index = 0;
 }
 
 /* Output a label to mark the beginning of a source code line entry
@@ -12351,11 +12191,10 @@ init_file_table ()
    'line_info_table' for later output of the .debug_line section.  */
 
 static void
-dwarf2out_source_line (line, filename)
-     unsigned int line;
-     const char *filename;
+dwarf2out_source_line (unsigned int line, const char *filename)
 {
-  if (debug_info_level >= DINFO_LEVEL_NORMAL)
+  if (debug_info_level >= DINFO_LEVEL_NORMAL
+      && line != 0)
     {
       function_section (current_function_decl);
 
@@ -12368,6 +12207,8 @@ dwarf2out_source_line (line, filename)
        {
          unsigned file_num = lookup_filename (filename);
 
+         file_num = maybe_emit_file (file_num);
+
          /* Emit the .loc directive understood by GNU as.  */
          fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line);
 
@@ -12390,14 +12231,13 @@ dwarf2out_source_line (line, filename)
            {
              separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
              separate_line_info_table
-               = (dw_separate_line_info_ref)
-                 ggc_realloc (separate_line_info_table,
+               = ggc_realloc (separate_line_info_table,
                               separate_line_info_table_allocated
                               * sizeof (dw_separate_line_info_entry));
-             memset ((separate_line_info_table 
-                      + separate_line_info_table_in_use), 
+             memset (separate_line_info_table
+                      + separate_line_info_table_in_use,
                      0,
-                     (LINE_INFO_TABLE_INCREMENT 
+                     (LINE_INFO_TABLE_INCREMENT
                       * sizeof (dw_separate_line_info_entry)));
            }
 
@@ -12438,9 +12278,7 @@ dwarf2out_source_line (line, filename)
 /* Record the beginning of a new source file.  */
 
 static void
-dwarf2out_start_source_file (lineno, filename)
-     unsigned int lineno;
-     const char *filename;
+dwarf2out_start_source_file (unsigned int lineno, const char *filename)
 {
   if (flag_eliminate_dwarf2_dups && !is_main_source)
     {
@@ -12459,6 +12297,7 @@ dwarf2out_start_source_file (lineno, filename)
       dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
       dw2_asm_output_data_uleb128 (lineno, "Included from line number %d",
                                   lineno);
+      maybe_emit_file (lookup_filename (filename));
       dw2_asm_output_data_uleb128 (lookup_filename (filename),
                                   "Filename we just started");
     }
@@ -12467,8 +12306,7 @@ dwarf2out_start_source_file (lineno, filename)
 /* Record the end of a source file.  */
 
 static void
-dwarf2out_end_source_file (lineno)
-     unsigned int lineno ATTRIBUTE_UNUSED;
+dwarf2out_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
 {
   if (flag_eliminate_dwarf2_dups)
     /* Record the end of the file for break_out_includes.  */
@@ -12486,9 +12324,8 @@ dwarf2out_end_source_file (lineno)
    initial whitespace, #, whitespace, directive-name, whitespace part.  */
 
 static void
-dwarf2out_define (lineno, buffer)
-     unsigned lineno ATTRIBUTE_UNUSED;
-     const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED,
+                 const char *buffer ATTRIBUTE_UNUSED)
 {
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
@@ -12504,9 +12341,8 @@ dwarf2out_define (lineno, buffer)
    initial whitespace, #, whitespace, directive-name, whitespace part.  */
 
 static void
-dwarf2out_undef (lineno, buffer)
-     unsigned lineno ATTRIBUTE_UNUSED;
-     const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
+                const char *buffer ATTRIBUTE_UNUSED)
 {
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
@@ -12520,18 +12356,12 @@ dwarf2out_undef (lineno, buffer)
 /* Set up for Dwarf output at the start of compilation.  */
 
 static void
-dwarf2out_init (main_input_filename)
-     const char *main_input_filename;
+dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
 {
   init_file_table ();
 
-  /* Add the name of the primary input file to the file table first,
-     under the assumption that we'll be emitting line number data for
-     it first, which avoids having to add an initial DW_LNS_set_file.  */
-  lookup_filename (main_input_filename);
-
   /* Allocate the initial hunk of the decl_die_table.  */
-  decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT 
+  decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT
                                      * sizeof (dw_die_ref));
   decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
   decl_die_table_in_use = 0;
@@ -12558,8 +12388,9 @@ dwarf2out_init (main_input_filename)
      value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
      will (typically) be a relative pathname and that this pathname should be
      taken as being relative to the directory from which the compiler was
-     invoked when the given (base) source file was compiled.  */
-  comp_unit_die = gen_compile_unit_die (main_input_filename);
+     invoked when the given (base) source file was compiled.  We will fill
+     in this value in dwarf2out_finish.  */
+  comp_unit_die = gen_compile_unit_die (NULL);
   is_main_source = 1;
 
   VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
@@ -12606,9 +12437,7 @@ dwarf2out_init (main_input_filename)
    ht_forall.  Emit one queued .debug_str string.  */
 
 static int
-output_indirect_string (h, v)
-     void **h;
-     void *v ATTRIBUTE_UNUSED;
+output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
 {
   struct indirect_string_node *node = (struct indirect_string_node *) *h;
 
@@ -12622,16 +12451,232 @@ output_indirect_string (h, v)
   return 1;
 }
 
+
+
+/* Clear the marks for a die and its children.
+   Be cool if the mark isn't set.  */
+
+static void
+prune_unmark_dies (dw_die_ref die)
+{
+  dw_die_ref c;
+  die->die_mark = 0;
+  for (c = die->die_child; c; c = c->die_sib)
+    prune_unmark_dies (c);
+}
+
+
+/* Given DIE that we're marking as used, find any other dies
+   it references as attributes and mark them as used.  */
+
+static void
+prune_unused_types_walk_attribs (dw_die_ref die)
+{
+  dw_attr_ref a;
+
+  for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
+    {
+      if (a->dw_attr_val.val_class == dw_val_class_die_ref)
+       {
+         /* A reference to another DIE.
+            Make sure that it will get emitted.  */
+         prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
+       }
+      else if (a->dw_attr == DW_AT_decl_file)
+       {
+         /* A reference to a file.  Make sure the file name is emitted.  */
+         a->dw_attr_val.v.val_unsigned =
+           maybe_emit_file (a->dw_attr_val.v.val_unsigned);
+       }
+    }
+}
+
+
+/* Mark DIE as being used.  If DOKIDS is true, then walk down
+   to DIE's children.  */
+
+static void
+prune_unused_types_mark (dw_die_ref die, int dokids)
+{
+  dw_die_ref c;
+
+  if (die->die_mark == 0)
+    {
+      /* We haven't done this node yet.  Mark it as used.  */
+      die->die_mark = 1;
+
+      /* We also have to mark its parents as used.
+        (But we don't want to mark our parents' kids due to this.)  */
+      if (die->die_parent)
+       prune_unused_types_mark (die->die_parent, 0);
+
+      /* Mark any referenced nodes.  */
+      prune_unused_types_walk_attribs (die);
+    }
+
+  if (dokids && die->die_mark != 2)
+    {
+      /* We need to walk the children, but haven't done so yet.
+        Remember that we've walked the kids.  */
+      die->die_mark = 2;
+
+      /* Walk them.  */
+      for (c = die->die_child; c; c = c->die_sib)
+       {
+         /* If this is an array type, we need to make sure our
+            kids get marked, even if they're types.  */
+         if (die->die_tag == DW_TAG_array_type)
+           prune_unused_types_mark (c, 1);
+         else
+           prune_unused_types_walk (c);
+       }
+    }
+}
+
+
+/* Walk the tree DIE and mark types that we actually use.  */
+
+static void
+prune_unused_types_walk (dw_die_ref die)
+{
+  dw_die_ref c;
+
+  /* Don't do anything if this node is already marked.  */
+  if (die->die_mark)
+    return;
+
+  switch (die->die_tag) {
+  case DW_TAG_const_type:
+  case DW_TAG_packed_type:
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_volatile_type:
+  case DW_TAG_typedef:
+  case DW_TAG_array_type:
+  case DW_TAG_structure_type:
+  case DW_TAG_union_type:
+  case DW_TAG_class_type:
+  case DW_TAG_friend:
+  case DW_TAG_variant_part:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_subroutine_type:
+  case DW_TAG_string_type:
+  case DW_TAG_set_type:
+  case DW_TAG_subrange_type:
+  case DW_TAG_ptr_to_member_type:
+  case DW_TAG_file_type:
+    /* It's a type node --- don't mark it.  */
+    return;
+
+  default:
+    /* Mark everything else.  */
+    break;
+  }
+
+  die->die_mark = 1;
+
+  /* Now, mark any dies referenced from here.  */
+  prune_unused_types_walk_attribs (die);
+
+  /* Mark children.  */
+  for (c = die->die_child; c; c = c->die_sib)
+    prune_unused_types_walk (c);
+}
+
+
+/* Remove from the tree DIE any dies that aren't marked.  */
+
+static void
+prune_unused_types_prune (dw_die_ref die)
+{
+  dw_die_ref c, p, n;
+  if (!die->die_mark)
+    abort();
+
+  p = NULL;
+  for (c = die->die_child; c; c = n)
+    {
+      n = c->die_sib;
+      if (c->die_mark)
+       {
+         prune_unused_types_prune (c);
+         p = c;
+       }
+      else
+       {
+         if (p)
+           p->die_sib = n;
+         else
+           die->die_child = n;
+         free_die (c);
+       }
+    }
+}
+
+
+/* Remove dies representing declarations that we never use.  */
+
+static void
+prune_unused_types (void)
+{
+  unsigned int i;
+  limbo_die_node *node;
+
+  /* Clear all the marks.  */
+  prune_unmark_dies (comp_unit_die);
+  for (node = limbo_die_list; node; node = node->next)
+    prune_unmark_dies (node->die);
+
+  /* Set the mark on nodes that are actually used.  */
+  prune_unused_types_walk (comp_unit_die);
+  for (node = limbo_die_list; node; node = node->next)
+    prune_unused_types_walk (node->die);
+
+  /* Also set the mark on nodes referenced from the
+     pubname_table or arange_table.  */
+  for (i = 0; i < pubname_table_in_use; i++)
+    prune_unused_types_mark (pubname_table[i].die, 1);
+  for (i = 0; i < arange_table_in_use; i++)
+    prune_unused_types_mark (arange_table[i], 1);
+
+  /* Get rid of nodes that aren't marked.  */
+  prune_unused_types_prune (comp_unit_die);
+  for (node = limbo_die_list; node; node = node->next)
+    prune_unused_types_prune (node->die);
+
+  /* Leave the marks clear.  */
+  prune_unmark_dies (comp_unit_die);
+  for (node = limbo_die_list; node; node = node->next)
+    prune_unmark_dies (node->die);
+}
+
 /* Output stuff that dwarf requires at the end of every file,
    and generate the DWARF-2 debugging info.  */
 
 static void
-dwarf2out_finish (input_filename)
-     const char *input_filename ATTRIBUTE_UNUSED;
+dwarf2out_finish (const char *filename)
 {
   limbo_die_node *node, *next_node;
   dw_die_ref die = 0;
 
+  /* Add the name for the main input file now.  We delayed this from
+     dwarf2out_init to avoid complications with PCH.  */
+  add_name_attribute (comp_unit_die, filename);
+  if (filename[0] != DIR_SEPARATOR)
+    add_comp_dir_attribute (comp_unit_die);
+  else if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL)
+    {
+      size_t i;
+      for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
+       if (VARRAY_CHAR_PTR (file_table, i)[0] != DIR_SEPARATOR
+           /* Don't add cwd for <built-in>.  */
+           && VARRAY_CHAR_PTR (file_table, i)[0] != '<')
+         {
+           add_comp_dir_attribute (comp_unit_die);
+           break;
+         }
+    }
+
   /* Traverse the limbo die list, and add parent/child links.  The only
      dies without parents that should be here are concrete instances of
      inline functions, and the comp_unit_die.  We can ignore the comp_unit_die.
@@ -12695,6 +12740,9 @@ dwarf2out_finish (input_filename)
      we'll see the end of an include file before the beginning.  */
   reverse_all_dies (comp_unit_die);
 
+  if (flag_eliminate_unused_debug_types)
+    prune_unused_types ();
+
   /* Generate separate CUs for each of the include files we've seen.
      They will go into limbo_die_list.  */
   if (flag_eliminate_dwarf2_dups)