OSDN Git Service

* config/i386/sol2.h (PREFERRED_DEBUGGING_TYPE): Use stabs.
[pf3gnuchains/gcc-fork.git] / gcc / dbxout.c
index 2aea943..6dd2f30 100644 (file)
@@ -1,5 +1,5 @@
 /* Output dbx-format symbol table information from GNU compiler.
-   Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92-97, 1998 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.  */
 
 
 /* Output dbx-format symbol table data.
@@ -66,11 +67,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
    For more on data type definitions, see `dbxout_type'.  */
 
-/* Include these first, because they may define MIN and MAX.  */
-#include <stdio.h>
-#include <errno.h>
-
 #include "config.h"
+#include "system.h"
+
 #include "tree.h"
 #include "rtl.h"
 #include "flags.h"
@@ -79,10 +78,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "reload.h"
 #include "defaults.h"
 #include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions.  */
-
-#ifndef errno
-extern int errno;
-#endif
+#include "dbxout.h"
+#include "toplev.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
@@ -126,9 +123,25 @@ extern int errno;
 #endif
 
 /* Nonzero means if the type has methods, only output debugging
-   information if methods are actually written to the asm file.  */
+   information if methods are actually written to the asm file.  This
+   optimization only works if the debugger can detect the special C++
+   marker.  */
+
+#define MINIMAL_DEBUG 1
+
+#ifdef NO_DOLLAR_IN_LABEL
+#ifdef NO_DOT_IN_LABEL
+#undef MINIMAL_DEBUG
+#define MINIMAL_DEBUG 0
+#endif
+#endif
+
+/* Typical USG systems don't have stab.h, and they also have
+   no use for DBX-format debugging info.  */
+
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
 
-static int flag_minimal_debug = 1;
+static int flag_minimal_debug = MINIMAL_DEBUG;
 
 /* Nonzero if we have actually used any of the GDB extensions
    to the debugging format.  The idea is that we use them for the
@@ -142,29 +155,26 @@ static int have_used_extensions = 0;
 
 static int source_label_number = 1;
 
-char *getpwd ();
-
-/* Typical USG systems don't have stab.h, and they also have
-   no use for DBX-format debugging info.  */
-
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-
 #ifdef DEBUG_SYMS_TEXT
 #define FORCE_TEXT text_section ();
 #else
 #define FORCE_TEXT
 #endif
 
-#if defined (USG) || defined (NO_STAB_H)
-#include "gstab.h"  /* If doing DBX on sysV, use our own stab.h.  */
+/* If there is a system stab.h, use it.  Otherwise, use our own.  */
+/* ??? This is supposed to describe the target's stab format, so using
+   the host HAVE_STAB_H appears to be wrong.  For now, we use our own file
+   when cross compiling.  */
+#if defined (USG) || !defined (HAVE_STAB_H) || defined (CROSS_COMPILE)
+#include "gstab.h" /* If doing DBX on sysV, use our own stab.h.  */
 #else
-#include <stab.h>  /* On BSD, use the system's stab.h.  */
+#include <stab.h>
 
 /* This is a GNU extension we need to reference in this file.  */
 #ifndef N_CATCH
 #define N_CATCH 0x54
 #endif
-#endif /* not USG */
+#endif
 
 #ifdef __GNU_STAB__
 #define STAB_CODE_TYPE enum __stab_debug_code
@@ -204,15 +214,28 @@ static char *cwd;
 
 enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
 
-/* Vector recording the status of describing C data types.
+/* Structure recording information about a C data type.
+   The status element says whether we have yet output
+   the definition of the type.  TYPE_XREF says we have
+   output it as a cross-reference only.
+   The file_number and type_number elements are used if DBX_USE_BINCL
+   is defined.  */
+
+struct typeinfo
+{
+  enum typestatus status;
+#ifdef DBX_USE_BINCL
+  int file_number;
+  int type_number;
+#endif
+};
+
+/* Vector recording information about C data types.
    When we first notice a data type (a tree node),
    we assign it a number using next_type_number.
-   That is its index in this vector.
-   The vector element says whether we have yet output
-   the definition of the type.  TYPE_XREF says we have
-   output it as a cross-reference only.  */
+   That is its index in this vector.  */
 
-enum typestatus *typevec;
+struct typeinfo *typevec;
 
 /* Number of elements of space allocated in `typevec'.  */
 
@@ -224,6 +247,29 @@ static int typevec_len;
 
 static int next_type_number;
 
