X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdwarf2out.c;h=04764ba7dfb945400d3a818525532a958ba43b38;hb=de9f96f2397d28b640d2b457a715ecec4e658556;hp=4eade28815a49e009ab322aeef7271da4c2a89ad;hpb=929d2a9097b205cfadb9d05a1cb639716c0746f1;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4eade28815a..04764ba7dfb 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -153,7 +153,7 @@ dwarf2out_do_frame (void) return true; if ((flag_unwind_tables || flag_exceptions) - && targetm.except_unwind_info () == UI_DWARF2) + && targetm.except_unwind_info (&global_options) == UI_DWARF2) return true; return false; @@ -189,7 +189,7 @@ dwarf2out_do_cfi_asm (void) dwarf2 unwind info for exceptions, then emit .debug_frame by hand. */ if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE && !flag_unwind_tables && !flag_exceptions - && targetm.except_unwind_info () != UI_DWARF2) + && targetm.except_unwind_info (&global_options) != UI_DWARF2) return false; saved_do_cfi_asm = true; @@ -546,6 +546,89 @@ static struct dw_loc_descr_struct *mem_loc_descriptor #define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG) #endif +/* Match the base name of a file to the base name of a compilation unit. */ + +static int +matches_main_base (const char *path) +{ + /* Cache the last query. */ + static const char *last_path = NULL; + static int last_match = 0; + if (path != last_path) + { + const char *base; + int length = base_of_path (path, &base); + last_path = path; + last_match = (length == main_input_baselength + && memcmp (base, main_input_basename, length) == 0); + } + return last_match; +} + +#ifdef DEBUG_DEBUG_STRUCT + +static int +dump_struct_debug (tree type, enum debug_info_usage usage, + enum debug_struct_file criterion, int generic, + int matches, int result) +{ + /* Find the type name. */ + tree type_decl = TYPE_STUB_DECL (type); + tree t = type_decl; + const char *name = 0; + if (TREE_CODE (t) == TYPE_DECL) + t = DECL_NAME (t); + if (t) + name = IDENTIFIER_POINTER (t); + + fprintf (stderr, " struct %d %s %s %s %s %d %p %s\n", + criterion, + DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr", + matches ? "bas" : "hdr", + generic ? "gen" : "ord", + usage == DINFO_USAGE_DFN ? ";" : + usage == DINFO_USAGE_DIR_USE ? "." : "*", + result, + (void*) type_decl, name); + return result; +} +#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \ + dump_struct_debug (type, usage, criterion, generic, matches, result) + +#else + +#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \ + (result) + +#endif + +static bool +should_emit_struct_debug (tree type, enum debug_info_usage usage) +{ + enum debug_struct_file criterion; + tree type_decl; + bool generic = lang_hooks.types.generic_p (type); + + if (generic) + criterion = debug_struct_generic[usage]; + else + criterion = debug_struct_ordinary[usage]; + + if (criterion == DINFO_STRUCT_FILE_NONE) + return DUMP_GSTRUCT (type, usage, criterion, generic, false, false); + if (criterion == DINFO_STRUCT_FILE_ANY) + return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); + + type_decl = TYPE_STUB_DECL (type); + + if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl)) + return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); + + if (matches_main_base (DECL_SOURCE_FILE (type_decl))) + return DUMP_GSTRUCT (type, usage, criterion, generic, true, true); + return DUMP_GSTRUCT (type, usage, criterion, generic, false, false); +} + /* Hook used by __throw. */ rtx @@ -3989,7 +4072,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, call-site information. We must emit this label if it might be used. */ if (!do_frame && (!flag_exceptions - || targetm.except_unwind_info () != UI_TARGET)) + || targetm.except_unwind_info (&global_options) != UI_TARGET)) return; fnsec = function_section (current_function_decl); @@ -4173,7 +4256,7 @@ dwarf2out_frame_init (void) dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET); if (targetm.debug_unwind_info () == UI_DWARF2 - || targetm.except_unwind_info () == UI_DWARF2) + || targetm.except_unwind_info (&global_options) == UI_DWARF2) initial_return_save (INCOMING_RETURN_ADDR_RTX); } @@ -4186,7 +4269,7 @@ dwarf2out_frame_finish (void) /* Output another copy for the unwinder. */ if ((flag_unwind_tables || flag_exceptions) - && targetm.except_unwind_info () == UI_DWARF2) + && targetm.except_unwind_info (&global_options) == UI_DWARF2) output_call_frame_info (1); } @@ -6181,6 +6264,7 @@ static void remove_child_TAG (dw_die_ref, enum dwarf_tag); static void add_child_die (dw_die_ref, dw_die_ref); static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree); static dw_die_ref lookup_type_die (tree); +static dw_die_ref lookup_type_die_strip_naming_typedef (tree); static void equate_type_number_to_die (tree, dw_die_ref); static hashval_t decl_die_table_hash (const void *); static int decl_die_table_eq (const void *, const void *); @@ -7362,6 +7446,15 @@ add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_ { dw_attr_node attr; +#ifdef ENABLE_CHECKING + gcc_assert (targ_die != NULL); +#else + /* With LTO we can end up trying to reference something we didn't create + a DIE for. Avoid crashing later on a NULL referenced DIE. */ + if (targ_die == NULL) + return; +#endif + attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_die_ref; attr.dw_attr_val.v.val_die_ref.die = targ_die; @@ -7941,6 +8034,27 @@ lookup_type_die (tree type) return TYPE_SYMTAB_DIE (type); } +/* Like lookup_type_die, but if type is an anonymous type named by a + typedef[1], return the DIE of the anonymous type instead the one of + the naming typedef. This is because in gen_typedef_die, we did + equate the anonymous struct named by the typedef with the DIE of + the naming typedef. So by default, lookup_type_die on an anonymous + struct yields the DIE of the naming typedef. + + [1]: Read the comment of is_naming_typedef_decl to learn about what + a naming typedef is. */ + +static inline dw_die_ref +lookup_type_die_strip_naming_typedef (tree type) +{ + dw_die_ref die = lookup_type_die (type); + if (TREE_CODE (type) == RECORD_TYPE + && die->die_tag == DW_TAG_typedef + && is_naming_typedef_decl (TYPE_NAME (type))) + die = get_AT_ref (die, DW_AT_type); + return die; +} + /* Equate a DIE to a given type specifier. */ static inline void @@ -8336,11 +8450,14 @@ print_die (dw_die_ref die, FILE *outfile) unsigned ix; print_spaces (outfile); - fprintf (outfile, "DIE %4ld: %s\n", - die->die_offset, dwarf_tag_name (die->die_tag)); + fprintf (outfile, "DIE %4ld: %s (%p)\n", + die->die_offset, dwarf_tag_name (die->die_tag), + (void*) die); print_spaces (outfile); fprintf (outfile, " abbrev id: %lu", die->die_abbrev); - fprintf (outfile, " offset: %ld\n", die->die_offset); + fprintf (outfile, " offset: %ld", die->die_offset); + fprintf (outfile, " mark: %d\n", die->die_mark); + if (dwarf_version >= 4 && die->die_id.die_type_node) { print_spaces (outfile); @@ -8404,6 +8521,7 @@ print_die (dw_die_ref die, FILE *outfile) AT_ref (a)->die_id.die_symbol); else fprintf (outfile, "die -> %ld", AT_ref (a)->die_offset); + fprintf (outfile, " (%p)", (void *) AT_ref (a)); } else fprintf (outfile, "die -> "); @@ -13494,11 +13612,18 @@ const_ok_for_output_1 (rtx *rtlp, void *data ATTRIBUTE_UNUSED) /* If delegitimize_address couldn't do anything with the UNSPEC, assume we can't express it in the debug info. */ #ifdef ENABLE_CHECKING - inform (current_function_decl - ? DECL_SOURCE_LOCATION (current_function_decl) - : UNKNOWN_LOCATION, - "non-delegitimized UNSPEC %d found in variable location", - XINT (rtl, 1)); + /* Don't complain about TLS UNSPECs, those are just too hard to + delegitimize. */ + if (XVECLEN (rtl, 0) != 1 + || GET_CODE (XVECEXP (rtl, 0, 0)) != SYMBOL_REF + || SYMBOL_REF_DECL (XVECEXP (rtl, 0, 0)) == NULL + || TREE_CODE (SYMBOL_REF_DECL (XVECEXP (rtl, 0, 0))) != VAR_DECL + || !DECL_THREAD_LOCAL_P (SYMBOL_REF_DECL (XVECEXP (rtl, 0, 0)))) + inform (current_function_decl + ? DECL_SOURCE_LOCATION (current_function_decl) + : UNKNOWN_LOCATION, + "non-delegitimized UNSPEC %d found in variable location", + XINT (rtl, 1)); #endif expansion_failed (NULL_TREE, rtl, "UNSPEC hasn't been delegitimized.\n"); @@ -17788,7 +17913,7 @@ scope_die_for (tree t, dw_die_ref context_die) scope_die = comp_unit_die (); } else - scope_die = lookup_type_die (containing_scope); + scope_die = lookup_type_die_strip_naming_typedef (containing_scope); } else scope_die = context_die; @@ -18615,7 +18740,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die) gcc_assert (!decl_ultimate_origin (member)); push_decl_scope (type); - type_die = lookup_type_die (type); + type_die = lookup_type_die_strip_naming_typedef (type); if (TREE_CODE (member) == FUNCTION_DECL) gen_subprogram_die (member, type_die); else if (TREE_CODE (member) == FIELD_DECL) @@ -21577,6 +21702,14 @@ dwarf2out_begin_function (tree fun) { if (function_section (fun) != text_section) have_multiple_function_sections = true; + else if (flag_reorder_blocks_and_partition && !cold_text_section) + { + gcc_assert (current_function_decl == fun); + cold_text_section = unlikely_text_section (); + switch_to_section (cold_text_section); + ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label); + switch_to_section (current_function_section ()); + } dwarf2out_note_section_used (); } @@ -21897,13 +22030,6 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) switch_to_section (text_section); ASM_OUTPUT_LABEL (asm_out_file, text_section_label); - if (flag_reorder_blocks_and_partition) - { - cold_text_section = unlikely_text_section (); - switch_to_section (cold_text_section); - ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label); - } - } /* Called before cgraph_optimize starts outputtting functions, variables @@ -21915,7 +22041,7 @@ dwarf2out_assembly_start (void) if (HAVE_GAS_CFI_SECTIONS_DIRECTIVE && dwarf2out_do_cfi_asm () && (!(flag_unwind_tables || flag_exceptions) - || targetm.except_unwind_info () != UI_DWARF2)) + || targetm.except_unwind_info (&global_options) != UI_DWARF2)) fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n"); } @@ -22866,7 +22992,6 @@ dwarf2out_finish (const char *filename) limbo_die_node *node, *next_node; comdat_type_node *ctnode; htab_t comdat_type_table; - dw_die_ref die = 0; unsigned int i; gen_remaining_tmpl_value_param_die_attribute (); @@ -22899,8 +23024,8 @@ dwarf2out_finish (const char *filename) instance. */ for (node = limbo_die_list; node; node = next_node) { + dw_die_ref die = node->die; next_node = node->next; - die = node->die; if (die->die_parent == NULL) { @@ -23009,9 +23134,9 @@ dwarf2out_finish (const char *filename) /* Output a terminator label for the .text section. */ switch_to_section (text_section); targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0); - if (flag_reorder_blocks_and_partition) + if (cold_text_section) { - switch_to_section (unlikely_text_section ()); + switch_to_section (cold_text_section); targetm.asm_out.internal_label (asm_out_file, COLD_END_LABEL, 0); } @@ -23078,7 +23203,7 @@ dwarf2out_finish (const char *filename) add_AT_macptr (comp_unit_die (), DW_AT_macro_info, macinfo_section_label); if (have_location_lists) - optimize_location_lists (die); + optimize_location_lists (comp_unit_die ()); /* Output all of the compilation units. We put the main one last so that the offsets are available to output_pubnames. */ @@ -23123,7 +23248,7 @@ dwarf2out_finish (const char *filename) ASM_GENERATE_INTERNAL_LABEL (loc_section_label, DEBUG_LOC_SECTION_LABEL, 0); ASM_OUTPUT_LABEL (asm_out_file, loc_section_label); - output_location_lists (die); + output_location_lists (comp_unit_die ()); } /* Output public names table if necessary. */