/* 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
*/
#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"
#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. */
#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));
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. */
#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
#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
#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. */
/* 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
#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. */
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
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
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;
template_name_p (name)
tree name;
{
- register const char *ptr = IDENTIFIER_POINTER (name);
+ const char *ptr = IDENTIFIER_POINTER (name);
while (*ptr && *ptr != '<')
ptr++;
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);
&& 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"))
static void
sdbout_block (block)
- register tree block;
+ tree block;
{
while (block)
{
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)
particular compilation. */
if (GET_CODE (value) == REG)
{
- regno = REGNO (DECL_RTL (decl));
+ regno = REGNO (value);
if (regno >= FIRST_PSEUDO_REGISTER)
return;
}
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.
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)
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. */
/* Machinery to record and output anonymous types. */
-static tree anonymous_types;
-
static void
sdbout_queue_anonymous_type (type)
tree type;
static void
sdbout_dequeue_anonymous_types ()
{
- register tree types, link;
+ tree types, link;
while (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);
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);
/* 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)
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.
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);
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);
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
static void
sdbout_label (insn)
- register rtx insn;
+ rtx insn;
{
PUT_SDB_DEF (LABEL_NAME (insn));
PUT_SDB_VAL (insn);
#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"