OSDN Git Service

* cppfiles.c (INO_T_EQ): Handle UWIN.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 12ad09a..2045ff4 100644 (file)
@@ -1,5 +1,5 @@
 /* Output Dwarf2 format symbol table information from the GNU C compiler.
-   Copyright (C) 1992, 93, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 95-98, 1999 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).
@@ -18,7 +18,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* The first part of this file deals with the DWARF 2 frame unwind
    information, which is also used by the GCC efficient exception handling
@@ -40,7 +41,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "expr.h"
 #include "except.h"
 #include "dwarf2.h"
+#include "dwarf2out.h"
 #include "toplev.h"
+#include "dyn-string.h"
 
 /* We cannot use <assert.h> in GCC source, since that would include
    GCC's assert.h, which may not be compatible with the host compiler.  */
@@ -58,6 +61,9 @@ int
 dwarf2out_do_frame ()
 {
   return (write_symbols == DWARF2_DEBUG
+#ifdef DWARF2_FRAME_INFO
+          || DWARF2_FRAME_INFO
+#endif
 #ifdef DWARF2_UNWIND_INFO
          || (flag_exceptions && ! exceptions_via_longjmp)
 #endif
@@ -66,10 +72,6 @@ dwarf2out_do_frame ()
 
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
-#ifndef __GNUC__
-#define inline
-#endif
-
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
 #define ASM_COMMENT_START ";#"
@@ -274,7 +276,7 @@ static void dwarf2out_stack_adjust  PROTO((rtx));
 
 #ifndef ASM_OUTPUT_DWARF_DATA1
 #define ASM_OUTPUT_DWARF_DATA1(FILE,VALUE) \
-  fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, VALUE)
+  fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) (VALUE))
 #endif
 
 #ifndef ASM_OUTPUT_DWARF_DELTA1
@@ -341,6 +343,16 @@ static void dwarf2out_stack_adjust PROTO((rtx));
   } while (0)
 #endif
 
+/* ??? This macro takes an RTX in dwarfout.c and a string in dwarf2out.c.
+   We resolve the conflict by creating a new macro ASM_OUTPUT_DWARF2_ADDR_CONST
+   for ports that want to support both DWARF1 and DWARF2.  This needs a better
+   solution.  See also the comments in sparc/sp64-elf.h.  */
+#ifdef ASM_OUTPUT_DWARF2_ADDR_CONST
+#undef ASM_OUTPUT_DWARF_ADDR_CONST
+#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,ADDR) \
+  ASM_OUTPUT_DWARF2_ADDR_CONST (FILE, ADDR)
+#endif
+
 #ifndef ASM_OUTPUT_DWARF_ADDR_CONST
 #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,ADDR)                         \
   fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, (ADDR))
@@ -362,24 +374,24 @@ static void dwarf2out_stack_adjust        PROTO((rtx));
 
 #ifndef ASM_OUTPUT_DWARF_DATA2
 #define ASM_OUTPUT_DWARF_DATA2(FILE,VALUE) \
-  fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, (unsigned) VALUE)
+  fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, (unsigned) (VALUE))
 #endif
 
 #ifndef ASM_OUTPUT_DWARF_DATA4
 #define ASM_OUTPUT_DWARF_DATA4(FILE,VALUE) \
-  fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_INT_ASM_OP, (unsigned) VALUE)
+  fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_INT_ASM_OP, (unsigned) (VALUE))
 #endif
 
 #ifndef ASM_OUTPUT_DWARF_DATA
 #define ASM_OUTPUT_DWARF_DATA(FILE,VALUE) \
   fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP, \
-          (unsigned long) VALUE)
+          (unsigned long) (VALUE))
 #endif
 
 #ifndef ASM_OUTPUT_DWARF_ADDR_DATA
 #define ASM_OUTPUT_DWARF_ADDR_DATA(FILE,VALUE) \
   fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_WORD_ASM_OP, \
-          (unsigned long) VALUE)
+          (unsigned long) (VALUE))
 #endif
 
 #ifndef ASM_OUTPUT_DWARF_DATA8
