OSDN Git Service

* configure.ac: Correct makeinfo version check.
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 0af958c..6d9689c 100644 (file)
@@ -1,12 +1,12 @@
 /* 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 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2007 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 +15,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
@@ -48,9 +47,25 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "debug.h"
 #include "tree.h"
 #include "ggc.h"
 #include "debug.h"
 #include "tree.h"
 #include "ggc.h"
+#include "varray.h"
 
 static GTY(()) tree anonymous_types;
 
 
 static GTY(()) tree anonymous_types;
 
+/* Counter to generate unique "names" for nameless struct members.  */
+
+static GTY(()) int unnamed_struct_number;
+
+/* Declarations whose debug info was deferred till end of compilation.  */
+
+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"
@@ -68,7 +83,7 @@ static GTY(()) tree anonymous_types;
 /* 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).  */
@@ -88,9 +103,6 @@ static GTY(()) tree anonymous_types;
 
 int sdb_begin_function_line = -1;
 
 
 int sdb_begin_function_line = -1;
 
-/* Counter to generate unique "names" for nameless struct members.  */
-
-static int unnamed_struct_number = 0;
 
 extern FILE *asm_out_file;
 
 
 extern FILE *asm_out_file;
 
@@ -239,11 +251,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.  */
 
@@ -252,7 +259,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.  */
@@ -275,11 +282,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
@@ -302,34 +304,39 @@ static struct sdb_file *current_file;
 /* The debug hooks structure.  */
 const struct gcc_debug_hooks sdb_debug_hooks =
 {
 /* The debug hooks structure.  */
 const struct gcc_debug_hooks sdb_debug_hooks =
 {
-  sdbout_init,                 /* init */
-  sdbout_finish,               /* finish */
-  debug_nothing_int_charstar,  /* define */
-  debug_nothing_int_charstar,  /* undef */
-  sdbout_start_source_file,    /* start_source_file */
-  sdbout_end_source_file,      /* end_source_file */
-  sdbout_begin_block,          /* begin_block */
-  sdbout_end_block,            /* end_block */
-  debug_true_tree,             /* ignore_block */
-  sdbout_source_line,          /* source_line */
+  sdbout_init,                          /* init */
+  sdbout_finish,                        /* finish */
+  debug_nothing_int_charstar,           /* define */
+  debug_nothing_int_charstar,           /* undef */
+  sdbout_start_source_file,             /* start_source_file */
+  sdbout_end_source_file,               /* end_source_file */
+  sdbout_begin_block,                   /* begin_block */
+  sdbout_end_block,                     /* end_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
      function entry.  */
 #ifdef MIPS_DEBUGGING_INFO
   /* Defer on MIPS systems so that parameter descriptions follow
      function entry.  */
-  debug_nothing_int_charstar,  /* begin_prologue */
-  sdbout_end_prologue,         /* end_prologue */
+  debug_nothing_int_charstar,           /* begin_prologue */
+  sdbout_end_prologue,                  /* end_prologue */
 #else
 #else
-  sdbout_begin_prologue,       /* begin_prologue */
-  debug_nothing_int_charstar,  /* end_prologue */
+  sdbout_begin_prologue,                /* begin_prologue */
+  debug_nothing_int_charstar,           /* end_prologue */
 #endif
 #endif
-  sdbout_end_epilogue,         /* end_epilogue */
-  sdbout_begin_function,       /* begin_function */
-  sdbout_end_function,         /* end_function */
-  debug_nothing_tree,          /* function_decl */
-  sdbout_global_decl,          /* global_decl */
-  debug_nothing_tree,          /* deferred_inline_function */
-  debug_nothing_tree,          /* outlining_inline_function */
-  sdbout_label,                        /* label */
-  debug_nothing_int            /* handle_pch */
+  sdbout_end_epilogue,                  /* end_epilogue */
+  sdbout_begin_function,                /* begin_function */
+  sdbout_end_function,                  /* end_function */
+  debug_nothing_tree,                   /* function_decl */
+  sdbout_global_decl,                   /* global_decl */
+  sdbout_symbol,                        /* type_decl */
+  debug_nothing_tree_tree,               /* 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_rtx,                    /* var_location */
+  debug_nothing_void,                    /* switch_text_section */
+  0                                      /* start_end_main_source_file */
 };
 
 /* Return a unique string to name an anonymous type.  */
 };
 
 /* Return a unique string to name an anonymous type.  */
@@ -339,7 +346,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;
@@ -518,15 +525,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;
       }
 
@@ -573,7 +580,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
@@ -686,6 +693,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))
@@ -704,7 +719,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)));
@@ -718,6 +733,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)))
@@ -730,7 +750,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 +782,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)
@@ -772,7 +792,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;
@@ -783,7 +803,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;
 
@@ -802,7 +822,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;
 
