OSDN Git Service

[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index c56aeec..8661080 100644 (file)
@@ -1,5 +1,5 @@
 /* Output Dwarf2 format symbol table information from the GNU C compiler.
-   Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 95, 96, 97, 1998 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).
@@ -27,18 +27,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    information.  */
 
 #include "config.h"
+#include "system.h"
 #include "defaults.h"
-#include <stdio.h>
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 #include "tree.h"
 #include "flags.h"
 #include "rtl.h"
@@ -50,6 +40,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.  */
@@ -67,6 +60,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
@@ -211,6 +207,7 @@ static void initial_return_save             PROTO((rtx));
 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));
 
 /* Definitions of defaults for assembler-dependent names of various
    pseudo-ops and section names.
@@ -282,7 +279,7 @@ static unsigned reg_number          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
@@ -349,6 +346,16 @@ static unsigned reg_number         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))
@@ -370,24 +377,24 @@ static unsigned reg_number                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
@@ -395,13 +402,13 @@ static unsigned reg_number                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
@@ -519,17 +526,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;
@@ -588,18 +597,26 @@ expand_builtin_dwarf_reg_size (reg_tree, target)
        continue;
 
       mode = reg_raw_mode[i];
+
       /* CCmode is arbitrarily given a size of 4 bytes.  It is more useful
         to use the same size as word_mode, since that reduces the number
         of ranges we need.  It should not matter, since the result should
         never be used for a condition code register anyways.  */
-      if (mode == CCmode)
+      if (GET_MODE_CLASS (mode) == MODE_CC)
        mode = word_mode;
+
       size = GET_MODE_SIZE (mode);
 
+      /* If this register is not valid in the specified mode and
+        we have a previous size, use that for the size of this
+        register to avoid making junk tiny ranges.  */
+      if (! HARD_REGNO_MODE_OK (i, mode) && last_size != -1)
+       size = last_size;
+
       if (size != last_size)
        {
          ranges[n_ranges].beg = i;
-         ranges[n_ranges].size = last_size = GET_MODE_SIZE (reg_raw_mode[i]);
+         ranges[n_ranges].size = last_size = size;
          ++n_ranges;
          if (n_ranges >= 5)
            abort ();
@@ -625,24 +642,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);
 }
@@ -847,6 +868,9 @@ static long cfa_store_offset;
 /* The running total of the size of arguments pushed onto the stack.  */
 static long args_size;
 
+/* The last args_size we actually output.  */
+static long old_args_size;
+
 /* Entry point to update the canonical frame address (CFA).
    LABEL is passed to add_fde_cfi.  The value of CFA is now to be
    calculated from REG+OFFSET.  */
@@ -914,7 +938,9 @@ reg_save (label, reg, sreg, offset)
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
 
-  if (sreg == -1)
+  /* The following comparison is correct. -1 is used to indicate that
+     the value isn't a register number.  */
+  if (sreg == (unsigned int) -1)
     {
       if (reg & ~0x3f)
        /* The register number won't fit in 6 bits, so we have to use
@@ -961,7 +987,13 @@ dwarf2out_args_size (label, size)
      char *label;
      long size;
 {
-  register dw_cfi_ref cfi = new_cfi ();
+  register dw_cfi_ref cfi;
+
+  if (size == old_args_size)
+    return;
+  old_args_size = size;
+
+  cfi = new_cfi ();
   cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
   cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
   add_fde_cfi (label, cfi);
@@ -1067,6 +1099,26 @@ dwarf2out_stack_adjust (insn)
   long offset;
   char *label;
 
+  if (! asynchronous_exceptions && GET_CODE (insn) == CALL_INSN)
+    {
+      /* Extract the size of the args from the CALL rtx itself.  */
+
+      insn = PATTERN (insn);
+      if (GET_CODE (insn) == PARALLEL)
+       insn = XVECEXP (insn, 0, 0);
+      if (GET_CODE (insn) == SET)
+       insn = SET_SRC (insn);
+      assert (GET_CODE (insn) == CALL);
+      dwarf2out_args_size ("", INTVAL (XEXP (insn, 1)));
+      return;
+    }
+
+  /* If only calls can throw, and we have a frame pointer,
+     save up adjustments until we see the CALL_INSN.  */
+  else if (! asynchronous_exceptions
+          && cfa_reg != STACK_POINTER_REGNUM)
+    return;
+
   if (GET_CODE (insn) == BARRIER)
     {
       /* When we see a BARRIER, we know to reset args_size to 0.  Usually
@@ -1175,7 +1227,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)
@@ -1195,7 +1252,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
@@ -1215,7 +1272,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;
@@ -1226,7 +1283,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;
                }
@@ -1262,7 +1319,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)
@@ -1279,7 +1336,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 ();
@@ -1295,8 +1352,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));
@@ -1339,11 +1396,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 ();
        }
@@ -1590,6 +1654,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.  */
@@ -1760,8 +1829,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)
@@ -1850,7 +1927,7 @@ dwarf2out_begin_prologue ()
   fde->dw_fde_end = NULL;
   fde->dw_fde_cfi = NULL;
 