@@ -387,13 +399,13 @@ static void dwarf2out_stack_adjust        PROTO((rtx));
   do {                                                                 \
     if (WORDS_BIG_ENDIAN)                                              \
       {                                                                        \
-       fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \
-       fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, LOW_VALUE);\
+       fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, (HIGH_VALUE));\
+       fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (LOW_VALUE));\
       }                                                                        \
     else                                                               \
       {                                                                        \
-       fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\
-       fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \
+       fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, (LOW_VALUE)); \
+       fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (HIGH_VALUE)); \
       }                                                                        \
   } while (0)
 #endif
@@ -511,17 +523,19 @@ expand_builtin_dwarf_fp_regnum ()
 #endif
 
 /* Return a pointer to a copy of the section string name S with all
-   attributes stripped off.  */
+   attributes stripped off, and an asterisk prepended (for assemble_name).  */
 
 static inline char *
 stripattributes (s)
      char *s;
 {
-  char *stripped = xstrdup (s);
+  char *stripped = xmalloc (strlen (s) + 2);
   char *p = stripped;
 
-  while (*p && *p != ',')
-    p++;
+  *p++ = '*';
+
+  while (*s && *s != ',')
+    *p++ = *s++;
 
   *p = '\0';
   return stripped;
@@ -625,24 +639,28 @@ expand_builtin_dwarf_reg_size (reg_tree, target)
     }
   else
     {
+      /* Initialize last_end to be larger than any possible
+        DWARF_FRAME_REGNUM.  */
+      int last_end = 0x7fffffff;
       --n_ranges;
       t = build_int_2 (ranges[n_ranges].size, 0);
-      size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
-      for (; n_ranges--; )
+      do
        {
-         if ((DWARF_FRAME_REGNUM (ranges[n_ranges].end)
-              - DWARF_FRAME_REGNUM (ranges[n_ranges].beg))
-             != ranges[n_ranges].end - ranges[n_ranges].beg)
+         int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
+         int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end);
+         if (beg < 0)
+           continue;
+         if (end >= last_end)
            abort ();
-         if (DWARF_FRAME_REGNUM (ranges[n_ranges].beg) >= size)
+         last_end = end;
+         if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg)
            abort ();
-         size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
          t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
-                           build_int_2 (DWARF_FRAME_REGNUM
-                                        (ranges[n_ranges].end), 0)));
+                           build_int_2 (end, 0)));
          t = fold (build (COND_EXPR, integer_type_node, t2,
                           build_int_2 (ranges[n_ranges].size, 0), t));
        }
+      while (--n_ranges >= 0);
     }
   return expand_expr (t, target, Pmode, 0);
 }
