OSDN Git Service

* sparc/sparc.md (eligible_for_return_delay): New attribute.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 58cf338..a79339c 100644 (file)
@@ -186,8 +186,8 @@ static unsigned current_funcdef_fde;
 
 /* Forward declarations for functions defined in this file.  */
 
-static char *stripattributes           PROTO((char *));
-static char *dwarf_cfi_name            PROTO((unsigned));
+static char *stripattributes           PROTO((const char *));
+static const char *dwarf_cfi_name      PROTO((unsigned));
 static dw_cfi_ref new_cfi              PROTO((void));
 static void add_cfi                    PROTO((dw_cfi_ref *, dw_cfi_ref));
 static unsigned long size_of_uleb128   PROTO((unsigned long));
@@ -205,6 +205,7 @@ static void output_cfi                      PROTO((dw_cfi_ref, dw_fde_ref));
 static void output_call_frame_info     PROTO((int));
 static unsigned reg_number             PROTO((rtx));
 static void dwarf2out_stack_adjust     PROTO((rtx));
+static void dwarf2out_frame_debug_expr PROTO((rtx, char *));
 
 /* Definitions of defaults for assembler-dependent names of various
    pseudo-ops and section names.
@@ -426,20 +427,20 @@ static void dwarf2out_stack_adjust        PROTO((rtx));
 
 #define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2)                    \
   assemble_integer (gen_rtx_MINUS (HImode,                             \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL1),        \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL2)),       \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL1),  \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
                    2, 1)
   
 #define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2)                    \
   assemble_integer (gen_rtx_MINUS (SImode,                             \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL1),        \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL2)),       \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL1),  \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
                    4, 1)
 
 #define ASM_OUTPUT_DWARF_ADDR_DELTA(FILE,LABEL1,LABEL2)                        \
   assemble_integer (gen_rtx_MINUS (Pmode,                              \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL1),        \
-                            gen_rtx_SYMBOL_REF (Pmode, LABEL2)),       \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL1),  \
+                                  gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
                    PTR_SIZE, 1)
 
 #define ASM_OUTPUT_DWARF_DELTA(FILE,LABEL1,LABEL2) \
@@ -471,7 +472,7 @@ static void dwarf2out_stack_adjust  PROTO((rtx));
 #define ASM_OUTPUT_DWARF_STRING(FILE,P) \
   do {                                                                       \
     register int slen = strlen(P);                                            \
-    register char *p = (P);                                                  \
+    register const char *p = (P);                                            \
     register int i;                                                          \
     fprintf (FILE, "\t.ascii \"");                                           \
     for (i = 0; i < slen; i++)                                               \
@@ -479,7 +480,7 @@ static void dwarf2out_stack_adjust  PROTO((rtx));
          register int c = p[i];                                              \
          if (c == '\"' || c == '\\')                                         \
            putc ('\\', FILE);                                                \
-         if (c >= ' ' && c < 0177)                                           \
+         if (ISPRINT(c))                                                     \
            putc (c, FILE);                                                   \
          else                                                                \
            {                                                                 \
@@ -527,7 +528,7 @@ expand_builtin_dwarf_fp_regnum ()
 
 static inline char *
 stripattributes (s)
-     char *s;
+     const char *s;
 {
   char *stripped = xmalloc (strlen (s) + 2);
   char *p = stripped;
@@ -667,7 +668,7 @@ expand_builtin_dwarf_reg_size (reg_tree, target)
 
 /* Convert a DWARF call frame info. operation to its string name */
 
-static char *
+static const char *
 dwarf_cfi_name (cfi_opc)
      register unsigned cfi_opc;
 {
@@ -1221,7 +1222,7 @@ dwarf2out_frame_debug_expr (expr, label)
           
           if (GET_CODE (x) == SET &&
              (RTX_FRAME_RELATED_P (x) || par_index == 0))
-             dwarf2out_frame_debug_expr (x, label);
+           dwarf2out_frame_debug_expr (x, label);
         }
       return;
     }
