OSDN Git Service

* sdbout.c (sdbout_symbol): Pass VOIDmode to eliminate_regs.
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 56cebba..818ff63 100644 (file)
@@ -1,12 +1,13 @@
 /* Output sdb-format symbol table information from GNU compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* Output sdb-format symbol table information from GNU compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /*  mike@tredysvr.Tredydev.Unisys.COM says:
 I modified the struct.c example and have a nm of a .o resulting from the
 
 /*  mike@tredysvr.Tredydev.Unisys.COM says:
 I modified the struct.c example and have a nm of a .o resulting from the
@@ -52,10 +52,6 @@ AT&T C compiler.  From the example below I would conclude the following:
 
 static GTY(()) tree anonymous_types;
 
 
 static GTY(()) tree anonymous_types;
 
-/* Counter for sdbout_source_line.  */
-
-static GTY(()) int sdbout_source_line_counter;
-
 /* Counter to generate unique "names" for nameless struct members.  */
 
 static GTY(()) int unnamed_struct_number;
 /* Counter to generate unique "names" for nameless struct members.  */
 
 static GTY(()) int unnamed_struct_number;
@@ -64,6 +60,13 @@ static GTY(()) int unnamed_struct_number;
 
 static GTY(()) varray_type deferred_global_decls;
 
 
 static GTY(()) varray_type deferred_global_decls;
 
+/* The C front end may call sdbout_symbol before sdbout_init runs.
+   We save all such decls in this list and output them when we get
+   to sdbout_init.  */
+
+static GTY(()) tree preinit_symbols;
+static GTY(()) bool sdbout_initialized;
+
 #ifdef SDB_DEBUGGING_INFO
 
 #include "rtl.h"
 #ifdef SDB_DEBUGGING_INFO
 
 #include "rtl.h"
@@ -81,7 +84,7 @@ static GTY(()) varray_type deferred_global_decls;
 /* 1 if PARM is passed to this function in memory.  */
 
 #define PARM_PASSED_IN_MEMORY(PARM) \
 /* 1 if PARM is passed to this function in memory.  */
 
 #define PARM_PASSED_IN_MEMORY(PARM) \