-  args_size = 0;
+  args_size = old_args_size = 0;
 }
 
 /* Output a marker (i.e. a label) for the absolute end of the generated code
@@ -1912,7 +1989,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'
@@ -2206,18 +2283,29 @@ static unsigned decl_die_table_in_use;
    decl_die_table.  */
 #define DECL_DIE_TABLE_INCREMENT 256
 
+/* Structure used for the decl_scope table.  scope is the current declaration
+   scope, and previous is the entry that is the parent of this scope.  This
+   is usually but not always the immediately preceeding entry.  */
+
+typedef struct decl_scope_struct
+{
+  tree scope;
+  int previous;
+}
+decl_scope_node;
+
 /* A pointer to the base of a table of references to declaration
    scopes.  This table is a display which tracks the nesting
    of declaration scopes at the current scope and containing
    scopes.  This table is used to find the proper place to
    define type declaration DIE's.  */
-static tree *decl_scope_table;
+static decl_scope_node *decl_scope_table;
 
 /* Number of elements currently allocated for the decl_scope_table.  */
-static unsigned decl_scope_table_allocated;
+static int decl_scope_table_allocated;
 
 /* Current level of nesting of declaration scopes.  */
-static unsigned decl_scope_depth;
+static int decl_scope_depth;
 
 /* Size (in elements) of increments by which we may expand the
    decl_scope_table.  */
@@ -2321,7 +2409,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));
@@ -2330,7 +2418,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));
@@ -2461,10 +2551,14 @@ 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
 static void gen_entry_point_die                PROTO((tree, dw_die_ref));
+#endif
 static void pend_type                  PROTO((tree));
 static void output_pending_types_for_scope PROTO((dw_die_ref));
 static void gen_inlined_enumeration_type_die PROTO((tree, dw_die_ref));
@@ -2577,13 +2671,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
@@ -2595,50 +2692,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:
@@ -2653,7 +2744,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
@@ -2665,23 +2756,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;
 
@@ -2692,28 +2779,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:
@@ -2728,9 +2809,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.  */
@@ -3427,6 +3515,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;
@@ -3453,6 +3542,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
@@ -3464,24 +3554,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
@@ -4393,29 +4473,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.  */
@@ -4658,7 +4727,7 @@ size_of_line_prolog ()
   size += DWARF_LINE_OPCODE_BASE - 1;
 
   /* Include directory table is empty (at present).  Count only the
-     the null byte used to terminate the table.  */
+     null byte used to terminate the table.  */
   size += 1;
 
   for (ft_index = 1; ft_index < file_table_in_use; ++ft_index)
@@ -5141,7 +5210,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)
@@ -5244,24 +5312,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);
@@ -5304,7 +5375,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:
@@ -5456,7 +5527,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);
@@ -5534,12 +5606,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);
 
@@ -5692,7 +5765,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);
@@ -5724,14 +5797,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;
@@ -6132,7 +6205,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;
@@ -6338,7 +6411,7 @@ reg_loc_descriptor (rtl)
   register dw_loc_descr_ref loc_result = NULL;
   register unsigned reg = reg_number (rtl);
 
-  if (reg >= 0 && reg <= 31)
+  if (reg <= 31)
     loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
   else
     loc_result = new_loc_descr (DW_OP_regx, reg, 0);
@@ -6363,7 +6436,7 @@ based_loc_descr (reg, offset)
 
   if (reg == fp_reg)
     loc_result = new_loc_descr (DW_OP_fbreg, offset, 0);
-  else if (reg >= 0 && reg <= 31)
+  else if (reg <= 31)
     loc_result = new_loc_descr (DW_OP_breg0 + reg, offset, 0);
   else
     loc_result = new_loc_descr (DW_OP_bregx, reg, offset);
