From 54ba1f0dee5132daad89f2d238141f347fdc9655 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 2 Jan 2002 10:22:13 -0800 Subject: [PATCH] dwarf2out.c (limbo_die_node): Add created_for member. * dwarf2out.c (limbo_die_node): Add created_for member. (new_die): New argument created_for. Update all callers. (mark_limbo_die_list): New. (dwarf2out_init): Register limbo_die_list as a root. (dwarf2out_finish): Force insert limbo dies into their function context. From-SVN: r48478 --- gcc/ChangeLog | 9 ++++ gcc/dwarf2out.c | 120 +++++++++++++++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 42 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0b274195fc..be53b578111 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-01-02 Richard Henderson + + * dwarf2out.c (limbo_die_node): Add created_for member. + (new_die): New argument created_for. Update all callers. + (mark_limbo_die_list): New. + (dwarf2out_init): Register limbo_die_list as a root. + (dwarf2out_finish): Force insert limbo dies into their function + context. + 2002-01-02 Nathan Sidwell PR c++/5089 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 890b9b4ba6e..298005abb9a 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1,5 +1,5 @@ /* Output Dwarf2 format symbol table information from the GNU C compiler. - Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Gary Funck (gary@intrepid.com). Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com). @@ -3177,6 +3177,7 @@ struct dw_ranges_struct typedef struct limbo_die_struct { dw_die_ref die; + tree created_for; struct limbo_die_struct *next; } limbo_die_node; @@ -3510,7 +3511,8 @@ static void remove_AT PARAMS ((dw_die_ref, static inline void free_die PARAMS ((dw_die_ref)); static void remove_children PARAMS ((dw_die_ref)); static void add_child_die PARAMS ((dw_die_ref, dw_die_ref)); -static dw_die_ref new_die PARAMS ((enum dwarf_tag, dw_die_ref)); +static dw_die_ref new_die PARAMS ((enum dwarf_tag, dw_die_ref, + tree)); static dw_die_ref lookup_type_die PARAMS ((tree)); static void equate_type_number_to_die PARAMS ((tree, dw_die_ref)); static dw_die_ref lookup_decl_die PARAMS ((tree)); @@ -3657,6 +3659,7 @@ static void add_loc_descr_to_loc_list PARAMS ((dw_loc_list_ref *, const char *, const char *, const char *)); static void output_loc_list PARAMS ((dw_loc_list_ref)); static char *gen_internal_sym PARAMS ((const char *)); +static void mark_limbo_die_list PARAMS ((void *)); /* Section names used to hold DWARF debugging information. */ #ifndef DEBUG_INFO_SECTION @@ -5047,9 +5050,10 @@ splice_child_die (parent, child) /* Return a pointer to a newly created DIE node. */ static inline dw_die_ref -new_die (tag_value, parent_die) +new_die (tag_value, parent_die, t) enum dwarf_tag tag_value; dw_die_ref parent_die; + tree t; { dw_die_ref die = (dw_die_ref) xcalloc (1, sizeof (die_node)); @@ -5063,6 +5067,7 @@ new_die (tag_value, parent_die) limbo_node = (limbo_die_node *) xmalloc (sizeof (limbo_die_node)); limbo_node->die = die; + limbo_node->created_for = t; limbo_node->next = limbo_die_list; limbo_die_list = limbo_node; } @@ -7351,7 +7356,7 @@ base_type_die (type) abort (); } - base_type_result = new_die (DW_TAG_base_type, comp_unit_die); + base_type_result = new_die (DW_TAG_base_type, comp_unit_die, type); if (demangle_name_func) type_name = (*demangle_name_func) (type_name); @@ -7500,17 +7505,17 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die) ; else if (is_const_type) { - mod_type_die = new_die (DW_TAG_const_type, comp_unit_die); + mod_type_die = new_die (DW_TAG_const_type, comp_unit_die, type); sub_die = modified_type_die (type, 0, is_volatile_type, context_die); } else if (is_volatile_type) { - mod_type_die = new_die (DW_TAG_volatile_type, comp_unit_die); + mod_type_die = new_die (DW_TAG_volatile_type, comp_unit_die, type); sub_die = modified_type_die (type, 0, 0, context_die); } else if (code == POINTER_TYPE) { - mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die); + mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die, type); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); #if 0 add_AT_unsigned (mod_type_die, DW_AT_address_class, 0); @@ -7519,7 +7524,7 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die) } else if (code == REFERENCE_TYPE) { - mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die); + mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); #if 0 add_AT_unsigned (mod_type_die, DW_AT_address_class, 0); @@ -8991,7 +8996,7 @@ add_bound_info (subrange_die, bound_attr, bound) && (! optimize || GET_CODE (SAVE_EXPR_RTL (bound)) == MEM)) { dw_die_ref ctx = lookup_decl_die (current_function_decl); - dw_die_ref decl_die = new_die (DW_TAG_variable, ctx); + dw_die_ref decl_die = new_die (DW_TAG_variable, ctx, bound); rtx loc = SAVE_EXPR_RTL (bound); /* If the RTL for the SAVE_EXPR is memory, handle the case where @@ -9045,7 +9050,7 @@ add_bound_info (subrange_die, bound_attr, bound) else ctx = lookup_decl_die (current_function_decl); - decl_die = new_die (DW_TAG_variable, ctx); + decl_die = new_die (DW_TAG_variable, ctx, bound); add_AT_flag (decl_die, DW_AT_artificial, 1); add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); add_AT_loc (decl_die, DW_AT_location, loc); @@ -9094,7 +9099,7 @@ add_subscript_info (type_die, type) /* Arrays come in three flavors: Unspecified bounds, fixed bounds, and (in GNU C only) variable bounds. Handle all three forms here. */ - subrange_die = new_die (DW_TAG_subrange_type, type_die); + subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL); if (domain) { /* We have an array type with specified bounds. */ @@ -9611,7 +9616,7 @@ gen_array_type_die (type, context_die) gen_type_die (TREE_TYPE (type), context_die); #endif - array_die = new_die (DW_TAG_array_type, scope_die); + array_die = new_die (DW_TAG_array_type, scope_die, type); #if 0 /* We default the array ordering. SDB will probably do @@ -9659,7 +9664,7 @@ gen_set_type_die (type, context_die) dw_die_ref context_die; { dw_die_ref type_die - = new_die (DW_TAG_set_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_set_type, scope_die_for (type, context_die), type); equate_type_number_to_die (type, type_die); add_type_attribute (type_die, TREE_TYPE (type), 0, 0, context_die); @@ -9672,7 +9677,7 @@ gen_entry_point_die (decl, context_die) dw_die_ref context_die; { tree origin = decl_ultimate_origin (decl); - dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die); + dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl); if (origin != NULL) add_abstract_origin_attribute (decl_die, origin); @@ -9709,7 +9714,7 @@ gen_inlined_enumeration_type_die (type, context_die) tree type; dw_die_ref context_die; { - dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die); + dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die, type); /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may be incomplete and such types are not marked. */ @@ -9723,7 +9728,7 @@ gen_inlined_structure_type_die (type, context_die) tree type; dw_die_ref context_die; { - dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die); + dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die, type); /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may be incomplete and such types are not marked. */ @@ -9737,7 +9742,7 @@ gen_inlined_union_type_die (type, context_die) tree type; dw_die_ref context_die; { - dw_die_ref type_die = new_die (DW_TAG_union_type, context_die); + dw_die_ref type_die = new_die (DW_TAG_union_type, context_die, type); /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may be incomplete and such types are not marked. */ @@ -9759,7 +9764,7 @@ gen_enumeration_type_die (type, context_die) if (type_die == NULL) { type_die = new_die (DW_TAG_enumeration_type, - scope_die_for (type, context_die)); + scope_die_for (type, context_die), type); equate_type_number_to_die (type, type_die); add_name_attribute (type_die, type_tag (type)); } @@ -9788,7 +9793,7 @@ gen_enumeration_type_die (type, context_die) for (link = TYPE_FIELDS (type); link != NULL; link = TREE_CHAIN (link)) { - dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die); + dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link); add_name_attribute (enum_die, IDENTIFIER_POINTER (TREE_PURPOSE (link))); @@ -9827,7 +9832,7 @@ gen_formal_parameter_die (node, context_die) dw_die_ref context_die; { dw_die_ref parm_die - = new_die (DW_TAG_formal_parameter, context_die); + = new_die (DW_TAG_formal_parameter, context_die, node); tree origin; switch (TREE_CODE_CLASS (TREE_CODE (node))) @@ -9870,10 +9875,10 @@ gen_formal_parameter_die (node, context_die) static void gen_unspecified_parameters_die (decl_or_type, context_die) - tree decl_or_type ATTRIBUTE_UNUSED; + tree decl_or_type; dw_die_ref context_die; { - new_die (DW_TAG_unspecified_parameters, context_die); + new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type); } /* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a @@ -10051,7 +10056,7 @@ gen_subprogram_die (decl, context_die) if (old_die && old_die->die_parent == NULL) add_child_die (context_die, old_die); - subr_die = new_die (DW_TAG_subprogram, context_die); + subr_die = new_die (DW_TAG_subprogram, context_die, decl); add_abstract_origin_attribute (subr_die, origin); } else if (old_die) @@ -10095,7 +10100,7 @@ gen_subprogram_die (decl, context_die) } else { - subr_die = new_die (DW_TAG_subprogram, context_die); + subr_die = new_die (DW_TAG_subprogram, context_die, decl); add_AT_die_ref (subr_die, DW_AT_specification, old_die); if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index) add_AT_unsigned (subr_die, DW_AT_decl_file, file_index); @@ -10107,7 +10112,7 @@ gen_subprogram_die (decl, context_die) } else { - subr_die = new_die (DW_TAG_subprogram, context_die); + subr_die = new_die (DW_TAG_subprogram, context_die, decl); if (TREE_PUBLIC (decl)) add_AT_flag (subr_die, DW_AT_external, 1); @@ -10297,7 +10302,7 @@ gen_variable_die (decl, context_die) dw_die_ref context_die; { tree origin = decl_ultimate_origin (decl); - dw_die_ref var_die = new_die (DW_TAG_variable, context_die); + dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl); dw_die_ref old_die = lookup_decl_die (decl); int declaration = (DECL_EXTERNAL (decl) @@ -10374,7 +10379,7 @@ gen_label_die (decl, context_die) dw_die_ref context_die; { tree origin = decl_ultimate_origin (decl); - dw_die_ref lbl_die = new_die (DW_TAG_label, context_die); + dw_die_ref lbl_die = new_die (DW_TAG_label, context_die, decl); rtx insn; char label[MAX_ARTIFICIAL_LABEL_BYTES]; @@ -10418,7 +10423,7 @@ gen_lexical_block_die (stmt, context_die, depth) dw_die_ref context_die; int depth; { - dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die); + dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt); char label[MAX_ARTIFICIAL_LABEL_BYTES]; if (! BLOCK_ABSTRACT (stmt)) @@ -10463,7 +10468,7 @@ gen_inlined_subroutine_die (stmt, context_die, depth) if (! BLOCK_ABSTRACT (stmt)) { dw_die_ref subr_die - = new_die (DW_TAG_inlined_subroutine, context_die); + = new_die (DW_TAG_inlined_subroutine, context_die, stmt); tree decl = block_ultimate_origin (stmt); char label[MAX_ARTIFICIAL_LABEL_BYTES]; @@ -10489,7 +10494,7 @@ gen_field_die (decl, context_die) tree decl; dw_die_ref context_die; { - dw_die_ref decl_die = new_die (DW_TAG_member, context_die); + dw_die_ref decl_die = new_die (DW_TAG_member, context_die, decl); add_name_and_src_coords_attributes (decl_die, decl); add_type_attribute (decl_die, member_declared_type (decl), @@ -10527,7 +10532,7 @@ gen_pointer_type_die (type, context_die) dw_die_ref context_die; { dw_die_ref ptr_die - = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type); equate_type_number_to_die (type, ptr_die); add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); @@ -10545,7 +10550,7 @@ gen_reference_type_die (type, context_die) dw_die_ref context_die; { dw_die_ref ref_die - = new_die (DW_TAG_reference_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type); equate_type_number_to_die (type, ref_die); add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); @@ -10561,7 +10566,8 @@ gen_ptr_to_mbr_type_die (type, context_die) dw_die_ref context_die; { dw_die_ref ptr_die - = new_die (DW_TAG_ptr_to_member_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_ptr_to_member_type, + scope_die_for (type, context_die), type); equate_type_number_to_die (type, ptr_die); add_AT_die_ref (ptr_die, DW_AT_containing_type, @@ -10581,7 +10587,7 @@ gen_compile_unit_die (filename) const char *language_string = lang_hooks.name; int language; - die = new_die (DW_TAG_compile_unit, NULL); + die = new_die (DW_TAG_compile_unit, NULL, NULL); add_name_attribute (die, filename); if (wd != NULL && filename[0] != DIR_SEPARATOR) @@ -10629,7 +10635,7 @@ gen_string_type_die (type, context_die) dw_die_ref context_die; { dw_die_ref type_die - = new_die (DW_TAG_string_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_string_type, scope_die_for (type, context_die), type); equate_type_number_to_die (type, type_die); @@ -10648,7 +10654,7 @@ gen_inheritance_die (binfo, context_die) tree binfo; dw_die_ref context_die; { - dw_die_ref die = new_die (DW_TAG_inheritance, context_die); + dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo); add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die); add_data_member_location_attribute (die, binfo); @@ -10757,7 +10763,7 @@ gen_struct_or_union_type_die (type, context_die) type_die = new_die (TREE_CODE (type) == RECORD_TYPE ? DW_TAG_structure_type : DW_TAG_union_type, - scope_die); + scope_die, type); equate_type_number_to_die (type, type_die); if (old_die) add_AT_die_ref (type_die, DW_AT_specification, old_die); @@ -10816,7 +10822,8 @@ gen_subroutine_type_die (type, context_die) { tree return_type = TREE_TYPE (type); dw_die_ref subr_die - = new_die (DW_TAG_subroutine_type, scope_die_for (type, context_die)); + = new_die (DW_TAG_subroutine_type, + scope_die_for (type, context_die), type); equate_type_number_to_die (type, subr_die); add_prototyped_attribute (subr_die, type); @@ -10838,7 +10845,7 @@ gen_typedef_die (decl, context_die) return; TREE_ASM_WRITTEN (decl) = 1; - type_die = new_die (DW_TAG_typedef, context_die); + type_die = new_die (DW_TAG_typedef, context_die, decl); origin = decl_ultimate_origin (decl); if (origin != NULL) add_abstract_origin_attribute (type_die, origin); @@ -11373,6 +11380,15 @@ gen_decl_die (decl, context_die) abort (); } } + +static void +mark_limbo_die_list (ptr) + void *ptr ATTRIBUTE_UNUSED; +{ + limbo_die_node *node; + for (node = limbo_die_list; node ; node = node->next) + ggc_mark_tree (node->created_for); +} /* Add Ada "use" clause information for SGI Workshop debugger. */ @@ -11385,7 +11401,7 @@ dwarf2out_add_library_unit_info (filename, context_list) if (filename != NULL) { - dw_die_ref unit_die = new_die (DW_TAG_module, comp_unit_die); + dw_die_ref unit_die = new_die (DW_TAG_module, comp_unit_die, NULL); tree context_list_decl = build_decl (LABEL_DECL, get_identifier (context_list), void_type_node); @@ -11733,7 +11749,7 @@ dwarf2out_start_source_file (lineno, filename) if (flag_eliminate_dwarf2_dups) { /* Record the beginning of the file for break_out_includes. */ - dw_die_ref bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die); + dw_die_ref bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL); add_AT_string (bincl_die, DW_AT_name, filename); } @@ -11756,7 +11772,7 @@ dwarf2out_end_source_file (lineno) { if (flag_eliminate_dwarf2_dups) /* Record the end of the file for break_out_includes. */ - new_die (DW_TAG_GNU_EINCL, comp_unit_die); + new_die (DW_TAG_GNU_EINCL, comp_unit_die, NULL); if (debug_info_level >= DINFO_LEVEL_VERBOSE) { @@ -11864,6 +11880,8 @@ dwarf2out_init (main_input_filename) VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray"); ggc_add_rtx_varray_root (&used_rtx_varray, 1); + ggc_add_root (&limbo_die_list, 1, 1, mark_limbo_die_list); + ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, DEBUG_ABBREV_SECTION_LABEL, 0); @@ -11961,11 +11979,29 @@ dwarf2out_finish (input_filename) if (die->die_parent == NULL) { dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); + tree context; if (origin) add_child_die (origin->die_parent, die); else if (die == comp_unit_die) ; + else if (node->created_for + && ((DECL_P (node->created_for) + && (context = DECL_CONTEXT (node->created_for))) + || (TYPE_P (node->created_for) + && (context = TYPE_CONTEXT (node->created_for)))) + && TREE_CODE (context) == FUNCTION_DECL) + { + /* In certain situations, the lexical block containing a + nested function can be optimized away, which results + in the nested function die being orphaned. Likewise + with the return type of that nested function. Force + this to be a child of the containing function. */ + origin = lookup_decl_die (context); + if (! origin) + abort (); + add_child_die (origin, die); + } else if (errorcount > 0 || sorrycount > 0) /* It's OK to be confused by errors in the input. */ add_child_die (comp_unit_die, die); -- 2.30.2