@@ -1019,7 +1037,7 @@ static void
 initial_return_save (rtl)
      register rtx rtl;
 {
-  unsigned reg = -1;
+  unsigned int reg = (unsigned int) -1;
   long offset = 0;
 
   switch (GET_CODE (rtl))
@@ -1206,7 +1224,12 @@ dwarf2out_frame_debug (insn)
 
   label = dwarf2out_cfi_label ();
     
-  insn = PATTERN (insn);
+  src = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
+  if (src)
+    insn = XEXP (src, 0);
+  else
+    insn = PATTERN (insn);
+
   /* Assume that in a PARALLEL prologue insn, only the first elt is
      significant.  Currently this is true.  */
   if (GET_CODE (insn) == PARALLEL)
@@ -1226,7 +1249,7 @@ dwarf2out_frame_debug (insn)
        {
          /* Setting FP from SP.  */
        case REG:
-         if (cfa_reg != REGNO (src))
+         if (cfa_reg != (unsigned) REGNO (src))
            abort ();
          if (REGNO (dest) != STACK_POINTER_REGNUM
              && !(frame_pointer_needed
@@ -1246,7 +1269,7 @@ dwarf2out_frame_debug (insn)
                  offset = INTVAL (XEXP (src, 1));
                  break;
                case REG:
-                 if (REGNO (XEXP (src, 1)) != cfa_temp_reg)
+                 if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
                    abort ();
                  offset = cfa_temp_value;
                  break;
@@ -1257,7 +1280,7 @@ dwarf2out_frame_debug (insn)
              if (XEXP (src, 0) == hard_frame_pointer_rtx)
                {
                  /* Restoring SP from FP in the epilogue.  */
-                 if (cfa_reg != HARD_FRAME_POINTER_REGNUM)
+                 if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
                    abort ();
                  cfa_reg = STACK_POINTER_REGNUM;
                }
@@ -1293,7 +1316,7 @@ dwarf2out_frame_debug (insn)
               else if (XEXP (src, 0) == hard_frame_pointer_rtx
                        && GET_CODE (XEXP (src, 1)) == CONST_INT)
                 {
-                 if (cfa_reg != HARD_FRAME_POINTER_REGNUM)
+                 if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
                    abort ();
                   offset = INTVAL (XEXP (src, 1));
                   if (GET_CODE (src) == PLUS)
@@ -1310,7 +1333,7 @@ dwarf2out_frame_debug (insn)
                  || XEXP (src, 1) != stack_pointer_rtx)
                abort ();
              if (GET_CODE (XEXP (src, 0)) != REG
-                 || REGNO (XEXP (src, 0)) != cfa_temp_reg)
+                 || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
                abort ();
              if (cfa_reg != STACK_POINTER_REGNUM)
                abort ();
@@ -1326,8 +1349,8 @@ dwarf2out_frame_debug (insn)
 
        case IOR:
          if (GET_CODE (XEXP (src, 0)) != REG
-             || REGNO (XEXP (src, 0)) != cfa_temp_reg
-             || REGNO (dest) != cfa_temp_reg
+             || (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));
@@ -1370,11 +1393,18 @@ dwarf2out_frame_debug (insn)
          if (GET_CODE (src) == MINUS)
            offset = -offset;
 
-         if (cfa_store_reg != REGNO (XEXP (XEXP (dest, 0), 0)))
+         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 ();
        }
@@ -1621,6 +1651,11 @@ output_cfi (cfi, fde)
 #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.  */
@@ -1653,7 +1688,7 @@ output_call_frame_info (for_eh)
 #else
       tree label = get_file_function_name ('F');
 
-      data_section ();
+      force_data_section ();
       ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
       ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
       ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
@@ -1791,8 +1826,16 @@ output_call_frame_info (for_eh)
       fputc ('\n', asm_out_file);
       ASM_OUTPUT_LABEL (asm_out_file, l1);
 
+      /* ??? This always emits a 4 byte offset when for_eh is true, but it
+        emits a target dependent sized offset when for_eh is not true.
+        This inconsistency may confuse gdb.  The only case where we need a
+        non-4 byte offset is for the Irix6 N64 ABI, so we may lose SGI
+        compatibility if we emit a 4 byte offset.  We need a 4 byte offset
+        though in order to be compatible with the dwarf_fde struct in frame.c.
+        If the for_eh case is changed, then the struct in frame.c has
+        to be adjusted appropriately.  */
       if (for_eh)
-       ASM_OUTPUT_DWARF_DELTA (asm_out_file, l1, "__FRAME_BEGIN__");
+       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, l1, "__FRAME_BEGIN__");
       else
        ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (FRAME_SECTION));
       if (flag_debug_asm)
@@ -1943,7 +1986,7 @@ dwarf2out_frame_finish ()
 /* And now, the support for symbolic debugging information.  */
 #ifdef DWARF2_DEBUGGING_INFO
 
-extern char *getpwd ();
+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'
@@ -2363,7 +2406,7 @@ static tree dwarf_last_decl;
 
 /* Forward declarations for functions defined in this file.  */
 
-static void addr_const_to_string       PROTO((char *, rtx));
+static void addr_const_to_string       PROTO((dyn_string_t, rtx));
 static char *addr_to_string            PROTO((rtx));
 static int is_pseudo_reg               PROTO((rtx));
 static tree type_main_variant          PROTO((tree));
@@ -2372,7 +2415,9 @@ 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));
+#if 0
 static char *dwarf_type_encoding_name  PROTO((unsigned));
+#endif
 static tree decl_ultimate_origin       PROTO((tree));
 static tree block_ultimate_origin      PROTO((tree));
 static tree decl_class_context         PROTO((tree));
