OSDN Git Service

($(OBJC_O)): Also depend on $(GCC_PASSES).
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index ebc7443..046ec32 100644 (file)
@@ -1,5 +1,5 @@
 /* Output sdb-format symbol table information from GNU compiler.
-   Copyright (C) 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,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.  */
 
 /*  mike@tredysvr.Tredydev.Unisys.COM says:
 I modified the struct.c example and have a nm of a .o resulting from the
@@ -34,7 +35,7 @@ AT&T C compiler.  From the example below I would conclude the following:
 4. All structure .defs are emitted before the typedefs that refer to them.
 
 5. All top level static and external variable definitions are moved to the
-   end of file with all top level statics occuring first before externs.
+   end of file with all top level statics occurring first before externs.
 
 6. All undefined references are at the end of the file.
 */
@@ -47,21 +48,24 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "rtl.h"
 #include <stdio.h>
 #include "regs.h"
+#include "defaults.h"
 #include "flags.h"
 #include "insn-config.h"
 #include "reload.h"
 
-/* Mips systems use the SDB functions to dump out symbols, but
-   do not supply usable syms.h include files.  */
-#if defined(USG) && !defined(MIPS)
+/* Mips systems use the SDB functions to dump out symbols, but do not
+   supply usable syms.h include files.  Which syms.h file to use is a
+   target parameter so don't use the native one if we're cross compiling.  */
+
+#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(CROSS_COMPILE)
 #include <syms.h>
 /* Use T_INT if we don't have T_VOID.  */
 #ifndef T_VOID
 #define T_VOID T_INT
 #endif
-#else /* not USG, or MIPS */
+#else
 #include "gsyms.h"
-#endif /* not USG, or MIPS */
+#endif
 
 /* #include <storclass.h>  used to be this instead of syms.h.  */
 
@@ -100,12 +104,20 @@ void sdbout_init ();
 void sdbout_symbol ();
 void sdbout_types();
 
-static void sdbout_typedefs ();
-static void sdbout_syms ();
-static void sdbout_one_type ();
-static void sdbout_queue_anonymous_type ();
-static void sdbout_dequeue_anonymous_type ();
-static int plain_type_1 ();
+static char *gen_fake_label            PROTO((void));
+static int plain_type                  PROTO((tree));
+static int template_name_p             PROTO((tree));
+static void sdbout_record_type_name    PROTO((tree));
+static int plain_type_1                        PROTO((tree, int));
+static void sdbout_block               PROTO((tree));
+static void sdbout_syms                        PROTO((tree));
+static void sdbout_queue_anonymous_type        PROTO((tree));
+static void sdbout_dequeue_anonymous_types PROTO((void));
+static void sdbout_type                        PROTO((tree));
+static void sbdout_field_types         PROTO((tree));
+static void sdbout_one_type            PROTO((tree));
+static void sdbout_parms               PROTO((tree));
+static void sdbout_reg_parms           PROTO((tree));
 \f
 /* Define the default sizes for various types.  */
 
