OSDN Git Service

* flags.h (g_switch_value): Change to an unsigned
[pf3gnuchains/gcc-fork.git] / gcc / sdbout.c
index accd9ed..9ad9f42 100644 (file)
@@ -1,23 +1,23 @@
 /* Output sdb-format symbol table information from GNU compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001  Free Software Foundation, Inc.
+   2000, 2001, 2002 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 version.
+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
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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
-along with GNU CC; 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 COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /*  mike@tredysvr.Tredydev.Unisys.COM says:
 I modified the struct.c example and have a nm of a .o resulting from the
@@ -42,11 +42,17 @@ AT&T C compiler.  From the example below I would conclude the following:
 */
 
 #include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "debug.h"
+#include "tree.h"
+#include "ggc.h"
+
+static GTY(()) tree anonymous_types;
 
 #ifdef SDB_DEBUGGING_INFO
 
-#include "system.h"
-#include "tree.h"
 #include "rtl.h"
 #include "regs.h"
 #include "flags.h"
@@ -54,10 +60,10 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "reload.h"
 #include "output.h"
 #include "toplev.h"
-#include "ggc.h"
 #include "tm_p.h"
 #include "gsyms.h"
-#include "debug.h"
+#include "langhooks.h"
+#include "target.h"
 
 /* 1 if PARM is passed to this function in memory.  */
 
@@ -93,17 +99,18 @@ extern tree current_function_decl;
 #include "sdbout.h"
 
 static void sdbout_init                        PARAMS ((const char *));
-static void sdbout_start_source_file   PARAMS ((unsigned, const char *));
-static void sdbout_end_source_file     PARAMS ((unsigned));
-static void sdbout_begin_block         PARAMS ((unsigned, unsigned));
-static void sdbout_end_block           PARAMS ((unsigned, unsigned));
+static void sdbout_finish              PARAMS ((const char *));
+static void sdbout_start_source_file   PARAMS ((unsigned int, const char *));
+static void sdbout_end_source_file     PARAMS ((unsigned int));
+static void sdbout_begin_block         PARAMS ((unsigned int, unsigned int));
+static void sdbout_end_block           PARAMS ((unsigned int, unsigned int));
 static void sdbout_source_line         PARAMS ((unsigned int, const char *));
-static void sdbout_end_epilogue                PARAMS ((void));
+static void sdbout_end_epilogue                PARAMS ((unsigned int, const char *));
 static void sdbout_global_decl         PARAMS ((tree));
 #ifndef MIPS_DEBUGGING_INFO
 static void sdbout_begin_prologue      PARAMS ((unsigned int, const char *));
 #endif
-static void sdbout_end_prologue                PARAMS ((unsigned int));
+static void sdbout_end_prologue                PARAMS ((unsigned int, const char *));
 static void sdbout_begin_function      PARAMS ((tree));
 static void sdbout_end_function                PARAMS ((unsigned int));
 static void sdbout_toplevel_data       PARAMS ((tree));
@@ -124,6 +131,7 @@ static void sdbout_field_types              PARAMS ((tree));
 static void sdbout_one_type            PARAMS ((tree));
 static void sdbout_parms               PARAMS ((tree));
 static void sdbout_reg_parms           PARAMS ((tree));
+static void sdbout_global_decl         PARAMS ((tree));
 \f
 /* Random macros describing parts of SDB data.  */
 
@@ -147,9 +155,8 @@ static void sdbout_reg_parms                PARAMS ((tree));
 #ifndef PUT_SDB_INT_VAL
 #define PUT_SDB_INT_VAL(a) \
  do {                                                                  \
-   fputs ("\t.val\t", asm_out_file);                                   \
-   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a));        \
-   fprintf (asm_out_file, "%s", SDB_DELIM);                            \
+   fprintf (asm_out_file, "\t.val\t" HOST_WIDE_INT_PRINT_DEC "%s",     \
+           (HOST_WIDE_INT) (a), SDB_DELIM);                            \
  } while (0)
 
 #endif
@@ -183,9 +190,8 @@ do { fprintf (asm_out_file, "\t.def\t");    \
 #ifndef PUT_SDB_SIZE
 #define PUT_SDB_SIZE(a) \
  do {                                                                  \
-   fputs ("\t.size\t", asm_out_file);                                  \
-   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a));        \
-   fprintf (asm_out_file, "%s", SDB_DELIM);                            \
+   fprintf (asm_out_file, "\t.size\t" HOST_WIDE_INT_PRINT_DEC "%s",    \
+           (HOST_WIDE_INT) (a), SDB_DELIM);                            \
  } while(0)
 #endif
 