@@ -2503,7 +2548,9 @@ static void add_type_attribute            PROTO((dw_die_ref, tree, int, int,
                                               dw_die_ref));
 static char *type_tag                  PROTO((tree));
 static tree member_declared_type       PROTO((tree));
+#if 0
 static char *decl_start_label          PROTO((tree));
+#endif
 static void gen_array_type_die         PROTO((tree, dw_die_ref));
 static void gen_set_type_die           PROTO((tree, dw_die_ref));
 #if 0
@@ -2621,13 +2668,16 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
    macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
    a string rather than writing to a file.  */
 #ifndef ASM_NAME_TO_STRING
-#define ASM_NAME_TO_STRING(STR, NAME) \
-  do {                                                                       \
-      if ((NAME)[0] == '*')                                                  \
-       strcpy (STR, NAME+1);                                                 \
-      else                                                                   \
-       strcpy (STR, NAME);                                                   \
-  }                                                                           \
+#define ASM_NAME_TO_STRING(STR, NAME)                  \
+  do {                                                 \
+      if ((NAME)[0] == '*')                            \
+       dyn_string_append (STR, NAME + 1);              \
+      else                                             \
+       {                                               \
+         dyn_string_append (STR, user_label_prefix);   \
+         dyn_string_append (STR, NAME);                \
+       }                                               \
+  }                                                    \
   while (0)
 #endif
 \f
@@ -2639,50 +2689,44 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
 
 static void
 addr_const_to_string (str, x)
-     char *str;
+     dyn_string_t str;
      rtx x;
 {
   char buf1[256];
-  char buf2[256];
 
 restart:
-  str[0] = '\0';
   switch (GET_CODE (x))
     {
     case PC:
       if (flag_pic)
-       strcat (str, ",");
+       dyn_string_append (str, ",");
       else
        abort ();
       break;
 
     case SYMBOL_REF:
-      ASM_NAME_TO_STRING (buf1, XSTR (x, 0));
-      strcat (str, buf1);
+      ASM_NAME_TO_STRING (str, XSTR (x, 0));
       break;
 
     case LABEL_REF:
       ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
-      ASM_NAME_TO_STRING (buf2, buf1);
-      strcat (str, buf2);
+      ASM_NAME_TO_STRING (str, buf1);
       break;
 
     case CODE_LABEL:
       ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
-      ASM_NAME_TO_STRING (buf2, buf1);
-      strcat (str, buf2);
+      ASM_NAME_TO_STRING (str, buf1);
       break;
 
     case CONST_INT:
       sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
-      strcat (str, buf1);
+      dyn_string_append (str, buf1);
       break;
 
     case CONST:
       /* This used to output parentheses around the expression, but that does 
          not work on the 386 (either ATT or BSD assembler).  */
-      addr_const_to_string (buf1, XEXP (x, 0));
-      strcat (str, buf1);
+      addr_const_to_string (str, XEXP (x, 0));
       break;
 
     case CONST_DOUBLE:
@@ -2697,7 +2741,7 @@ restart:
          else
            sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
                     CONST_DOUBLE_LOW (x));
-         strcat (str, buf1);
+         dyn_string_append (str, buf1);
        }
       else
        /* We can't handle floating point constants; PRINT_OPERAND must
@@ -2709,23 +2753,19 @@ restart:
       /* Some assemblers need integer constants to appear last (eg masm).  */
       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
        {
-         addr_const_to_string (buf1, XEXP (x, 1));
-         strcat (str, buf1);
+         addr_const_to_string (str, XEXP (x, 1));
          if (INTVAL (XEXP (x, 0)) >= 0)
-           strcat (str, "+");
+           dyn_string_append (str, "+");
 
-         addr_const_to_string (buf1, XEXP (x, 0));
-         strcat (str, buf1);
+         addr_const_to_string (str, XEXP (x, 0));
        }
       else
        {
-         addr_const_to_string (buf1, XEXP (x, 0));
-         strcat (str, buf1);
+         addr_const_to_string (str, XEXP (x, 0));
          if (INTVAL (XEXP (x, 1)) >= 0)
-           strcat (str, "+");
+           dyn_string_append (str, "+");
 
-         addr_const_to_string (buf1, XEXP (x, 1));
-         strcat (str, buf1);
+         addr_const_to_string (str, XEXP (x, 1));
        }
       break;
 
