OSDN Git Service

* libsupc++/del_op.cc: Don't include cstdlib when !_GLIBCXX_HOSTED.
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index 9175417..91a7a2c 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -48,17 +48,25 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "debug.h"
 #include "tree.h"
 #include "ggc.h"
+#include "varray.h"
 
 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;
 
+/* 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"
@@ -76,7 +84,7 @@ static GTY(()) int unnamed_struct_number;
 /* 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).  */
@@ -244,11 +252,6 @@ do { fprintf (asm_out_file, "\t.tag\t");   \
           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.  */
 
@@ -280,11 +283,6 @@ do { fprintf (asm_out_file, "\t.tag\t");   \
 
 #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
@@ -307,34 +305,37 @@ static struct sdb_file *current_file;
 /* 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_tree,                      /* ignore_block */
+  sdbout_source_line,                   /* source_line */
 #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
-  sdbout_begin_prologue,       /* begin_prologue */
-  debug_nothing_int_charstar,  /* end_prologue */
+  sdbout_begin_prologue,                /* begin_prologue */
+  debug_nothing_int_charstar,           /* end_prologue */
 #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 */
 };
 
 /* Return a unique string to name an anonymous type.  */
@@ -344,7 +345,7 @@ gen_fake_label (void)
 {
   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;
@@ -523,15 +524,15 @@ plain_type_1 (tree type, int level)
          }
 
        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)
-         return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
+         return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
        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)
-         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 */
-         return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+         return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
        return 0;
       }
 
@@ -691,6 +692,14 @@ sdbout_symbol (tree decl, int local)
   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))
@@ -709,7 +718,7 @@ sdbout_symbol (tree decl, int local)
         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)));
@@ -723,6 +732,11 @@ sdbout_symbol (tree decl, int local)
        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)))
@@ -735,7 +749,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.  */
-      abort ();
+      gcc_unreachable ();
 
     case VAR_DECL:
       /* Don't mention a variable that is external.
@@ -767,7 +781,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 (GET_CODE (value) == REG)
+      if (REG_P (value))
        {
          regno = REGNO (value);
          if (regno >= FIRST_PSEUDO_REGISTER)
@@ -777,7 +791,7 @@ sdbout_symbol (tree decl, int local)
        {
          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;
@@ -788,7 +802,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.  */
-      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;
 
@@ -807,7 +821,7 @@ sdbout_symbol (tree decl, int local)
 
       /* Defer SDB information for top-level initialized variables! */
       if (! local
-         && GET_CODE (value) == MEM
+         && MEM_P (value)
          && DECL_INITIAL (decl))
        return;
 
@@ -822,7 +836,7 @@ sdbout_symbol (tree decl, int local)
       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);
@@ -843,9 +857,9 @@ sdbout_symbol (tree decl, int local)
          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
@@ -855,7 +869,7 @@ sdbout_symbol (tree decl, int local)
           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);
@@ -878,14 +892,14 @@ sdbout_symbol (tree decl, int local)
          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 (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 (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
@@ -919,10 +933,9 @@ sdbout_toplevel_data (tree decl)
   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));
@@ -1086,7 +1099,6 @@ sdbout_one_type (tree type)
        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);
@@ -1126,17 +1138,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.  */
-       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;
+               
                if (TYPE_NAME (child_type) == 0)
                  continue;
                if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
@@ -1159,11 +1171,11 @@ sdbout_one_type (tree type)
              }
          }
 
-       /* output the individual fields */
+       /* Output the individual fields.  */
 
        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)));
@@ -1206,7 +1218,7 @@ sdbout_one_type (tree type)
                  }
                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);
@@ -1268,7 +1280,7 @@ sdbout_parms (tree parms)
            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
@@ -1287,7 +1299,7 @@ sdbout_parms (tree 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)
@@ -1307,7 +1319,7 @@ sdbout_parms (tree parms)
            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.  */
@@ -1329,7 +1341,7 @@ sdbout_parms (tree parms)
            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.  */
@@ -1338,8 +1350,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.  */
-           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));
@@ -1376,7 +1388,7 @@ sdbout_reg_parms (tree parms)
 
        /* 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))
          {
@@ -1389,7 +1401,7 @@ sdbout_reg_parms (tree parms)
            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)
@@ -1436,10 +1448,12 @@ sdbout_global_decl (tree decl)
         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.  */
-      if (DECL_INITIAL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+      if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl)))
        sdbout_toplevel_data (decl);
     }
 }
@@ -1450,29 +1464,10 @@ sdbout_global_decl (tree decl)
 static void
 sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
 {
-  tree decl = (*lang_hooks.decls.getdecls) ();
-  unsigned int len = list_length (decl);
-  tree *vec = xmalloc (sizeof (tree) * len);
-  unsigned int i;
-
-  /* Process the decls in reverse order--earliest first.  Put them
-     into VEC from back to front, then take out from front.  */
+  size_t i;
 
-  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.
@@ -1541,9 +1536,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)
     {
-#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)
@@ -1646,7 +1640,7 @@ sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
   n->next = current_file;
   n->name = filename;
   current_file = n;
-  PUT_SDB_SRC_FILE (filename);
+  output_file_directive (asm_out_file, filename);
 #endif
 }
 
@@ -1661,7 +1655,7 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
   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
 }
 
@@ -1670,11 +1664,23 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
 static void
 sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
 {
+  tree t;
+
 #ifdef MIPS_DEBUGGING_INFO
   current_file = xmalloc (sizeof *current_file);
   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 */