@@ -242,14 +248,14 @@ do { fprintf (asm_out_file, "\t.tag\t");  \
 #endif
 
 /* Return the sdb tag identifier string for TYPE
-   if TYPE has already been defined; otherwise return a null pointer.   */
+   if TYPE has already been defined; otherwise return a null pointer.  */
 
 #define KNOWN_TYPE_TAG(type)  TYPE_SYMTAB_POINTER (type)
 
 /* Set the sdb tag identifier string for TYPE to NAME.  */
 
 #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
-  TYPE_SYMTAB_POINTER (TYPE) = (NAME)
+  TYPE_SYMTAB_POINTER (TYPE) = (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.  */
@@ -261,7 +267,8 @@ do { fprintf (asm_out_file, "\t.tag\t");    \
 
 /* Ensure we don't output a negative line number.  */
 #define MAKE_LINE_SAFE(line)  \
-  if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1
+  if ((int) line <= sdb_begin_function_line) \
+    line = sdb_begin_function_line + 1
 
 /* Perform linker optimization of merging header file definitions together
    for targets with MIPS_DEBUGGING_INFO defined.  This won't work without a
@@ -296,18 +303,18 @@ static struct sdb_file *current_file;
 #endif /* MIPS_DEBUGGING_INFO */
 \f
 /* The debug hooks structure.  */
-struct gcc_debug_hooks sdb_debug_hooks =
+const struct gcc_debug_hooks sdb_debug_hooks =
 {
-  sdbout_init,
-  debug_nothing_charstar,
-  debug_nothing_int_charstar,
-  debug_nothing_int_charstar,
-  sdbout_start_source_file,
-  sdbout_end_source_file,
-  sdbout_begin_block,
-  sdbout_end_block,
+  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,
+  sdbout_source_line,          /* source_line */
 #ifdef MIPS_DEBUGGING_INFO
   /* Defer on MIPS systems so that parameter descriptions follow
      function entry.  */
@@ -315,16 +322,17 @@ struct gcc_debug_hooks sdb_debug_hooks =
   sdbout_end_prologue,         /* end_prologue */
 #else
   sdbout_begin_prologue,       /* begin_prologue */
-  debug_nothing_int,           /* end_prologue */
+  debug_nothing_int_charstar,  /* end_prologue */
 #endif
-  sdbout_end_epilogue,
-  sdbout_begin_function,
-  sdbout_end_function,
+  sdbout_end_epilogue,         /* end_epilogue */
+  sdbout_begin_function,       /* begin_function */
+  sdbout_end_function,         /* end_function */
   debug_nothing_tree,          /* function_decl */
-  sdbout_global_decl,
+  sdbout_global_decl,          /* global_decl */
   debug_nothing_tree,          /* deferred_inline_function */
   debug_nothing_tree,          /* outlining_inline_function */
-  sdbout_label
+  sdbout_label,                        /* label */
+  debug_nothing_int            /* handle_pch */
 };
 \f
 #if 0
@@ -355,8 +363,7 @@ gen_fake_label ()
   char *labelstr;
   SDB_GENERATE_FAKE (label, unnamed_struct_number);
   unnamed_struct_number++;
-  labelstr = (char *) permalloc (strlen (label) + 1);
-  strcpy (labelstr, label);
+  labelstr = xstrdup (label);
   return labelstr;
 }
 \f
@@ -378,9 +385,9 @@ gen_fake_label ()
    PREV is the number describing the target, value or element type.
    DT_type describes how to transform that type.  */
 #define PUSH_DERIVED_LEVEL(DT_type,PREV)               \
-  ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT)                \
-   | ((int)DT_type << (int)N_BTSHFT)                   \
-   | ((PREV) & (int)N_BTMASK))
+  ((((PREV) & ~(int) N_BTMASK) << (int) N_TSHIFT)              \
+   | ((int) DT_type << (int) N_BTSHFT)                 \
+   | ((PREV) & (int) N_BTMASK))
 
 /* Number of elements used in sdb_dims.  */
 static int sdb_n_dims = 0;
