X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdbxout.c;h=9e3ffb4ea8b527bafb9f9e3584b8610bed79c568;hb=e2585cd835ae2dfa42f12b9ff4bbb56d339a83c9;hp=7932701cf0a406c58bcf43c9df609b61f4f1a6e0;hpb=132cc6f4849ae24539818643a5b4ceacaf27839f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 7932701cf0a..9e3ffb4ea8b 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1,6 +1,6 @@ /* Output dbx-format symbol table information from GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -179,25 +179,40 @@ static GTY(()) int typevec_len; static GTY(()) int next_type_number; +/* The C front end may call dbxout_symbol before dbxout_init runs. + We save all such decls in this list and output them when we get + to dbxout_init. */ + +static GTY(()) tree preinit_symbols; + enum binclstatus {BINCL_NOT_REQUIRED, BINCL_PENDING, BINCL_PROCESSED}; /* When using N_BINCL in dbx output, each type number is actually a pair of the file number and the type number within the file. This is a stack of input files. */ -struct dbx_file GTY(()) +struct dbx_file { struct dbx_file *next; int file_number; int next_type_number; - enum binclstatus bincl_status; /* Keep track of lazy bincl. */ - const char *pending_bincl_name; /* Name of bincl. */ - struct dbx_file *prev; /* Chain to traverse all pending bincls. */ + enum binclstatus bincl_status; /* Keep track of lazy bincl. */ + const char *pending_bincl_name; /* Name of bincl. */ + struct dbx_file *prev; /* Chain to traverse all pending bincls. */ }; -/* This is the top of the stack. */ - -static GTY(()) struct dbx_file *current_file; +/* This is the top of the stack. + + This is not saved for PCH, because restoring a PCH should not change it. + next_file_number does have to be saved, because the PCH may use some + file numbers; however, just before restoring a PCH, next_file_number + should always be 0 because we should not have needed any file numbers + yet. */ + +#if (defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)) \ + && defined (DBX_USE_BINCL) +static struct dbx_file *current_file; +#endif /* This is the next file number to use. */ @@ -328,7 +343,6 @@ static void dbxout_finish (const char *); static void dbxout_start_source_file (unsigned, const char *); static void dbxout_end_source_file (unsigned); static void dbxout_typedefs (tree); -static void dbxout_fptype_value (tree); static void dbxout_type_index (tree); #if DBX_CONTIN_LENGTH > 0 static void dbxout_continue (void); @@ -351,6 +365,7 @@ static void dbxout_prepare_symbol (tree); static void dbxout_finish_symbol (tree); static void dbxout_block (tree, int, tree); static void dbxout_global_decl (tree); +static void dbxout_type_decl (tree, int); static void dbxout_handle_pch (unsigned); /* The debug hooks structure. */ @@ -374,23 +389,27 @@ const struct gcc_debug_hooks dbx_debug_hooks = dbxout_end_source_file, dbxout_begin_block, dbxout_end_block, - debug_true_tree, /* ignore_block */ - dbxout_source_line, /* source_line */ - dbxout_source_line, /* begin_prologue: just output line info */ - debug_nothing_int_charstar, /* end_prologue */ - debug_nothing_int_charstar, /* end_epilogue */ + debug_true_tree, /* ignore_block */ + dbxout_source_line, /* source_line */ + dbxout_source_line, /* begin_prologue: just output + line info */ + debug_nothing_int_charstar, /* end_prologue */ + debug_nothing_int_charstar, /* end_epilogue */ #ifdef DBX_FUNCTION_FIRST dbxout_begin_function, #else - debug_nothing_tree, /* begin_function */ + debug_nothing_tree, /* begin_function */ #endif - debug_nothing_int, /* end_function */ + debug_nothing_int, /* end_function */ dbxout_function_decl, - dbxout_global_decl, /* global_decl */ - debug_nothing_tree, /* deferred_inline_function */ - debug_nothing_tree, /* outlining_inline_function */ - debug_nothing_rtx, /* label */ - dbxout_handle_pch /* handle_pch */ + dbxout_global_decl, /* global_decl */ + dbxout_type_decl, /* type_decl */ + debug_nothing_tree_tree, /* imported_module_or_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx, /* label */ + dbxout_handle_pch, /* handle_pch */ + debug_nothing_rtx /* var_location */ }; #endif /* DBX_DEBUGGING_INFO */ @@ -405,19 +424,22 @@ const struct gcc_debug_hooks xcoff_debug_hooks = dbxout_end_source_file, xcoffout_begin_block, xcoffout_end_block, - debug_true_tree, /* ignore_block */ + debug_true_tree, /* ignore_block */ xcoffout_source_line, - xcoffout_begin_prologue, /* begin_prologue */ - debug_nothing_int_charstar, /* end_prologue */ + xcoffout_begin_prologue, /* begin_prologue */ + debug_nothing_int_charstar, /* end_prologue */ xcoffout_end_epilogue, - debug_nothing_tree, /* begin_function */ + debug_nothing_tree, /* begin_function */ xcoffout_end_function, - debug_nothing_tree, /* function_decl */ - dbxout_global_decl, /* global_decl */ - debug_nothing_tree, /* deferred_inline_function */ - debug_nothing_tree, /* outlining_inline_function */ - debug_nothing_rtx, /* label */ - dbxout_handle_pch /* handle_pch */ + debug_nothing_tree, /* function_decl */ + dbxout_global_decl, /* global_decl */ + dbxout_type_decl, /* type_decl */ + debug_nothing_tree_tree, /* imported_module_or_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx, /* label */ + dbxout_handle_pch, /* handle_pch */ + debug_nothing_rtx /* var_location */ }; #endif /* XCOFF_DEBUGGING_INFO */ @@ -426,11 +448,14 @@ static void dbxout_function_end (void) { char lscope_label_name[100]; + + function_section (current_function_decl); + /* Convert Ltext into the appropriate format for local labels in case the system doesn't insert underscores in front of user generated labels. */ ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno); - (*targetm.asm_out.internal_label) (asmfile, "Lscope", scope_labelno); + targetm.asm_out.internal_label (asmfile, "Lscope", scope_labelno); scope_labelno++; /* By convention, GCC will mark the end of a function with an N_FUN @@ -454,7 +479,7 @@ static void dbxout_init (const char *input_file_name) { char ltext_label_name[100]; - tree syms = (*lang_hooks.decls.getdecls) (); + tree syms = lang_hooks.decls.getdecls (); asmfile = asm_out_file; @@ -498,7 +523,7 @@ dbxout_init (const char *input_file_name) assemble_name (asmfile, ltext_label_name); fputc ('\n', asmfile); text_section (); - (*targetm.asm_out.internal_label) (asmfile, "Ltext", 0); + targetm.asm_out.internal_label (asmfile, "Ltext", 0); #endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ #ifdef DBX_OUTPUT_GCC_MARKER @@ -514,7 +539,7 @@ dbxout_init (const char *input_file_name) next_type_number = 1; #ifdef DBX_USE_BINCL - current_file = ggc_alloc (sizeof *current_file); + current_file = xmalloc (sizeof *current_file); current_file->next = NULL; current_file->file_number = 0; current_file->next_type_number = 1; @@ -524,25 +549,23 @@ dbxout_init (const char *input_file_name) current_file->pending_bincl_name = NULL; #endif - /* Make sure that types `int' and `char' have numbers 1 and 2. - Definitions of other integer types will refer to those numbers. - (Actually it should no longer matter what their numbers are. - Also, if any types with tags have been defined, dbxout_symbol - will output them first, so the numbers won't be 1 and 2. That - happens in C++. So it's a good thing it should no longer matter). */ - -#ifdef DBX_OUTPUT_STANDARD_TYPES - DBX_OUTPUT_STANDARD_TYPES (syms); -#endif - /* Get all permanent types that have typedef names, and output them all, except for those already output. Some language front ends - put these declarations in the top-level scope; some do not. */ - dbxout_typedefs ((*lang_hooks.decls.builtin_type_decls) ()); + put these declarations in the top-level scope; some do not; + the latter are responsible for calling debug_hooks->type_decl from + their record_builtin_type function. */ dbxout_typedefs (syms); + + if (preinit_symbols) + { + tree t; + for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t)) + dbxout_symbol (TREE_VALUE (t), 0); + preinit_symbols = 0; + } } -/* Output any typedef names for types described by TYPE_DECLs in SYMS. */ +/* Output any typedef names for types described by TYPE_DECLs in SYMS. */ static void dbxout_typedefs (tree syms) @@ -554,7 +577,7 @@ dbxout_typedefs (tree syms) tree type = TREE_TYPE (syms); if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && COMPLETE_TYPE_P (type) + && COMPLETE_OR_VOID_TYPE_P (type) && ! TREE_ASM_WRITTEN (TYPE_NAME (type))) dbxout_symbol (TYPE_NAME (type), 0); } @@ -626,7 +649,7 @@ dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED, const char *filename ATTRIBUTE_UNUSED) { #ifdef DBX_USE_BINCL - struct dbx_file *n = ggc_alloc (sizeof *n); + struct dbx_file *n = xmalloc (sizeof *n); n->next = current_file; n->next_type_number = 1; @@ -708,8 +731,11 @@ dbxout_source_file (FILE *file, const char *filename) && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) ; /* Don't change section amid function. */ else - text_section (); - (*targetm.asm_out.internal_label) (file, "Ltext", source_label_number); + { + if (!in_text_section () && !in_unlikely_text_section ()) + text_section (); + } + targetm.asm_out.internal_label (file, "Ltext", source_label_number); source_label_number++; lastfile = filename; } @@ -737,7 +763,7 @@ static void dbxout_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n) { emit_pending_bincls_if_required (); - (*targetm.asm_out.internal_label) (asmfile, "LBB", n); + targetm.asm_out.internal_label (asmfile, "LBB", n); } /* Describe the end line-number of an internal block within a function. */ @@ -746,7 +772,7 @@ static void dbxout_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n) { emit_pending_bincls_if_required (); - (*targetm.asm_out.internal_label) (asmfile, "LBE", n); + targetm.asm_out.internal_label (asmfile, "LBE", n); } /* Output dbx data for a function definition. @@ -792,6 +818,14 @@ dbxout_global_decl (tree decl) } } +/* This is just a function-type adapter; dbxout_symbol does exactly + what we want but returns an int. */ +static void +dbxout_type_decl (tree decl, int local) +{ + dbxout_symbol (decl, local); +} + /* At the end of compilation, finish writing the symbol table. Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is to do nothing. */ @@ -806,60 +840,6 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED) debug_free_queue (); } -/* Output floating point type values used by the 'R' stab letter. - These numbers come from include/aout/stab_gnu.h in binutils/gdb. - - There are only 3 real/complex types defined, and we need 7/6. - We use NF_SINGLE as a generic float type, and NF_COMPLEX as a generic - complex type. Since we have the type size anyways, we don't really need - to distinguish between different FP types, we only need to distinguish - between float and complex. This works fine with gdb. - - We only use this for complex types, to avoid breaking backwards - compatibility for real types. complex types aren't in ISO C90, so it is - OK if old debuggers don't understand the debug info we emit for them. */ - -/* ??? These are supposed to be IEEE types, but we don't check for that. - We could perhaps add additional numbers for non-IEEE types if we need - them. */ - -static void -dbxout_fptype_value (tree type) -{ - char value = '0'; - enum machine_mode mode = TYPE_MODE (type); - - if (TREE_CODE (type) == REAL_TYPE) - { - if (mode == SFmode) - value = '1'; - else if (mode == DFmode) - value = '2'; - else if (mode == TFmode || mode == XFmode) - value = '6'; - else - /* Use NF_SINGLE as a generic real type for other sizes. */ - value = '1'; - } - else if (TREE_CODE (type) == COMPLEX_TYPE) - { - if (mode == SCmode) - value = '3'; - else if (mode == DCmode) - value = '4'; - else if (mode == TCmode || mode == XCmode) - value = '5'; - else - /* Use NF_COMPLEX as a generic complex type for other sizes. */ - value = '3'; - } - else - abort (); - - putc (value, asmfile); - CHARS (1); -} - /* Output the index of a type. */ static void @@ -910,6 +890,11 @@ dbxout_type_fields (tree type) field that we can support. */ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) { + /* If one of the nodes is an error_mark or its type is then + return early. */ + if (tem == error_mark_node || TREE_TYPE (tem) == error_mark_node) + return; + /* Omit here local type decls until we know how to support them. */ if (TREE_CODE (tem) == TYPE_DECL /* Omit fields whose position or size are variable or too large to @@ -1405,7 +1390,7 @@ dbxout_type (tree type, int full) break; case INTEGER_TYPE: - if (type == char_type_node && ! TREE_UNSIGNED (type)) + if (type == char_type_node && ! TYPE_UNSIGNED (type)) { /* Output the type `char' as a subrange of itself! I don't understand this definition, just copied it @@ -1513,7 +1498,7 @@ dbxout_type (tree type, int full) fprintf (asmfile, "r"); CHARS (1); dbxout_type_index (char_type_node); - fprintf (asmfile, ";0;%d;", TREE_UNSIGNED (type) ? 255 : 127); + fprintf (asmfile, ";0;%d;", TYPE_UNSIGNED (type) ? 255 : 127); CHARS (7); } break; @@ -1542,15 +1527,14 @@ dbxout_type (tree type, int full) break; case COMPLEX_TYPE: - /* Differs from the REAL_TYPE by its new data type number */ + /* Differs from the REAL_TYPE by its new data type number. + R3 is NF_COMPLEX. We don't try to use any of the other NF_* + codes since gdb doesn't care anyway. */ if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) { - putc ('R', asmfile); - CHARS (1); - dbxout_fptype_value (type); - putc (';', asmfile); - CHARS (1); + fputs ("R3;", asmfile); + CHARS (3); print_wide_int (2 * int_size_in_bytes (TREE_TYPE (type))); fputs (";0;", asmfile); CHARS (3); @@ -1720,8 +1704,10 @@ dbxout_type (tree type, int full) if (use_gnu_debug_info_extensions) { have_used_extensions = 1; - putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile); - putc (access == access_public_node ? '2' : '0', asmfile); + putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile); + putc (access == access_public_node ? '2' : + (access == access_protected_node ? '1' :'0'), + asmfile); CHARS (2); if (TREE_VIA_VIRTUAL (child) && strcmp (lang_hooks.name, "GNU C++") == 0) @@ -1934,10 +1920,10 @@ print_int_cst_bounds_in_octal_p (tree type) && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node) || ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - && TREE_UNSIGNED (type)) + && TYPE_UNSIGNED (type)) || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT || (TYPE_PRECISION (type) == HOST_BITS_PER_WIDE_INT - && TREE_UNSIGNED (type)))) + && TYPE_UNSIGNED (type)))) return TRUE; else return FALSE; @@ -2089,11 +2075,6 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) /* "Intercept" dbxout_symbol() calls like we do all debug_hooks. */ ++debug_nesting; - /* Cast avoids warning in old compilers. */ - current_sym_code = (STAB_CODE_TYPE) 0; - current_sym_value = 0; - current_sym_addr = 0; - /* Ignore nameless syms, but don't ignore type tags. */ if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL) @@ -2104,14 +2085,22 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) symbol nodees are flagged with TREE_USED. Ignore any that aren't flaged as TREE_USED. */ + if (flag_debug_only_used_symbols + && (!TREE_USED (decl) + && (TREE_CODE (decl) != VAR_DECL || !DECL_INITIAL (decl)))) + DBXOUT_DECR_NESTING_AND_RETURN (0); + + /* If dbxout_init has not yet run, queue this symbol for later. */ + if (!typevec) + { + preinit_symbols = tree_cons (0, decl, preinit_symbols); + DBXOUT_DECR_NESTING_AND_RETURN (0); + } + if (flag_debug_only_used_symbols) { tree t; - if (!TREE_USED (decl) - && (TREE_CODE (decl) != VAR_DECL || !DECL_INITIAL (decl))) - DBXOUT_DECR_NESTING_AND_RETURN (0); - /* We now have a used symbol. We need to generate the info for the symbol's type in addition to the symbol itself. These type symbols are queued to be generated after were done with @@ -2215,6 +2204,20 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) if (TREE_ASM_WRITTEN (decl) || TYPE_DECL_SUPPRESS_DEBUG (decl)) DBXOUT_DECR_NESTING_AND_RETURN (0); + /* Don't output typedefs for types with magic type numbers (XCOFF). */ +#ifdef DBX_ASSIGN_FUNDAMENTAL_TYPE_NUMBER + { + int fundamental_type_number = + DBX_ASSIGN_FUNDAMENTAL_TYPE_NUMBER (decl); + + if (fundamental_type_number != 0) + { + TREE_ASM_WRITTEN (decl) = 1; + TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = fundamental_type_number; + DBXOUT_DECR_NESTING_AND_RETURN (0); + } + } +#endif FORCE_TEXT; result = 1; { @@ -2394,7 +2397,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) } else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE) { - /* don't know how to do this yet. */ + /* Don't know how to do this yet. */ } break; } @@ -2506,11 +2509,27 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) if (GET_CODE (current_sym_addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (current_sym_addr)) { - rtx tmp = get_pool_constant (current_sym_addr); + bool marked; + rtx tmp = get_pool_constant_mark (current_sym_addr, &marked); - if (GET_CODE (tmp) == SYMBOL_REF - || GET_CODE (tmp) == LABEL_REF) - current_sym_addr = tmp; + if (GET_CODE (tmp) == SYMBOL_REF) + { + current_sym_addr = tmp; + if (CONSTANT_POOL_ADDRESS_P (current_sym_addr)) + get_pool_constant_mark (current_sym_addr, &marked); + else + marked = true; + } + else if (GET_CODE (tmp) == LABEL_REF) + { + current_sym_addr = tmp; + marked = true; + } + + /* If all references to the constant pool were optimized + out, we just ignore the symbol. */ + if (!marked) + return 0; } /* Ultrix `as' seems to need this. */ @@ -2541,8 +2560,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) then it means the object is variable-sized and address through that register or stack slot. DBX has no way to represent this so all we can do is output the variable as a pointer. - If it's not a parameter, ignore it. - (VAR_DECLs like this can be made by integrate.c.) */ + If it's not a parameter, ignore it. */ { if (GET_CODE (XEXP (home, 0)) == REG) { @@ -2620,10 +2638,6 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) else dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0)); - /* Cast avoids warning in old compilers. */ - current_sym_code = (STAB_CODE_TYPE) 0; - current_sym_value = 0; - current_sym_addr = 0; dbxout_prepare_symbol (decl); if (WORDS_BIG_ENDIAN) @@ -2663,9 +2677,11 @@ dbxout_symbol_name (tree decl, const char *suffix, int letter) { const char *name; - if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) - /* One slight hitch: if this is a VAR_DECL which is a static - class member, we must put out the mangled name instead of the + if (DECL_CONTEXT (decl) + && (TYPE_P (DECL_CONTEXT (decl)) + || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)) + /* One slight hitch: if this is a VAR_DECL which is a class member + or a namespace member, we must put out the mangled name instead of the DECL_NAME. Note also that static member (variable) names DO NOT begin with underscores in .stabs directives. */ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); @@ -2691,6 +2707,14 @@ dbxout_prepare_symbol (tree decl ATTRIBUTE_UNUSED) dbxout_source_file (asmfile, filename); #endif + + /* Initialize variables used to communicate each symbol's debug + information to dbxout_finish_symbol with zeroes. */ + + /* Cast avoids warning in old compilers. */ + current_sym_code = (STAB_CODE_TYPE) 0; + current_sym_value = 0; + current_sym_addr = 0; } static void @@ -2747,7 +2771,10 @@ dbxout_parms (tree parms) emit_pending_bincls_if_required (); for (; parms; parms = TREE_CHAIN (parms)) - if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node) + if (DECL_NAME (parms) + && TREE_TYPE (parms) != error_mark_node + && DECL_RTL_SET_P (parms) + && DECL_INCOMING_RTL (parms)) { dbxout_prepare_symbol (parms);