@@ -2736,28 +2776,22 @@ restart:
       if (GET_CODE (x) != MINUS)
        goto restart;
 
-      addr_const_to_string (buf1, XEXP (x, 0));
-      strcat (str, buf1);
-      strcat (str, "-");
+      addr_const_to_string (str, XEXP (x, 0));
+      dyn_string_append (str, "-");
       if (GET_CODE (XEXP (x, 1)) == CONST_INT
          && INTVAL (XEXP (x, 1)) < 0)
        {
-         strcat (str, ASM_OPEN_PAREN);
-         addr_const_to_string (buf1, XEXP (x, 1));
-         strcat (str, buf1);
-         strcat (str, ASM_CLOSE_PAREN);
+         dyn_string_append (str, ASM_OPEN_PAREN);
+         addr_const_to_string (str, XEXP (x, 1));
+         dyn_string_append (str, ASM_CLOSE_PAREN);
        }
       else
-       {
-         addr_const_to_string (buf1, XEXP (x, 1));
-         strcat (str, buf1);
-       }
+       addr_const_to_string (str, XEXP (x, 1));
       break;
 
     case ZERO_EXTEND:
     case SIGN_EXTEND:
-      addr_const_to_string (buf1, XEXP (x, 0));
-      strcat (str, buf1);
+      addr_const_to_string (str, XEXP (x, 0));
       break;
 
     default:
@@ -2772,9 +2806,16 @@ static char *
 addr_to_string (x)
      rtx x;
 {
-  char buf[1024];
-  addr_const_to_string (buf, x);
-  return xstrdup (buf);
+  dyn_string_t ds = dyn_string_new (256);
+  char *s;
+
+  addr_const_to_string (ds, x);
+  
+  /* Return the dynamically allocated string, but free the
+     dyn_string_t itself.  */
+  s = ds->s;
+  free (ds);
+  return s;
 }
 
 /* Test if rtl node points to a pseudo register.  */
@@ -3471,6 +3512,7 @@ dwarf_stack_op_name (op)
 
 /* Convert a DWARF type code into its string name.  */
 
+#if 0
 static char *
 dwarf_type_encoding_name (enc)
      register unsigned enc;
@@ -3497,6 +3539,7 @@ dwarf_type_encoding_name (enc)
       return "DW_ATE_<unknown>";
     }
 }
+#endif
 \f
 /* Determine the "ultimate origin" of a decl.  The decl may be an inlined
    instance of an inlined instance of a decl which is local to an inline
@@ -3508,24 +3551,14 @@ static tree
 decl_ultimate_origin (decl)
      register tree decl;
 {
-  register tree immediate_origin = DECL_ABSTRACT_ORIGIN (decl);
-
-  if (immediate_origin == NULL_TREE)
-    return NULL_TREE;
-  else
-    {
-      register tree ret_val;
-      register tree lookahead = immediate_origin;
-
-      do
-       {
-         ret_val = lookahead;
-         lookahead = DECL_ABSTRACT_ORIGIN (ret_val);
-       }
-      while (lookahead != NULL && lookahead != ret_val);
+#ifdef ENABLE_CHECKING 
+  if (DECL_FROM_INLINE (DECL_ORIGIN (decl)))
+    /* Since the DECL_ABSTRACT_ORIGIN for a DECL is supposed to be the
+       most distant ancestor, this should never happen.  */
+    abort ();
+#endif
 
-      return ret_val;
-    }
+  return DECL_ABSTRACT_ORIGIN (decl);
 }
 
 /* Determine the "ultimate origin" of a block.  The block may be an inlined
@@ -4437,29 +4470,18 @@ build_abbrev_table (die)
     build_abbrev_table (c);
 }
 \f
-/* Return the size of a string, including the null byte.  */
+/* Return the size of a string, including the null byte.
+
+   This used to treat backslashes as escapes, and hence they were not included
+   in the count.  However, that conflicts with what ASM_OUTPUT_ASCII does,
+   which treats a backslash as a backslash, escaping it if necessary, and hence
+   we must include them in the count.  */
 
 static unsigned long
 size_of_string (str)
      register char *str;
 {
-  register unsigned long size = 0;
-  register unsigned long slen = strlen (str);
-  register unsigned long i;
-  register unsigned c;
-
-  for (i = 0; i < slen; ++i)
-    {
-      c = str[i];
-      if (c == '\\')
-       ++i;
-
-      size += 1;
-    }
-
-  /* Null terminator.  */
-  size += 1;
-  return size;
+  return strlen (str) + 1;
 }
 
 /* Return the size of a location descriptor.  */
