OSDN Git Service

2000-07-21 Alexandre Petit-Bianco <apbianco@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 8fdb72c..f0075d5 100644 (file)
@@ -1,5 +1,6 @@
 /* Output sdb-format symbol table information from GNU compiler.
-   Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+   Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -44,25 +45,31 @@ AT&T C compiler.  From the example below I would conclude the following:
 
 #ifdef SDB_DEBUGGING_INFO
 
+#include "system.h"
 #include "tree.h"
 #include "rtl.h"
-#include <stdio.h>
 #include "regs.h"
+#include "defaults.h"
 #include "flags.h"
 #include "insn-config.h"
 #include "reload.h"
+#include "output.h"
+#include "toplev.h"
+#include "tm_p.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) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__)
+/* 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(__INTERIX) && !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.  */
 
@@ -97,16 +104,24 @@ extern FILE *asm_out_file;
 
 extern tree current_function_decl;
 
-void sdbout_init ();
-void sdbout_symbol ();
-void sdbout_types();
+#include "sdbout.h"
 
-static void sdbout_typedefs ();
-static void sdbout_syms ();
-static void sdbout_one_type ();
-static void sdbout_queue_anonymous_type ();
-static void sdbout_dequeue_anonymous_types ();
-static int plain_type_1 ();
+static char *gen_fake_label            PARAMS ((void));
+static int plain_type                  PARAMS ((tree));
+static int template_name_p             PARAMS ((tree));
+static void sdbout_record_type_name    PARAMS ((tree));
+static int plain_type_1                        PARAMS ((tree, int));
+static void sdbout_block               PARAMS ((tree));
+static void sdbout_syms                        PARAMS ((tree));
+#ifdef SDB_ALLOW_FORWARD_REFERENCES
+static void sdbout_queue_anonymous_type        PARAMS ((tree));
+static void sdbout_dequeue_anonymous_types PARAMS ((void));
+#endif
+static void sdbout_type                        PARAMS ((tree));
+static void sdbout_field_types         PARAMS ((tree));
+static void sdbout_one_type            PARAMS ((tree));
+static void sdbout_parms               PARAMS ((tree));
+static void sdbout_reg_parms           PARAMS ((tree));
 \f
 /* Define the default sizes for various types.  */
 
@@ -162,7 +177,13 @@ static int plain_type_1 ();
 #endif
 
 #ifndef PUT_SDB_INT_VAL
-#define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\t.val\t%d%s", (a), SDB_DELIM)
+#define PUT_SDB_INT_VAL(a) \
+ do {                                                                  \
+   fputs ("\t.val\t", asm_out_file);                                   \
+   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a));        \
+   fprintf (asm_out_file, "%s", SDB_DELIM);                            \
+ } while (0)
+
 #endif
 
 #ifndef PUT_SDB_VAL
@@ -192,7 +213,12 @@ do { fprintf (asm_out_file, "\t.def\t");   \
 #endif
 
 #ifndef PUT_SDB_SIZE
-#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\t.size\t%d%s", a, SDB_DELIM)
+#define PUT_SDB_SIZE(a) \
+ do {                                                                  \
+   fputs ("\t.size\t", asm_out_file);                                  \
+   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a));        \
+   fprintf (asm_out_file, "%s", SDB_DELIM);                            \
+ } while(0)
 #endif
 
 #ifndef PUT_SDB_START_DIM
@@ -277,15 +303,53 @@ 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;
+  const 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.  */
 
 void
 sdbout_init (asm_file, input_file_name, syms)
-     FILE *asm_file;
-     char *input_file_name;
-     tree syms;
+     FILE *asm_file ATTRIBUTE_UNUSED;
+     const char *input_file_name ATTRIBUTE_UNUSED;
+     tree syms ATTRIBUTE_UNUSED;
 {
+#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))
@@ -293,13 +357,6 @@ sdbout_init (asm_file, input_file_name, syms)
        && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
       sdbout_symbol (t, 0);
 #endif  
-
-#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);
-#endif
 }
 
 #if 0