@@ -258,12 +270,12 @@ do { fprintf (asm_out_file, "\t.def\t");          \
 /* Return the sdb tag identifier string for TYPE
    if TYPE has already been defined; otherwise return a null pointer.   */
 
-#define KNOWN_TYPE_TAG(type) (char *)(TYPE_SYMTAB_ADDRESS (type))
+#define KNOWN_TYPE_TAG(type)  TYPE_SYMTAB_POINTER (type)
 
 /* Set the sdb tag identifier string for TYPE to NAME.  */
 
 #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
-  (TYPE_SYMTAB_ADDRESS (TYPE) = (int)(NAME))
+  TYPE_SYMTAB_POINTER (TYPE) = (NAME)
 
 /* Return the name (a string) of the struct, union or enum tag
    described by the TREE_LIST node LINK.  This is 0 for an anonymous one.  */
@@ -276,6 +288,38 @@ do { fprintf (asm_out_file, "\t.def\t");           \
 /* Ensure we don't output a negative line number.  */
 #define MAKE_LINE_SAFE(line)  \
   if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1
+
+/* Perform linker optimization of merging header file definitions together
+   for targets with MIPS_DEBUGGING_INFO defined.  This won't work without a
+   post 960826 version of GAS.  Nothing breaks with earlier versions of GAS,
+   the optimization just won't be done.  The native assembler already has the
+   necessary support.  */
+
+#ifdef MIPS_DEBUGGING_INFO
+
+#ifndef PUT_SDB_SRC_FILE
+#define PUT_SDB_SRC_FILE(FILENAME) \
+output_file_directive (asm_out_file, (FILENAME))
+#endif
+
+/* ECOFF linkers have an optimization that does the same kind of thing as
+   N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the
+   executable.  To achieve this, GCC must output a .file for each file
+   name change.  */
+
+/* This is a stack of input files.  */
+
+struct sdb_file
+{
+  struct sdb_file *next;
+  char *name;
+};
+
+/* This is the top of the stack.  */
+
+static struct sdb_file *current_file;
+
+#endif /* MIPS_DEBUGGING_INFO */
 \f
 /* Set up for SDB output at the start of compilation.  */
 
@@ -285,12 +329,19 @@ sdbout_init (asm_file, input_file_name, syms)
      char *input_file_name;
      tree syms;
 {
-#if 0 /* Nothing need be output for the predefined types.  */
-  /* Get all permanent types that have typedef names,
-     and output them all, except for those already output.  */
-
-  sdbout_typedefs (syms);
+#ifdef MIPS_DEBUGGING_INFO
+  current_file = (struct sdb_file *) xmalloc (sizeof *current_file);
+  current_file->next = NULL;
+  current_file->name = input_file_name;
 #endif
+
+#ifdef RMS_QUICK_HACK_1
+  tree t;
+  for (t = syms; t; t = TREE_CHAIN (t))
+    if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0
+       && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
+      sdbout_symbol (t, 0);
+#endif  
 }
 
 #if 0
@@ -303,11 +354,10 @@ tag_of_ru_type (type,link)
      tree type,link;
 {
   if (TYPE_SYMTAB_ADDRESS (type))
-    return (char *)TYPE_SYMTAB_ADDRESS (type);
+    return TYPE_SYMTAB_ADDRESS (type);
   if (link && TREE_PURPOSE (link)
       && IDENTIFIER_POINTER (TREE_PURPOSE (link)))
-    TYPE_SYMTAB_ADDRESS (type)
-      = (int)IDENTIFIER_POINTER (TREE_PURPOSE (link));
+    TYPE_SYMTAB_ADDRESS (type) = IDENTIFIER_POINTER (TREE_PURPOSE (link));
   else
     return (char *) TYPE_SYMTAB_ADDRESS (type);
 }
@@ -344,8 +394,10 @@ gen_fake_label ()
 /* Produce the number that describes a pointer, function or array type.
    PREV is the number describing the target, value or element type.
    DT_type describes how to transform that type.  */
-#define PUSH_DERIVED_LEVEL(DT_type,PREV) \
-  ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))
+#define PUSH_DERIVED_LEVEL(DT_type,PREV)               \
+  ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT)                \
+   | ((int)DT_type << (int)N_BTSHFT)                   \
+   | ((PREV) & (int)N_BTMASK))
 
 /* Number of elements used in sdb_dims.  */
 static int sdb_n_dims = 0;
@@ -360,7 +412,7 @@ static int
 plain_type (type)
      tree type;
 {
-  int val = plain_type_1 (type);
+  int val = plain_type_1 (type, 0);
 
   /* If we have already saved up some array dimensions, print them now.  */
   if (sdb_n_dims > 0)
@@ -387,6 +439,17 @@ plain_type (type)
   return val;
 }
 