@@ -5185,7 +5207,6 @@ output_die (die)
   register unsigned long ref_offset;
   register unsigned long size;
   register dw_loc_descr_ref loc;
-  register int i;
 
   output_uleb128 (die->die_abbrev);
   if (flag_debug_asm)
@@ -5288,24 +5309,27 @@ output_die (die)
          break;
 
        case dw_val_class_float:
-         ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
-                                 a->dw_attr_val.v.val_float.length * 4);
-         if (flag_debug_asm)
-           fprintf (asm_out_file, "\t%s %s",
-                    ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
-
-         fputc ('\n', asm_out_file);
-         for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i)
-           {
-             ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
-                                     a->dw_attr_val.v.val_float.array[i]);
-             if (flag_debug_asm)
-               fprintf (asm_out_file, "\t%s fp constant word %d",
-                        ASM_COMMENT_START, i);
+         {
+           register unsigned int i;
+           ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
+                                   a->dw_attr_val.v.val_float.length * 4);
+           if (flag_debug_asm)
+             fprintf (asm_out_file, "\t%s %s",
+                      ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
+
+           fputc ('\n', asm_out_file);
+           for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i)
+             {
+               ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
+                                       a->dw_attr_val.v.val_float.array[i]);
+               if (flag_debug_asm)
+                 fprintf (asm_out_file, "\t%s fp constant word %u",
+                          ASM_COMMENT_START, i);
 
-             fputc ('\n', asm_out_file);
-           }
+               fputc ('\n', asm_out_file);
+             }
          break;
+         }
 
        case dw_val_class_flag:
          ASM_OUTPUT_DWARF_DATA1 (asm_out_file, a->dw_attr_val.v.val_flag);
@@ -5348,7 +5372,7 @@ output_die (die)
          else
            ASM_OUTPUT_ASCII (asm_out_file,
                              a->dw_attr_val.v.val_str,
-                             strlen (a->dw_attr_val.v.val_str) + 1);
+                             (int) strlen (a->dw_attr_val.v.val_str) + 1);
          break;
 
        default:
@@ -5500,7 +5524,8 @@ output_pubnames ()
        }
       else
        {
-         ASM_OUTPUT_ASCII (asm_out_file, pub->name, strlen (pub->name) + 1);
+         ASM_OUTPUT_ASCII (asm_out_file, pub->name,
+                           (int) strlen (pub->name) + 1);
        }
 
       fputc ('\n', asm_out_file);
@@ -5578,12 +5603,13 @@ output_aranges ()
             ASM_COMMENT_START, 2 * PTR_SIZE);
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_SECTION);
+  ASM_OUTPUT_DWARF_ADDR (asm_out_file, stripattributes (TEXT_SECTION));
   if (flag_debug_asm)
     fprintf (asm_out_file, "\t%s Address", ASM_COMMENT_START);
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_DWARF_ADDR_DELTA (asm_out_file, text_end_label, TEXT_SECTION);
+  ASM_OUTPUT_DWARF_ADDR_DELTA (asm_out_file, text_end_label,
+                              stripattributes (TEXT_SECTION));
   if (flag_debug_asm)
     fprintf (asm_out_file, "%s Length", ASM_COMMENT_START);
 
@@ -5736,7 +5762,7 @@ output_line_info ()
        {
          ASM_OUTPUT_ASCII (asm_out_file,
                            file_table[ft_index],
-                           strlen (file_table[ft_index]) + 1);
+                           (int) strlen (file_table[ft_index]) + 1);
        }
 
       fputc ('\n', asm_out_file);