@@ -7133,10 +7206,22 @@ add_bound_info (subrange_die, bound_attr, bound)
        {
          register dw_die_ref ctx = lookup_decl_die (current_function_decl);
          register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
+         register rtx loc = SAVE_EXPR_RTL (bound);
+
+         /* If the RTL for the SAVE_EXPR is memory, handle the case where
+            it references an outer function's frame.  */
+
+         if (GET_CODE (loc) == MEM)
+           {
+             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);
+           }
+
          add_AT_flag (decl_die, DW_AT_artificial, 1);
          add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
-         add_AT_location_description (decl_die, DW_AT_location,
-                                      SAVE_EXPR_RTL (bound));
+         add_AT_location_description (decl_die, DW_AT_location, loc);
          add_AT_die_ref (subrange_die, bound_attr, decl_die);
        }
 
@@ -7163,7 +7248,9 @@ add_subscript_info (type_die, type)
      register dw_die_ref type_die;
      register tree type;
 {
+#ifndef MIPS_DEBUGGING_INFO
   register unsigned dimension_number;
+#endif
   register tree lower, upper;
   register dw_die_ref subrange_die;
 
@@ -7452,19 +7539,55 @@ static void
 push_decl_scope (scope)
      tree scope;
 {
+  tree containing_scope;
+  int i;
+
   /* Make room in the decl_scope_table, if necessary.  */
   if (decl_scope_table_allocated == decl_scope_depth)
     {
       decl_scope_table_allocated += DECL_SCOPE_TABLE_INCREMENT;
       decl_scope_table
-       = (tree *) xrealloc (decl_scope_table,
-                            decl_scope_table_allocated * sizeof (tree));
+       = (decl_scope_node *) xrealloc (decl_scope_table,
+                                       (decl_scope_table_allocated
+                                        * sizeof (decl_scope_node)));
     }
 
-  decl_scope_table[decl_scope_depth++] = scope;
+  decl_scope_table[decl_scope_depth].scope = scope;
+
+  /* Sometimes, while recursively emitting subtypes within a class type,
+     we end up recuring on a subtype at a higher level then the current
+     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')
+    containing_scope = TYPE_CONTEXT (scope);
+  else
+    containing_scope = NULL_TREE;
+
+  /* The normal case.  */
+  if (decl_scope_depth == 0
+      || containing_scope == NULL_TREE
+      /* Ignore namespaces for the moment.  */
+      || TREE_CODE (containing_scope) == NAMESPACE_DECL
+      || containing_scope == decl_scope_table[decl_scope_depth - 1].scope)
+    decl_scope_table[decl_scope_depth].previous = decl_scope_depth - 1;
+  else
+    {
+      /* We need to search for the containing_scope.  */
+      for (i = 0; i < decl_scope_depth; i++)
+       if (decl_scope_table[i].scope == containing_scope)
+         break;
+
+      if (i == decl_scope_depth)
+       abort ();
+      else
+       decl_scope_table[decl_scope_depth].previous = i;
+    }
+
+  decl_scope_depth++;
 }
 
-/* Return the DIE for the scope the immediately contains this declaration.  */
+/* Return the DIE for the scope that immediately contains this declaration.  */
 
 static dw_die_ref
 scope_die_for (t, context_die)
@@ -7473,7 +7596,7 @@ scope_die_for (t, context_die)
 {
   register dw_die_ref scope_die = NULL;
   register tree containing_scope;
-  register unsigned long i;
+  register int i;
 
   /* Walk back up the declaration tree looking for a place to define
      this type.  */
@@ -7484,6 +7607,10 @@ scope_die_for (t, context_die)
   else
     containing_scope = DECL_CONTEXT (t);
 
+  /* Ignore namespaces for the moment.  */
+  if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
+    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
@@ -7494,12 +7621,31 @@ scope_die_for (t, context_die)
     scope_die = comp_unit_die;
   else
     {
-      for (i = decl_scope_depth, scope_die = context_die;
-          i > 0 && decl_scope_table[i - 1] != containing_scope;
-          scope_die = scope_die->die_parent, --i)
+      for (i = decl_scope_depth - 1, scope_die = context_die;
+          i >= 0 && decl_scope_table[i].scope != containing_scope;
+          (scope_die = scope_die->die_parent,
+           i = decl_scope_table[i].previous))
        ;
 
-      if (i == 0)
+      /* ??? Integrate_decl_tree does not handle BLOCK_TYPE_TAGS, nor
+        does it try to handle types defined by TYPE_DECLs.  Such types
+        thus have an incorrect TYPE_CONTEXT, which points to the block
+        they were originally defined in, instead of the current block
+        created by function inlining.  We try to detect that here and
+        work around it.  */
+
+      if (i < 0 && scope_die == comp_unit_die
+         && TREE_CODE (containing_scope) == BLOCK
+         && is_tagged_type (t)
+         && (block_ultimate_origin (decl_scope_table[decl_scope_depth - 1].scope)
+             == containing_scope))
+       {
+         scope_die = context_die;
+         /* Since the checks below are no longer applicable.  */
+         i = 0;
+       }
+
+      if (i < 0)
        {
          if (scope_die != comp_unit_die
              || TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
@@ -7610,6 +7756,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;
@@ -7627,6 +7774,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
@@ -7701,6 +7849,7 @@ gen_set_type_die (type, context_die)
   add_type_attribute (type_die, TREE_TYPE (type), 0, 0, context_die);
 }
 
+#if 0
 static void
 gen_entry_point_die (decl, context_die)
      register tree decl;
@@ -7722,6 +7871,7 @@ gen_entry_point_die (decl, context_die)
   else
     add_AT_lbl_id (decl_die, DW_AT_low_pc, decl_start_label (decl));
 }
+#endif
 
 /* Remember a type in the pending_types_list.  */
 
@@ -7929,8 +8079,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
@@ -8044,7 +8193,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
@@ -8805,7 +8964,7 @@ gen_type_die (type, context_die)
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
-  /* We are going to output a DIE to represent the unqualified version of of
+  /* 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.  */
   type = type_main_variant (type);
@@ -8950,7 +9109,7 @@ gen_tagged_type_instantiation_die (type, context_die)
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
-  /* We are going to output a DIE to represent the unqualified version of of
+  /* We are going to output a DIE to represent the unqualified version of
      this type (i.e. without any const or volatile qualifiers) so make sure
      that we have the main variant (i.e. the unqualified version) of this
      type now.  */
@@ -9065,7 +9224,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)
@@ -9152,7 +9311,7 @@ gen_decl_die (decl, context_die)
 
   /* If this ..._DECL node is marked to be ignored, then ignore it. But don't 
      ignore a function definition, since that would screw up our count of
-     blocks, and that it turn will completely screw up the the labels we will 
+     blocks, and that in turn will completely screw up the labels we will 
      reference in subsequent DW_AT_low_pc and DW_AT_high_pc attributes (for
      subsequent blocks).  */
   if (DECL_IGNORED_P (decl) && TREE_CODE (decl) != FUNCTION_DECL)
@@ -9284,14 +9443,14 @@ dwarf2out_decl (decl)
   /* If this ..._DECL node is marked to be ignored, then ignore it.  We gotta 
      hope that the node in question doesn't represent a function definition.
      If it does, then totally ignoring it is bound to screw up our count of
-     blocks, and that it turn will completely screw up the the labels we will 
+     blocks, and that in turn will completely screw up the labels we will 
      reference in subsequent DW_AT_low_pc and DW_AT_high_pc attributes (for
      subsequent blocks).  (It's too bad that BLOCK nodes don't carry their
      own sequence numbers with them!) */
   if (DECL_IGNORED_P (decl))
     {
       if (TREE_CODE (decl) == FUNCTION_DECL
-         && DECL_INITIAL (decl) != NULL)
+          && DECL_INITIAL (decl) != NULL)
        abort ();
 
       return;
@@ -9554,7 +9713,7 @@ dwarf2out_line (filename, line)
 
 void
 dwarf2out_start_source_file (filename)
-     register char *filename;
+     register char *filename ATTRIBUTE_UNUSED;
 {
 }
 
@@ -9589,8 +9748,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;
 {
 }
 
@@ -9622,9 +9781,10 @@ dwarf2out_init (asm_out_file, main_input_filename)
 
   /* Allocate the initial hunk of the decl_scope_table.  */
   decl_scope_table
-    = (tree *) xmalloc (DECL_SCOPE_TABLE_INCREMENT * sizeof (tree));
+    = (decl_scope_node *) xmalloc (DECL_SCOPE_TABLE_INCREMENT
+                                  * sizeof (decl_scope_node));
   bzero ((char *) decl_scope_table,
-        DECL_SCOPE_TABLE_INCREMENT * sizeof (tree));
+        DECL_SCOPE_TABLE_INCREMENT * sizeof (decl_scope_node));
   decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
   decl_scope_depth = 0;
 
@@ -9723,7 +9883,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);
        }