+#ifdef DBX_USE_BINCL
+
+/* When using N_BINCL in dbx output, each type number is actually a
+   pair of the file number and the type number within the file.
+   This is a stack of input files.  */
+
+struct dbx_file
+{
+  struct dbx_file *next;
+  int file_number;
+  int next_type_number;
+};
+
+/* This is the top of the stack.  */
+
+static struct dbx_file *current_file;
+
+/* This is the next file number to use.  */
+
+static int next_file_number;
+
+#endif /* DBX_USE_BINCL */
+
 /* In dbx output, we must assign symbol-blocks id numbers
    in the order in which their beginnings are encountered.
    We output debugging info that refers to the beginning and
@@ -274,121 +320,53 @@ static int current_sym_nchars;
 void dbxout_types ();
 void dbxout_args ();
 void dbxout_symbol ();
-static void dbxout_type_name ();
-static void dbxout_type ();
-static void dbxout_typedefs ();
-static void dbxout_symbol_name ();
-static void dbxout_symbol_location ();
-static void dbxout_prepare_symbol ();
-static void dbxout_finish_symbol ();
-static void dbxout_continue ();
-static void print_int_cst_octal ();
-static void print_octal ();
+
+#if defined(ASM_OUTPUT_SECTION_NAME)
+static void dbxout_function_end                PROTO((void));
+#endif
+static void dbxout_typedefs            PROTO((tree));
+static void dbxout_type_index          PROTO((tree));
+#if DBX_CONTIN_LENGTH > 0
+static void dbxout_continue            PROTO((void));
+#endif
+static void dbxout_type_fields         PROTO((tree));
+static void dbxout_type_method_1       PROTO((tree, char *));
+static void dbxout_type_methods                PROTO((tree));
+static void dbxout_range_type          PROTO((tree));
+static void dbxout_type                        PROTO((tree, int, int));
+static void print_int_cst_octal                PROTO((tree));
+static void print_octal                        PROTO((unsigned HOST_WIDE_INT, int));
+static void dbxout_type_name           PROTO((tree));
+static void dbxout_symbol_location     PROTO((tree, tree, char *, rtx));
+static void dbxout_symbol_name         PROTO((tree, char *, int));
+static void dbxout_prepare_symbol      PROTO((tree));
+static void dbxout_finish_symbol       PROTO((tree));
+static void dbxout_block               PROTO((tree, int, tree));
+static void dbxout_really_begin_function PROTO((tree));
 \f
-#if 0 /* Not clear we will actually need this.  */
-
-/* Return the absolutized filename for the given relative
-   filename.  Note that if that filename is already absolute, it may
-   still be returned in a modified form because this routine also
-   eliminates redundant slashes and single dots and eliminates double
-   dots to get a shortest possible filename from the given input
-   filename.  The absolutization of relative filenames is made by
-   assuming that the given filename is to be taken as relative to
-   the first argument (cwd) or to the current directory if cwd is
-   NULL.  */
-
-static char *
-abspath (rel_filename)
-     char *rel_filename;
+#if defined(ASM_OUTPUT_SECTION_NAME)
+static void
+dbxout_function_end ()
 {
-  /* Setup the current working directory as needed.  */
-  char *abs_buffer
-    = (char *) alloca (strlen (cwd) + strlen (rel_filename) + 1);
-  char *endp = abs_buffer;
-  char *outp, *inp;
-  char *value;
-
-  /* Copy the filename (possibly preceded by the current working
-     directory name) into the absolutization buffer.  */
-
-  {
-    char *src_p;
-
-    if (rel_filename[0] != '/')
-      {
-        src_p = cwd;
-        while (*endp++ = *src_p++)
-          continue;
-        *(endp-1) = '/';                       /* overwrite null */
-      }
-    src_p = rel_filename;
-    while (*endp++ = *src_p++)
-      continue;
-    if (endp[-1] == '/')
-      *endp = '\0';
-
-  /* Now make a copy of abs_buffer into abs_buffer, shortening the
-     filename (by taking out slashes and dots) as we go.  */
-
-  outp = inp = abs_buffer;
-  *outp++ = *inp++;            /* copy first slash */
-  for (;;)
-    {
-      if (!inp[0])
-        break;
-      else if (inp[0] == '/' && outp[-1] == '/')
-        {
-          inp++;
-          continue;
-        }
-      else if (inp[0] == '.' && outp[-1] == '/')
-        {
-          if (!inp[1])
-                  break;
-          else if (inp[1] == '/')
-            {
-                    inp += 2;
-                    continue;
-            }
-          else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
-            {
-                    inp += (inp[2] == '/') ? 3 : 2;
-                    outp -= 2;
-                    while (outp >= abs_buffer && *outp != '/')
-               outp--;
-                    if (outp < abs_buffer)
-                {
-                  /* Catch cases like /.. where we try to backup to a
-                     point above the absolute root of the logical file
-                     system.  */
-
-                 fprintf (stderr, "%s: invalid file name: %s\n",
-                          pname, rel_filename);
-                 exit (1);
-               }
-                    *++outp = '\0';
-                    continue;
-            }
-        }
-      *outp++ = *inp++;
-    }
-
-  /* On exit, make sure that there is a trailing null, and make sure that
-     the last character of the returned string is *not* a slash.  */
-
-  *outp = '\0';
-  if (outp[-1] == '/')
-    *--outp  = '\0';
-
-  /* Make a copy (in the heap) of the stuff left in the absolutization
-     buffer and return a pointer to the copy.  */
-
-  value = (char *) oballoc (strlen (abs_buffer) + 1);
-  strcpy (value, abs_buffer);
-  return value;
+  static int scope_labelno = 0;
+  char lscope_label_name[100];
+  /* Convert Ltext into the appropriate format for local labels in case
+     the system doesn't insert underscores in front of user generated
+     labels.  */
+  ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
+  ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno);
+  scope_labelno++;
+
+  /* By convention, GCC will mark the end of a function with an N_FUN
+     symbol and an empty string.  */
+  fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN);
+  assemble_name (asmfile, lscope_label_name);
+  fputc ('-', asmfile);
+  assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
+  fprintf (asmfile, "\n");
 }
-#endif /* 0 */
-\f
+#endif /* ! NO_DBX_FUNCTION_END */
+
 /* At the beginning of compilation, start writing the symbol table.
    Initialize `typevec' and output the standard data types of C.  */
 