@@ -1244,8 +1245,8 @@ dwarf2out_frame_debug_expr (expr, label)
           if (cfa_reg != (unsigned) REGNO (src))
             abort ();
           if (REGNO (dest) != STACK_POINTER_REGNUM
-       && !(frame_pointer_needed
-            && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
+             && !(frame_pointer_needed
+                  && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
             abort ();
           cfa_reg = REGNO (dest);
           break;
@@ -1254,83 +1255,83 @@ dwarf2out_frame_debug_expr (expr, label)
         case MINUS:
           if (dest == stack_pointer_rtx)
             {
-       /* Adjusting SP.  */
-       switch (GET_CODE (XEXP (src, 1)))
-         {
-         case CONST_INT:
-           offset = INTVAL (XEXP (src, 1));
-           break;
-         case REG:
-           if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
-             abort ();
-           offset = cfa_temp_value;
-           break;
-         default:
-           abort ();
-         }
-
-       if (XEXP (src, 0) == hard_frame_pointer_rtx)
-         {
-           /* Restoring SP from FP in the epilogue.  */
-           if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
-             abort ();
-           cfa_reg = STACK_POINTER_REGNUM;
-         }
-       else if (XEXP (src, 0) != stack_pointer_rtx)
-         abort ();
-
-       if (GET_CODE (src) == PLUS)
-         offset = -offset;
-       if (cfa_reg == STACK_POINTER_REGNUM)
-         cfa_offset += offset;
-       if (cfa_store_reg == STACK_POINTER_REGNUM)
-         cfa_store_offset += offset;
+             /* Adjusting SP.  */
+             switch (GET_CODE (XEXP (src, 1)))
+               {
+               case CONST_INT:
+                 offset = INTVAL (XEXP (src, 1));
+                 break;
+               case REG:
+                 if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
+                   abort ();
+                 offset = cfa_temp_value;
+                 break;
+               default:
+                 abort ();
+               }
+
+             if (XEXP (src, 0) == hard_frame_pointer_rtx)
+               {
+                 /* Restoring SP from FP in the epilogue.  */
+                 if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+                   abort ();
+                 cfa_reg = STACK_POINTER_REGNUM;
+               }
+             else if (XEXP (src, 0) != stack_pointer_rtx)
+               abort ();
+
+             if (GET_CODE (src) == PLUS)
+               offset = -offset;
+             if (cfa_reg == STACK_POINTER_REGNUM)
+               cfa_offset += offset;
+             if (cfa_store_reg == STACK_POINTER_REGNUM)
+               cfa_store_offset += offset;
             }
           else if (dest == hard_frame_pointer_rtx)
             {
-       /* Either setting the FP from an offset of the SP,
-          or adjusting the FP */
-       if (! frame_pointer_needed
-           || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
-         abort ();
-
-       if (XEXP (src, 0) == stack_pointer_rtx
-           && GET_CODE (XEXP (src, 1)) == CONST_INT)
-         {
-           if (cfa_reg != STACK_POINTER_REGNUM)
-             abort ();
-           offset = INTVAL (XEXP (src, 1));
-           if (GET_CODE (src) == PLUS)
-             offset = -offset;
-           cfa_offset += offset;
-           cfa_reg = HARD_FRAME_POINTER_REGNUM;
-         }
-       else if (XEXP (src, 0) == hard_frame_pointer_rtx
-                && GET_CODE (XEXP (src, 1)) == CONST_INT)
-         {
-           if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
-             abort ();
-           offset = INTVAL (XEXP (src, 1));
-           if (GET_CODE (src) == PLUS)
-             offset = -offset;
-           cfa_offset += offset;
-         }
-
-       else 
-         abort();
+             /* Either setting the FP from an offset of the SP,
+                or adjusting the FP */
+             if (! frame_pointer_needed
+                 || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
+               abort ();
+
+             if (XEXP (src, 0) == stack_pointer_rtx
+                 && GET_CODE (XEXP (src, 1)) == CONST_INT)
+               {
+                 if (cfa_reg != STACK_POINTER_REGNUM)
+                   abort ();
+                 offset = INTVAL (XEXP (src, 1));
+                 if (GET_CODE (src) == PLUS)
+                   offset = -offset;
+                 cfa_offset += offset;
+                 cfa_reg = HARD_FRAME_POINTER_REGNUM;
+               }
+             else if (XEXP (src, 0) == hard_frame_pointer_rtx
+                      && GET_CODE (XEXP (src, 1)) == CONST_INT)
+               {
+                 if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+                   abort ();
+                 offset = INTVAL (XEXP (src, 1));
+                 if (GET_CODE (src) == PLUS)
+                   offset = -offset;
+                 cfa_offset += offset;
+               }
+
+             else 
+               abort();
             }
           else
             {
-       if (GET_CODE (src) != PLUS
-           || XEXP (src, 1) != stack_pointer_rtx)
-         abort ();
-       if (GET_CODE (XEXP (src, 0)) != REG
-           || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
-         abort ();
-       if (cfa_reg != STACK_POINTER_REGNUM)
-         abort ();
-       cfa_store_reg = REGNO (dest);
-       cfa_store_offset = cfa_offset - cfa_temp_value;
+             if (GET_CODE (src) != PLUS
+                 || XEXP (src, 1) != stack_pointer_rtx)
+               abort ();
+             if (GET_CODE (XEXP (src, 0)) != REG
+                 || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
+               abort ();
+             if (cfa_reg != STACK_POINTER_REGNUM)
+               abort ();
+             cfa_store_reg = REGNO (dest);
+             cfa_store_offset = cfa_offset - cfa_temp_value;
             }
           break;
 
@@ -1341,9 +1342,9 @@ dwarf2out_frame_debug_expr (expr, label)
 
         case IOR:
           if (GET_CODE (XEXP (src, 0)) != REG
-       || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg
-       || (unsigned) REGNO (dest) != cfa_temp_reg
-       || GET_CODE (XEXP (src, 1)) != CONST_INT)
+             || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg
+             || (unsigned) REGNO (dest) != cfa_temp_reg
+             || GET_CODE (XEXP (src, 1)) != CONST_INT)
             abort ();
           cfa_temp_value |= INTVAL (XEXP (src, 1));
           break;
@@ -1352,61 +1353,61 @@ dwarf2out_frame_debug_expr (expr, label)
           abort ();
         }
       dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
-    break;
+      break;
 
-  case MEM:
-    /* Saving a register to the stack.  Make sure dest is relative to the
-       CFA register.  */
-    if (GET_CODE (src) != REG)
-      abort ();
-    switch (GET_CODE (XEXP (dest, 0)))
-      {
-        /* With a push.  */
-      case PRE_INC:
-      case PRE_DEC:
-        offset = GET_MODE_SIZE (GET_MODE (dest));
-        if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
-          offset = -offset;
-
-        if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
-            || cfa_store_reg != STACK_POINTER_REGNUM)
-          abort ();
-        cfa_store_offset += offset;
-        if (cfa_reg == STACK_POINTER_REGNUM)
-          cfa_offset = cfa_store_offset;
+    case MEM:
+      /* Saving a register to the stack.  Make sure dest is relative to the
+        CFA register.  */
+      if (GET_CODE (src) != REG)
+       abort ();
+      switch (GET_CODE (XEXP (dest, 0)))
+       {
+         /* With a push.  */
+       case PRE_INC:
+       case PRE_DEC:
+         offset = GET_MODE_SIZE (GET_MODE (dest));
+         if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
+           offset = -offset;
 
-        offset = -cfa_store_offset;
-        break;
+         if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
+             || cfa_store_reg != STACK_POINTER_REGNUM)
+           abort ();
+         cfa_store_offset += offset;
+         if (cfa_reg == STACK_POINTER_REGNUM)
+           cfa_offset = cfa_store_offset;
 
-        /* With an offset.  */
-      case PLUS:
-      case MINUS:
-        offset = INTVAL (XEXP (XEXP (dest, 0), 1));
-        if (GET_CODE (XEXP (dest, 0)) == MINUS)
-          offset = -offset;
+         offset = -cfa_store_offset;
+         break;
 
-        if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
-          abort ();
-        offset -= cfa_store_offset;
-        break;
-
-        /* Without an offset.  */
-      case REG:
-        if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
-          abort();
-        offset = -cfa_store_offset;
-        break;
-
-      default:
-        abort ();
-      }
-    dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
-    dwarf2out_reg_save (label, REGNO (src), offset);
-    break;
+         /* With an offset.  */
+       case PLUS:
+       case MINUS:
+         offset = INTVAL (XEXP (XEXP (dest, 0), 1));
+         if (GET_CODE (XEXP (dest, 0)) == MINUS)
+           offset = -offset;
 
-  default:
-    abort ();
-  }
+         if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
+           abort ();
+         offset -= cfa_store_offset;
+         break;
+
+         /* Without an offset.  */
+       case REG:
+         if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
+           abort();
+         offset = -cfa_store_offset;
+         break;
+
+       default:
+         abort ();
+       }
+      dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
+      dwarf2out_reg_save (label, REGNO (src), offset);
+      break;
+
+    default:
+      abort ();
+    }
 }
 
 