@@ -474,6 +531,7 @@ plain_type_1 (type, level)
     {
     case VOID_TYPE:
       return T_VOID;
+    case BOOLEAN_TYPE:
     case INTEGER_TYPE:
       {
        int size = int_size_in_bytes (type) * BITS_PER_UNIT;
@@ -489,10 +547,14 @@ plain_type_1 (type, level)
          {
            char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
 
+           if (!strcmp (name, "char"))
+             return T_CHAR;
            if (!strcmp (name, "unsigned char"))
              return T_UCHAR;
            if (!strcmp (name, "signed char"))
              return T_CHAR;
+           if (!strcmp (name, "int"))
+             return T_INT;
            if (!strcmp (name, "unsigned int"))
              return T_UINT;
            if (!strcmp (name, "short int"))
@@ -505,12 +567,12 @@ plain_type_1 (type, level)
              return T_ULONG;
          }
 
+       if (size == INT_TYPE_SIZE)
+         return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
        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 */
@@ -520,11 +582,18 @@ plain_type_1 (type, level)
 
     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;
+#else
+       if (precision == LONG_DOUBLE_TYPE_SIZE)
+         return T_DOUBLE;      /* better than nothing */
+#endif
        return 0;
       }
 
@@ -538,8 +607,14 @@ plain_type_1 (type, level)
        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
+              && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0
+              && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
+              && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+              && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0)
+              ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+                 - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1)
               : 0);
+
        return PUSH_DERIVED_LEVEL (DT_ARY, m);
       }
 
@@ -564,8 +639,8 @@ plain_type_1 (type, level)
               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.
@@ -606,15 +681,12 @@ plain_type_1 (type, level)
 }
 \f
 /* Output the symbols defined in block number DO_BLOCK.
-   Set NEXT_BLOCK_NUMBER to 0 before calling.
 
    This function works by walking the tree structure of blocks,
    counting blocks until it finds the desired block.  */
 
 static int do_block = 0;
 
-static int next_block_number;
-
 static void
 sdbout_block (block)
      register tree block;
@@ -625,17 +697,13 @@ sdbout_block (block)
       if (TREE_USED (block))
        {
          /* When we reach the specified block, output its symbols.  */
-         if (next_block_number == do_block)
-           {
-             sdbout_syms (BLOCK_VARS (block));
-           }
+         if (BLOCK_NUMBER (block) == do_block)
+           sdbout_syms (BLOCK_VARS (block));
 
          /* If we are past the specified block, stop the scan.  */
-         if (next_block_number > do_block)
+         if (BLOCK_NUMBER (block) > do_block)
            return;
 
-         next_block_number++;
-
          /* Scan the blocks within this block.  */
          sdbout_block (BLOCK_SUBBLOCKS (block));
        }
@@ -691,7 +759,10 @@ sdbout_symbol (decl, local)
       context = decl_function_context (decl);
       if (context == current_function_decl)
        return;
-      if (DECL_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)
@@ -739,7 +810,7 @@ sdbout_symbol (decl, local)
 
       DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
 #ifdef LEAF_REG_REMAP
-      if (leaf_function)
+      if (current_function_uses_only_leaf_regs)
        leaf_renumber_regs_insn (DECL_RTL (decl));
 #endif
       value = DECL_RTL (decl);
@@ -789,7 +860,7 @@ sdbout_symbol (decl, local)
          || TREE_CODE (type) == UNION_TYPE
          || TREE_CODE (type) == QUAL_UNION_TYPE)
        {
-         if (TYPE_SIZE (type) != 0             /* not a forward reference */
+         if (COMPLETE_TYPE_P (type)            /* not a forward reference */
              && KNOWN_TYPE_TAG (type) == 0)    /* not yet declared */
            sdbout_one_type (type);
        }
@@ -857,7 +928,12 @@ sdbout_symbol (decl, local)
              PUT_SDB_SCL (C_AUTO);
            }
 