+static int
+template_name_p (name)
+     tree name;
+{
+  register char *ptr = IDENTIFIER_POINTER (name);
+  while (*ptr && *ptr != '<')
+    ptr++;
+
+  return *ptr != '\0';
+}
+
 static void
 sdbout_record_type_name (type)
      tree type;
@@ -402,19 +465,19 @@ sdbout_record_type_name (type)
       tree t = 0;
       /* Find the IDENTIFIER_NODE for the type name.  */
       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
-       {
-         t = TYPE_NAME (type);
-       }
-#if 1  /* As a temprary hack, use typedef names for C++ only.  */
-      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
-              && TYPE_LANG_SPECIFIC (type))
+       t = TYPE_NAME (type);
+      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
        {
          t = DECL_NAME (TYPE_NAME (type));
+         /* The DECL_NAME for templates includes "<>", which breaks
+            most assemblers.  Use its assembler name instead, which
+            has been mangled into being safe.  */
+         if (t && template_name_p (t))
+           t = DECL_ASSEMBLER_NAME (TYPE_NAME (type));
        }
-#endif
 
       /* Now get the name as a string, or invent one.  */
-      if (t != 0)
+      if (t != NULL_TREE)
        name = IDENTIFIER_POINTER (t);
     }
 
@@ -429,15 +492,25 @@ sdbout_record_type_name (type)
 #endif
 }
 
+/* Return the .type value for type TYPE.
+
+   LEVEL indicates how many levels deep we have recursed into the type.
+   The SDB debug format can only represent 6 derived levels of types.
+   After that, we must output inaccurate debug info.  We deliberately
+   stop before the 7th level, so that ADA recursive types will not give an
+   infinite loop.  */
+
 static int
-plain_type_1 (type)
+plain_type_1 (type, level)
      tree type;