@@ -403,8 +381,7 @@ dbxout_init (asm_file, input_file_name, syms)
   asmfile = asm_file;
 
   typevec_len = 100;
-  typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);
-  bzero ((char *) typevec, typevec_len * sizeof typevec[0]);
+  typevec = (struct typeinfo *) xcalloc (typevec_len, sizeof typevec[0]);
 
   /* Convert Ltext into the appropriate format for local labels in case
      the system doesn't insert underscores in front of user generated
@@ -463,6 +440,14 @@ dbxout_init (asm_file, input_file_name, syms)
   next_type_number = 1;
   next_block_number = 2;
 
+#ifdef DBX_USE_BINCL
+  current_file = (struct dbx_file *) xmalloc (sizeof *current_file);
+  current_file->next = NULL;
+  current_file->file_number = 0;
+  current_file->next_type_number = 1;
+  next_file_number = 1;
+#endif
+
   /* Make sure that types `int' and `char' have numbers 1 and 2.
      Definitions of other integer types will refer to those numbers.
      (Actually it should no longer matter what their numbers are.
@@ -498,12 +483,47 @@ dbxout_typedefs (syms)
          tree type = TREE_TYPE (syms);
          if (TYPE_NAME (type)
              && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+             && TYPE_SIZE (type) != NULL_TREE
              && ! TREE_ASM_WRITTEN (TYPE_NAME (type)))
            dbxout_symbol (TYPE_NAME (type), 0);
        }
     }
 }
 
+/* Change to reading from a new source file.  Generate a N_BINCL stab.  */
+
+void
+dbxout_start_new_source_file (filename)
+     char *filename ATTRIBUTE_UNUSED;
+{
+#ifdef DBX_USE_BINCL
+  struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n);
+
+  n->next = current_file;
+  n->file_number = next_file_number++;
+  n->next_type_number = 1;
+  current_file = n;
+  fprintf (asmfile, "%s ", ASM_STABS_OP);
+  output_quoted_string (asmfile, filename);
+  fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
+#endif
+}
+
+/* Revert to reading a previous source file.  Generate a N_EINCL stab.  */
+
+void
+dbxout_resume_previous_source_file ()
+{
+#ifdef DBX_USE_BINCL
+  struct dbx_file *next;
+
+  fprintf (asmfile, "%s %d,0,0,0\n", ASM_STABN_OP, N_EINCL);
+  next = current_file->next;
+  free (current_file);
+  current_file = next;
+#endif
+}
+
 /* Output debugging info to FILE to switch to sourcefile FILENAME.  */
 
 void
@@ -555,18 +575,35 @@ dbxout_source_line (file, filename, lineno)
 
 /* At the end of compilation, finish writing the symbol table.
    Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is
-   to do nothing. */
+   to do nothing.  */
 
 void
 dbxout_finish (file, filename)
-     FILE *file;
-     char *filename;
+     FILE *file ATTRIBUTE_UNUSED;
+     char *filename ATTRIBUTE_UNUSED;
 {
 #ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename);
 #endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */
 }
 
+/* Output the index of a type.  */
+
+static void
+dbxout_type_index (type)
+     tree type;
+{
+#ifndef DBX_USE_BINCL
+  fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
+  CHARS (3);
+#else
+  struct typeinfo *t = &typevec[TYPE_SYMTAB_ADDRESS (type)];
+  fprintf (asmfile, "(%d,%d)", t->file_number, t->type_number);
+  CHARS (7);
+#endif
+}
+
+#if DBX_CONTIN_LENGTH > 0
 /* Continue a symbol-description that gets too big.
    End one symbol table entry with a double-backslash
    and start a new one, eventually producing something like
@@ -585,6 +622,7 @@ dbxout_continue ()
   fprintf (asmfile, "%s \"", ASM_STABS_OP);
   current_sym_nchars = 0;
 }
+#endif /* DBX_CONTIN_LENGTH > 0 */
 \f
 /* Subroutine of `dbxout_type'.  Output the type fields of TYPE.
    This must be a separate function because anonymous unions require
@@ -608,12 +646,16 @@ dbxout_type_fields (type)
                   || TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST))
        continue;
       /* Omit here the nameless fields that are used to skip bits.  */
+      else if (DECL_IGNORED_P (tem))
+       continue;
       else if (TREE_CODE (tem) != CONST_DECL)
        {
          /* Continue the line if necessary,
             but not before the first field.  */
          if (tem != TYPE_FIELDS (type))
-           CONTIN;
+           {
+             CONTIN;
+           }
 
          if (use_gnu_debug_info_extensions
              && flag_minimal_debug
@@ -622,13 +664,15 @@ dbxout_type_fields (type)
              && DECL_ASSEMBLER_NAME (tem))
            {
              have_used_extensions = 1;
-             CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem)))));
+             CHARS (3 + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (tem)));
              fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile);
              dbxout_type (DECL_FCONTEXT (tem), 0, 0);
              fprintf (asmfile, ":");
              dbxout_type (TREE_TYPE (tem), 0, 0);
-             fprintf (asmfile, ",%d;",
+             fputc (',', asmfile);
+             fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                       TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+             fputc (';', asmfile);
              continue;
            }
 
@@ -677,9 +721,13 @@ dbxout_type_fields (type)
            }
          else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
            {
-             fprintf (asmfile, ",%d,%d;",
-                      TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)),
+             fputc (',', asmfile);
+             fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                      TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+             fputc (',', asmfile);
+             fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                       TREE_INT_CST_LOW (DECL_SIZE (tem)));
+             fputc (';', asmfile);
            }
          CHARS (23);
        }