@@ -426,7 +433,7 @@ static int
 template_name_p (name)
      tree name;
 {
-  register const char *ptr = IDENTIFIER_POINTER (name);
+  const char *ptr = IDENTIFIER_POINTER (name);
   while (*ptr && *ptr != '<')
     ptr++;
 
@@ -446,6 +453,7 @@ sdbout_record_type_name (type)
   if (TYPE_NAME (type) != 0)
     {
       tree t = 0;
+
       /* Find the IDENTIFIER_NODE for the type name.  */
       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
        t = TYPE_NAME (type);
@@ -513,7 +521,7 @@ plain_type_1 (type, level)
            && DECL_NAME (TYPE_NAME (type)) != 0
            && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
          {
-           const char *name
+           const char *const name
              = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
 
            if (!strcmp (name, "char"))
@@ -658,7 +666,7 @@ static int do_block = 0;
 
 static void
 sdbout_block (block)
-     register tree block;
+     tree block;
 {
   while (block)
     {
@@ -777,7 +785,7 @@ sdbout_symbol (decl, local)
       if (!DECL_RTL_SET_P (decl))
        return;
 
-      SET_DECL_RTL (decl, 
+      SET_DECL_RTL (decl,
                    eliminate_regs (DECL_RTL (decl), 0, NULL_RTX));
 #ifdef LEAF_REG_REMAP
       if (current_function_uses_only_leaf_regs)
@@ -793,7 +801,7 @@ sdbout_symbol (decl, local)
         particular compilation.  */
       if (GET_CODE (value) == REG)
        {
-         regno = REGNO (DECL_RTL (decl));
+         regno = REGNO (value);
          if (regno >= FIRST_PSEUDO_REGISTER)
            return;
        }
@@ -806,8 +814,8 @@ sdbout_symbol (decl, local)
              if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
                return;
            }
-         regno = REGNO (alter_subreg (DECL_RTL (decl)));
-         value = DECL_RTL (decl);
+         regno = REGNO (alter_subreg (&value));
+         SET_DECL_RTL (decl, value);
        }
       /* Don't output anything if an auto variable
         gets RTL that is static.
@@ -853,12 +861,12 @@ sdbout_symbol (decl, local)
          if (TREE_PUBLIC (decl))
            {
              PUT_SDB_VAL (XEXP (value, 0));
-              PUT_SDB_SCL (C_EXT);
+             PUT_SDB_SCL (C_EXT);
            }
          else
            {
              PUT_SDB_VAL (XEXP (value, 0));
-              PUT_SDB_SCL (C_STAT);
+             PUT_SDB_SCL (C_STAT);
            }
        }
       else if (regno >= 0)
@@ -918,23 +926,6 @@ sdbout_symbol (decl, local)
          PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
          PUT_SDB_SCL (C_AUTO);
        }
-      else if (GET_CODE (value) == MEM && GET_CODE (XEXP (value, 0)) == CONST)
-       {
-         /* Handle an obscure case which can arise when optimizing and
-            when there are few available registers.  (This is *always*
-            the case for i386/i486 targets).  The DECL_RTL looks like
-            (MEM (CONST ...)) even though this variable is a local `auto'
-            or a local `register' variable.  In effect, what has happened
-            is that the reload pass has seen that all assignments and
-            references for one such a local variable can be replaced by
-            equivalent assignments and references to some static storage
-            variable, thereby avoiding the need for a register.  In such
-            cases we're forced to lie to debuggers and tell them that
-            this variable was itself `static'.  */
-         PUT_SDB_DEF (name);
-         PUT_SDB_VAL (XEXP (XEXP (value, 0), 0));
-         PUT_SDB_SCL (C_STAT);
-       }
       else
        {
          /* It is something we don't know how to represent for SDB.  */
@@ -984,8 +975,6 @@ sdbout_toplevel_data (decl)
 
 /* Machinery to record and output anonymous types.  */
 
-static tree anonymous_types;
-
 static void
 sdbout_queue_anonymous_type (type)
      tree type;
@@ -996,7 +985,7 @@ sdbout_queue_anonymous_type (type)
 static void
 sdbout_dequeue_anonymous_types ()
 {
-  register tree types, link;
+  tree types, link;
 
   while (anonymous_types)
     {
@@ -1005,7 +994,7 @@ sdbout_dequeue_anonymous_types ()
 
       for (link = types; link; link = TREE_CHAIN (link))
        {
-         register tree type = TREE_VALUE (link);
+         tree type = TREE_VALUE (link);
 
          if (type && ! TREE_ASM_WRITTEN (type))
            sdbout_one_type (type);
@@ -1020,9 +1009,9 @@ sdbout_dequeue_anonymous_types ()
 
 void
 sdbout_types (types)
-     register tree types;
+     tree types;
 {
-  register tree link;
+  tree link;
 
   for (link = types; link; link = TREE_CHAIN (link))
     sdbout_one_type (link);
@@ -1179,7 +1168,7 @@ sdbout_one_type (type)
 
        /* Print out the base class information with fields
           named after the types they hold.  */
-       /* This is only relevent to aggregate types.  TYPE_BINFO is used
+       /* 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)
@@ -1489,23 +1478,53 @@ sdbout_global_decl (decl)
      tree decl;
 {
   if (TREE_CODE (decl) == VAR_DECL
-      && DECL_INITIAL (decl)
-      && ! DECL_EXTERNAL (decl)
-      && DECL_RTL (decl) != 0)
+      && !DECL_EXTERNAL (decl)
+      && DECL_RTL_SET_P (decl))
     {
       /* The COFF linker can move initialized global vars to the end.
-        And that can screw up the symbol ordering.  By putting the
-        symbols in that order to begin with, we avoid a problem.
-        mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
-      if (TREE_PUBLIC (decl))
+        And that can screw up the symbol ordering.  Defer those for
+        sdbout_finish ().  */
+      if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
        sdbout_symbol (decl, 0);
 
       /* Output COFF information for non-global file-scope initialized
         variables.  */
-      if (GET_CODE (DECL_RTL (decl)) == MEM)
+      if (DECL_INITIAL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
        sdbout_toplevel_data (decl);
     }
 }
+
+/* Output initialized global vars at the end, in the order of
+   definition.  See comment in sdbout_global_decl.  */
+
+static void
+sdbout_finish (main_filename)
+     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;
+
+  /* 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);
+}
 \f
 /* Describe the beginning of an internal block within a function.
    Also output descriptions of variables defined in this block.
@@ -1574,7 +1593,7 @@ sdbout_source_line (line, filename)
      const char *filename ATTRIBUTE_UNUSED;
 {
   /* COFF relative line numbers must be positive.  */
-  if (line > sdb_begin_function_line)
+  if ((int) line > sdb_begin_function_line)
     {
 #ifdef ASM_OUTPUT_SOURCE_LINE
       ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
@@ -1608,13 +1627,14 @@ sdbout_begin_prologue (line, file)
      unsigned int line;
      const char *file ATTRIBUTE_UNUSED;
 {
-  sdbout_end_prologue (line);
+  sdbout_end_prologue (line, file);
 }
 #endif
 
 static void
-sdbout_end_prologue (line)
+sdbout_end_prologue (line, file)
      unsigned int line;
+     const char *file ATTRIBUTE_UNUSED;
 {
   sdb_begin_function_line = line - 1;
   PUT_SDB_FUNCTION_START (line);
@@ -1644,9 +1664,11 @@ sdbout_end_function (line)
    Called after the epilogue is output.  */
 
 static void
-sdbout_end_epilogue ()
+sdbout_end_epilogue (line, file)
+     unsigned int line ATTRIBUTE_UNUSED;
+     const char *file ATTRIBUTE_UNUSED;
 {
-  const char *name
+  const char *const name ATTRIBUTE_UNUSED
     = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
 
 #ifdef PUT_SDB_EPILOGUE_END
@@ -1664,7 +1686,7 @@ sdbout_end_epilogue ()
 
 static void
 sdbout_label (insn)
-     register rtx insn;
+     rtx insn;
 {
   PUT_SDB_DEF (LABEL_NAME (insn));
   PUT_SDB_VAL (insn);
@@ -1720,15 +1742,18 @@ sdbout_init (input_file_name)
 
 #ifdef RMS_QUICK_HACK_1
   tree t;
-  for (t = getdecls (); t; t = TREE_CHAIN (t))
+  for (t = (*lang_hooks.decls.getdecls) (); t; t = TREE_CHAIN (t))
     if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0
        && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
       sdbout_symbol (t, 0);
 #endif  
-
-#ifdef SDB_ALLOW_FORWARD_REFERENCES
-  ggc_add_tree_root (&anonymous_types, 1);
-#endif
 }
 
+#else  /* SDB_DEBUGGING_INFO */
+
+/* This should never be used, but its address is needed for comparisons.  */
+const struct gcc_debug_hooks sdb_debug_hooks;
+
 #endif /* SDB_DEBUGGING_INFO */
+
+#include "gt-sdbout.h"