@@ -1673,24 +1674,6 @@ output_cfi (cfi, fde)
      }
 }
 
-#if !defined (EH_FRAME_SECTION)
-#if defined (EH_FRAME_SECTION_ASM_OP)
-#define EH_FRAME_SECTION() eh_frame_section();
-#else
-#if defined (ASM_OUTPUT_SECTION_NAME)
-#define EH_FRAME_SECTION()                             \
-  do {                                                 \
-      named_section (NULL_TREE, ".eh_frame", 0);       \
-  } while (0)
-#endif
-#endif
-#endif
-
-/* If we aren't using crtstuff to run ctors, don't use it for EH.  */
-#if !defined (HAS_INIT_SECTION) && !defined (INIT_SECTION_ASM_OP)
-#undef EH_FRAME_SECTION
-#endif
-
 /* Output the call frame information used to used to record information
    that relates to calculating the frame pointer, and records the
    location of saved registers.  */
@@ -1984,9 +1967,7 @@ void
 dwarf2out_frame_init ()
 {
   /* Allocate the initial hunk of the fde_table.  */
-  fde_table
-    = (dw_fde_ref) xmalloc (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
-  bzero ((char *) fde_table, FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
+  fde_table = (dw_fde_ref) xcalloc (FDE_TABLE_INCREMENT, sizeof (dw_fde_node));
   fde_table_allocated = FDE_TABLE_INCREMENT;
   fde_table_in_use = 0;
 
@@ -2021,8 +2002,6 @@ dwarf2out_frame_finish ()
 /* And now, the support for symbolic debugging information.  */
 #ifdef DWARF2_DEBUGGING_INFO
 
-extern char *getpwd PROTO((void));
-
 /* NOTE: In the comments in this file, many references are made to
    "Debugging Information Entries".  This term is abbreviated as `DIE'
    throughout the remainder of this file.  */
@@ -2221,7 +2200,6 @@ limbo_die_node;
 
 extern int flag_traditional;
 extern char *version_string;
-extern char *language_string;
 
 /* Fixed size portion of the DWARF compilation unit header.  */
 #define DWARF_COMPILE_UNIT_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 3)
@@ -2236,6 +2214,11 @@ extern char *language_string;
 #define DWARF_ARANGES_HEADER_SIZE \
   (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, PTR_SIZE * 2) - DWARF_OFFSET_SIZE)
 
+/* The default is to have gcc emit the line number tables.  */
+#ifndef DWARF2_ASM_LINE_DEBUG_INFO
+#define DWARF2_ASM_LINE_DEBUG_INFO 0
+#endif
+
 /* Define the architecture-dependent minimum instruction length (in bytes).
    In this implementation of DWARF, this field is used for information
    purposes only.  Since GCC generates assembly language, we have
@@ -2426,6 +2409,22 @@ static unsigned pending_types;
    be enough for most typical programs.         */
 #define PENDING_TYPES_INCREMENT 64
 
+/* A pointer to the base of a list of incomplete types which might be
+   completed at some later time.  */
+
+static tree *incomplete_types_list;
+
+/* Number of elements currently allocated for the incomplete_types_list.  */
+static unsigned incomplete_types_allocated;
+
+/* Number of elements of incomplete_types_list currently in use.  */
+static unsigned incomplete_types;
+
+/* Size (in elements) of increments by which we may expand the incomplete
+   types list.  Actually, a single hunk of space of this size should
+   be enough for most typical programs.         */
+#define INCOMPLETE_TYPES_INCREMENT 64
+
 /* Record whether the function being analyzed contains inlined functions.  */
 static int current_function_has_inlines;
 #if 0 && defined (MIPS_DEBUGGING_INFO)
@@ -2445,12 +2444,12 @@ static char *addr_to_string             PROTO((rtx));
 static int is_pseudo_reg               PROTO((rtx));
 static tree type_main_variant          PROTO((tree));
 static int is_tagged_type              PROTO((tree));
-static char *dwarf_tag_name            PROTO((unsigned));
-static char *dwarf_attr_name           PROTO((unsigned));
-static char *dwarf_form_name           PROTO((unsigned));
-static char *dwarf_stack_op_name       PROTO((unsigned));
+static const char *dwarf_tag_name      PROTO((unsigned));
+static const char *dwarf_attr_name     PROTO((unsigned));
+static const char *dwarf_form_name     PROTO((unsigned));
+static const char *dwarf_stack_op_name PROTO((unsigned));
 #if 0
-static char *dwarf_type_encoding_name  PROTO((unsigned));
+static const char *dwarf_type_encoding_name PROTO((unsigned));
 #endif
 static tree decl_ultimate_origin       PROTO((tree));
 static tree block_ultimate_origin      PROTO((tree));
@@ -2471,7 +2470,8 @@ static void add_AT_float          PROTO((dw_die_ref,
                                               enum dwarf_attribute,
                                               unsigned, long *));
 static void add_AT_string              PROTO((dw_die_ref,
-                                              enum dwarf_attribute, char *));
+                                              enum dwarf_attribute,
+                                              const char *));
 static void add_AT_die_ref             PROTO((dw_die_ref,
                                               enum dwarf_attribute,
                                               dw_die_ref));