@@ -5768,14 +5794,14 @@ output_line_info ()
   fputc ('\n', asm_out_file);
   ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_SECTION);
+  ASM_OUTPUT_DWARF_ADDR (asm_out_file, stripattributes (TEXT_SECTION));
   fputc ('\n', asm_out_file);
 
   /* Generate the line number to PC correspondence table, encoded as
      a series of state machine operations.  */
   current_file = 1;
   current_line = 1;
-  strcpy (prev_line_label, TEXT_SECTION);
+  strcpy (prev_line_label, stripattributes (TEXT_SECTION));
   for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
     {
       register dw_line_info_ref line_info;
@@ -6176,7 +6202,7 @@ base_type_die (type)
   base_type_result = new_die (DW_TAG_base_type, comp_unit_die);
   add_AT_string (base_type_result, DW_AT_name, type_name);
   add_AT_unsigned (base_type_result, DW_AT_byte_size,
-                  TYPE_PRECISION (type) / BITS_PER_UNIT);
+                  int_size_in_bytes (type));
   add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
 
   return base_type_result;
@@ -7058,6 +7084,38 @@ add_location_or_const_value_attribute (die, decl)
                   && TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
                rtl = DECL_INCOMING_RTL (decl);
        }
+
+      /* If the parm was passed in registers, but lives on the stack, then
+        make a big endian correction if the mode of the type of the
+        parameter is not the same as the mode of the rtl.  */
+      /* ??? This is the same series of checks that are made in dbxout.c before
+        we reach the big endian correction code there.  It isn't clear if all
+        of these checks are necessary here, but keeping them all is the safe
+        thing to do.  */
+      else if (GET_CODE (rtl) == MEM
+              && XEXP (rtl, 0) != const0_rtx
+              && ! CONSTANT_P (XEXP (rtl, 0))
+              /* Not passed in memory.  */
+              && GET_CODE (DECL_INCOMING_RTL (decl)) != MEM
+              /* Not passed by invisible reference.  */
+              && (GET_CODE (XEXP (rtl, 0)) != REG
+                  || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM
+                  || REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+                  || REGNO (XEXP (rtl, 0)) == ARG_POINTER_REGNUM
+#endif
+                    )
+              /* Big endian correction check.  */
+              && BYTES_BIG_ENDIAN
+              && TYPE_MODE (TREE_TYPE (decl)) != GET_MODE (rtl)
+              && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl)))
+                  < UNITS_PER_WORD))
+       {
+         int offset = (UNITS_PER_WORD
+                       - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))));
+         rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)),
+                            plus_constant (XEXP (rtl, 0), offset));
+       }
     }
 
   if (rtl == NULL_RTX)
@@ -7530,7 +7588,7 @@ push_decl_scope (scope)
      subtype.  In such a case, we need to search the decl_scope_table to
      find the parent of this subtype.  */
 
-  if (TREE_CODE_CLASS (TREE_CODE (scope)) == 't')
+  if (AGGREGATE_TYPE_P (scope))
     containing_scope = TYPE_CONTEXT (scope);
   else
     containing_scope = NULL_TREE;
@@ -7582,6 +7640,12 @@ scope_die_for (t, context_die)
   if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
     containing_scope = NULL_TREE;
 