-         type = build_pointer_type (TREE_TYPE (decl));
+         /* Effectively do build_pointer_type, but don't cache this type,
+            since it might be temporary whereas the type it points to
+            might have been saved for inlining.  */
+         /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
+         type = make_node (POINTER_TYPE);
+         TREE_TYPE (type) = TREE_TYPE (decl);
        }
       else if (GET_CODE (value) == MEM
               && ((GET_CODE (XEXP (value, 0)) == PLUS
@@ -898,6 +974,9 @@ sdbout_symbol (decl, local)
          return;
        }
       break;
+
+    default:
+      break;
     }
   PUT_SDB_TYPE (plain_type (type));
   PUT_SDB_ENDEF;
@@ -936,7 +1015,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;
 
@@ -1006,11 +1085,20 @@ sdbout_field_types (type)
      tree type;
 {
   tree tail;
+
   for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
-    if (TREE_CODE (TREE_TYPE (tail)) == POINTER_TYPE)
-      sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
-    else
-      sdbout_one_type (TREE_TYPE (tail));
+    /* This condition should match the one for emitting the actual members
+       below.  */
+    if (TREE_CODE (tail) == FIELD_DECL
+       && DECL_NAME (tail) != 0
+       && ! host_integerp (DECL_SIZE (tail), 1)
+       && ! host_integerp (bit_position (tail), 0))
+      {
+       if (POINTER_TYPE_P (TREE_TYPE (tail)))
+         sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
+       else
+         sdbout_one_type (TREE_TYPE (tail));
+      }
 }
 
 /* Use this to put out the top level defined record and union types
@@ -1043,7 +1131,7 @@ sdbout_one_type (type)
        return;
 
       /* Output nothing if type is not yet defined.  */
-      if (TYPE_SIZE (type) == 0)
+      if (!COMPLETE_TYPE_P (type))
        return;
 
       TREE_ASM_WRITTEN (type) = 1;
@@ -1084,7 +1172,7 @@ sdbout_one_type (type)
       /* Output a structure type.  */
       {
        int size = int_size_in_bytes (type);
-       int member_scl;
+       int member_scl = 0;
        tree tem;
        int i, n_baseclasses = 0;
 
@@ -1113,6 +1201,9 @@ sdbout_one_type (type)
            PUT_SDB_TYPE (T_ENUM);
            member_scl = C_MOE;
            break;
+
+         default:
+           break;
          }
 
        PUT_SDB_SIZE (size);
@@ -1120,48 +1211,57 @@ sdbout_one_type (type)
 
        /* Print out the base class information with fields
           named after the types they hold.  */
-       if (TYPE_BINFO (type)
-           && TYPE_BINFO_BASETYPES (type))
-         n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
-       for (i = 0; i < n_baseclasses; i++)
+       /* This is only relevent to aggregate types.  TYPE_BINFO is used
+          for other purposes in an ENUMERAL_TYPE, so we must exclude that
+          case.  */
+       if (TREE_CODE (type) != ENUMERAL_TYPE)
          {
-           tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
-           tree child_type = BINFO_TYPE (child);
-           tree child_type_name;
-           if (TYPE_NAME (child_type) == 0)
-             continue;
-           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)
+           if (TYPE_BINFO (type)
+               && TYPE_BINFO_BASETYPES (type))
+             n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
+           for (i = 0; i < n_baseclasses; i++)
              {
-               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;
+               tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)),
+                                          i);
+               tree child_type = BINFO_TYPE (child);
+               tree child_type_name;
+               if (TYPE_NAME (child_type) == 0)
+                 continue;
+               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));
+                   if (child_type_name && template_name_p (child_type_name))
+                     child_type_name
+                       = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
+                 }
+               else
+                 continue;
 
-           CONTIN;
-           PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
-           PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child)));
-           PUT_SDB_SCL (member_scl);
-           sdbout_type (BINFO_TYPE (child));
-           PUT_SDB_ENDEF;
+               CONTIN;
+               PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
+               PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0));
+               PUT_SDB_SCL (member_scl);
+               sdbout_type (BINFO_TYPE (child));
+               PUT_SDB_ENDEF;
+             }
          }
 
        /* output the individual fields */
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
-         for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
-           {
-             PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
-             PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem)));
-             PUT_SDB_SCL (C_MOE);
-             PUT_SDB_TYPE (T_MOE);
-             PUT_SDB_ENDEF;
-           }
-
+         {
+           for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+             if (host_integerp (TREE_VALUE (tem), 0))
+               {
+                 PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
+                 PUT_SDB_INT_VAL (tree_low_cst (TREE_VALUE (tem), 0));
+                 PUT_SDB_SCL (C_MOE);
+                 PUT_SDB_TYPE (T_MOE);
+                 PUT_SDB_ENDEF;
+               }
+         }
        else                    /* record or union type */
          for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
            /* Output the name, type, position (in bits), size (in bits)
@@ -1172,8 +1272,8 @@ sdbout_one_type (type)
               Also omit non FIELD_DECL nodes that GNU C++ may put here.  */
            if (TREE_CODE (tem) == FIELD_DECL
                && DECL_NAME (tem) != 0
-               && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST
-               && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
+               && host_integerp (DECL_SIZE (tem), 1)
+               && host_integerp (bit_position (tem), 0))
              {
                char *name;
 
@@ -1182,15 +1282,14 @@ sdbout_one_type (type)
                PUT_SDB_DEF (name);
                if (DECL_BIT_FIELD_TYPE (tem))
                  {
-                   PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+                   PUT_SDB_INT_VAL (int_bit_position (tem));
                    PUT_SDB_SCL (C_FIELD);
                    sdbout_type (DECL_BIT_FIELD_TYPE (tem));
-                   PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem)));
+                   PUT_SDB_SIZE (tree_low_cst (DECL_SIZE (tem), 1));
                  }
                else
                  {
-                   PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))
-                                    / BITS_PER_UNIT);
+                   PUT_SDB_INT_VAL (int_bit_position (tem) / BITS_PER_UNIT);
                    PUT_SDB_SCL (member_scl);
                    sdbout_type (TREE_TYPE (tem));
                  }