@@ -2535,7 +2535,7 @@ static void output_loc_operands           PROTO((dw_loc_descr_ref));
 static unsigned long sibling_offset    PROTO((dw_die_ref));
 static void output_die                 PROTO((dw_die_ref));
 static void output_compilation_unit_header PROTO((void));
-static char *dwarf2_name               PROTO((tree, int));
+static const char *dwarf2_name         PROTO((tree, int));
 static void add_pubname                        PROTO((tree, dw_die_ref));
 static void output_pubnames            PROTO((void));
 static void add_arange                 PROTO((tree, dw_die_ref));
@@ -2550,7 +2550,7 @@ static int type_is_enum                   PROTO((tree));
 static dw_loc_descr_ref reg_loc_descriptor PROTO((rtx));
 static dw_loc_descr_ref based_loc_descr        PROTO((unsigned, long));
 static int is_based_loc                        PROTO((rtx));
-static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx));
+static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx, enum machine_mode mode));
 static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
 static dw_loc_descr_ref loc_descriptor PROTO((rtx));
 static unsigned ceiling                        PROTO((unsigned, unsigned));
@@ -2563,7 +2563,7 @@ static void add_AT_location_description   PROTO((dw_die_ref,
 static void add_data_member_location_attribute PROTO((dw_die_ref, tree));
 static void add_const_value_attribute  PROTO((dw_die_ref, rtx));
 static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
-static void add_name_attribute         PROTO((dw_die_ref, char *));
+static void add_name_attribute         PROTO((dw_die_ref, const char *));
 static void add_bound_info             PROTO((dw_die_ref,
                                               enum dwarf_attribute, tree));
 static void add_subscript_info         PROTO((dw_die_ref, tree));
@@ -2619,7 +2619,9 @@ static void gen_block_die         PROTO((tree, dw_die_ref, int));
 static void decls_for_scope            PROTO((tree, dw_die_ref, int));
 static int is_redundant_typedef                PROTO((tree));
 static void gen_decl_die               PROTO((tree, dw_die_ref));
-static unsigned lookup_filename                PROTO((char *));
+static unsigned lookup_filename                PROTO((const char *));
+static void add_incomplete_type                PROTO((tree));
+static void retry_incomplete_types     PROTO((void));
 
 /* Section names used to hold DWARF debugging information.  */
 #ifndef DEBUG_INFO_SECTION
@@ -2728,7 +2730,7 @@ static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
        dyn_string_append (STR, NAME + 1);              \
       else                                             \
        {                                               \
-         char *newstr;                                 \
+         const char *newstr;                           \
          STRIP_NAME_ENCODING (newstr, NAME);           \
          dyn_string_append (STR, user_label_prefix);   \
          dyn_string_append (STR, newstr);              \
@@ -2920,7 +2922,7 @@ is_tagged_type (type)
 
 /* Convert a DIE tag into its string name.  */
 
-static char *
+static const char *
 dwarf_tag_name (tag)
      register unsigned tag;
 {
@@ -3037,7 +3039,7 @@ dwarf_tag_name (tag)
 
 /* Convert a DWARF attribute code into its string name.  */
 
-static char *
+static const char *
 dwarf_attr_name (attr)
      register unsigned attr;
 {
@@ -3210,7 +3212,7 @@ dwarf_attr_name (attr)
 
 /* Convert a DWARF value form code into its string name.  */
 
-static char *
+static const char *
 dwarf_form_name (form)
      register unsigned form;
 {
@@ -3265,7 +3267,7 @@ dwarf_form_name (form)
 
 /* Convert a DWARF stack opcode into its string name.  */
 
-static char *
+static const char *
 dwarf_stack_op_name (op)
      register unsigned op;
 {
@@ -3569,7 +3571,7 @@ dwarf_stack_op_name (op)
 /* Convert a DWARF type code into its string name.  */
 
 #if 0
-static char *
+static const char *
 dwarf_type_encoding_name (enc)
      register unsigned enc;
 {
@@ -3788,7 +3790,7 @@ static inline void
 add_AT_string (die, attr_kind, str)
      register dw_die_ref die;
      register enum dwarf_attribute attr_kind;
-     register char *str;
+     register const char *str;
 {
   register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
 
@@ -4066,7 +4068,7 @@ remove_AT (die, attr_kind)
      register enum dwarf_attribute attr_kind;
 {
   register dw_attr_ref a;
-  register dw_attr_ref removed = NULL;;
+  register dw_attr_ref removed = NULL;
 
   if (die != NULL)
     {
@@ -4426,7 +4428,8 @@ debug_dwarf ()
 {
   print_indent = 0;
   print_die (comp_unit_die, stderr);
-  print_dwarf_line_table (stderr);
+  if (! DWARF2_ASM_LINE_DEBUG_INFO)
+    print_dwarf_line_table (stderr);
 }
 \f
 /* Traverse the DIE, and add a sibling attribute if it may have the
@@ -5119,6 +5122,9 @@ output_abbrev_section ()
 
       fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP);
     }
+
+  /* Terminate the table.  */
+  fprintf (asm_out_file, "\t%s\t0\n", ASM_BYTE_OP);
 }
 
 /* Output location description stack opcode's operands (if any).  */
@@ -5499,7 +5505,7 @@ output_compilation_unit_header ()
    of decl_printable_name for C++ looks like "A::f(int)".  Let's drop the
    argument list, and maybe the scope.  */
 
-static char *
+static const char *
 dwarf2_name (decl, scope)
      tree decl;
      int scope;
@@ -5653,8 +5659,14 @@ output_aranges ()
             ASM_COMMENT_START);
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 4);
-  if (PTR_SIZE == 8)
+  /* We need to align to twice the pointer size here.
+     If DWARF_OFFSET_SIZE == 4, then we have emitted 12 bytes, and need 4
+     bytes of padding to align for either 4 or 8 byte pointers.  */
+  ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
+  /* If DWARF_OFFSET_SIZE == 8, then we have emitted 20 bytes, and need 12
+     bytes of padding to align for 8 byte pointers.  We have already emitted
+     4 bytes of padding, so emit 8 more here.  */
+  if (DWARF_OFFSET_SIZE == 8)
     fprintf (asm_out_file, ",0,0");
 
   if (flag_debug_asm)
@@ -6546,11 +6558,15 @@ is_based_loc (rtl)
    When creating memory location descriptors, we are effectively transforming
    the RTL for a memory-resident object into its Dwarf postfix expression
    equivalent.  This routine recursively descends an RTL tree, turning
-   it into Dwarf postfix code as it goes.  */
+   it into Dwarf postfix code as it goes.
+
+   MODE is the mode of the memory reference, needed to handle some
+   autoincrement addressing modes.  */
 
 static dw_loc_descr_ref
-mem_loc_descriptor (rtl)
+mem_loc_descriptor (rtl, mode)
      register rtx rtl;
+     enum machine_mode mode;
 {
   dw_loc_descr_ref mem_loc_result = NULL;
   /* Note that for a dynamically sized array, the location we will generate a 
@@ -6560,6 +6576,13 @@ mem_loc_descriptor (rtl)
 
   switch (GET_CODE (rtl))
     {
+    case POST_INC:
+    case POST_DEC:
+      /* POST_INC and POST_DEC can be handled just like a SUBREG.  So we
+        just fall into the SUBREG code.  */
+
+      /* ... fall through ... */
+
     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
@@ -6588,10 +6611,14 @@ mem_loc_descriptor (rtl)
       break;
 
     case MEM:
-      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0));
+      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
       add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
       break;
 
+     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.  */
     case CONST:
     case SYMBOL_REF:
       mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
@@ -6599,14 +6626,27 @@ mem_loc_descriptor (rtl)
       mem_loc_result->dw_loc_oprnd1.v.val_addr = addr_to_string (rtl);
       break;
 
+    case PRE_INC:
+    case PRE_DEC:
+      /* Turn these into a PLUS expression and fall into the PLUS code
+        below.  */
+      rtl = gen_rtx_PLUS (word_mode, XEXP (rtl, 0),
+                         GEN_INT (GET_CODE (rtl) == PRE_INC
+                                  ? GET_MODE_UNIT_SIZE (mode) 
+                                  : - GET_MODE_UNIT_SIZE (mode)));
+                         
+      /* ... fall through ... */
+
     case PLUS:
       if (is_based_loc (rtl))
        mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
                                          INTVAL (XEXP (rtl, 1)));
       else
        {
-         add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
-         add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
+         add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0),
+                                                             mode));
+         add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1),
+                                                             mode));
          add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_plus, 0, 0));
        }
       break;