@@ -724,8 +772,9 @@ dbxout_type_method_1 (decl, debug_name)
         - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
   if (DECL_VINDEX (decl))
     {
-      fprintf (asmfile, "%d;",
+      fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
               TREE_INT_CST_LOW (DECL_VINDEX (decl)));
+      fputc (';', asmfile);
       dbxout_type (DECL_CONTEXT (decl), 0, 0);
       fprintf (asmfile, ";");
       CHARS (8);
@@ -764,13 +813,7 @@ dbxout_type_methods (type)
       {
        static int warned;
        if (!warned)
-         {
            warned = 1;
-#ifdef HAVE_TEMPLATES
-           if (warn_template_debugging)
-             warning ("dbx info for template class methods not yet supported");
-#endif
-         }
        return;
       }
   }
@@ -780,7 +823,7 @@ dbxout_type_methods (type)
 
   sprintf(formatted_type_identifier_length, "%d", type_identifier_length);
 
-  if (TREE_CODE (methods) == FUNCTION_DECL)
+  if (TREE_CODE (methods) != TREE_VEC)
     fndecl = methods;
   else if (TREE_VEC_ELT (methods, 0) != NULL_TREE)
     fndecl = TREE_VEC_ELT (methods, 0);
@@ -804,7 +847,7 @@ dbxout_type_methods (type)
          /* This is the "mangled" name of the method.
             It encodes the argument types.  */
          char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
-         int destructor = 0;
+         int show_arg_types = 0;
 
          CONTIN;
 
@@ -815,10 +858,23 @@ dbxout_type_methods (type)
 
          if (flag_minimal_debug)
            {
+             char marker;
+
+             /* We can't optimize a method which uses an anonymous
+                 class, because the debugger will not be able to
+                 associate the arbitrary class name with the actual
+                 class.  */
+#ifndef NO_DOLLAR_IN_LABEL
+             marker = '$';
+#else
+             marker = '.';
+#endif
+             if (strchr (debug_name, marker))
+               show_arg_types = 1;
              /* Detect ordinary methods because their mangled names
                 start with the operation name.  */
-             if (!strncmp (IDENTIFIER_POINTER (name), debug_name,
-                           IDENTIFIER_LENGTH (name)))
+             else if (!strncmp (IDENTIFIER_POINTER (name), debug_name,
+                                IDENTIFIER_LENGTH (name)))
                {
                  debug_name += IDENTIFIER_LENGTH (name);
                  if (debug_name[0] == '_' && debug_name[1] == '_')
@@ -828,7 +884,7 @@ dbxout_type_methods (type)
                      /* Get past const and volatile qualifiers.  */
                      while (*method_name == 'C' || *method_name == 'V')
                        method_name++;
-                     /* Skip digits for length of type_encoding. */
+                     /* Skip digits for length of type_encoding.  */
                      while (*method_name == *length_ptr && *length_ptr)
                          length_ptr++, method_name++;
                      if (! strncmp (method_name,
@@ -845,7 +901,7 @@ dbxout_type_methods (type)
                  char *length_ptr = formatted_type_identifier_length;
                  while (*ctor_name == 'C' || *ctor_name == 'V')
                    ctor_name++;
-                 /* Skip digits for length of type_encoding. */
+                 /* Skip digits for length of type_encoding.  */
                  while (*ctor_name == *length_ptr && *length_ptr)
                      length_ptr++, ctor_name++;
                  if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name,
@@ -854,7 +910,7 @@ dbxout_type_methods (type)
                }
              /* The other alternative is a destructor.  */
              else
-               destructor = 1;
+               show_arg_types = 1;
 
              /* Output the operation name just once, for the first method
                 that we output.  */
@@ -866,7 +922,7 @@ dbxout_type_methods (type)
                }
            }
 
-         dbxout_type (TREE_TYPE (fndecl), 0, destructor);
+         dbxout_type (TREE_TYPE (fndecl), 0, show_arg_types);
 
          dbxout_type_method_1 (fndecl, debug_name);
        }
@@ -880,7 +936,7 @@ dbxout_type_methods (type)
 
 /* Emit a "range" type specification, which has the form:
    "r<index type>;<lower bound>;<upper bound>;".
-   TYPE is an INTEGER_TYPE. */
+   TYPE is an INTEGER_TYPE.  */
 
 static void
 dbxout_range_type (type)
@@ -893,18 +949,39 @@ dbxout_range_type (type)
     dbxout_type (type, 0, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */
   else
     {
-      /* This used to say `r1' and we used to take care
-        to make sure that `int' was type number 1.  */
-      fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (integer_type_node));
+      /* Traditionally, we made sure 'int' was type 1, and builtin types
+        were defined to be sub-ranges of int.  Unfortunately, this
+        does not allow us to distinguish true sub-ranges from integer
+        types.  So, instead we define integer (non-sub-range) types as
+        sub-ranges of themselves.  This matters for Chill.  If this isn't
+        a subrange type, then we want to define it in terms of itself.
+        However, in C, this may be an anonymous integer type, and we don't
+        want to emit debug info referring to it.  Just calling
+        dbxout_type_index won't work anyways, because the type hasn't been
+        defined yet.  We make this work for both cases by checked to see
+        whether this is a defined type, referring to it if it is, and using
+        'int' otherwise.  */
+      if (TYPE_SYMTAB_ADDRESS (type) != 0)
+       dbxout_type_index (type);
+      else
+       dbxout_type_index (integer_type_node);
     }
   if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