@@ -1205,6 +1304,9 @@ sdbout_one_type (type)
        PUT_SDB_SIZE (size);
        PUT_SDB_ENDEF;
        break;
+
+      default:
+       break;
       }
     }
 }
@@ -1236,8 +1338,8 @@ 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, NULL_RTX);
+       DECL_INCOMING_RTL (parms)
+         eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
        DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
 
        if (PARM_PASSED_IN_MEMORY (parms))
@@ -1256,7 +1358,6 @@ sdbout_parms (parms)
              current_sym_value = 0;
 
            if (GET_CODE (DECL_RTL (parms)) == REG
-               && REGNO (DECL_RTL (parms)) >= 0
                && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              type = DECL_ARG_TYPE (parms);
            else
@@ -1304,8 +1405,7 @@ sdbout_parms (parms)
               pretend the parm was passed there.  It would be more consistent
               to describe the register where the parm was passed,
               but in practice that register usually holds something else.  */
-           if (REGNO (DECL_RTL (parms)) >= 0
-               && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
+           if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              best_rtl = DECL_RTL (parms);
            /* If the parm lives nowhere,
               use the register where it was passed.  */
@@ -1315,7 +1415,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
@@ -1338,7 +1438,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;
          }
       }
@@ -1367,7 +1467,6 @@ sdbout_reg_parms (parms)
        /* Report parms that live in registers during the function
           but were passed in memory.  */
        if (GET_CODE (DECL_RTL (parms)) == REG
-           && REGNO (DECL_RTL (parms)) >= 0
            && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
            && PARM_PASSED_IN_MEMORY (parms))
          {
@@ -1376,7 +1475,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.  */
@@ -1422,7 +1521,7 @@ sdbout_reg_parms (parms)
 
 void
 sdbout_begin_block (file, line, n)
-     FILE *file;
+     FILE *file ATTRIBUTE_UNUSED;
      int line;
      int n;
 {
@@ -1440,15 +1539,13 @@ sdbout_begin_block (file, line, n)
   if (n == 1)
     {
       /* Include the outermost BLOCK's variables in block 1.  */
-      next_block_number = 0;
-      do_block = 0;
+      do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
       sdbout_block (DECL_INITIAL (decl));
     }
   /* If -g1, suppress all the internal symbols of functions
      except for arguments.  */
   if (debug_info_level != DINFO_LEVEL_TERSE)
     {
-      next_block_number = 0;
       do_block = n;
       sdbout_block (DECL_INITIAL (decl));
     }
@@ -1462,9 +1559,9 @@ sdbout_begin_block (file, line, n)
 
 void
 sdbout_end_block (file, line, n)
-     FILE *file;
+     FILE *file ATTRIBUTE_UNUSED;
      int line;
-     int n;
+     int n ATTRIBUTE_UNUSED;
 {
   MAKE_LINE_SAFE (line);
 
@@ -1544,4 +1641,35 @@ sdbout_label (insn)
   PUT_SDB_ENDEF;
 }
 
+/* Change to reading from a new source file.  */
+
+void
+sdbout_start_new_source_file (filename)
+     const char *filename ATTRIBUTE_UNUSED;
+{
+#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 */