@@ -6614,8 +6654,8 @@ mem_loc_descriptor (rtl)
     case MULT:
       /* If a pseudo-reg is optimized away, it is possible for it to
         be replaced with a MEM containing a multiply.  */
-      add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
-      add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
+      add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0), mode));
+      add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1), mode));
       add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
       break;
 
@@ -6682,7 +6722,7 @@ loc_descriptor (rtl)
       break;
 
     case MEM:
-      loc_result = mem_loc_descriptor (XEXP (rtl, 0));
+      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
       break;
 
     case CONCAT:
@@ -7167,7 +7207,8 @@ add_location_or_const_value_attribute (die, decl)
            rtl = DECL_INCOMING_RTL (decl);
          else if (! BYTES_BIG_ENDIAN
                   && TREE_CODE (declared_type) == INTEGER_TYPE
-                  && TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
+                  && (GET_MODE_SIZE (TYPE_MODE (declared_type))
+                      <= GET_MODE_SIZE (TYPE_MODE (passed_type))))
                rtl = DECL_INCOMING_RTL (decl);
        }
 
@@ -7249,7 +7290,7 @@ add_location_or_const_value_attribute (die, decl)
 static inline void
 add_name_attribute (die, name_string)
      register dw_die_ref die;
-     register char *name_string;
+     register const char *name_string;
 {
   if (name_string != NULL && *name_string != 0)
     add_AT_string (die, DW_AT_name, name_string);
@@ -7331,7 +7372,7 @@ add_bound_info (subrange_die, bound_attr, bound)
              rtx new_addr = fix_lexical_addr (XEXP (loc, 0), bound);
 
              if (XEXP (loc, 0) != new_addr)
-               loc = gen_rtx (MEM, GET_MODE (loc), new_addr);
+               loc = gen_rtx_MEM (GET_MODE (loc), new_addr);
            }
 
          add_AT_flag (decl_die, DW_AT_artificial, 1);
