X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fsdbout.c;h=818ff63cd760688f156b953fe79722d606e8012d;hp=accd9edb25976e44d6ee1415198ba10c179981fe;hb=46b5e7dce99bf275c52c5165f1b6ed091df79680;hpb=b29760a8e6a82c8ddbb584af71ccfdf5a051b96f diff --git a/gcc/sdbout.c b/gcc/sdbout.c index accd9edb259..818ff63cd76 100644 --- a/gcc/sdbout.c +++ b/gcc/sdbout.c @@ -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, 2003, 2004, 2005, 2007, 2008 + 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 3, 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 COPYING3. If not see +. */ /* 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,33 @@ 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" +#include "varray.h" + +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 "system.h" -#include "tree.h" #include "rtl.h" #include "regs.h" #include "flags.h" @@ -54,15 +76,15 @@ 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. */ #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). */ @@ -82,9 +104,6 @@ AT&T C compiler. From the example below I would conclude the following: 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; @@ -92,43 +111,42 @@ 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_source_line PARAMS ((unsigned int, const char *)); -static void sdbout_end_epilogue PARAMS ((void)); -static void sdbout_global_decl PARAMS ((tree)); +static void sdbout_init (const char *); +static void sdbout_finish (const char *); +static void sdbout_start_source_file (unsigned int, const char *); +static void sdbout_end_source_file (unsigned int); +static void sdbout_begin_block (unsigned int, unsigned int); +static void sdbout_end_block (unsigned int, unsigned int); +static void sdbout_source_line (unsigned int, const char *); +static void sdbout_end_epilogue (unsigned int, const char *); +static void sdbout_global_decl (tree); #ifndef MIPS_DEBUGGING_INFO -static void sdbout_begin_prologue PARAMS ((unsigned int, const char *)); +static void sdbout_begin_prologue (unsigned int, const char *); #endif -static void sdbout_end_prologue PARAMS ((unsigned int)); -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_label PARAMS ((rtx)); -static char *gen_fake_label PARAMS ((void)); -static int plain_type PARAMS ((tree)); -static int template_name_p PARAMS ((tree)); -static void sdbout_record_type_name PARAMS ((tree)); -static int plain_type_1 PARAMS ((tree, int)); -static void sdbout_block PARAMS ((tree)); -static void sdbout_syms PARAMS ((tree)); +static void sdbout_end_prologue (unsigned int, const char *); +static void sdbout_begin_function (tree); +static void sdbout_end_function (unsigned int); +static void sdbout_toplevel_data (tree); +static void sdbout_label (rtx); +static char *gen_fake_label (void); +static int plain_type (tree); +static int template_name_p (tree); +static void sdbout_record_type_name (tree); +static int plain_type_1 (tree, int); +static void sdbout_block (tree); +static void sdbout_syms (tree); #ifdef SDB_ALLOW_FORWARD_REFERENCES -static void sdbout_queue_anonymous_type PARAMS ((tree)); -static void sdbout_dequeue_anonymous_types PARAMS ((void)); +static void sdbout_queue_anonymous_type (tree); +static void sdbout_dequeue_anonymous_types (void); #endif -static void sdbout_type PARAMS ((tree)); -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)); - -/* Random macros describing parts of SDB data. */ +static void sdbout_type (tree); +static void sdbout_field_types (tree); +static void sdbout_one_type (tree); +static void sdbout_parms (tree); +static void sdbout_reg_parms (tree); +static void sdbout_global_decl (tree); -/* Put something here if lines get too long */ -#define CONTIN +/* Random macros describing parts of SDB data. */ /* Default value of delimiter is ";". */ #ifndef SDB_DELIM @@ -147,9 +165,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 @@ -164,7 +181,7 @@ static void sdbout_reg_parms PARAMS ((tree)); #ifndef PUT_SDB_DEF #define PUT_SDB_DEF(a) \ do { fprintf (asm_out_file, "\t.def\t"); \ - assemble_name (asm_out_file, a); \ + assemble_name (asm_out_file, a); \ fprintf (asm_out_file, SDB_DELIM); } while (0) #endif @@ -183,9 +200,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 @@ -236,20 +252,15 @@ 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. */ + 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) = (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. */ @@ -261,7 +272,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 @@ -271,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 @@ -294,72 +301,59 @@ struct sdb_file static struct sdb_file *current_file; #endif /* MIPS_DEBUGGING_INFO */ - + /* 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, - debug_true_tree, /* ignore_block */ - sdbout_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. */ - 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, /* end_prologue */ + sdbout_begin_prologue, /* begin_prologue */ + debug_nothing_int_charstar, /* end_prologue */ #endif - sdbout_end_epilogue, - sdbout_begin_function, - sdbout_end_function, - debug_nothing_tree, /* function_decl */ - sdbout_global_decl, - debug_nothing_tree, /* deferred_inline_function */ - debug_nothing_tree, /* outlining_inline_function */ - sdbout_label + 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_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_rtx, /* var_location */ + debug_nothing_void, /* switch_text_section */ + debug_nothing_tree_tree, /* set_name */ + 0 /* start_end_main_source_file */ }; - -#if 0 - -/* return the tag identifier for type - */ - -char * -tag_of_ru_type (type,link) - tree type,link; -{ - if (TYPE_SYMTAB_ADDRESS (type)) - return TYPE_SYMTAB_ADDRESS (type); - if (link && TREE_PURPOSE (link) - && IDENTIFIER_POINTER (TREE_PURPOSE (link))) - TYPE_SYMTAB_ADDRESS (type) = IDENTIFIER_POINTER (TREE_PURPOSE (link)); - else - return (char *) TYPE_SYMTAB_ADDRESS (type); -} -#endif /* Return a unique string to name an anonymous type. */ static char * -gen_fake_label () +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 = (char *) permalloc (strlen (label) + 1); - strcpy (labelstr, label); + labelstr = xstrdup (label); return labelstr; } - + /* Return the number which describes TYPE for SDB. For pointers, etc., this function is recursive. Each record, union or enumeral type must already have had a @@ -378,9 +372,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; @@ -392,8 +386,7 @@ static int sdb_dims[SDB_MAX_DIM]; static int sdb_type_size = -1; static int -plain_type (type) - tree type; +plain_type (tree type) { int val = plain_type_1 (type, 0); @@ -423,10 +416,9 @@ plain_type (type) } static int -template_name_p (name) - tree name; +template_name_p (tree name) { - register const char *ptr = IDENTIFIER_POINTER (name); + const char *ptr = IDENTIFIER_POINTER (name); while (*ptr && *ptr != '<') ptr++; @@ -434,8 +426,7 @@ template_name_p (name) } static void -sdbout_record_type_name (type) - tree type; +sdbout_record_type_name (tree type) { const char *name = 0; int no_name; @@ -446,6 +437,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); @@ -484,9 +476,7 @@ sdbout_record_type_name (type) infinite loop. */ static int -plain_type_1 (type, level) - tree type; - int level; +plain_type_1 (tree type, int level) { if (type == 0) type = void_type_node; @@ -513,7 +503,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")) @@ -537,15 +527,15 @@ plain_type_1 (type, 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; } @@ -592,7 +582,7 @@ plain_type_1 (type, level) case QUAL_UNION_TYPE: case ENUMERAL_TYPE: { - char *tag; + const char *tag; #ifdef SDB_ALLOW_FORWARD_REFERENCES sdbout_record_type_name (type); #endif @@ -648,7 +638,7 @@ plain_type_1 (type, level) return 0; } } - + /* Output the symbols defined in block number DO_BLOCK. This function works by walking the tree structure of blocks, @@ -657,8 +647,7 @@ plain_type_1 (type, level) static int do_block = 0; static void -sdbout_block (block) - register tree block; +sdbout_block (tree block) { while (block) { @@ -680,12 +669,11 @@ sdbout_block (block) block = BLOCK_CHAIN (block); } } - + /* Call sdbout_symbol on each decl in the chain SYMS. */ static void -sdbout_syms (syms) - tree syms; +sdbout_syms (tree syms) { while (syms) { @@ -699,9 +687,7 @@ sdbout_syms (syms) LOCAL is nonzero if the symbol is not file-scope. */ void -sdbout_symbol (decl, local) - tree decl; - int local; +sdbout_symbol (tree decl, int local) { tree type = TREE_TYPE (decl); tree context = NULL_TREE; @@ -709,13 +695,15 @@ sdbout_symbol (decl, local) int regno = -1; const char *name; - sdbout_one_type (type); + /* 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; + } -#if 0 /* This loses when functions are marked to be ignored, - which happens in the C++ front end. */ - if (DECL_IGNORED_P (decl)) - return; -#endif + sdbout_one_type (type); switch (TREE_CODE (decl)) { @@ -733,7 +721,7 @@ sdbout_symbol (decl, 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))); @@ -747,6 +735,11 @@ sdbout_symbol (decl, 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))) @@ -759,7 +752,7 @@ sdbout_symbol (decl, 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. @@ -777,8 +770,8 @@ sdbout_symbol (decl, local) if (!DECL_RTL_SET_P (decl)) return; - SET_DECL_RTL (decl, - eliminate_regs (DECL_RTL (decl), 0, NULL_RTX)); + SET_DECL_RTL (decl, + 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)); @@ -791,9 +784,9 @@ sdbout_symbol (decl, 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 (DECL_RTL (decl)); + regno = REGNO (value); if (regno >= FIRST_PSEUDO_REGISTER) return; } @@ -801,18 +794,18 @@ sdbout_symbol (decl, 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; } - 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. 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; @@ -831,7 +824,7 @@ sdbout_symbol (decl, local) /* Defer SDB information for top-level initialized variables! */ if (! local - && GET_CODE (value) == MEM + && MEM_P (value) && DECL_INITIAL (decl)) return; @@ -846,19 +839,19 @@ sdbout_symbol (decl, 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); 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) @@ -867,9 +860,9 @@ sdbout_symbol (decl, 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 @@ -879,7 +872,7 @@ sdbout_symbol (decl, 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); @@ -902,14 +895,14 @@ sdbout_symbol (decl, 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 @@ -918,23 +911,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. */ @@ -948,23 +924,21 @@ sdbout_symbol (decl, local) PUT_SDB_TYPE (plain_type (type)); PUT_SDB_ENDEF; } - + /* Output SDB information for a top-level initialized variable that has been delayed. */ static void -sdbout_toplevel_data (decl) - tree decl; +sdbout_toplevel_data (tree decl) { tree type = TREE_TYPE (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)); @@ -979,24 +953,21 @@ sdbout_toplevel_data (decl) PUT_SDB_TYPE (plain_type (type)); PUT_SDB_ENDEF; } - + #ifdef SDB_ALLOW_FORWARD_REFERENCES /* Machinery to record and output anonymous types. */ -static tree anonymous_types; - static void -sdbout_queue_anonymous_type (type) - tree type; +sdbout_queue_anonymous_type (tree type) { anonymous_types = tree_cons (NULL_TREE, type, anonymous_types); } static void -sdbout_dequeue_anonymous_types () +sdbout_dequeue_anonymous_types (void) { - register tree types, link; + tree types, link; while (anonymous_types) { @@ -1005,7 +976,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); @@ -1014,15 +985,14 @@ sdbout_dequeue_anonymous_types () } #endif - + /* Given a chain of ..._TYPE nodes, all of which have names, output definitions of those names, as typedefs. */ void -sdbout_types (types) - register tree types; +sdbout_types (tree types) { - register tree link; + tree link; for (link = types; link; link = TREE_CHAIN (link)) sdbout_one_type (link); @@ -1033,8 +1003,7 @@ sdbout_types (types) } static void -sdbout_type (type) - tree type; +sdbout_type (tree type) { if (type == error_mark_node) type = integer_type_node; @@ -1048,8 +1017,7 @@ sdbout_type (type) Now james@bigtex.cactus.org says to try them. */ static void -sdbout_field_types (type) - tree type; +sdbout_field_types (tree type) { tree tail; @@ -1077,14 +1045,13 @@ sdbout_field_types (type) It may NOT be called recursively. */ static void -sdbout_one_type (type) - tree type; +sdbout_one_type (tree type) { if (current_function_decl != NULL_TREE && 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)) { @@ -1103,11 +1070,11 @@ sdbout_one_type (type) return; TREE_ASM_WRITTEN (type) = 1; -#if 1 + /* 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; @@ -1121,9 +1088,6 @@ sdbout_one_type (type) int ccccc; } badtype; */ -#if 0 - TREE_ASM_BEING_WRITTEN (type) = 1; -#endif /* This change, which ought to make better output, used to make the COFF assembler unhappy. Changes involving KNOWN_TYPE_TAG may fix the problem. */ @@ -1132,17 +1096,12 @@ sdbout_one_type (type) are not used if forward references are in use. */ if (TREE_CODE (type) != ENUMERAL_TYPE) sdbout_field_types (type); -#if 0 - TREE_ASM_WRITTEN (type) = 1; -#endif -#endif /* Output a structure 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); @@ -1179,20 +1138,20 @@ 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) + 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) @@ -1207,7 +1166,6 @@ sdbout_one_type (type) else continue; - CONTIN; PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name)); PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0)); PUT_SDB_SCL (member_scl); @@ -1216,19 +1174,26 @@ sdbout_one_type (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)) - 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)) @@ -1246,7 +1211,6 @@ sdbout_one_type (type) { const char *name; - CONTIN; name = IDENTIFIER_POINTER (DECL_NAME (tem)); PUT_SDB_DEF (name); if (DECL_BIT_FIELD_TYPE (tem)) @@ -1264,7 +1228,7 @@ sdbout_one_type (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); @@ -1279,7 +1243,7 @@ sdbout_one_type (type) } } } - + /* The following two functions output definitions of function parameters. Each parameter gets a definition locating it in the parameter list. Each parameter that is a register variable gets a second definition @@ -1293,8 +1257,7 @@ sdbout_one_type (type) of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ static void -sdbout_parms (parms) - tree parms; +sdbout_parms (tree parms) { for (; parms; parms = TREE_CHAIN (parms)) if (DECL_NAME (parms)) @@ -1308,9 +1271,9 @@ sdbout_parms (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, - eliminate_regs (DECL_RTL (parms), 0, NULL_RTX)); + eliminate_regs (DECL_RTL (parms), VOIDmode, NULL_RTX)); if (PARM_PASSED_IN_MEMORY (parms)) { @@ -1327,7 +1290,7 @@ sdbout_parms (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 @@ -1346,7 +1309,7 @@ sdbout_parms (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) @@ -1366,7 +1329,7 @@ sdbout_parms (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. */ @@ -1388,7 +1351,7 @@ sdbout_parms (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. */ @@ -1397,8 +1360,8 @@ sdbout_parms (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)); @@ -1426,8 +1389,7 @@ sdbout_parms (parms) PARMS is a chain of PARM_DECL nodes. */ static void -sdbout_reg_parms (parms) - tree parms; +sdbout_reg_parms (tree parms) { for (; parms; parms = TREE_CHAIN (parms)) if (DECL_NAME (parms)) @@ -1436,7 +1398,7 @@ sdbout_reg_parms (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)) { @@ -1449,7 +1411,7 @@ sdbout_reg_parms (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) @@ -1480,33 +1442,44 @@ sdbout_reg_parms (parms) } } } - + /* Output debug information for a global DECL. Called from toplev.c after compilation proper has finished. */ static void -sdbout_global_decl (decl) - tree decl; +sdbout_global_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); + else + VARRAY_PUSH_TREE (deferred_global_decls, decl); /* Output COFF information for non-global file-scope initialized variables. */ - if (GET_CODE (DECL_RTL (decl)) == MEM) + if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl))) 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 (const char *main_filename ATTRIBUTE_UNUSED) +{ + size_t i; + + 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. Also output descriptions of variables defined in this block. @@ -1516,9 +1489,7 @@ sdbout_global_decl (decl) if the count starts at 0 for the outermost one. */ static void -sdbout_begin_block (line, n) - unsigned int line; - unsigned int n; +sdbout_begin_block (unsigned int line, unsigned int n) { tree decl = current_function_decl; MAKE_LINE_SAFE (line); @@ -1553,9 +1524,7 @@ sdbout_begin_block (line, n) /* Describe the end line-number of an internal block within a function. */ static void -sdbout_end_block (line, n) - unsigned int line; - unsigned int n ATTRIBUTE_UNUSED; +sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED) { MAKE_LINE_SAFE (line); @@ -1568,16 +1537,17 @@ sdbout_end_block (line, n) 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 -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 (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); +#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) @@ -1590,8 +1560,7 @@ sdbout_source_line (line, filename) Called from assemble_start_function. */ static void -sdbout_begin_function (decl) - tree decl ATTRIBUTE_UNUSED; +sdbout_begin_function (tree decl ATTRIBUTE_UNUSED) { sdbout_symbol (current_function_decl, 0); } @@ -1604,17 +1573,14 @@ sdbout_begin_function (decl) #ifndef MIPS_DEBUGGING_INFO static void -sdbout_begin_prologue (line, file) - unsigned int line; - const char *file ATTRIBUTE_UNUSED; +sdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED) { - sdbout_end_prologue (line); + sdbout_end_prologue (line, file); } #endif static void -sdbout_end_prologue (line) - unsigned int line; +sdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED) { sdb_begin_function_line = line - 1; PUT_SDB_FUNCTION_START (line); @@ -1626,8 +1592,7 @@ sdbout_end_prologue (line) Describe end of outermost block. */ static void -sdbout_end_function (line) - unsigned int line; +sdbout_end_function (unsigned int line) { #ifdef SDB_ALLOW_FORWARD_REFERENCES sdbout_dequeue_anonymous_types (); @@ -1644,9 +1609,10 @@ sdbout_end_function (line) Called after the epilogue is output. */ static void -sdbout_end_epilogue () +sdbout_end_epilogue (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 @@ -1663,8 +1629,7 @@ sdbout_end_epilogue () is present. */ static void -sdbout_label (insn) - register rtx insn; +sdbout_label (rtx insn) { PUT_SDB_DEF (LABEL_NAME (insn)); PUT_SDB_VAL (insn); @@ -1676,25 +1641,23 @@ sdbout_label (insn) /* Change to reading from a new source file. */ static void -sdbout_start_source_file (line, filename) - unsigned int line ATTRIBUTE_UNUSED; - const char *filename ATTRIBUTE_UNUSED; +sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED, + const char *filename ATTRIBUTE_UNUSED) { #ifdef MIPS_DEBUGGING_INFO - struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n); + struct sdb_file *n = XNEW (struct sdb_file); n->next = current_file; n->name = filename; current_file = n; - PUT_SDB_SRC_FILE (filename); + output_file_directive (asm_out_file, filename); #endif } /* Revert to reading a previous source file. */ static void -sdbout_end_source_file (line) - unsigned int line ATTRIBUTE_UNUSED; +sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED) { #ifdef MIPS_DEBUGGING_INFO struct sdb_file *next; @@ -1702,33 +1665,39 @@ sdbout_end_source_file (line) 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 } /* Set up for SDB output at the start of compilation. */ static void -sdbout_init (input_file_name) - const char *input_file_name ATTRIBUTE_UNUSED; +sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED) { + tree t; + #ifdef MIPS_DEBUGGING_INFO - current_file = (struct sdb_file *) xmalloc (sizeof *current_file); + current_file = XNEW (struct sdb_file); current_file->next = NULL; current_file->name = input_file_name; #endif -#ifdef RMS_QUICK_HACK_1 - tree t; - for (t = 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 + VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls"); -#ifdef SDB_ALLOW_FORWARD_REFERENCES - ggc_add_tree_root (&anonymous_types, 1); -#endif + /* 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 */ + +/* 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"