- (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
+ (MEM_P (DECL_INCOMING_RTL (PARM)))
 
 /* A C expression for the integer offset value of an automatic variable
    (C_AUTO) having address X (an RTX).  */
 
 /* A C expression for the integer offset value of an automatic variable
    (C_AUTO) having address X (an RTX).  */
@@ -249,11 +252,6 @@ do { fprintf (asm_out_file, "\t.tag\t");   \
           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
 #endif
 
           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
 #endif
 
-#ifndef SDB_GENERATE_FAKE
-#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
-  sprintf ((BUFFER), ".%dfake", (NUMBER));
-#endif
-
 /* Return the sdb tag identifier string for TYPE
    if TYPE has already been defined; otherwise return a null pointer.  */
 
 /* Return the sdb tag identifier string for TYPE
    if TYPE has already been defined; otherwise return a null pointer.  */
 
@@ -262,7 +260,7 @@ do { fprintf (asm_out_file, "\t.tag\t");    \
 /* Set the sdb tag identifier string for TYPE to NAME.  */
 
 #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
 /* Set the sdb tag identifier string for TYPE to NAME.  */
 
 #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
-  TYPE_SYMTAB_POINTER (TYPE) = (char *)(NAME)
+  TYPE_SYMTAB_POINTER (TYPE) = (const char *)(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.  */
 
 /* 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.  */
@@ -285,11 +283,6 @@ do { fprintf (asm_out_file, "\t.tag\t");   \
 
 #ifdef MIPS_DEBUGGING_INFO
 
 
 #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
 /* 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
@@ -320,7 +313,7 @@ const struct gcc_debug_hooks sdb_debug_hooks =
   sdbout_end_source_file,               /* end_source_file */
   sdbout_begin_block,                   /* begin_block */
   sdbout_end_block,                     /* end_block */
   sdbout_end_source_file,               /* end_source_file */
   sdbout_begin_block,                   /* begin_block */
   sdbout_end_block,                     /* end_block */
-  debug_true_tree,                      /* ignore_block */
+  debug_true_const_tree,                /* ignore_block */
   sdbout_source_line,                   /* source_line */
 #ifdef MIPS_DEBUGGING_INFO
   /* Defer on MIPS systems so that parameter descriptions follow
   sdbout_source_line,                   /* source_line */
 #ifdef MIPS_DEBUGGING_INFO
   /* Defer on MIPS systems so that parameter descriptions follow
@@ -336,13 +329,16 @@ const struct gcc_debug_hooks sdb_debug_hooks =
   sdbout_end_function,                  /* end_function */
   debug_nothing_tree,                   /* function_decl */
   sdbout_global_decl,                   /* global_decl */
   sdbout_end_function,                  /* end_function */
   debug_nothing_tree,                   /* function_decl */
   sdbout_global_decl,                   /* global_decl */
-  sdbout_type_decl,                     /* type_decl */
-  debug_nothing_tree_tree,               /* imported_module_or_decl */
+  sdbout_symbol,                        /* type_decl */
+  debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   sdbout_label,                                 /* label */
   debug_nothing_int,                    /* handle_pch */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   sdbout_label,                                 /* label */
   debug_nothing_int,                    /* handle_pch */
-  debug_nothing_rtx                     /* var_location */
+  debug_nothing_rtx,                    /* var_location */
+  debug_nothing_void,                    /* switch_text_section */
+  debug_nothing_tree_tree,              /* set_name */
+  0                                      /* start_end_main_source_file */
 };
 
 /* Return a unique string to name an anonymous type.  */
 };
 
 /* Return a unique string to name an anonymous type.  */
@@ -352,7 +348,7 @@ gen_fake_label (void)
 {
   char label[10];
   char *labelstr;
 {
   char label[10];
   char *labelstr;
-  SDB_GENERATE_FAKE (label, unnamed_struct_number);
+  sprintf (label, ".%dfake", unnamed_struct_number);
   unnamed_struct_number++;
   labelstr = xstrdup (label);
   return labelstr;
   unnamed_struct_number++;
   labelstr = xstrdup (label);
   return labelstr;
@@ -531,15 +527,15 @@ plain_type_1 (tree type, int level)
          }
 
        if (size == INT_TYPE_SIZE)
          }
 
        if (size == INT_TYPE_SIZE)
-         return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
+         return (TYPE_UNSIGNED (type) ? T_UINT : T_INT);
        if (size == CHAR_TYPE_SIZE)
        if (size == CHAR_TYPE_SIZE)
-         return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
+         return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
        if (size == SHORT_TYPE_SIZE)
        if (size == SHORT_TYPE_SIZE)
-         return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
+         return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT);
        if (size == LONG_TYPE_SIZE)
        if (size == LONG_TYPE_SIZE)
-         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+         return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
        if (size == LONG_LONG_TYPE_SIZE)        /* better than nothing */
        if (size == LONG_LONG_TYPE_SIZE)        /* better than nothing */
-         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+         return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
        return 0;
       }
 
        return 0;
       }
 