+  /* Ignore function type "scopes" from the C frontend.  They mean that
+     a tagged type is local to a parmlist of a function declarator, but
+     that isn't useful to DWARF.  */
+  if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE)
+    containing_scope = NULL_TREE;
+
   /* Function-local tags and functions get stuck in limbo until they are
      fixed up by decls_for_scope.  */
   if (context_die == NULL && containing_scope != NULL_TREE
@@ -7618,12 +7682,14 @@ scope_die_for (t, context_die)
 
       if (i < 0)
        {
-         if (scope_die != comp_unit_die
-             || TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
+         if (TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
            abort ();
          if (debug_info_level > DINFO_LEVEL_TERSE
              && !TREE_ASM_WRITTEN (containing_scope))
            abort ();
+
+         /* If none of the current dies are suitable, we get file scope.  */
+         scope_die = comp_unit_die;
        }
     }
 
@@ -7727,6 +7793,7 @@ member_declared_type (member)
 /* Get the decl's label, as described by its RTL. This may be different
    from the DECL_NAME name used in the source file.  */
 
+#if 0
 static char *
 decl_start_label (decl)
      register tree decl;
@@ -7744,6 +7811,7 @@ decl_start_label (decl)
   fnname = XSTR (x, 0);
   return fnname;
 }
+#endif
 \f
 /* These routines generate the internal representation of the DIE's for
    the compilation unit.  Debugging information is collected by walking
@@ -8048,8 +8116,7 @@ gen_unspecified_parameters_die (decl_or_type, context_die)
      register tree decl_or_type;
      register dw_die_ref context_die;
 {
-  register dw_die_ref parm_die = new_die (DW_TAG_unspecified_parameters,
-                                         context_die);
+  new_die (DW_TAG_unspecified_parameters, context_die);
 }
 
 /* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a
@@ -8163,7 +8230,17 @@ gen_subprogram_die (decl, context_die)
        = lookup_filename (DECL_SOURCE_FILE (decl));
 
       if (get_AT_flag (old_die, DW_AT_declaration) != 1)
-       abort ();
+       {
+         /* ??? This can happen if there is a bug in the program, for
+            instance, if it has duplicate function definitions.  Ideally,
+            we should detect this case and ignore it.  For now, if we have
+            already reported an error, any error at all, then assume that
+            we got here because of a input error, not a dwarf2 bug.  */
+         extern int errorcount;
+         if (errorcount)
+           return;
+         abort ();
+       }
 
       /* If the definition comes from the same place as the declaration,
         maybe use the old DIE.  We always want the DIE for this function
@@ -8798,7 +8875,7 @@ gen_struct_or_union_type_die (type, context_die)
     return;
 
   if (TYPE_CONTEXT (type) != NULL_TREE
-      && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't')
+      && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)))
     nested = 1;
 
   scope_die = scope_die_for (type, context_die);
@@ -9011,7 +9088,7 @@ gen_type_die (type, context_die)
       /* If this is a nested type whose containing class hasn't been
         written out yet, writing it out will cover this one, too.  */
       if (TYPE_CONTEXT (type)
-         && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't'
+         && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
          && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
        {
          gen_type_die (TYPE_CONTEXT (type), context_die);
@@ -9030,7 +9107,7 @@ gen_type_die (type, context_die)
        gen_struct_or_union_type_die (type, context_die);
 
       if (TYPE_CONTEXT (type)
-         && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't'
+         && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
          && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
        pop_decl_scope ();
 
@@ -9184,7 +9261,7 @@ gen_block_die (stmt, context_die, depth)
 }
 
 /* Generate all of the decls declared within a given scope and (recursively)
-   all of it's sub-blocks.  */
+   all of its sub-blocks.  */
 
 static void
 decls_for_scope (stmt, context_die, depth)
@@ -9410,7 +9487,7 @@ dwarf2out_decl (decl)
   if (DECL_IGNORED_P (decl))
     {
       if (TREE_CODE (decl) == FUNCTION_DECL
-         && DECL_INITIAL (decl) != NULL)
+          && DECL_INITIAL (decl) != NULL)
        abort ();
 
       return;
@@ -9673,7 +9750,7 @@ dwarf2out_line (filename, line)
 
 void
 dwarf2out_start_source_file (filename)
-     register char *filename;
+     register char *filename ATTRIBUTE_UNUSED;
 {
 }
 
@@ -9708,8 +9785,8 @@ dwarf2out_define (lineno, buffer)
 
 void
 dwarf2out_undef (lineno, buffer)
-     register unsigned lineno;
-     register char *buffer;
+     register unsigned lineno ATTRIBUTE_UNUSED;
+     register char *buffer ATTRIBUTE_UNUSED;
 {
 }
 
@@ -9843,7 +9920,8 @@ dwarf2out_finish ()
         was in .text.  */
       if (separate_line_info_table_in_use == 0)
        {
-         add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, TEXT_SECTION);
+         add_AT_lbl_id (comp_unit_die, DW_AT_low_pc,
+                        stripattributes (TEXT_SECTION));
          add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label);
        }