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
This commit is contained in:
Richard Henderson 2002-01-02 10:22:13 -08:00 committed by Richard Henderson
parent adddf5bf27
commit 54ba1f0dee
2 changed files with 87 additions and 42 deletions

View File

@ -1,3 +1,12 @@
2002-01-02 Richard Henderson <rth@redhat.com>
* 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 <nathan@codesourcery.com>
PR c++/5089

View File

@ -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);