-    fprintf (asmfile, ";%d", 
-            TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)));
+    {
+      fputc (';', asmfile);
+      fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+              TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)));
+    }
   else
     fprintf (asmfile, ";0");
-  if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
-    fprintf (asmfile, ";%d;", 
-            TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
+  if (TYPE_MAX_VALUE (type) 
+      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
+    {
+      fputc (';', asmfile);
+      fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+              TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
+      fputc (';', asmfile);
+    }
   else
     fprintf (asmfile, ";-1;");
 }
@@ -938,7 +1015,18 @@ dbxout_type (type, full, show_arg_types)
     type = integer_type_node;
   else
     {
-      type = TYPE_MAIN_VARIANT (type);
+      /* Try to find the "main variant" with the same name but not const
+        or volatile.  (Since stabs does not distinguish const and volatile,
+        there is no need to make them separate types.  But types with
+        different names are usefully distinguished.) */
+        
+      for (tem = TYPE_MAIN_VARIANT (type); tem; tem = TYPE_NEXT_VARIANT (tem))
+       if (!TYPE_READONLY (tem) && !TYPE_VOLATILE (tem)
+           && TYPE_NAME (tem) == TYPE_NAME (type))
+         {
+           type = tem;
+           break;
+         }
       if (TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)))
@@ -954,18 +1042,24 @@ dbxout_type (type, full, show_arg_types)
 
       if (next_type_number == typevec_len)
        {
-         typevec =
-           (enum typestatus *) xrealloc (typevec,
-                                         typevec_len * 2 * sizeof typevec[0]);
+         typevec
+           = (struct typeinfo *) xrealloc (typevec,
+                                           typevec_len * 2 * sizeof typevec[0]);
          bzero ((char *) (typevec + typevec_len),
                 typevec_len * sizeof typevec[0]);
          typevec_len *= 2;
        }
+
+#ifdef DBX_USE_BINCL
+      typevec[TYPE_SYMTAB_ADDRESS (type)].file_number
+       = current_file->file_number;
+      typevec[TYPE_SYMTAB_ADDRESS (type)].type_number
+       = current_file->next_type_number++;
+#endif
     }
 
   /* Output the number of this type, to refer to it.  */
-  fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
-  CHARS (3);
+  dbxout_type_index (type);
 
 #ifdef DBX_TYPE_DEFINED
   if (DBX_TYPE_DEFINED (type))
@@ -975,7 +1069,7 @@ dbxout_type (type, full, show_arg_types)
   /* If this type's definition has been output or is now being output,
      that is all.  */
 
-  switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
+  switch (typevec[TYPE_SYMTAB_ADDRESS (type)].status)
     {
     case TYPE_UNSEEN:
       break;
@@ -1013,7 +1107,7 @@ dbxout_type (type, full, show_arg_types)
        /* No way in DBX fmt to describe a variable size.  */
        || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
       {
-       typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+       typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
        return;
       }
 #endif
@@ -1026,7 +1120,14 @@ dbxout_type (type, full, show_arg_types)
   /* Mark it as defined, so that if it is self-referent
      we will not get into an infinite recursion of definitions.  */
 
-  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
+  typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_DEFINED;
+
+  if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+      && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
+    { 
+      dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0, 0);
+      return;
+    }
 
   switch (TREE_CODE (type))
     {
@@ -1037,25 +1138,33 @@ dbxout_type (type, full, show_arg_types)
         without saying what it is.  The debugger will make it
         a void type when the reference is seen, and nothing will
         ever override that default.  */
-      fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
-      CHARS (3);
+      dbxout_type_index (type);
       break;
 
     case INTEGER_TYPE:
       if (type == char_type_node && ! TREE_UNSIGNED (type))
-       /* Output the type `char' as a subrange of itself!
-          I don't understand this definition, just copied it
-          from the output of pcc.
-          This used to use `r2' explicitly and we used to
-          take care to make sure that `char' was type number 2.  */
-       fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type));
+       {
+         /* Output the type `char' as a subrange of itself!
+            I don't understand this definition, just copied it
+            from the output of pcc.
+            This used to use `r2' explicitly and we used to
+            take care to make sure that `char' was type number 2.  */
+         fprintf (asmfile, "r");
+         dbxout_type_index (type);
+         fprintf (asmfile, ";0;127;");
+       }
+      /* This used to check if the type's precision was more than
+        HOST_BITS_PER_WIDE_INT.  That is wrong since gdb uses a
+        long (it has no concept of HOST_BITS_PER_WIDE_INT).  */
       else if (use_gnu_debug_info_extensions
               && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
-                  || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT))
+                  || TYPE_PRECISION (type) >= HOST_BITS_PER_LONG))
        {
          /* This used to say `r1' and we used to take care
             to make sure that `int' was type number 1.  */
-         fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node));
+         fprintf (asmfile, "r");
+         dbxout_type_index (integer_type_node);
+         fprintf (asmfile, ";");
          print_int_cst_octal (TYPE_MIN_VALUE (type));
          fprintf (asmfile, ";");
          print_int_cst_octal (TYPE_MAX_VALUE (type));