@@ -8035,6 +8076,39 @@ output_pending_types_for_scope (context_die)
     }
 }
 
+/* Remember a type in the incomplete_types_list.  */
+
+static void
+add_incomplete_type (type)
+     tree type;
+{
+  if (incomplete_types == incomplete_types_allocated)
+    {
+      incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT;
+      incomplete_types_list
+       = (tree *) xrealloc (incomplete_types_list,
+                            sizeof (tree) * incomplete_types_allocated);
+    }
+
+  incomplete_types_list[incomplete_types++] = type;
+}
+
+/* Walk through the list of incomplete types again, trying once more to
+   emit full debugging info for them.  */
+
+static void
+retry_incomplete_types ()
+{
+  register tree type;
+
+  while (incomplete_types)
+    {
+      --incomplete_types;
+      type = incomplete_types_list[incomplete_types];
+      gen_type_die (type, comp_unit_die);
+    }
+}
+
 /* Generate a DIE to represent an inlined instance of an enumeration type.  */
 
 static void
@@ -8199,7 +8273,7 @@ gen_formal_parameter_die (node, context_die)
 
 static void
 gen_unspecified_parameters_die (decl_or_type, context_die)
-     register tree decl_or_type;
+     register tree decl_or_type ATTRIBUTE_UNUSED;
      register dw_die_ref context_die;
 {
   new_die (DW_TAG_unspecified_parameters, context_die);
@@ -8322,7 +8396,6 @@ gen_subprogram_die (decl, context_die)
             we should detect this case and ignore it.  For now, if we have
             already reported an error, any error at all, then assume that
             we got here because of a input error, not a dwarf2 bug.  */
-         extern int errorcount;
          if (errorcount)
            return;
          abort ();
@@ -8339,7 +8412,7 @@ gen_subprogram_die (decl, context_die)
           || context_die == NULL)
          && get_AT_unsigned (old_die, DW_AT_decl_file) == file_index
          && (get_AT_unsigned (old_die, DW_AT_decl_line)
-             == DECL_SOURCE_LINE (decl)))
+             == (unsigned)DECL_SOURCE_LINE (decl)))
        {
          subr_die = old_die;
 
@@ -8354,7 +8427,7 @@ gen_subprogram_die (decl, context_die)
          if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index)
            add_AT_unsigned (subr_die, DW_AT_decl_file, file_index);
          if (get_AT_unsigned (old_die, DW_AT_decl_line)
-             != DECL_SOURCE_LINE (decl))
+             != (unsigned)DECL_SOURCE_LINE (decl))
            add_AT_unsigned
              (subr_die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
        }