+     int level;
 {
   if (type == 0)
     type = void_type_node;
-  if (type == error_mark_node)
+  else if (type == error_mark_node)
     type = integer_type_node;
-  type = TYPE_MAIN_VARIANT (type);
+  else
+    type = TYPE_MAIN_VARIANT (type);
 
   switch (TREE_CODE (type))
     {
@@ -446,39 +519,80 @@ plain_type_1 (type)
     case INTEGER_TYPE:
       {
        int size = int_size_in_bytes (type) * BITS_PER_UNIT;
+
+       /* Carefully distinguish all the standard types of C,
+          without messing up if the language is not C.
+          Note that we check only for the names that contain spaces;
+          other names might occur by coincidence in other languages.  */
+       if (TYPE_NAME (type) != 0
+           && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+           && DECL_NAME (TYPE_NAME (type)) != 0
+           && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
+         {
+           char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+           if (!strcmp (name, "unsigned char"))
+             return T_UCHAR;
+           if (!strcmp (name, "signed char"))
+             return T_CHAR;
+           if (!strcmp (name, "unsigned int"))
+             return T_UINT;
+           if (!strcmp (name, "short int"))
+             return T_SHORT;
+           if (!strcmp (name, "short unsigned int"))
+             return T_USHORT;
+           if (!strcmp (name, "long int"))
+             return T_LONG;
+           if (!strcmp (name, "long unsigned int"))
+             return T_ULONG;
+         }
+
        if (size == CHAR_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
        if (size == SHORT_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
        if (size == INT_TYPE_SIZE)
          return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
+       if (size == LONG_TYPE_SIZE)
+         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+       if (size == LONG_LONG_TYPE_SIZE)        /* better than nothing */
+         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
        return 0;
       }
 
     case REAL_TYPE:
       {
-       int size = int_size_in_bytes (type) * BITS_PER_UNIT;
-       if (size == FLOAT_TYPE_SIZE)
+       int precision = TYPE_PRECISION (type);
+       if (precision == FLOAT_TYPE_SIZE)
          return T_FLOAT;
-       if (size == DOUBLE_TYPE_SIZE)
+       if (precision == DOUBLE_TYPE_SIZE)
          return T_DOUBLE;
+#ifdef EXTENDED_SDB_BASIC_TYPES
+       if (precision == LONG_DOUBLE_TYPE_SIZE)
+         return T_LNGDBL;
+#endif
        return 0;
       }
 
     case ARRAY_TYPE:
       {
        int m;
-       m = plain_type_1 (TREE_TYPE (type));
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        if (sdb_n_dims < SDB_MAX_DIM)
          sdb_dims[sdb_n_dims++]
            = (TYPE_DOMAIN (type)
-              ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1
+              ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
+                 - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1)
               : 0);
        return PUSH_DERIVED_LEVEL (DT_ARY, m);
       }
 
     case RECORD_TYPE:
     case UNION_TYPE:
+    case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       {
        char *tag;
@@ -497,8 +611,8 @@ plain_type_1 (type)
               only if the .def has already been finished.
               At least on 386, the Unix assembler
               cannot handle forward references to tags.  */
-           /* But the 88100, it requires them, sigh... */
-           /* And the MIPS requires unknown refs as well... */
+           /* But the 88100, it requires them, sigh...  */
+           /* And the MIPS requires unknown refs as well...  */
            tag = KNOWN_TYPE_TAG (type);
            PUT_SDB_TAG (tag);
            /* These 3 lines used to follow the close brace.
@@ -510,18 +624,27 @@ plain_type_1 (type)
          }
        return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
                : (TREE_CODE (type) == UNION_TYPE) ? T_UNION
+               : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION
                : T_ENUM);
       }
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       int m = plain_type_1 (TREE_TYPE (type));
+       int m;
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        return PUSH_DERIVED_LEVEL (DT_PTR, m);
       }
     case FUNCTION_TYPE:
     case METHOD_TYPE:
       {
-       int m = plain_type_1 (TREE_TYPE (type));
+       int m;
+       if (level >= 6)
+         return T_VOID;
+       else
+         m = plain_type_1 (TREE_TYPE (type), level+1);
        return PUSH_DERIVED_LEVEL (DT_FCN, m);
       }
     default:
@@ -590,7 +713,6 @@ sdbout_symbol (decl, local)
      tree decl;
      int local;
 {
-  int letter = 0;
   tree type = TREE_TYPE (decl);
   tree context = NULL_TREE;
   rtx value;
@@ -599,6 +721,12 @@ sdbout_symbol (decl, local)
 
   sdbout_one_type (type);
 
+#if 0 /* This loses when functions are marked to be ignored,
+        which happens in the C++ front end.  */
+  if (DECL_IGNORED_P (decl))
+    return;
+#endif
+
   switch (TREE_CODE (decl))
     {
     case CONST_DECL:
@@ -610,7 +738,10 @@ sdbout_symbol (decl, local)
       context = decl_function_context (decl);
       if (context == current_function_decl)
        return;
-      if (TREE_EXTERNAL (decl))
+      /* Check DECL_INITIAL to distinguish declarations from definitions.
+        Don't output debug info here for declarations; they will have
+        a DECL_INITIAL value of 0.  */
+      if (! DECL_INITIAL (decl))
        return;
       if (GET_CODE (DECL_RTL (decl)) != MEM
          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
@@ -624,9 +755,14 @@ sdbout_symbol (decl, local)
       /* Done with tagged types.  */
       if (DECL_NAME (decl) == 0)
        return;
+      if (DECL_IGNORED_P (decl))
+       return;
 
       /* Output typedef name.  */
-      PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
+      if (template_name_p (DECL_NAME (decl)))
+       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+      else
+       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
       PUT_SDB_SCL (C_TPDEF);
       break;
 
@@ -638,7 +774,11 @@ sdbout_symbol (decl, local)
     case VAR_DECL:
       /* Don't mention a variable that is external.
         Let the file that defines it describe it.  */
-      if (TREE_EXTERNAL (decl))
+      if (DECL_EXTERNAL (decl))
+       return;
+
+      /* Ignore __FUNCTION__, etc.  */
+      if (DECL_IGNORED_P (decl))
        return;
 
       /* If there was an error in the declaration, don't dump core
@@ -647,7 +787,12 @@ sdbout_symbol (decl, local)
       if (DECL_RTL (decl) == 0)
        return;
 
-      value = eliminate_regs (DECL_RTL (decl), 0, 0);
+      DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX, 0);
+#ifdef LEAF_REG_REMAP
+      if (leaf_function)
+       leaf_renumber_regs_insn (DECL_RTL (decl));
+#endif
+      value = DECL_RTL (decl);
 
       /* Don't mention a variable at all
         if it was completely optimized into nothingness.
@@ -659,11 +804,9 @@ sdbout_symbol (decl, local)
        {
          regno = REGNO (DECL_RTL (decl));
          if (regno >= FIRST_PSEUDO_REGISTER)
-           regno = reg_renumber[REGNO (DECL_RTL (decl))];
-         if (regno < 0)
            return;
        }
-      else if (GET_CODE (DECL_RTL (decl)) == SUBREG)
+      else if (GET_CODE (value) == SUBREG)
        {
          int offset = 0;
          while (GET_CODE (value) == SUBREG)
@@ -675,18 +818,26 @@ sdbout_symbol (decl, local)
            {
              regno = REGNO (value);
              if (regno >= FIRST_PSEUDO_REGISTER)
-               regno = reg_renumber[REGNO (value)];
-             if (regno >= 0)
-               regno += offset;
+               return;
+             regno += offset;
            }
+         alter_subreg (DECL_RTL (decl));
+         value = DECL_RTL (decl);
        }
+      /* Don't output anything if an auto variable
+        gets RTL that is static.
+        GAS version 2.2 can't handle such output.  */
+      else if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0))
+              && ! TREE_STATIC (decl))
+       return;
 
       /* Emit any structure, union, or enum type that has not been output.
         This occurs for tag-less structs (et al) used to declare variables
         within functions.  */
       if (TREE_CODE (type) == ENUMERAL_TYPE
          || TREE_CODE (type) == RECORD_TYPE
-         || TREE_CODE (type) == UNION_TYPE)
+         || TREE_CODE (type) == UNION_TYPE
+         || TREE_CODE (type) == QUAL_UNION_TYPE)
        {
          if (TYPE_SIZE (type) != 0             /* not a forward reference */
              && KNOWN_TYPE_TAG (type) == 0)    /* not yet declared */
@@ -699,8 +850,13 @@ sdbout_symbol (decl, local)
          && DECL_INITIAL (decl))
        return;
 
+      /* C++ in 2.3 makes nameless symbols.  That will be fixed later.
+        For now, avoid crashing.  */
+      if (DECL_NAME (decl) == NULL_TREE)
+       return;
+
       /* Record the name for, starting a symtab entry.  */
-      name = IDENTIFIER_POINTER (DECL_NAME (decl));
+      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
       if (GET_CODE (value) == MEM
          && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
@@ -726,7 +882,7 @@ sdbout_symbol (decl, local)
       else if (GET_CODE (value) == MEM
               && (GET_CODE (XEXP (value, 0)) == MEM
                   || (GET_CODE (XEXP (value, 0)) == REG
-                      && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM
+                      && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM
                       && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
        /* If the value is indirect by memory or by a register
           that isn't the frame pointer
@@ -754,12 +910,17 @@ sdbout_symbol (decl, local)
          type = build_pointer_type (TREE_TYPE (decl));
        }
       else if (GET_CODE (value) == MEM
-              && GET_CODE (XEXP (value, 0)) == PLUS
-              && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
-              && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
+              && ((GET_CODE (XEXP (value, 0)) == PLUS
+                   && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
+                   && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
+                  /* This is for variables which are at offset zero from
+                     the frame pointer.  This happens on the Alpha.
+                     Non-frame pointer registers are excluded above.  */
+                  || (GET_CODE (XEXP (value, 0)) == REG)))
        {
-         /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
-            We want the value of that CONST_INT.  */
+         /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
+            or (MEM (REG...)).  We want the value of that CONST_INT
+            or zero.  */
          PUT_SDB_DEF (name);
          PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
          PUT_SDB_SCL (C_AUTO);
@@ -801,6 +962,9 @@ sdbout_toplevel_data (decl)
 {
   tree type = TREE_TYPE (decl);
 
+  if (DECL_IGNORED_P (decl))
+    return;
+
   if (! (TREE_CODE (decl) == VAR_DECL
         && GET_CODE (DECL_RTL (decl)) == MEM
         && DECL_INITIAL (decl)))
@@ -822,7 +986,7 @@ sdbout_toplevel_data (decl)
 \f
 #ifdef SDB_ALLOW_FORWARD_REFERENCES
 
-/* Machinery to record and output anonymous types. */
+/* Machinery to record and output anonymous types.  */
 
 static tree anonymous_types;
 
@@ -847,7 +1011,7 @@ sdbout_dequeue_anonymous_types ()
        {
          register tree type = TREE_VALUE (link);
 
-         if (! TREE_ASM_WRITTEN (type))
+         if (type && ! TREE_ASM_WRITTEN (type))
            sdbout_one_type (type);
        }
     }
@@ -876,7 +1040,6 @@ static void
 sdbout_type (type)
      tree type;
 {
-  register tree tem;
   if (type == error_mark_node)
     type = integer_type_node;
   PUT_SDB_TYPE (plain_type (type));
@@ -911,12 +1074,17 @@ static void
 sdbout_one_type (type)
      tree type;
 {
-  text_section ();
+  if (current_function_decl != NULL_TREE
+      && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
+    ; /* Don't change section amid function.  */
+  else
+    text_section ();
 
   switch (TREE_CODE (type))
     {
     case RECORD_TYPE:
     case UNION_TYPE:
+    case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       type = TYPE_MAIN_VARIANT (type);
       /* Don't output a type twice.  */
@@ -931,7 +1099,7 @@ sdbout_one_type (type)
       TREE_ASM_WRITTEN (type) = 1;
 #if 1
       /* This is reputed to cause trouble with the following case,
-        but perhaps checking TYPE_SIZE above will fix it.
+        but perhaps checking TYPE_SIZE above will fix it.  */
 
       /* Here is a test case:
 
@@ -978,6 +1146,7 @@ sdbout_one_type (type)
        switch (TREE_CODE (type))
          {
          case UNION_TYPE:
+         case QUAL_UNION_TYPE:
            PUT_SDB_SCL (C_UNTAG);
            PUT_SDB_TYPE (T_UNION);
            member_scl = C_MOU;
@@ -1014,7 +1183,12 @@ sdbout_one_type (type)
            if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
              child_type_name = TYPE_NAME (child_type);
            else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
-             child_type_name = DECL_NAME (TYPE_NAME (child_type));
+             {
+               child_type_name = DECL_NAME (TYPE_NAME (child_type));
+               if (child_type_name && template_name_p (child_type_name))
+                 child_type_name
+                   = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
+             }
            else
              continue;
 
@@ -1051,8 +1225,11 @@ sdbout_one_type (type)
                && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST
                && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
              {
+               char *name;
+
                CONTIN;
-               PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (tem)));
+               name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));
+               PUT_SDB_DEF (name);
                if (DECL_BIT_FIELD_TYPE (tem))
                  {
                    PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
@@ -1109,9 +1286,9 @@ sdbout_parms (parms)
 
        /* Perform any necessary register eliminations on the parameter's rtl,
           so that the debugging output will be accurate.  */
-       DECL_INCOMING_RTL (parms) =
-         eliminate_regs (DECL_INCOMING_RTL (parms), 0, 0);
-       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, 0);
+       DECL_INCOMING_RTL (parms)
+         = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX, 0);
+       DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX, 0);
 
        if (PARM_PASSED_IN_MEMORY (parms))
          {
@@ -1142,12 +1319,12 @@ sdbout_parms (parms)
                   the parm with the variable's declared type, and adjust
                   the address if the least significant bytes (which we are
                   using) are not the first ones.  */
-#if BYTES_BIG_ENDIAN
-               if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
+               if (BYTES_BIG_ENDIAN
+                   && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
                  current_sym_value +=
                    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
-#endif
+
                if (GET_CODE (DECL_RTL (parms)) == MEM
                    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
@@ -1188,7 +1365,7 @@ sdbout_parms (parms)
            PUT_SDB_DEF (name);
            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl)));
            PUT_SDB_SCL (C_REGPARM);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
        else if (GET_CODE (DECL_RTL (parms)) == MEM
@@ -1211,7 +1388,7 @@ sdbout_parms (parms)
            PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value,
                                                  XEXP (DECL_RTL (parms), 0)));
            PUT_SDB_SCL (C_ARG);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
       }
@@ -1249,7 +1426,7 @@ sdbout_reg_parms (parms)
            PUT_SDB_DEF (name);
            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
            PUT_SDB_SCL (C_REG);
-           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
+           PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
        /* Report parms that live in memory but not where they were passed.  */
@@ -1264,11 +1441,11 @@ sdbout_reg_parms (parms)
            /* A parm declared char is really passed as an int,
               so it occupies the least significant bytes.
               On a big-endian machine those are not the low-numbered ones.  */
-#if BYTES_BIG_ENDIAN
-           if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
+           if (BYTES_BIG_ENDIAN
+               && offset != -1
+               && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
              offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
-#endif
            if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
 #endif
              {
@@ -1301,7 +1478,15 @@ sdbout_begin_block (file, line, n)
 {
   tree decl = current_function_decl;
   MAKE_LINE_SAFE (line);
-  PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
+
+  /* The SCO compiler does not emit a separate block for the function level
+     scope, so we avoid it here also.  However, mips ECOFF compilers do emit
+     a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
+#ifndef MIPS_DEBUGGING_INFO
+  if (n != 1)
+#endif
+    PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
+
   if (n == 1)
     {
       /* Include the outermost BLOCK's variables in block 1.  */
@@ -1326,11 +1511,19 @@ sdbout_begin_block (file, line, n)
 /* Describe the end line-number of an internal block within a function.  */
 
 void
-sdbout_end_block (file, line)
+sdbout_end_block (file, line, n)
      FILE *file;
      int line;
+     int n;
 {
   MAKE_LINE_SAFE (line);
+
+  /* The SCO compiler does not emit a separate block for the function level
+     scope, so we avoid it here also.  However, mips ECOFF compilers do emit
+     a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
+#ifndef MIPS_DEBUGGING_INFO
+  if (n != 1)
+#endif
   PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
 }
 
@@ -1401,4 +1594,35 @@ sdbout_label (insn)
   PUT_SDB_ENDEF;
 }
 
+/* Change to reading from a new source file.  */
+
+void
+sdbout_start_new_source_file (filename)
+     char *filename;
+{
+#ifdef MIPS_DEBUGGING_INFO
+  struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n);
+
+  n->next = current_file;
+  n->name = filename;
+  current_file = n;
+  PUT_SDB_SRC_FILE (filename);
+#endif
+}
+
+/* Revert to reading a previous source file.  */
+
+void
+sdbout_resume_previous_source_file ()
+{
+#ifdef MIPS_DEBUGGING_INFO
+  struct sdb_file *next;
+
+  next = current_file->next;
+  free (current_file);
+  current_file = next;
+  PUT_SDB_SRC_FILE (current_file->name);
+#endif
+}
+
 #endif /* SDB_DEBUGGING_INFO */