@@ -1063,33 +1172,47 @@ dbxout_type (type, full, show_arg_types)
        }
       else /* Output other integer types as subranges of `int'.  */
        dbxout_range_type (type);
-      CHARS (25);
+      CHARS (22);
       break;
 
     case REAL_TYPE:
       /* This used to say `r1' and we used to take care
         to make sure that `int' was type number 1.  */
-      fprintf (asmfile, "r%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node),
-              int_size_in_bytes (type));
-      CHARS (16);
+      fprintf (asmfile, "r");
+      dbxout_type_index (integer_type_node);
+      fputc (';', asmfile);
+      fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type));
+      fputs (";0;", asmfile);
+      CHARS (13);
       break;
 
     case CHAR_TYPE:
       if (use_gnu_debug_info_extensions)
-       fprintf (asmfile, "@s%d;-20;",
-                BITS_PER_UNIT * int_size_in_bytes (type));
+       {
+         fputs ("@s", asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                  BITS_PER_UNIT * int_size_in_bytes (type));
+         fputs (";-20;", asmfile);
+       }
       else
-       /* Output the type `char' as a subrange of itself.
-          That is what pcc seems to do.  */
-      fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node),
-              TREE_UNSIGNED (type) ? 255 : 127);
+       {
+         /* Output the type `char' as a subrange of itself.
+            That is what pcc seems to do.  */
+         fprintf (asmfile, "r");
+         dbxout_type_index (char_type_node);
+         fprintf (asmfile, ";0;%d;", TREE_UNSIGNED (type) ? 255 : 127);
+       }
       CHARS (9);
       break;
 
     case BOOLEAN_TYPE:
       if (use_gnu_debug_info_extensions)
-       fprintf (asmfile, "@s%d;-16;",
-                BITS_PER_UNIT * int_size_in_bytes (type));
+       {
+         fputs ("@s", asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                  BITS_PER_UNIT * int_size_in_bytes (type));
+         fputs (";-16;", asmfile);
+       }
       else /* Define as enumeral type (False, True) */
        fprintf (asmfile, "eFalse:0,True:1,;");
       CHARS (17);
@@ -1106,16 +1229,20 @@ dbxout_type (type, full, show_arg_types)
 
       if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
        {
-         fprintf (asmfile, "r%d;%d;0;",
-                  TYPE_SYMTAB_ADDRESS (type),
+         fprintf (asmfile, "r");
+         dbxout_type_index (type);
+         fputc (';', asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                   int_size_in_bytes (TREE_TYPE (type)));
-         CHARS (15);           /* The number is probably incorrect here.  */
+         fputs (";0;", asmfile);
+         CHARS (12);           /* The number is probably incorrect here.  */
        }
       else
        {
          /* Output a complex integer type as a structure,
             pending some other way to do it.  */
-         fprintf (asmfile, "s%d", int_size_in_bytes (type));
+         fputc ('s', asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type));
 
          fprintf (asmfile, "real:");
          CHARS (10);
@@ -1137,10 +1264,12 @@ dbxout_type (type, full, show_arg_types)
       if (use_gnu_debug_info_extensions)
        {
          have_used_extensions = 1;
-         fprintf (asmfile, "@s%d;",
+         fputs ("@s", asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                   BITS_PER_UNIT * int_size_in_bytes (type));
+         fputc (';', asmfile);
          /* Check if a bitstring type, which in Chill is
-            different from a [power]set. */
+            different from a [power]set.  */
          if (TYPE_STRING_FLAG (type))
            fprintf (asmfile, "@S;");
        }
@@ -1150,12 +1279,26 @@ dbxout_type (type, full, show_arg_types)
       break;
 
     case ARRAY_TYPE:
+      /* Make arrays of packed bits look like bitstrings for chill.  */
+      if (TYPE_PACKED (type) && use_gnu_debug_info_extensions)
+       {
+         have_used_extensions = 1;
+         fputs ("@s", asmfile);
+         fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                  BITS_PER_UNIT * int_size_in_bytes (type));
+         fputc (';', asmfile);
+         fprintf (asmfile, "@S;");
+         putc ('S', asmfile);
+         CHARS (1);
+         dbxout_type (TYPE_DOMAIN (type), 0, 0);
+         break;
+       }
       /* Output "a" followed by a range type definition
         for the index type of the array
         followed by a reference to the target-type.
         ar1;0;N;M for a C array of type M and size N+1.  */
       /* Check if a character string type, which in Chill is
-        different from an array of characters. */
+        different from an array of characters.  */
       if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions)
        {
          have_used_extensions = 1;
@@ -1163,14 +1306,17 @@ dbxout_type (type, full, show_arg_types)
        }
       tem = TYPE_DOMAIN (type);
       if (tem == NULL)
-       fprintf (asmfile, "ar%d;0;-1;",
-                TYPE_SYMTAB_ADDRESS (integer_type_node));
+       {
+         fprintf (asmfile, "ar");
+         dbxout_type_index (integer_type_node);
+         fprintf (asmfile, ";0;-1;");
+       }
       else
        {
          fprintf (asmfile, "a");
          dbxout_range_type (tem);
        }
-      CHARS (17);
+      CHARS (14);
       dbxout_type (TREE_TYPE (type), 0, 0);
       break;
 