@@ -817,7 +837,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);
@@ -838,9 +858,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
@@ -850,7 +870,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);
@@ -873,14 +893,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
@@ -914,10 +934,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));
@@ -1030,7 +1049,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))
     {
@@ -1053,7 +1072,7 @@ sdbout_one_type (tree type)
       /* This is reputed to cause trouble with the following case,
         but perhaps checking TYPE_SIZE above will fix it.  */
 
       /* This is reputed to cause trouble with the following case,
         but perhaps checking TYPE_SIZE above will fix it.  */
 
-      /* Here is a test case:
+      /* Here is a testcase:
 
        struct foo {
          struct badstr *bbb;
 
        struct foo {
          struct badstr *bbb;
@@ -1081,7 +1100,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);
@@ -1121,17 +1139,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)
@@ -1154,11 +1172,11 @@ sdbout_one_type (tree type)
              }
          }
 
              }
          }
 
-       /* output the individual fields */
+       /* Output the individual fields.  */
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
          {
 
        if (TREE_CODE (type) == ENUMERAL_TYPE)
          {
-           for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+           for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
              if (host_integerp (TREE_VALUE (tem), 0))
                {
                  PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
              if (host_integerp (TREE_VALUE (tem), 0))
                {
                  PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
@@ -1201,7 +1219,7 @@ sdbout_one_type (tree type)
                  }
                PUT_SDB_ENDEF;
              }
                  }
                PUT_SDB_ENDEF;
              }
-       /* output end of a structure,union, or enumeral definition */
+       /* Output end of a structure,union, or enumeral definition.  */
 
        PUT_SDB_PLAIN_DEF ("eos");
        PUT_SDB_INT_VAL (size);
 
        PUT_SDB_PLAIN_DEF ("eos");
        PUT_SDB_INT_VAL (size);
@@ -1263,7 +1281,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
@@ -1282,7 +1300,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)
@@ -1302,7 +1320,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.  */
@@ -1324,7 +1342,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.  */
@@ -1333,8 +1351,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));
@@ -1371,7 +1389,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))
          {
@@ -1384,7 +1402,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)
@@ -1431,10 +1449,12 @@ sdbout_global_decl (tree decl)
         sdbout_finish ().  */
       if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
        sdbout_symbol (decl, 0);
         sdbout_finish ().  */
       if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
        sdbout_symbol (decl, 0);
+      else
+       VARRAY_PUSH_TREE (deferred_global_decls, 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);
     }
 }
@@ -1445,29 +1465,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)
 {
-  tree decl = (*lang_hooks.decls.getdecls) ();
-  unsigned int len = list_length (decl);
-  tree *vec = (tree *) xmalloc (sizeof (tree) * len);
-  unsigned int i;
+  size_t i;
 
 
-  /* Process the decls in reverse order--earliest first.  Put them
-     into VEC from back to front, then take out from front.  */
-
-  for (i = 0; i < len; i++, decl = TREE_CHAIN (decl))
-    vec[len - i - 1] = decl;
-
-  for (i = 0; i < len; i++)
-    {
-      decl = vec[i];
-      if (TREE_CODE (decl) == VAR_DECL
-         && ! DECL_EXTERNAL (decl)
-         && DECL_INITIAL (decl)
-         && TREE_PUBLIC (decl)
-         && DECL_RTL_SET_P (decl))
-       sdbout_symbol (decl, 0);
-    }
-
-  free (vec);
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
+    sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
 }
 
 /* Describe the beginning of an internal block within a function.
 }
 
 /* Describe the beginning of an internal block within a function.
@@ -1527,16 +1528,17 @@ sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED)
   PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
 }
 
   PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
 }
 
+/* Output a line number symbol entry for source file FILENAME and line
+   number LINE.  */
+
 static void
 static void
-sdbout_source_line (line, filename)
-     unsigned int line;
-     const char *filename ATTRIBUTE_UNUSED;
+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
-      ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+#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)
@@ -1569,9 +1571,7 @@ sdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
 #endif
 
 static void
 #endif
 
 static void
-sdbout_end_prologue (line, file)
-     unsigned int line;
-     const char *file ATTRIBUTE_UNUSED;
+sdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
 {
   sdb_begin_function_line = line - 1;
   PUT_SDB_FUNCTION_START (line);
 {
   sdb_begin_function_line = line - 1;
   PUT_SDB_FUNCTION_START (line);
@@ -1636,12 +1636,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 = (struct sdb_file *) xmalloc (sizeof *n);
+  struct sdb_file *n = xmalloc (sizeof *n);
 
   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
 }
 
@@ -1656,7 +1656,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
 }
 
@@ -1665,11 +1665,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 = (struct sdb_file *) xmalloc (sizeof *current_file);
+  current_file = xmalloc (sizeof *current_file);
   current_file->next = NULL;
   current_file->name = input_file_name;
 #endif
   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 */