@@ -586,7 +582,7 @@ plain_type_1 (tree type, int level)
     case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       {
     case QUAL_UNION_TYPE:
     case ENUMERAL_TYPE:
       {
-       char *tag;
+       const char *tag;
 #ifdef SDB_ALLOW_FORWARD_REFERENCES
        sdbout_record_type_name (type);
 #endif
 #ifdef SDB_ALLOW_FORWARD_REFERENCES
        sdbout_record_type_name (type);
 #endif
@@ -699,6 +695,14 @@ sdbout_symbol (tree decl, int local)
   int regno = -1;
   const char *name;
 
   int regno = -1;
   const char *name;
 
+  /* If we are called before sdbout_init is run, just save the symbol
+     for later.  */
+  if (!sdbout_initialized)
+    {
+      preinit_symbols = tree_cons (0, decl, preinit_symbols);
+      return;
+    }
+
   sdbout_one_type (type);
 
   switch (TREE_CODE (decl))
   sdbout_one_type (type);
 
   switch (TREE_CODE (decl))
@@ -717,7 +721,7 @@ sdbout_symbol (tree decl, int local)
         a DECL_INITIAL value of 0.  */
       if (! DECL_INITIAL (decl))
        return;
         a DECL_INITIAL value of 0.  */
       if (! DECL_INITIAL (decl))
        return;
-      if (GET_CODE (DECL_RTL (decl)) != MEM
+      if (!MEM_P (DECL_RTL (decl))
          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
        return;
       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
        return;
       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
@@ -731,6 +735,11 @@ sdbout_symbol (tree decl, int local)
        return;
       if (DECL_IGNORED_P (decl))
        return;
        return;
       if (DECL_IGNORED_P (decl))
        return;
+      /* Don't output intrinsic types.  GAS chokes on SDB .def
+        statements that contain identifiers with embedded spaces
+        (eg "unsigned long").  */
+      if (DECL_IS_BUILTIN (decl))
+       return;
 
       /* Output typedef name.  */
       if (template_name_p (DECL_NAME (decl)))
 
       /* Output typedef name.  */
       if (template_name_p (DECL_NAME (decl)))
@@ -743,7 +752,7 @@ sdbout_symbol (tree decl, int local)
     case PARM_DECL:
       /* Parm decls go in their own separate chains
         and are output by sdbout_reg_parms and sdbout_parms.  */
     case PARM_DECL:
       /* Parm decls go in their own separate chains
         and are output by sdbout_reg_parms and sdbout_parms.  */
-      abort ();
+      gcc_unreachable ();
 
     case VAR_DECL:
       /* Don't mention a variable that is external.
 
     case VAR_DECL:
       /* Don't mention a variable that is external.
@@ -762,7 +771,7 @@ sdbout_symbol (tree decl, int local)
        return;
 
       SET_DECL_RTL (decl,
        return;
 
       SET_DECL_RTL (decl,
-                   eliminate_regs (DECL_RTL (decl), 0, NULL_RTX));
+                   eliminate_regs (DECL_RTL (decl), VOIDmode, NULL_RTX));
 #ifdef LEAF_REG_REMAP
       if (current_function_uses_only_leaf_regs)
        leaf_renumber_regs_insn (DECL_RTL (decl));
 #ifdef LEAF_REG_REMAP
       if (current_function_uses_only_leaf_regs)
        leaf_renumber_regs_insn (DECL_RTL (decl));
@@ -775,7 +784,7 @@ sdbout_symbol (tree decl, int local)
         If DECL was from an inline function, then its rtl
         is not identically the rtl that was used in this
         particular compilation.  */
         If DECL was from an inline function, then its rtl
         is not identically the rtl that was used in this
         particular compilation.  */
-      if (GET_CODE (value) == REG)
+      if (REG_P (value))
        {
          regno = REGNO (value);
          if (regno >= FIRST_PSEUDO_REGISTER)
        {
          regno = REGNO (value);
          if (regno >= FIRST_PSEUDO_REGISTER)
@@ -785,7 +794,7 @@ sdbout_symbol (tree decl, int local)
        {
          while (GET_CODE (value) == SUBREG)
            value = SUBREG_REG (value);
        {
          while (GET_CODE (value) == SUBREG)
            value = SUBREG_REG (value);
-         if (GET_CODE (value) == REG)
+         if (REG_P (value))
            {
              if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
                return;
            {
              if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
                return;
@@ -796,7 +805,7 @@ sdbout_symbol (tree decl, int local)
       /* Don't output anything if an auto variable
         gets RTL that is static.
         GAS version 2.2 can't handle such output.  */
       /* 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))
+      else if (MEM_P (value) && CONSTANT_P (XEXP (value, 0))
               && ! TREE_STATIC (decl))
        return;
 
               && ! TREE_STATIC (decl))
        return;
 
@@ -815,7 +824,7 @@ sdbout_symbol (tree decl, int local)
 
       /* Defer SDB information for top-level initialized variables! */
       if (! local
 
       /* Defer SDB information for top-level initialized variables! */
       if (! local
-         && GET_CODE (value) == MEM
+         && MEM_P (value)
          && DECL_INITIAL (decl))
        return;
 
          && DECL_INITIAL (decl))
        return;
 
@@ -830,7 +839,7 @@ sdbout_symbol (tree decl, int local)
       else
        name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
       else
        name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
-      if (GET_CODE (value) == MEM
+      if (MEM_P (value)
          && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
        {
          PUT_SDB_DEF (name);
          && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
        {
          PUT_SDB_DEF (name);
@@ -851,9 +860,9 @@ sdbout_symbol (tree decl, int local)
          PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
          PUT_SDB_SCL (C_REG);
        }
          PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
          PUT_SDB_SCL (C_REG);
        }
-      else if (GET_CODE (value) == MEM
-              && (GET_CODE (XEXP (value, 0)) == MEM
-                  || (GET_CODE (XEXP (value, 0)) == REG
+      else if (MEM_P (value)
+              && (MEM_P (XEXP (value, 0))
+                  || (REG_P (XEXP (value, 0))
                       && 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
                       && 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
@@ -863,7 +872,7 @@ sdbout_symbol (tree decl, int local)
           so all we can do is output the variable as a pointer.  */
        {
          PUT_SDB_DEF (name);
           so all we can do is output the variable as a pointer.  */
        {
          PUT_SDB_DEF (name);
-         if (GET_CODE (XEXP (value, 0)) == REG)
+         if (REG_P (XEXP (value, 0)))
            {
              PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
              PUT_SDB_SCL (C_REG);
            {
              PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
              PUT_SDB_SCL (C_REG);
@@ -886,14 +895,14 @@ sdbout_symbol (tree decl, int local)
          type = make_node (POINTER_TYPE);
          TREE_TYPE (type) = TREE_TYPE (decl);
        }
          type = make_node (POINTER_TYPE);
          TREE_TYPE (type) = TREE_TYPE (decl);
        }
-      else if (GET_CODE (value) == MEM
+      else if (MEM_P (value)
               && ((GET_CODE (XEXP (value, 0)) == PLUS
               && ((GET_CODE (XEXP (value, 0)) == PLUS
-                   && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
+                   && REG_P (XEXP (XEXP (value, 0), 0))
                    && 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 (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)))
+                  || (REG_P (XEXP (value, 0)))))
        {
          /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
             or (MEM (REG...)).  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
@@ -927,10 +936,9 @@ sdbout_toplevel_data (tree decl)
   if (DECL_IGNORED_P (decl))
     return;
 
   if (DECL_IGNORED_P (decl))
     return;
 
-  if (! (TREE_CODE (decl) == VAR_DECL
-        && GET_CODE (DECL_RTL (decl)) == MEM
-        && DECL_INITIAL (decl)))
-    abort ();
+  gcc_assert (TREE_CODE (decl) == VAR_DECL);
+  gcc_assert (MEM_P (DECL_RTL (decl)));
+  gcc_assert (DECL_INITIAL (decl));
 
   PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
   PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
 
   PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
   PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
@@ -1043,7 +1051,7 @@ sdbout_one_type (tree type)
       && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
     ; /* Don't change section amid function.  */
   else
       && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
     ; /* Don't change section amid function.  */
   else
-    text_section ();
+    switch_to_section (text_section);
 
   switch (TREE_CODE (type))
     {
 
   switch (TREE_CODE (type))
     {
@@ -1094,7 +1102,6 @@ sdbout_one_type (tree type)
        int size = int_size_in_bytes (type);
        int member_scl = 0;
        tree tem;
        int size = int_size_in_bytes (type);
        int member_scl = 0;
        tree tem;
-       int i, n_baseclasses = 0;
 
        /* Record the type tag, but not in its permanent place just yet.  */
        sdbout_record_type_name (type);
 
        /* Record the type tag, but not in its permanent place just yet.  */
        sdbout_record_type_name (type);
@@ -1134,17 +1141,17 @@ sdbout_one_type (tree type)
        /* This is only relevant to aggregate types.  TYPE_BINFO is used
           for other purposes in an ENUMERAL_TYPE, so we must exclude that
           case.  */
        /* This is only relevant 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)
+       if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type))
          {
          {
-           if (TYPE_BINFO (type)
-               && TYPE_BINFO_BASETYPES (type))
-             n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
-           for (i = 0; i < n_baseclasses; i++)
+           int i;
+           tree binfo, child;
+
+           for (binfo = TYPE_BINFO (type), i = 0;
+                BINFO_BASE_ITERATE (binfo, i, child); i++)
              {
              {
-               tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)),
-                                          i);
                tree child_type = BINFO_TYPE (child);
                tree child_type_name;
                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)
                if (TYPE_NAME (child_type) == 0)
                  continue;
                if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
@@ -1171,15 +1178,22 @@ sdbout_one_type (tree type)
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
          {
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
          {
-           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;
-               }
+           for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
+             {
+               tree value = TREE_VALUE (tem);
+
+               if (TREE_CODE (value) == CONST_DECL)
+                 value = DECL_INITIAL (value);
+
+               if (host_integerp (value, 0))
+                 {
+                   PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
+                   PUT_SDB_INT_VAL (tree_low_cst (value, 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))
          }
        else                    /* record or union type */
          for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
@@ -1257,9 +1271,9 @@ sdbout_parms (tree parms)
        /* Perform any necessary register eliminations on the parameter's rtl,
           so that the debugging output will be accurate.  */
        DECL_INCOMING_RTL (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);
+         = eliminate_regs (DECL_INCOMING_RTL (parms), VOIDmode, NULL_RTX);
        SET_DECL_RTL (parms,
        SET_DECL_RTL (parms,
-                     eliminate_regs (DECL_RTL (parms), 0, NULL_RTX));
+                     eliminate_regs (DECL_RTL (parms), VOIDmode, NULL_RTX));
 
        if (PARM_PASSED_IN_MEMORY (parms))
          {
 
        if (PARM_PASSED_IN_MEMORY (parms))
          {
@@ -1276,7 +1290,7 @@ sdbout_parms (tree parms)
            else
              current_sym_value = 0;
 
            else
              current_sym_value = 0;
 
-           if (GET_CODE (DECL_RTL (parms)) == REG
+           if (REG_P (DECL_RTL (parms))
                && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              type = DECL_ARG_TYPE (parms);
            else
                && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              type = DECL_ARG_TYPE (parms);
            else
@@ -1295,7 +1309,7 @@ sdbout_parms (tree parms)
                    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
 
                    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
                     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
 
-               if (GET_CODE (DECL_RTL (parms)) == MEM
+               if (MEM_P (DECL_RTL (parms))
                    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
                        == CONST_INT)
                    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
                        == CONST_INT)
@@ -1315,7 +1329,7 @@ sdbout_parms (tree parms)
            PUT_SDB_TYPE (plain_type (type));
            PUT_SDB_ENDEF;
          }
            PUT_SDB_TYPE (plain_type (type));
            PUT_SDB_ENDEF;
          }
-       else if (GET_CODE (DECL_RTL (parms)) == REG)
+       else if (REG_P (DECL_RTL (parms)))
          {
            rtx best_rtl;
            /* Parm passed in registers and lives in registers or nowhere.  */
          {
            rtx best_rtl;
            /* Parm passed in registers and lives in registers or nowhere.  */
@@ -1337,7 +1351,7 @@ sdbout_parms (tree parms)
            PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
            PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
            PUT_SDB_ENDEF;
          }
-       else if (GET_CODE (DECL_RTL (parms)) == MEM
+       else if (MEM_P (DECL_RTL (parms))
                 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
          {
            /* Parm was passed in registers but lives on the stack.  */
                 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
          {
            /* Parm was passed in registers but lives on the stack.  */
@@ -1346,8 +1360,8 @@ sdbout_parms (tree parms)
               in which case we want the value of that CONST_INT,
               or (MEM (REG ...)) or (MEM (MEM ...)),
               in which case we use a value of zero.  */
               in which case we want the value of that CONST_INT,
               or (MEM (REG ...)) or (MEM (MEM ...)),
               in which case we use a value of zero.  */
-           if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
-               || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM)
+           if (REG_P (XEXP (DECL_RTL (parms), 0))
+               || MEM_P (XEXP (DECL_RTL (parms), 0)))
              current_sym_value = 0;
            else
              current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
              current_sym_value = 0;
            else
              current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
@@ -1384,7 +1398,7 @@ sdbout_reg_parms (tree parms)
 
        /* Report parms that live in registers during the function
           but were passed in memory.  */
 
        /* Report parms that live in registers during the function
           but were passed in memory.  */
-       if (GET_CODE (DECL_RTL (parms)) == REG
+       if (REG_P (DECL_RTL (parms))
            && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
            && PARM_PASSED_IN_MEMORY (parms))
          {
            && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
            && PARM_PASSED_IN_MEMORY (parms))
          {
@@ -1397,7 +1411,7 @@ sdbout_reg_parms (tree parms)
            PUT_SDB_ENDEF;
          }
        /* Report parms that live in memory but not where they were passed.  */
            PUT_SDB_ENDEF;
          }
        /* Report parms that live in memory but not where they were passed.  */
-       else if (GET_CODE (DECL_RTL (parms)) == MEM
+       else if (MEM_P (DECL_RTL (parms))
                 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
                 && PARM_PASSED_IN_MEMORY (parms)
                 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
                 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
                 && PARM_PASSED_IN_MEMORY (parms)
@@ -1449,7 +1463,7 @@ sdbout_global_decl (tree decl)
 
       /* Output COFF information for non-global file-scope initialized
         variables.  */
 
       /* Output COFF information for non-global file-scope initialized
         variables.  */
-      if (DECL_INITIAL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+      if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl)))
        sdbout_toplevel_data (decl);
     }
 }
        sdbout_toplevel_data (decl);
     }
 }
@@ -1460,12 +1474,10 @@ sdbout_global_decl (tree decl)
 static void
 sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
 {
 static void
 sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
 {
-  int i;
+  size_t i;
 
   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
     sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
 
   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
     sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
-
-  VARRAY_FREE (deferred_global_decls);
 }
 
 /* Describe the beginning of an internal block within a function.
 }
 
 /* Describe the beginning of an internal block within a function.
@@ -1534,9 +1546,8 @@ sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED)
   /* COFF relative line numbers must be positive.  */
   if ((int) line > sdb_begin_function_line)
     {
   /* COFF relative line numbers must be positive.  */
   if ((int) line > sdb_begin_function_line)
     {
-#ifdef ASM_OUTPUT_SOURCE_LINE
-      sdbout_source_line_counter += 1;
-      ASM_OUTPUT_SOURCE_LINE (asm_out_file, line, sdbout_source_line_counter);
+#ifdef SDB_OUTPUT_SOURCE_LINE
+      SDB_OUTPUT_SOURCE_LINE (asm_out_file, line);
 #else
       fprintf (asm_out_file, "\t.ln\t%d\n",
               ((sdb_begin_function_line > -1)
 #else
       fprintf (asm_out_file, "\t.ln\t%d\n",
               ((sdb_begin_function_line > -1)
@@ -1634,12 +1645,12 @@ sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
                          const char *filename ATTRIBUTE_UNUSED)
 {
 #ifdef MIPS_DEBUGGING_INFO
                          const char *filename ATTRIBUTE_UNUSED)
 {
 #ifdef MIPS_DEBUGGING_INFO
-  struct sdb_file *n = xmalloc (sizeof *n);
+  struct sdb_file *n = XNEW (struct sdb_file);
 
   n->next = current_file;
   n->name = filename;
   current_file = n;
 
   n->next = current_file;
   n->name = filename;
   current_file = n;
-  PUT_SDB_SRC_FILE (filename);
+  output_file_directive (asm_out_file, filename);
 #endif
 }
 
 #endif
 }
 
@@ -1654,7 +1665,7 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
   next = current_file->next;
   free (current_file);
   current_file = next;
   next = current_file->next;
   free (current_file);
   current_file = next;
-  PUT_SDB_SRC_FILE (current_file->name);
+  output_file_directive (asm_out_file, current_file->name);
 #endif
 }
 
 #endif
 }
 
@@ -1663,13 +1674,23 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
 static void
 sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
 {
 static void
 sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
 {
+  tree t;
+
 #ifdef MIPS_DEBUGGING_INFO
 #ifdef MIPS_DEBUGGING_INFO
-  current_file = xmalloc (sizeof *current_file);
+  current_file = XNEW (struct sdb_file);
   current_file->next = NULL;
   current_file->name = input_file_name;
 #endif
 
   VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls");
   current_file->next = NULL;
   current_file->name = input_file_name;
 #endif
 
   VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls");
+
+  /* Emit debug information which was queued by sdbout_symbol before
+     we got here.  */
+  sdbout_initialized = true;
+
+  for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t))
+    sdbout_symbol (TREE_VALUE (t), 0);
+  preinit_symbols = 0;
 }
 
 #else  /* SDB_DEBUGGING_INFO */
 }
 
 #else  /* SDB_DEBUGGING_INFO */