@@ -1180,7 +1326,9 @@ dbxout_type (type, full, show_arg_types)
       {
        int i, n_baseclasses = 0;
 
-       if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0)
+       if (TYPE_BINFO (type) != 0
+           && TREE_CODE (TYPE_BINFO (type)) == TREE_VEC
+           && TYPE_BINFO_BASETYPES (type) != 0)
          n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
 
        /* Output a structure type.  We must use the same test here as we
@@ -1214,12 +1362,13 @@ dbxout_type (type, full, show_arg_types)
            else
              fprintf (asmfile, "$$%d", anonymous_type_number++);
            fprintf (asmfile, ":");
-           typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+           typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
            break;
          }
 
        /* Identify record or union, and print its size.  */
-       fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
+       fputc (((TREE_CODE (type) == RECORD_TYPE) ? 's' : 'u'), asmfile);
+       fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                 int_size_in_bytes (type));
 
        if (use_gnu_debug_info_extensions)
@@ -1243,8 +1392,9 @@ dbxout_type (type, full, show_arg_types)
                putc (TREE_VIA_PUBLIC (child) ? '2'
                      : '0',
                      asmfile);
-               fprintf (asmfile, "%d,",
+               fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                         TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
+               fputc (',', asmfile);
                CHARS (15);
                dbxout_type (BINFO_TYPE (child), 0, 0);
                putc (';', asmfile);
@@ -1256,9 +1406,13 @@ dbxout_type (type, full, show_arg_types)
                dbxout_type_name (BINFO_TYPE (child));
                putc (':', asmfile);
                dbxout_type (BINFO_TYPE (child), full, 0);
-               fprintf (asmfile, ",%d,%d;",
-                        TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT,
+               fputc (',', asmfile);
+               fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                        TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
+               fputc (',', asmfile);
+               fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
                         TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT);
+               fputc (';', asmfile);
                CHARS (20);
              }
          }
@@ -1311,7 +1465,7 @@ dbxout_type (type, full, show_arg_types)
          fprintf (asmfile, "xe");
          CHARS (3);
          dbxout_type_name (type);
-         typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
+         typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF;
          fprintf (asmfile, ":");
          return;
        }
@@ -1327,18 +1481,20 @@ dbxout_type (type, full, show_arg_types)
        {
          fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
          if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
-           fprintf (asmfile, "%lu",
-                    (unsigned long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
+           fprintf (asmfile, HOST_WIDE_INT_PRINT_UNSIGNED,
+                    TREE_INT_CST_LOW (TREE_VALUE (tem)));
          else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
                   && TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
-           fprintf (asmfile, "%ld",
-                    (long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
+           fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC,
+                    TREE_INT_CST_LOW (TREE_VALUE (tem)));
          else
            print_int_cst_octal (TREE_VALUE (tem));
          fprintf (asmfile, ",");
          CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
          if (TREE_CHAIN (tem) != 0)
-           CONTIN;
+           {
+             CONTIN;
+           }
        }
       putc (';', asmfile);
       CHARS (1);
@@ -1362,6 +1518,7 @@ dbxout_type (type, full, show_arg_types)
              /* Normally, just output the return type.
                 The argument types are encoded in the method name.  */
              putc ('#', asmfile);
+             CHARS (1);
              dbxout_type (TREE_TYPE (type), 0, 0);
              putc (';', asmfile);
              CHARS (1);
@@ -1466,7 +1623,7 @@ print_int_cst_octal (c)
                  << (HOST_BITS_PER_WIDE_INT / 3 * 3))
                 - 1);
 
-      fprintf (asmfile, "%o%01o", beg, middle);
+      fprintf (asmfile, "%o%01o", (int)beg, (int)middle);
       print_octal (end, HOST_BITS_PER_WIDE_INT / 3);
     }
 }
@@ -1479,7 +1636,7 @@ print_octal (value, digits)
   int i;
 
   for (i = digits - 1; i >= 0; i--)
-    fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7));
+    fprintf (asmfile, "%01o", (int)((value >> (3 * i)) & 7));
 }
 
 /* Output the name of type TYPE, with no punctuation.
@@ -1592,7 +1749,7 @@ dbxout_symbol (decl, local)
 
       /* If this typedef name was defined by outputting the type,
         don't duplicate it.  */
-      if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
+      if (typevec[TYPE_SYMTAB_ADDRESS (type)].status == TYPE_DEFINED
          && TYPE_NAME (TREE_TYPE (decl)) == decl)
        return;
 #endif
@@ -1624,10 +1781,7 @@ dbxout_symbol (decl, local)
                && !TREE_ASM_WRITTEN (TYPE_NAME (type))
                /* Distinguish the implicit typedefs of C++
                   from explicit ones that might be found in C.  */
-                && (!strcmp (lang_identify (), "cplusplus") 
-                   /* The following line maybe unnecessary;
-                      in 2.6, try removing it.  */
-                   || DECL_SOURCE_LINE (decl) == 0))
+                && DECL_ARTIFICIAL (decl))
              {
                tree name = TYPE_NAME (type);
                if (TREE_CODE (name) == TYPE_DECL)
@@ -1652,7 +1806,10 @@ dbxout_symbol (decl, local)
            if ((TREE_CODE (type) == RECORD_TYPE
                 || TREE_CODE (type) == UNION_TYPE
                 || TREE_CODE (type) == QUAL_UNION_TYPE)
-               && TYPE_NAME (type) == decl)
+               && TYPE_NAME (type) == decl
+               /* Distinguish the implicit typedefs of C++
+                  from explicit ones that might be found in C.  */
+                && DECL_ARTIFICIAL (decl))
              {
                if (use_gnu_debug_info_extensions && have_used_extensions)
                  {
@@ -1759,8 +1916,10 @@ dbxout_symbol (decl, local)
 #ifdef DBX_OUTPUT_CONSTANT_SYMBOL
                  DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);
 #else
-                 fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n",
-                          ASM_STABS_OP, name, ival, N_LSYM);
+                 fprintf (asmfile, "%s \"%s:c=i", ASM_STABS_OP, name);
+
+                 fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, ival);
+                 fprintf (asmfile, "\",0x%x,0,0,0\n", N_LSYM);
 #endif
                  return;
                }
