X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fdbxout.c;h=8b11a9a371d0c1bfc4eb8db869d363056e023134;hp=e9ad8d3bf79ef4716ea0484b6251c4c55706ad8d;hb=e845094d53e25f0adf1b8ff5269638c5d8f20cc7;hpb=5ac2bc3750f62309057e35c4ca540d1688470757 diff --git a/gcc/dbxout.c b/gcc/dbxout.c index e9ad8d3bf79..8b11a9a371d 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1,12 +1,13 @@ /* 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, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of GCC. 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 +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +16,8 @@ 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 GCC; 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 +. */ /* Output dbx-format symbol table data. @@ -89,6 +89,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "langhooks.h" #include "obstack.h" +#include "expr.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" @@ -241,13 +242,6 @@ static GTY(()) int scope_labelno; static GTY(()) int dbxout_source_line_counter; -/* Nonzero if we have actually used any of the GDB extensions - to the debugging format. The idea is that we use them for the - first time only if there's a strong reason, but once we have done that, - we use them whenever convenient. */ - -static GTY(()) int have_used_extensions = 0; - /* Number for the next N_SOL filename stabs label. The number 0 is reserved for the N_SO filename stabs label. */ @@ -275,7 +269,7 @@ static int pending_bincls = 0; static const char *base_input_file; #ifdef DEBUG_SYMS_TEXT -#define FORCE_TEXT function_section (current_function_decl); +#define FORCE_TEXT switch_to_section (current_function_section ()) #else #define FORCE_TEXT #endif @@ -332,7 +326,6 @@ static void dbxout_type_name (tree); static void dbxout_class_name_qualifiers (tree); static int dbxout_symbol_location (tree, tree, const char *, rtx); static void dbxout_symbol_name (tree, const char *, int); -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); @@ -343,7 +336,7 @@ static void dbxout_handle_pch (unsigned); static void dbxout_source_line (unsigned int, const char *); static void dbxout_begin_prologue (unsigned int, const char *); static void dbxout_source_file (const char *); -static void dbxout_function_end (void); +static void dbxout_function_end (tree); static void dbxout_begin_function (tree); static void dbxout_begin_block (unsigned, unsigned); static void dbxout_end_block (unsigned, unsigned); @@ -359,7 +352,7 @@ const struct gcc_debug_hooks dbx_debug_hooks = dbxout_end_source_file, dbxout_begin_block, dbxout_end_block, - debug_true_tree, /* ignore_block */ + debug_true_const_tree, /* ignore_block */ dbxout_source_line, /* source_line */ dbxout_begin_prologue, /* begin_prologue */ debug_nothing_int_charstar, /* end_prologue */ @@ -378,7 +371,9 @@ const struct gcc_debug_hooks dbx_debug_hooks = debug_nothing_tree, /* outlining_inline_function */ debug_nothing_rtx, /* label */ dbxout_handle_pch, /* handle_pch */ - debug_nothing_rtx /* var_location */ + debug_nothing_rtx, /* var_location */ + debug_nothing_void, /* switch_text_section */ + 0 /* start_end_main_source_file */ }; #endif /* DBX_DEBUGGING_INFO */ @@ -393,7 +388,7 @@ 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_const_tree, /* ignore_block */ xcoffout_source_line, xcoffout_begin_prologue, /* begin_prologue */ debug_nothing_int_charstar, /* end_prologue */ @@ -408,7 +403,9 @@ const struct gcc_debug_hooks xcoff_debug_hooks = debug_nothing_tree, /* outlining_inline_function */ debug_nothing_rtx, /* label */ dbxout_handle_pch, /* handle_pch */ - debug_nothing_rtx /* var_location */ + debug_nothing_rtx, /* var_location */ + debug_nothing_void, /* switch_text_section */ + 0 /* start_end_main_source_file */ }; #endif /* XCOFF_DEBUGGING_INFO */ @@ -859,7 +856,7 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code, obstack_1grow (&stabstr_ob, '\0'); len = obstack_object_size (&stabstr_ob); - chunk = str = obstack_finish (&stabstr_ob); + chunk = str = XOBFINISH (&stabstr_ob, char *); /* Within the buffer are a sequence of NUL-separated strings, each of which is to be written out as a separate stab @@ -892,7 +889,7 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code, comma than to do a two-character fputs. */ obstack_grow (&stabstr_ob, "\",", 2); len = obstack_object_size (&stabstr_ob); - str = obstack_finish (&stabstr_ob); + str = XOBFINISH (&stabstr_ob, char *); fwrite (str, 1, len, asm_out_file); DBX_FINISH_STABS (sym, code, line, addr, label, number); @@ -903,39 +900,48 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code, #if defined (DBX_DEBUGGING_INFO) static void -dbxout_function_end (void) +dbxout_function_end (tree decl) { char lscope_label_name[100]; /* The Lscope label must be emitted even if we aren't doing anything else; dbxout_block needs it. */ - function_section (current_function_decl); + switch_to_section (function_section (current_function_decl)); /* Convert Lscope 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 (asm_out_file, "Lscope", scope_labelno); - scope_labelno++; /* The N_FUN tag at the end of the function is a GNU extension, which may be undesirable, and is unnecessary if we do not have named sections. */ if (!use_gnu_debug_info_extensions || NO_DBX_FUNCTION_END - || !targetm.have_named_sections) + || !targetm.have_named_sections + || DECL_IGNORED_P (decl)) return; /* By convention, GCC will mark the end of a function with an N_FUN symbol and an empty string. */ -#ifdef DBX_OUTPUT_NFUN - DBX_OUTPUT_NFUN (asm_out_file, lscope_label_name, current_function_decl); -#else - dbxout_begin_empty_stabs (N_FUN); - dbxout_stab_value_label_diff (lscope_label_name, - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - -#endif + if (flag_reorder_blocks_and_partition) + { + dbxout_begin_empty_stabs (N_FUN); + dbxout_stab_value_label_diff (cfun->hot_section_end_label, + cfun->hot_section_label); + dbxout_begin_empty_stabs (N_FUN); + dbxout_stab_value_label_diff (cfun->cold_section_end_label, + cfun->cold_section_label); + } + else + { + char begin_label[20]; + /* Reference current function start using LFBB. */ + ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno); + dbxout_begin_empty_stabs (N_FUN); + dbxout_stab_value_label_diff (lscope_label_name, begin_label); + } if (!NO_DBX_BNSYM_ENSYM && !flag_debug_only_used_symbols) dbxout_stabd (N_ENSYM, 0); @@ -960,6 +966,8 @@ get_lang_number (void) return N_SO_PASCAL; else if (strcmp (language_string, "GNU Objective-C") == 0) return N_SO_OBJC; + else if (strcmp (language_string, "GNU Objective-C++") == 0) + return N_SO_OBJCPLUS; else return 0; @@ -974,6 +982,7 @@ dbxout_init (const char *input_file_name) char ltext_label_name[100]; bool used_ltext_label_name = false; tree syms = lang_hooks.decls.getdecls (); + const char *mapped_name; typevec_len = 100; typevec = ggc_calloc (typevec_len, sizeof typevec[0]); @@ -999,6 +1008,7 @@ dbxout_init (const char *input_file_name) cwd = "/"; else if (!IS_DIR_SEPARATOR (cwd[strlen (cwd) - 1])) cwd = concat (cwd, "/", NULL); + cwd = remap_debug_filename (cwd); } #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asm_out_file, cwd); @@ -1009,17 +1019,18 @@ dbxout_init (const char *input_file_name) #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ } + mapped_name = remap_debug_filename (input_file_name); #ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME - DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, input_file_name); + DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, mapped_name); #else - dbxout_begin_simple_stabs_desc (input_file_name, N_SO, get_lang_number ()); + dbxout_begin_simple_stabs_desc (mapped_name, N_SO, get_lang_number ()); dbxout_stab_value_label (ltext_label_name); used_ltext_label_name = true; #endif if (used_ltext_label_name) { - text_section (); + switch_to_section (text_section); targetm.asm_out.internal_label (asm_out_file, "Ltext", 0); } @@ -1035,7 +1046,7 @@ dbxout_init (const char *input_file_name) next_type_number = 1; #ifdef DBX_USE_BINCL - current_file = xmalloc (sizeof *current_file); + current_file = XNEW (struct dbx_file); current_file->next = NULL; current_file->file_number = 0; current_file->next_type_number = 1; @@ -1144,7 +1155,7 @@ dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED, const char *filename ATTRIBUTE_UNUSED) { #ifdef DBX_USE_BINCL - struct dbx_file *n = xmalloc (sizeof *n); + struct dbx_file *n = XNEW (struct dbx_file); n->next = current_file; n->next_type_number = 1; @@ -1154,7 +1165,7 @@ dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED, n->prev = NULL; current_file->prev = n; n->bincl_status = BINCL_PENDING; - n->pending_bincl_name = filename; + n->pending_bincl_name = remap_debug_filename (filename); pending_bincls = 1; current_file = n; #endif @@ -1203,6 +1214,9 @@ dbxout_handle_pch (unsigned at_end) } #if defined (DBX_DEBUGGING_INFO) + +static void dbxout_block (tree, int, tree); + /* Output debugging info to FILE to switch to sourcefile FILENAME. */ static void @@ -1218,15 +1232,16 @@ dbxout_source_file (const char *filename) { /* Don't change section amid function. */ if (current_function_decl == NULL_TREE) - text_section (); + switch_to_section (text_section); - dbxout_begin_simple_stabs (filename, N_SOL); + dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL); dbxout_stab_value_internal_label ("Ltext", &source_label_number); lastfile = filename; } } -/* Output N_BNSYM and line number symbol entry. */ +/* Output N_BNSYM, line number symbol entry, and local symbol at + function scope */ static void dbxout_begin_prologue (unsigned int lineno, const char *filename) @@ -1237,7 +1252,14 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename) && !flag_debug_only_used_symbols) dbxout_stabd (N_BNSYM, 0); + /* pre-increment the scope counter */ + scope_labelno++; + dbxout_source_line (lineno, filename); + /* Output function begin block at function scope, referenced + by dbxout_block, dbxout_source_line and dbxout_function_end. */ + emit_pending_bincls_if_required (); + targetm.asm_out.internal_label (asm_out_file, "LFBB", scope_labelno); } /* Output a line number symbol entry for source file FILENAME and line @@ -1253,11 +1275,12 @@ dbxout_source_line (unsigned int lineno, const char *filename) #else if (DBX_LINES_FUNCTION_RELATIVE) { - rtx begin_label = XEXP (DECL_RTL (current_function_decl), 0); + char begin_label[20]; dbxout_begin_stabn_sline (lineno); + /* Reference current function start using LFBB. */ + ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno); dbxout_stab_value_internal_label_diff ("LM", &dbxout_source_line_counter, - XSTR (begin_label, 0)); - + begin_label); } else dbxout_stabd (N_SLINE, lineno); @@ -1296,7 +1319,7 @@ dbxout_function_decl (tree decl) dbxout_begin_function (decl); #endif dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); - dbxout_function_end (); + dbxout_function_end (decl); } #endif /* DBX_DEBUGGING_INFO */ @@ -1306,9 +1329,7 @@ dbxout_function_decl (tree decl) static void dbxout_global_decl (tree decl) { - if (TREE_CODE (decl) == VAR_DECL - && ! DECL_EXTERNAL (decl) - && DECL_RTL_SET_P (decl)) /* Not necessary? */ + if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) { int saved_tree_used = TREE_USED (decl); TREE_USED (decl) = 1; @@ -1335,7 +1356,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED) DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename); #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END { - text_section (); + switch_to_section (text_section); dbxout_begin_empty_stabs (N_SO); dbxout_stab_value_internal_label ("Letext", 0); } @@ -1387,14 +1408,14 @@ dbxout_type_fields (tree type) /* Omit here local type decls until we know how to support them. */ if (TREE_CODE (tem) == TYPE_DECL + /* Omit here the nameless fields that are used to skip bits. */ + || DECL_IGNORED_P (tem) /* Omit fields whose position or size are variable or too large to represent. */ || (TREE_CODE (tem) == FIELD_DECL && (! host_integerp (bit_position (tem), 0) || ! DECL_SIZE (tem) - || ! host_integerp (DECL_SIZE (tem), 1))) - /* Omit here the nameless fields that are used to skip bits. */ - || DECL_IGNORED_P (tem)) + || ! host_integerp (DECL_SIZE (tem), 1)))) continue; else if (TREE_CODE (tem) != CONST_DECL) @@ -1412,7 +1433,6 @@ dbxout_type_fields (tree type) && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem) || TREE_CODE (tem) != FIELD_DECL)) { - have_used_extensions = 1; stabstr_C ('/'); stabstr_C (DECL_ACCESSIBILITY_CHAR (tem)); } @@ -1427,7 +1447,6 @@ dbxout_type_fields (tree type) { tree name = DECL_ASSEMBLER_NAME (tem); - have_used_extensions = 1; stabstr_C (':'); stabstr_I (name); stabstr_C (';'); @@ -1635,11 +1654,15 @@ dbxout_type (tree type, int full) tree tem; tree main_variant; static int anonymous_type_number = 0; + bool vector_type = false; if (TREE_CODE (type) == VECTOR_TYPE) - /* The frontend feeds us a representation for the vector as a struct - containing an array. Pull out the array type. */ - type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type))); + { + /* The frontend feeds us a representation for the vector as a struct + containing an array. Pull out the array type. */ + type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type))); + vector_type = true; + } /* If there was an input error and we don't really have a type, avoid crashing and write something that is at least valid @@ -1838,7 +1861,6 @@ dbxout_type (tree type, int full) if (use_gnu_debug_info_extensions && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) { - have_used_extensions = 1; stabstr_S ("@s"); stabstr_D (TYPE_PRECISION (type)); stabstr_C (';'); @@ -1855,7 +1877,6 @@ dbxout_type (tree type, int full) if (use_gnu_debug_info_extensions && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) { - have_used_extensions = 1; stabstr_S ("@s"); stabstr_D (TYPE_PRECISION (type)); stabstr_C (';'); @@ -1890,6 +1911,7 @@ dbxout_type (tree type, int full) break; case REAL_TYPE: + case FIXED_POINT_TYPE: /* This used to say `r1' and we used to take care to make sure that `int' was type number 1. */ stabstr_C ('r'); @@ -1899,28 +1921,9 @@ dbxout_type (tree type, int full) stabstr_S (";0;"); break; - case CHAR_TYPE: - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - stabstr_S ("@s"); - stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type)); - stabstr_S (";-20;"); - } - else - { - /* Output the type `char' as a subrange of itself. - That is what pcc seems to do. */ - stabstr_C ('r'); - dbxout_type_index (char_type_node); - stabstr_S (TYPE_UNSIGNED (type) ? ";0;255;" : ";0;127;"); - } - break; - case BOOLEAN_TYPE: if (use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_S ("@s"); stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type)); stabstr_S (";-16;"); @@ -1929,11 +1932,6 @@ dbxout_type (tree type, int full) stabstr_S ("eFalse:0,True:1,;"); break; - case FILE_TYPE: - stabstr_C ('d'); - dbxout_type (TREE_TYPE (type), 0); - break; - case COMPLEX_TYPE: /* 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_* @@ -1967,28 +1965,10 @@ dbxout_type (tree type, int full) } break; - case SET_TYPE: - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - stabstr_S ("@s"); - stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type)); - stabstr_C (';'); - - /* Check if a bitstring type, which in Chill is - different from a [power]set. */ - if (TYPE_STRING_FLAG (type)) - stabstr_S ("@S;"); - } - stabstr_C ('S'); - dbxout_type (TYPE_DOMAIN (type), 0); - break; - case ARRAY_TYPE: /* Make arrays of packed bits look like bitstrings for chill. */ if (TYPE_PACKED (type) && use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_S ("@s"); stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type)); stabstr_S (";@S;S"); @@ -1996,6 +1976,9 @@ dbxout_type (tree type, int full) break; } + if (use_gnu_debug_info_extensions && vector_type) + stabstr_S ("@V;"); + /* Output "a" followed by a range type definition for the index type of the array followed by a reference to the target-type. @@ -2004,7 +1987,6 @@ dbxout_type (tree type, int full) different from an array of characters. */ if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_S ("@S;"); } tem = TYPE_DOMAIN (type); @@ -2047,7 +2029,11 @@ dbxout_type (tree type, int full) another type's definition; instead, output an xref and let the definition come when the name is defined. */ stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu"); - if (TYPE_NAME (type) != 0) + if (TYPE_NAME (type) != 0 + /* The C frontend creates for anonymous variable length + records/unions TYPE_NAME with DECL_NAME NULL. */ + && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL + || DECL_NAME (TYPE_NAME (type)))) dbxout_type_name (type); else { @@ -2068,13 +2054,12 @@ dbxout_type (tree type, int full) { int i; tree child; - VEC (tree) *accesses = BINFO_BASE_ACCESSES (binfo); + VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (binfo); if (use_gnu_debug_info_extensions) { if (BINFO_N_BASE_BINFOS (binfo)) { - have_used_extensions = 1; stabstr_C ('!'); stabstr_U (BINFO_N_BASE_BINFOS (binfo)); stabstr_C (','); @@ -2087,13 +2072,13 @@ dbxout_type (tree type, int full) if (use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_C (BINFO_VIRTUAL_P (child) ? '1' : '0'); stabstr_C (access == access_public_node ? '2' : access == access_protected_node ? '1' :'0'); if (BINFO_VIRTUAL_P (child) - && strcmp (lang_hooks.name, "GNU C++") == 0) + && (strcmp (lang_hooks.name, "GNU C++") == 0 + || strcmp (lang_hooks.name, "GNU Objective-C++") == 0)) /* For a virtual base, print the (negative) offset within the vtable where we must look to find the necessary adjustment. */ @@ -2132,7 +2117,6 @@ dbxout_type (tree type, int full) dbxout_type_fields (type); if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) { - have_used_extensions = 1; dbxout_type_methods (type); } @@ -2142,7 +2126,6 @@ dbxout_type (tree type, int full) /* Avoid the ~ if we don't really need it--it confuses dbx. */ && TYPE_VFIELD (type)) { - have_used_extensions = 1; /* We need to write out info about what field this class uses as its "main" vtable pointer field, because if this @@ -2173,7 +2156,6 @@ dbxout_type (tree type, int full) if (use_gnu_debug_info_extensions && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) { - have_used_extensions = 1; stabstr_S ("@s"); stabstr_D (TYPE_PRECISION (type)); stabstr_C (';'); @@ -2209,7 +2191,6 @@ dbxout_type (tree type, int full) case METHOD_TYPE: if (use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_C ('#'); /* Write the argument types out longhand. */ @@ -2227,7 +2208,6 @@ dbxout_type (tree type, int full) case OFFSET_TYPE: if (use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_C ('@'); dbxout_type (TYPE_OFFSET_BASETYPE (type), 0); stabstr_C (','); @@ -2241,7 +2221,6 @@ dbxout_type (tree type, int full) case REFERENCE_TYPE: if (use_gnu_debug_info_extensions) { - have_used_extensions = 1; stabstr_C ('&'); } else @@ -2342,6 +2321,149 @@ dbxout_class_name_qualifiers (tree decl) } } +/* This is a specialized subset of expand_expr for use by dbxout_symbol in + evaluating DECL_VALUE_EXPR. In particular, we stop if we find decls that + havn't been expanded, or if the expression is getting so complex we won't + be able to represent it in stabs anyway. Returns NULL on failure. */ + +static rtx +dbxout_expand_expr (tree expr) +{ + switch (TREE_CODE (expr)) + { + case VAR_DECL: + /* We can't handle emulated tls variables, because the address is an + offset to the return value of __emutls_get_address, and there is no + way to express that in stabs. Also, there are name mangling issues + here. We end up with references to undefined symbols if we don't + disable debug info for these variables. */ + if (!targetm.have_tls && DECL_THREAD_LOCAL_P (expr)) + return NULL; + /* FALLTHRU */ + + case PARM_DECL: + if (DECL_HAS_VALUE_EXPR_P (expr)) + return dbxout_expand_expr (DECL_VALUE_EXPR (expr)); + /* FALLTHRU */ + + case CONST_DECL: + case RESULT_DECL: + return DECL_RTL_IF_SET (expr); + + case INTEGER_CST: + return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER); + + case COMPONENT_REF: + case ARRAY_REF: + case ARRAY_RANGE_REF: + case BIT_FIELD_REF: + { + enum machine_mode mode; + HOST_WIDE_INT bitsize, bitpos; + tree offset, tem; + int volatilep = 0, unsignedp = 0; + rtx x; + + tem = get_inner_reference (expr, &bitsize, &bitpos, &offset, + &mode, &unsignedp, &volatilep, true); + + x = dbxout_expand_expr (tem); + if (x == NULL || !MEM_P (x)) + return NULL; + if (offset != NULL) + { + if (!host_integerp (offset, 0)) + return NULL; + x = adjust_address_nv (x, mode, tree_low_cst (offset, 0)); + } + if (bitpos != 0) + x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT); + + return x; + } + + default: + return NULL; + } +} + +/* Helper function for output_used_types. Queue one entry from the + used types hash to be output. */ + +static int +output_used_types_helper (void **slot, void *data) +{ + tree type = *slot; + VEC(tree, heap) **types_p = data; + + if ((TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE + || TREE_CODE (type) == ENUMERAL_TYPE) + && TYPE_STUB_DECL (type) + && DECL_P (TYPE_STUB_DECL (type)) + && ! DECL_IGNORED_P (TYPE_STUB_DECL (type))) + VEC_quick_push (tree, *types_p, TYPE_STUB_DECL (type)); + else if (TYPE_NAME (type) + && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) + VEC_quick_push (tree, *types_p, TYPE_NAME (type)); + + return 1; +} + +/* This is a qsort callback which sorts types and declarations into a + predictable order (types, then declarations, sorted by UID + within). */ + +static int +output_types_sort (const void *pa, const void *pb) +{ + const tree lhs = *((const tree *)pa); + const tree rhs = *((const tree *)pb); + + if (TYPE_P (lhs)) + { + if (TYPE_P (rhs)) + return TYPE_UID (lhs) - TYPE_UID (rhs); + else + return 1; + } + else + { + if (TYPE_P (rhs)) + return -1; + else + return DECL_UID (lhs) - DECL_UID (rhs); + } +} + + +/* Force all types used by this function to be output in debug + information. */ + +static void +output_used_types (void) +{ + if (cfun && cfun->used_types_hash) + { + VEC(tree, heap) *types; + int i; + tree type; + + types = VEC_alloc (tree, heap, htab_elements (cfun->used_types_hash)); + htab_traverse (cfun->used_types_hash, output_used_types_helper, &types); + + /* Sort by UID to prevent dependence on hash table ordering. */ + qsort (VEC_address (tree, types), VEC_length (tree, types), + sizeof (tree), output_types_sort); + + for (i = 0; VEC_iterate (tree, types, i, type); i++) + debug_queue_symbol (type); + + VEC_free (tree, heap, types); + } +} + /* Output a .stabs for the symbol defined by DECL, which must be a ..._DECL node in the normal namespace. It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL. @@ -2354,6 +2476,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) tree type = TREE_TYPE (decl); tree context = NULL_TREE; int result = 0; + rtx decl_rtl; /* "Intercept" dbxout_symbol() calls like we do all debug_hooks. */ ++debug_nesting; @@ -2365,7 +2488,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) DBXOUT_DECR_NESTING_AND_RETURN (0); /* If we are to generate only the symbols actually used then such - symbol nodees are flagged with TREE_USED. Ignore any that + symbol nodes are flagged with TREE_USED. Ignore any that aren't flaged as TREE_USED. */ if (flag_debug_only_used_symbols @@ -2438,7 +2561,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) break; case FUNCTION_DECL: - if (DECL_RTL (decl) == 0) + decl_rtl = DECL_RTL_IF_SET (decl); + if (!decl_rtl) DBXOUT_DECR_NESTING_AND_RETURN (0); if (DECL_EXTERNAL (decl)) break; @@ -2446,10 +2570,16 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) context = decl_function_context (decl); if (context == current_function_decl) break; - if (!MEM_P (DECL_RTL (decl)) - || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) + /* Don't mention an inline instance of a nested function. */ + if (context && DECL_FROM_INLINE (decl)) + break; + if (!MEM_P (decl_rtl) + || GET_CODE (XEXP (decl_rtl, 0)) != SYMBOL_REF) break; + if (flag_debug_only_used_symbols) + output_used_types (); + dbxout_begin_complex_stabs (); stabstr_I (DECL_ASSEMBLER_NAME (decl)); stabstr_S (TREE_PUBLIC (decl) ? ":F" : ":f"); @@ -2471,8 +2601,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) stabstr_I (DECL_NAME (context)); } - dbxout_finish_complex_stabs (decl, N_FUN, XEXP (DECL_RTL (decl), 0), - 0, 0); + dbxout_finish_complex_stabs (decl, N_FUN, XEXP (decl_rtl, 0), 0, 0); break; case TYPE_DECL: @@ -2514,7 +2643,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) || TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE) && TYPE_NAME (type) == decl - && !(use_gnu_debug_info_extensions && have_used_extensions) + && !use_gnu_debug_info_extensions && !TREE_ASM_WRITTEN (TYPE_NAME (type)) /* Distinguish the implicit typedefs of C++ from explicit ones that might be found in C. */ @@ -2540,11 +2669,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) dbxout_begin_complex_stabs (); - /* Output leading class/struct qualifiers. - ??? why not set have_used_extensions here ... because - then the test of it below would always be true, I - guess. But it's not clear to me why we shouldn't do - that always in extended mode. */ + /* Output leading class/struct qualifiers. */ if (use_gnu_debug_info_extensions) dbxout_class_name_qualifiers (decl); @@ -2561,7 +2686,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) from explicit ones that might be found in C. */ && DECL_ARTIFICIAL (decl)) { - if (use_gnu_debug_info_extensions && have_used_extensions) + if (use_gnu_debug_info_extensions) { stabstr_C ('T'); TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1; @@ -2626,10 +2751,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) gcc_unreachable (); case RESULT_DECL: - /* Named return value, treat like a VAR_DECL. */ case VAR_DECL: - if (! DECL_RTL_SET_P (decl)) - DBXOUT_DECR_NESTING_AND_RETURN (0); /* Don't mention a variable that is external. Let the file that defines it describe it. */ if (DECL_EXTERNAL (decl)) @@ -2644,7 +2766,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) && host_integerp (DECL_INITIAL (decl), 0) && ! TREE_ASM_WRITTEN (decl) && (DECL_CONTEXT (decl) == NULL_TREE - || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK) + || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK + || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL) && TREE_PUBLIC (decl) == 0) { /* The sun4 assembler does not grok this. */ @@ -2655,8 +2778,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl)); dbxout_begin_complex_stabs (); - stabstr_I (DECL_NAME (decl)); - stabstr_S (":c=i"); + dbxout_symbol_name (decl, NULL, 'c'); + stabstr_S ("=i"); stabstr_D (ival); dbxout_finish_complex_stabs (0, N_LSYM, 0, 0, 0); DBXOUT_DECR_NESTING; @@ -2667,13 +2790,17 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) } /* else it is something we handle like a normal variable. */ - SET_DECL_RTL (decl, eliminate_regs (DECL_RTL (decl), 0, NULL_RTX)); + decl_rtl = dbxout_expand_expr (decl); + if (!decl_rtl) + DBXOUT_DECR_NESTING_AND_RETURN (0); + + decl_rtl = eliminate_regs (decl_rtl, 0, NULL_RTX); #ifdef LEAF_REG_REMAP if (current_function_uses_only_leaf_regs) - leaf_renumber_regs_insn (DECL_RTL (decl)); + leaf_renumber_regs_insn (decl_rtl); #endif - result = dbxout_symbol_location (decl, type, 0, DECL_RTL (decl)); + result = dbxout_symbol_location (decl, type, 0, decl_rtl); break; default: @@ -2750,6 +2877,37 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) letter = decl_function_context (decl) ? 'V' : 'S'; + /* Some ports can transform a symbol ref into a label ref, + because the symbol ref is too far away and has to be + dumped into a constant pool. Alternatively, the symbol + in the constant pool might be referenced by a different + symbol. */ + if (GET_CODE (addr) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (addr)) + { + bool marked; + rtx tmp = get_pool_constant_mark (addr, &marked); + + if (GET_CODE (tmp) == SYMBOL_REF) + { + addr = tmp; + if (CONSTANT_POOL_ADDRESS_P (addr)) + get_pool_constant_mark (addr, &marked); + else + marked = true; + } + else if (GET_CODE (tmp) == LABEL_REF) + { + addr = tmp; + marked = true; + } + + /* If all references to the constant pool were optimized + out, we just ignore the symbol. */ + if (!marked) + return 0; + } + /* This should be the same condition as in assemble_variable, but we don't have access to dont_output_data here. So, instead, we rely on the fact that error_mark_node initializers always @@ -2764,40 +2922,9 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home) code = DBX_STATIC_CONST_VAR_CODE; else { - /* Some ports can transform a symbol ref into a label ref, - because the symbol ref is too far away and has to be - dumped into a constant pool. Alternatively, the symbol - in the constant pool might be referenced by a different - symbol. */ - if (GET_CODE (addr) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (addr)) - { - bool marked; - rtx tmp = get_pool_constant_mark (addr, &marked); - - if (GET_CODE (tmp) == SYMBOL_REF) - { - addr = tmp; - if (CONSTANT_POOL_ADDRESS_P (addr)) - get_pool_constant_mark (addr, &marked); - else - marked = true; - } - else if (GET_CODE (tmp) == LABEL_REF) - { - 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. */ #ifdef DBX_STATIC_STAB_DATA_SECTION - data_section (); + switch_to_section (data_section); #endif code = N_STSYM; } @@ -3231,6 +3358,8 @@ dbxout_args (tree args) } } +#if defined (DBX_DEBUGGING_INFO) + /* Subroutine of dbxout_block. Emit an N_LBRAC stab referencing LABEL. BEGIN_LABEL is the name of the beginning of the function, which may be required. */ @@ -3238,15 +3367,11 @@ static void dbx_output_lbrac (const char *label, const char *begin_label ATTRIBUTE_UNUSED) { -#ifdef DBX_OUTPUT_LBRAC - DBX_OUTPUT_LBRAC (asm_out_file, label); -#else dbxout_begin_stabn (N_LBRAC); if (DBX_BLOCKS_FUNCTION_RELATIVE) dbxout_stab_value_label_diff (label, begin_label); else dbxout_stab_value_label (label); -#endif } /* Subroutine of dbxout_block. Emit an N_RBRAC stab referencing LABEL. @@ -3256,15 +3381,11 @@ static void dbx_output_rbrac (const char *label, const char *begin_label ATTRIBUTE_UNUSED) { -#ifdef DBX_OUTPUT_RBRAC - DBX_OUTPUT_RBRAC (asm_out_file, label); -#else dbxout_begin_stabn (N_RBRAC); if (DBX_BLOCKS_FUNCTION_RELATIVE) dbxout_stab_value_label_diff (label, begin_label); else dbxout_stab_value_label (label); -#endif } /* Output everything about a symbol block (a BLOCK node @@ -3287,8 +3408,9 @@ dbx_output_rbrac (const char *label, static void dbxout_block (tree block, int depth, tree args) { - const char *begin_label - = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); + char begin_label[20]; + /* Reference current function start using LFBB. */ + ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno); while (block) { @@ -3317,7 +3439,7 @@ dbxout_block (tree block, int depth, tree args) if (depth == 0) /* The outermost block doesn't get LBB labels; use - the function symbol. */ + the LFBB local symbol emitted by dbxout_begin_prologue. */ scope_start = begin_label; else { @@ -3368,11 +3490,15 @@ dbxout_block (tree block, int depth, tree args) Usually this follows the function's code, but on some systems, it comes before. */ -#if defined (DBX_DEBUGGING_INFO) static void dbxout_begin_function (tree decl) { - int saved_tree_used1 = TREE_USED (decl); + int saved_tree_used1; + + if (DECL_IGNORED_P (decl)) + return; + + saved_tree_used1 = TREE_USED (decl); TREE_USED (decl) = 1; if (DECL_NAME (DECL_RESULT (decl)) != 0) {