@@ -8591,7 +8664,7 @@ gen_variable_die (decl, context_die)
            add_AT_unsigned (var_die, DW_AT_decl_file, file_index);
 
          if (get_AT_unsigned (old_die, DW_AT_decl_line)
-             != DECL_SOURCE_LINE (decl))
+             != (unsigned)DECL_SOURCE_LINE (decl))
 
            add_AT_unsigned (var_die, DW_AT_decl_line,
                             DECL_SOURCE_LINE (decl));
@@ -9026,7 +9099,13 @@ gen_struct_or_union_type_die (type, context_die)
        }
     }
   else
-    add_AT_flag (type_die, DW_AT_declaration, 1);
+    {
+      add_AT_flag (type_die, DW_AT_declaration, 1);
+
+      /* We can't do this for function-local types, and we don't need to.  */
+      if (TREE_PERMANENT (type))
+       add_incomplete_type (type);
+    }
 }
 
 /* Generate a DIE for a subroutine _type_.  */
@@ -9735,7 +9814,7 @@ dwarf2out_label (insn)
 
 static unsigned
 lookup_filename (file_name)
-     char *file_name;
+     const char *file_name;
 {
   static unsigned last_file_lookup_index = 0;
   register unsigned i;
@@ -9777,18 +9856,40 @@ lookup_filename (file_name)
 
 void
 dwarf2out_line (filename, line)
-     register char *filename;
+     register const char *filename;
      register unsigned line;
 {
   if (debug_info_level >= DINFO_LEVEL_NORMAL)
     {
       function_section (current_function_decl);
 
-      if (DECL_SECTION_NAME (current_function_decl))
+      if (DWARF2_ASM_LINE_DEBUG_INFO)
+       {
+         static const char *lastfile;
+
+         /* Emit the .file and .loc directives understood by GNU as.  */
+         if (lastfile == 0 || strcmp (filename, lastfile))
+           {
+             fprintf (asm_out_file, "\t.file 0 \"%s\"\n", filename);
+             lastfile = filename;
+           }
+
+         fprintf (asm_out_file, "\t.loc 0 %d 0\n", line);
+
+         /* Indicate that line number info exists.  */
+         ++line_info_table_in_use;
+
+         /* Indicate that multiple line number tables exist.  */
+         if (DECL_SECTION_NAME (current_function_decl))
+           ++separate_line_info_table_in_use;
+       }
+      else if (DECL_SECTION_NAME (current_function_decl))
        {
          register dw_separate_line_info_ref line_info;
          ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
                                     separate_line_info_table_in_use);
+         if (flag_debug_asm)
+           fprintf (asm_out_file, "\t%s line %d", ASM_COMMENT_START, line);
          fputc ('\n', asm_out_file);
 
          /* expand the line info table if necessary */
@@ -9816,6 +9917,8 @@ dwarf2out_line (filename, line)
 
          ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
                                     line_info_table_in_use);
+         if (flag_debug_asm)
+           fprintf (asm_out_file, "\t%s line %d", ASM_COMMENT_START, line);
          fputc ('\n', asm_out_file);
 
          /* Expand the line info table if necessary.  */
@@ -9842,7 +9945,7 @@ dwarf2out_line (filename, line)
 
 void
 dwarf2out_start_source_file (filename)
-     register char *filename ATTRIBUTE_UNUSED;
+     register const char *filename ATTRIBUTE_UNUSED;
 {
 }
 
@@ -9860,8 +9963,8 @@ dwarf2out_end_source_file ()
 
 void
 dwarf2out_define (lineno, buffer)
-     register unsigned lineno;
-     register char *buffer;
+     register unsigned lineno ATTRIBUTE_UNUSED;
+     register const char *buffer ATTRIBUTE_UNUSED;
 {
   static int initialized = 0;
   if (!initialized)
@@ -9878,7 +9981,7 @@ dwarf2out_define (lineno, buffer)
 void
 dwarf2out_undef (lineno, buffer)
      register unsigned lineno ATTRIBUTE_UNUSED;
-     register char *buffer ATTRIBUTE_UNUSED;
+     register const char *buffer ATTRIBUTE_UNUSED;
 {
 }
 
@@ -9893,8 +9996,7 @@ dwarf2out_init (asm_out_file, main_input_filename)
   primary_filename = main_input_filename;
 
   /* Allocate the initial hunk of the file_table.  */
-  file_table = (char **) xmalloc (FILE_TABLE_INCREMENT * sizeof (char *));
-  bzero ((char *) file_table, FILE_TABLE_INCREMENT * sizeof (char *));
+  file_table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
   file_table_allocated = FILE_TABLE_INCREMENT;
 
   /* Skip the first entry - file numbers begin at 1.  */
@@ -9902,37 +10004,29 @@ dwarf2out_init (asm_out_file, main_input_filename)
 
   /* Allocate the initial hunk of the decl_die_table.  */
   decl_die_table
-    = (dw_die_ref *) xmalloc (DECL_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
-  bzero ((char *) decl_die_table,
-        DECL_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
+    = (dw_die_ref *) xcalloc (DECL_DIE_TABLE_INCREMENT, sizeof (dw_die_ref));
   decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
   decl_die_table_in_use = 0;
 
   /* Allocate the initial hunk of the decl_scope_table.  */
   decl_scope_table
-    = (decl_scope_node *) xmalloc (DECL_SCOPE_TABLE_INCREMENT
-                                  * sizeof (decl_scope_node));
-  bzero ((char *) decl_scope_table,
-        DECL_SCOPE_TABLE_INCREMENT * sizeof (decl_scope_node));
+    = (decl_scope_node *) xcalloc (DECL_SCOPE_TABLE_INCREMENT,
+                                  sizeof (decl_scope_node));
   decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
   decl_scope_depth = 0;
 
   /* Allocate the initial hunk of the abbrev_die_table.  */
   abbrev_die_table
-    = (dw_die_ref *) xmalloc (ABBREV_DIE_TABLE_INCREMENT
-                             * sizeof (dw_die_ref));
-  bzero ((char *) abbrev_die_table,
-        ABBREV_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
+    = (dw_die_ref *) xcalloc (ABBREV_DIE_TABLE_INCREMENT,
+                             sizeof (dw_die_ref));
   abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
   /* Zero-th entry is allocated, but unused */
   abbrev_die_table_in_use = 1;
 
   /* Allocate the initial hunk of the line_info_table.  */
   line_info_table
-    = (dw_line_info_ref) xmalloc (LINE_INFO_TABLE_INCREMENT
-                                 * sizeof (dw_line_info_entry));
-  bzero ((char *) line_info_table,
-        LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
+    = (dw_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
+                                 sizeof (dw_line_info_entry));
   line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
   /* Zero-th entry is allocated, but unused */
   line_info_table_in_use = 1;
@@ -9946,7 +10040,10 @@ dwarf2out_init (asm_out_file, main_input_filename)
 
   ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0);
-  ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+  if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
+    ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+  else
+    strcpy (text_section_label, stripattributes (TEXT_SECTION));
   ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, 
                               DEBUG_INFO_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, 
@@ -9955,7 +10052,8 @@ dwarf2out_init (asm_out_file, main_input_filename)
   ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
   ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
   ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION);
-  ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
+  if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
+    ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
   ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION);
   ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
   ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
@@ -9995,6 +10093,10 @@ dwarf2out_finish ()
       free (node);
     }
 
+  /* Walk through the list of incomplete types again, trying once more to
+     emit full debugging info for them.  */
+  retry_incomplete_types ();
+
   /* Traverse the DIE tree and add sibling attributes to those DIE's
      that have children.  */
   add_sibling_attributes (comp_unit_die);
@@ -10019,9 +10121,12 @@ dwarf2out_finish ()
   /* Output the source line correspondence table.  */
   if (line_info_table_in_use > 1 || separate_line_info_table_in_use)
     {
-      fputc ('\n', asm_out_file);
-      ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
-      output_line_info ();
+      if (! DWARF2_ASM_LINE_DEBUG_INFO)
+       {
+         fputc ('\n', asm_out_file);
+         ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
+         output_line_info ();
+       }
 
       /* We can only use the low/high_pc attributes if all of the code
         was in .text.  */