@@ -1775,11 +1934,15 @@ dbxout_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
 
       dbxout_symbol_location (decl, type, 0, DECL_RTL (decl));
+      break;
+      
+    default:
+      break;
     }
 }
 \f
@@ -1800,7 +1963,7 @@ dbxout_symbol_location (decl, type, suffix, home)
   /* Don't mention a variable at all
      if it was completely optimized into nothingness.
      
-     If the decl was from an inline function, then it's rtl
+     If the decl was from an inline function, then its rtl
      is not identically the rtl that was used in this
      particular compilation.  */
   if (GET_CODE (home) == REG)
@@ -1886,7 +2049,12 @@ dbxout_symbol_location (decl, type, suffix, home)
   else if (GET_CODE (home) == MEM
           && (GET_CODE (XEXP (home, 0)) == MEM
               || (GET_CODE (XEXP (home, 0)) == REG
-                  && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM)))
+                  && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
+                  && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+                  && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
+#endif
+                  )))
     /* If the value is indirect by memory or by a register
        that isn't the frame pointer
        then it means the object is variable-sized and address through
@@ -2006,15 +2174,9 @@ dbxout_symbol_name (decl, suffix, letter)
 {
   /* One slight hitch: if this is a VAR_DECL which is a static
      class member, we must put out the mangled name instead of the
-     DECL_NAME.  */
-
-  char *name;
-  /* Note also that static member (variable) names DO NOT begin
+     DECL_NAME.  Note also that static member (variable) names DO NOT begin
      with underscores in .stabs directives.  */
-  if (DECL_LANG_SPECIFIC (decl))
-    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  else
-    name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   if (name == 0)
     name = "(anon)";
   fprintf (asmfile, "%s \"%s%s:", ASM_STABS_OP, name,
@@ -2025,7 +2187,7 @@ dbxout_symbol_name (decl, suffix, letter)
 
 static void
 dbxout_prepare_symbol (decl)
-     tree decl;
+     tree decl ATTRIBUTE_UNUSED;
 {
 #ifdef WINNING_GDB
   char *filename = DECL_SOURCE_FILE (decl);
@@ -2094,7 +2256,7 @@ dbxout_parms (parms)
          = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
        DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
 #ifdef LEAF_REG_REMAP
-       if (leaf_function)
+       if (current_function_uses_only_leaf_regs)
          {
            leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms));
            leaf_renumber_regs_insn (DECL_RTL (parms));
@@ -2134,7 +2296,21 @@ dbxout_parms (parms)
                         DBX_MEMPARM_STABS_LETTER);
              }
 
-           dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
+           /* It is quite tempting to use:
+              
+                  dbxout_type (TREE_TYPE (parms), 0, 0);
+
+              as the next statement, rather than using DECL_ARG_TYPE(), so
+              that gcc reports the actual type of the parameter, rather
+              than the promoted type.  This certainly makes GDB's life
+              easier, at least for some ports.  The change is a bad idea
+              however, since GDB expects to be able access the type without
+              performing any conversions.  So for example, if we were
+              passing a float to an unprototyped function, gcc will store a
+              double on the stack, but if we emit a stab saying the type is a
+              float, then gdb will only read in a single value, and this will
+              produce an erropneous value.  */
+           dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
            current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr);
            dbxout_finish_symbol (parms);
          }
@@ -2264,6 +2440,15 @@ dbxout_parms (parms)
              current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
            current_sym_addr = 0;
 
+           /* Make a big endian correction if the mode of the type of the
+              parameter is not the same as the mode of the rtl.  */
+           if (BYTES_BIG_ENDIAN
+               && TYPE_MODE (TREE_TYPE (parms)) != GET_MODE (DECL_RTL (parms))
+               && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))) < UNITS_PER_WORD)
+             {
+               current_sym_value += UNITS_PER_WORD - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms)));
+             }
+
            FORCE_TEXT;
            if (DECL_NAME (parms))
              {
@@ -2495,7 +2680,7 @@ dbxout_really_begin_function (decl)
 
 void
 dbxout_begin_function (decl)
-     tree decl;
+     tree decl ATTRIBUTE_UNUSED;
 {
 #ifdef DBX_FUNCTION_FIRST
   dbxout_really_begin_function (decl);
@@ -2519,5 +2704,13 @@ dbxout_function (decl)
 #ifdef DBX_OUTPUT_FUNCTION_END
   DBX_OUTPUT_FUNCTION_END (asmfile, decl);
 #endif
+#if defined(ASM_OUTPUT_SECTION_NAME)
+  if (use_gnu_debug_info_extensions
+#if defined(NO_DBX_FUNCTION_END)
+      && ! NO_DBX_FUNCTION_END
+#endif
+      )
+    dbxout_function_end ();
+#endif
 }
-#endif /* DBX_DEBUGGING_INFO */
+#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */