re PR debug/39267 (gdb testsuite regressions)
PR debug/39267 * tree.h (BLOCK_NONLOCALIZED_VARS, BLOCK_NUM_NONLOCALIZED_VARS, BLOCK_NONLOCALIZED_VAR): New macros. (tree_block): Add nonlocalized_vars. * dwarf2out.c (gen_formal_parameter_die, gen_variable_die, gen_decl_die): Add origin argument; allow generation of die with origin at hand only. (gen_member_die, gen_type_die_with_usage, force_decl_die, declare_in_namespace, gen_namescpace_die, dwarf2out_decl): Update use of gen_*. (gen_block_die): Fix checking for unused blocks. (process_scope_var): Break out from .... ; work with origins only. (decls_for_scope) ... here; process nonlocalized list. (dwarf2out_ignore_block): Look for nonlocalized vars. * tree-ssa-live.c (remove_unused_scope_block_p): Look for nonlocalized vars. (dump_scope_block): Dump them. * tree-inline.c (remap_decls): Handle nonlocalized vars. (remap_block): Likewise. (can_be_nonlocal): New predicate. (copy_bind_expr, copy_gimple_bind): Update use of remap_block. From-SVN: r144529
This commit is contained in:
parent
7a9d3fe886
commit
526d73abff
|
@ -1,3 +1,24 @@
|
|||
2009-03-01 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR debug/39267
|
||||
* tree.h (BLOCK_NONLOCALIZED_VARS, BLOCK_NUM_NONLOCALIZED_VARS,
|
||||
BLOCK_NONLOCALIZED_VAR): New macros.
|
||||
(tree_block): Add nonlocalized_vars.
|
||||
* dwarf2out.c (gen_formal_parameter_die, gen_variable_die, gen_decl_die): Add
|
||||
origin argument; allow generation of die with origin at hand only.
|
||||
(gen_member_die, gen_type_die_with_usage, force_decl_die,
|
||||
declare_in_namespace, gen_namescpace_die, dwarf2out_decl): Update use of gen_*.
|
||||
(gen_block_die): Fix checking for unused blocks.
|
||||
(process_scope_var): Break out from .... ; work with origins only.
|
||||
(decls_for_scope) ... here; process nonlocalized list.
|
||||
(dwarf2out_ignore_block): Look for nonlocalized vars.
|
||||
* tree-ssa-live.c (remove_unused_scope_block_p): Look for nonlocalized vars.
|
||||
(dump_scope_block): Dump them.
|
||||
* tree-inline.c (remap_decls): Handle nonlocalized vars.
|
||||
(remap_block): Likewise.
|
||||
(can_be_nonlocal): New predicate.
|
||||
(copy_bind_expr, copy_gimple_bind): Update use of remap_block.
|
||||
|
||||
2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
|
239
gcc/dwarf2out.c
239
gcc/dwarf2out.c
|
@ -5153,11 +5153,11 @@ static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
|
|||
static void gen_inlined_structure_type_die (tree, dw_die_ref);
|
||||
static void gen_inlined_union_type_die (tree, dw_die_ref);
|
||||
static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
|
||||
static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
|
||||
static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
|
||||
static void gen_unspecified_parameters_die (tree, dw_die_ref);
|
||||
static void gen_formal_types_die (tree, dw_die_ref);
|
||||
static void gen_subprogram_die (tree, dw_die_ref);
|
||||
static void gen_variable_die (tree, dw_die_ref);
|
||||
static void gen_variable_die (tree, tree, dw_die_ref);
|
||||
static void gen_const_die (tree, dw_die_ref);
|
||||
static void gen_label_die (tree, dw_die_ref);
|
||||
static void gen_lexical_block_die (tree, dw_die_ref, int);
|
||||
|
@ -5177,7 +5177,7 @@ static void gen_block_die (tree, dw_die_ref, int);
|
|||
static void decls_for_scope (tree, dw_die_ref, int);
|
||||
static int is_redundant_typedef (const_tree);
|
||||
static void gen_namespace_die (tree);
|
||||
static void gen_decl_die (tree, dw_die_ref);
|
||||
static void gen_decl_die (tree, tree, dw_die_ref);
|
||||
static dw_die_ref force_decl_die (tree);
|
||||
static dw_die_ref force_type_die (tree);
|
||||
static dw_die_ref setup_namespace_context (tree, dw_die_ref);
|
||||
|
@ -13293,16 +13293,17 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
|
|||
argument type of some subprogram type. */
|
||||
|
||||
static dw_die_ref
|
||||
gen_formal_parameter_die (tree node, dw_die_ref context_die)
|
||||
gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
|
||||
{
|
||||
tree node_or_origin = node ? node : origin;
|
||||
dw_die_ref parm_die
|
||||
= new_die (DW_TAG_formal_parameter, context_die, node);
|
||||
tree origin;
|
||||
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (node)))
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin)))
|
||||
{
|
||||
case tcc_declaration:
|
||||
origin = decl_ultimate_origin (node);
|
||||
if (!origin)
|
||||
origin = decl_ultimate_origin (node);
|
||||
if (origin != NULL)
|
||||
add_abstract_origin_attribute (parm_die, origin);
|
||||
else
|
||||
|
@ -13321,15 +13322,17 @@ gen_formal_parameter_die (tree node, dw_die_ref context_die)
|
|||
add_AT_flag (parm_die, DW_AT_artificial, 1);
|
||||
}
|
||||
|
||||
equate_decl_number_to_die (node, parm_die);
|
||||
if (! DECL_ABSTRACT (node))
|
||||
add_location_or_const_value_attribute (parm_die, node, DW_AT_location);
|
||||
if (node)
|
||||
equate_decl_number_to_die (node, parm_die);
|
||||
if (! DECL_ABSTRACT (node_or_origin))
|
||||
add_location_or_const_value_attribute (parm_die, node_or_origin,
|
||||
DW_AT_location);
|
||||
|
||||
break;
|
||||
|
||||
case tcc_type:
|
||||
/* We were called with some kind of a ..._TYPE node. */
|
||||
add_type_attribute (parm_die, node, 0, 0, context_die);
|
||||
add_type_attribute (parm_die, node_or_origin, 0, 0, context_die);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -13382,7 +13385,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
|
|||
break;
|
||||
|
||||
/* Output a (nameless) DIE to represent the formal parameter itself. */
|
||||
parm_die = gen_formal_parameter_die (formal_type, context_die);
|
||||
parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
|
||||
if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
|
||||
&& link == first_parm_type)
|
||||
|| (arg && DECL_ARTIFICIAL (arg)))
|
||||
|
@ -13442,7 +13445,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
|
|||
}
|
||||
}
|
||||
else
|
||||
gen_variable_die (member, type_die);
|
||||
gen_variable_die (member, NULL_TREE, type_die);
|
||||
|
||||
pop_decl_scope ();
|
||||
}
|
||||
|
@ -13787,7 +13790,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
|
|||
"__builtin_va_alist"))
|
||||
gen_unspecified_parameters_die (parm, subr_die);
|
||||
else
|
||||
gen_decl_die (parm, subr_die);
|
||||
gen_decl_die (parm, NULL, subr_die);
|
||||
}
|
||||
|
||||
/* Decide whether we need an unspecified_parameters DIE at the end.
|
||||
|
@ -13829,7 +13832,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
|
|||
{
|
||||
/* Emit a DW_TAG_variable DIE for a named return value. */
|
||||
if (DECL_NAME (DECL_RESULT (decl)))
|
||||
gen_decl_die (DECL_RESULT (decl), subr_die);
|
||||
gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
|
||||
|
||||
current_function_has_inlines = 0;
|
||||
decls_for_scope (outer_scope, subr_die, 0);
|
||||
|
@ -13871,17 +13874,18 @@ common_block_die_table_eq (const void *x, const void *y)
|
|||
return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
|
||||
}
|
||||
|
||||
/* Generate a DIE to represent a declared data object. */
|
||||
/* Generate a DIE to represent a declared data object.
|
||||
Either DECL or ORIGIN must be non-null. */
|
||||
|
||||
static void
|
||||
gen_variable_die (tree decl, dw_die_ref context_die)
|
||||
gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
|
||||
{
|
||||
HOST_WIDE_INT off;
|
||||
tree com_decl;
|
||||
tree decl_or_origin = decl ? decl : origin;
|
||||
dw_die_ref var_die;
|
||||
tree origin = decl_ultimate_origin (decl);
|
||||
dw_die_ref old_die = lookup_decl_die (decl);
|
||||
int declaration = (DECL_EXTERNAL (decl)
|
||||
dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
|
||||
int declaration = (DECL_EXTERNAL (decl_or_origin)
|
||||
/* If DECL is COMDAT and has not actually been
|
||||
emitted, we cannot take its address; there
|
||||
might end up being no definition anywhere in
|
||||
|
@ -13899,11 +13903,15 @@ gen_variable_die (tree decl, dw_die_ref context_die)
|
|||
Here, S<int>::i is not DECL_EXTERNAL, but no
|
||||
definition is required, so the compiler will
|
||||
not emit a definition. */
|
||||
|| (TREE_CODE (decl) == VAR_DECL
|
||||
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
|
||||
|| (TREE_CODE (decl_or_origin) == VAR_DECL
|
||||
&& DECL_COMDAT (decl_or_origin)
|
||||
&& !TREE_ASM_WRITTEN (decl_or_origin))
|
||||
|| class_or_namespace_scope_p (context_die));
|
||||
|
||||
com_decl = fortran_common (decl, &off);
|
||||
if (!origin)
|
||||
origin = decl_ultimate_origin (decl);
|
||||
|
||||
com_decl = fortran_common (decl_or_origin, &off);
|
||||
|
||||
/* Symbol in common gets emitted as a child of the common block, in the form
|
||||
of a data member. */
|
||||
|
@ -13914,7 +13922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
|
|||
dw_loc_descr_ref loc;
|
||||
die_node com_die_arg;
|
||||
|
||||
var_die = lookup_decl_die (decl);
|
||||
var_die = lookup_decl_die (decl_or_origin);
|
||||
if (var_die)
|
||||
{
|
||||
if (get_AT (var_die, DW_AT_location) == NULL)
|
||||
|
@ -14071,20 +14079,22 @@ gen_variable_die (tree decl, dw_die_ref context_die)
|
|||
if (declaration)
|
||||
add_AT_flag (var_die, DW_AT_declaration, 1);
|
||||
|
||||
if (DECL_ABSTRACT (decl) || declaration)
|
||||
if (decl && (DECL_ABSTRACT (decl) || declaration))
|
||||
equate_decl_number_to_die (decl, var_die);
|
||||
|
||||
if (! declaration && ! DECL_ABSTRACT (decl))
|
||||
if (! declaration && ! DECL_ABSTRACT (decl_or_origin))
|
||||
{
|
||||
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
|
||||
&& !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|
||||
defer_location (decl, var_die);
|
||||
if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin)
|
||||
&& !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
|
||||
defer_location (decl_or_origin, var_die);
|
||||
else
|
||||
add_location_or_const_value_attribute (var_die, decl, DW_AT_location);
|
||||
add_pubname (decl, var_die);
|
||||
add_location_or_const_value_attribute (var_die,
|
||||
decl_or_origin,
|
||||
DW_AT_location);
|
||||
add_pubname (decl_or_origin, var_die);
|
||||
}
|
||||
else
|
||||
tree_add_const_value_attribute (var_die, decl);
|
||||
tree_add_const_value_attribute (var_die, decl_or_origin);
|
||||
}
|
||||
|
||||
/* Generate a DIE to represent a named constant. */
|
||||
|
@ -14209,7 +14219,7 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
{
|
||||
dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
|
||||
|
||||
if (! BLOCK_ABSTRACT (stmt))
|
||||
if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
|
||||
add_high_low_attributes (stmt, stmt_die);
|
||||
|
||||
decls_for_scope (stmt, stmt_die, depth);
|
||||
|
@ -14234,7 +14244,8 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
= new_die (DW_TAG_inlined_subroutine, context_die, stmt);
|
||||
|
||||
add_abstract_origin_attribute (subr_die, decl);
|
||||
add_high_low_attributes (stmt, subr_die);
|
||||
if (TREE_ASM_WRITTEN (stmt))
|
||||
add_high_low_attributes (stmt, subr_die);
|
||||
add_call_src_coords_attributes (stmt, subr_die);
|
||||
|
||||
decls_for_scope (stmt, subr_die, depth);
|
||||
|
@ -14466,7 +14477,7 @@ gen_member_die (tree type, dw_die_ref context_die)
|
|||
if (child)
|
||||
splice_child_die (context_die, child);
|
||||
else
|
||||
gen_decl_die (member, context_die);
|
||||
gen_decl_die (member, NULL, context_die);
|
||||
}
|
||||
|
||||
/* Now output info about the function members (if any). */
|
||||
|
@ -14480,7 +14491,7 @@ gen_member_die (tree type, dw_die_ref context_die)
|
|||
if (child)
|
||||
splice_child_die (context_die, child);
|
||||
else
|
||||
gen_decl_die (member, context_die);
|
||||
gen_decl_die (member, NULL, context_die);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14655,7 +14666,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
|
|||
gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
|
||||
|
||||
TREE_ASM_WRITTEN (type) = 1;
|
||||
gen_decl_die (TYPE_NAME (type), context_die);
|
||||
gen_decl_die (TYPE_NAME (type), NULL, context_die);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -14858,7 +14869,6 @@ static void
|
|||
gen_block_die (tree stmt, dw_die_ref context_die, int depth)
|
||||
{
|
||||
int must_output_die = 0;
|
||||
tree decl;
|
||||
bool inlined_func;
|
||||
|
||||
/* Ignore blocks that are NULL. */
|
||||
|
@ -14893,21 +14903,16 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
if (debug_info_level > DINFO_LEVEL_TERSE)
|
||||
/* We are not in terse mode so *any* local declaration counts
|
||||
as being a "significant" one. */
|
||||
must_output_die = (BLOCK_VARS (stmt) != NULL
|
||||
must_output_die = ((BLOCK_VARS (stmt) != NULL
|
||||
|| BLOCK_NUM_NONLOCALIZED_VARS (stmt))
|
||||
&& (TREE_USED (stmt)
|
||||
|| TREE_ASM_WRITTEN (stmt)
|
||||
|| BLOCK_ABSTRACT (stmt)));
|
||||
else
|
||||
/* We are in terse mode, so only local (nested) function
|
||||
definitions count as "significant" local declarations. */
|
||||
for (decl = BLOCK_VARS (stmt);
|
||||
decl != NULL; decl = TREE_CHAIN (decl))
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_INITIAL (decl))
|
||||
{
|
||||
must_output_die = 1;
|
||||
break;
|
||||
}
|
||||
else if ((TREE_USED (stmt)
|
||||
|| TREE_ASM_WRITTEN (stmt)
|
||||
|| BLOCK_ABSTRACT (stmt))
|
||||
&& !dwarf2out_ignore_block (stmt))
|
||||
must_output_die = 1;
|
||||
}
|
||||
|
||||
/* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
|
||||
|
@ -14928,6 +14933,35 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
|
|||
decls_for_scope (stmt, context_die, depth);
|
||||
}
|
||||
|
||||
/* Process variable DECL (or variable with origin ORIGIN) within
|
||||
block STMT and add it to CONTEXT_DIE. */
|
||||
static void
|
||||
process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
|
||||
{
|
||||
dw_die_ref die;
|
||||
tree decl_or_origin = decl ? decl : origin;
|
||||
tree ultimate_origin = origin ? decl_ultimate_origin (origin) : NULL;
|
||||
|
||||
if (ultimate_origin)
|
||||
origin = ultimate_origin;
|
||||
|
||||
if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
|
||||
die = lookup_decl_die (decl_or_origin);
|
||||
else if (TREE_CODE (decl_or_origin) == TYPE_DECL
|
||||
&& TYPE_DECL_IS_STUB (decl_or_origin))
|
||||
die = lookup_type_die (TREE_TYPE (decl_or_origin));
|
||||
else
|
||||
die = NULL;
|
||||
|
||||
if (die != NULL && die->die_parent == NULL)
|
||||
add_child_die (context_die, die);
|
||||
else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
|
||||
dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin),
|
||||
stmt, context_die);
|
||||
else
|
||||
gen_decl_die (decl, origin, context_die);
|
||||
}
|
||||
|
||||
/* Generate all of the decls declared within a given scope and (recursively)
|
||||
all of its sub-blocks. */
|
||||
|
||||
|
@ -14935,38 +14969,22 @@ static void
|
|||
decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
|
||||
{
|
||||
tree decl;
|
||||
unsigned int i;
|
||||
tree subblocks;
|
||||
|
||||
/* Ignore NULL blocks. */
|
||||
if (stmt == NULL_TREE)
|
||||
return;
|
||||
|
||||
if (TREE_USED (stmt))
|
||||
{
|
||||
/* Output the DIEs to represent all of the data objects and typedefs
|
||||
declared directly within this block but not within any nested
|
||||
sub-blocks. Also, nested function and tag DIEs have been
|
||||
generated with a parent of NULL; fix that up now. */
|
||||
for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
|
||||
{
|
||||
dw_die_ref die;
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
die = lookup_decl_die (decl);
|
||||
else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
|
||||
die = lookup_type_die (TREE_TYPE (decl));
|
||||
else
|
||||
die = NULL;
|
||||
|
||||
if (die != NULL && die->die_parent == NULL)
|
||||
add_child_die (context_die, die);
|
||||
else if (TREE_CODE (decl) == IMPORTED_DECL)
|
||||
dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
|
||||
stmt, context_die);
|
||||
else
|
||||
gen_decl_die (decl, context_die);
|
||||
}
|
||||
}
|
||||
/* Output the DIEs to represent all of the data objects and typedefs
|
||||
declared directly within this block but not within any nested
|
||||
sub-blocks. Also, nested function and tag DIEs have been
|
||||
generated with a parent of NULL; fix that up now. */
|
||||
for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
|
||||
process_scope_var (stmt, decl, NULL_TREE, context_die);
|
||||
for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
|
||||
process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i),
|
||||
context_die);
|
||||
|
||||
/* If we're at -g1, we're not interested in subblocks. */
|
||||
if (debug_info_level <= DINFO_LEVEL_TERSE)
|
||||
|
@ -15049,7 +15067,7 @@ force_decl_die (tree decl)
|
|||
gen_decl_die() call. */
|
||||
saved_external_flag = DECL_EXTERNAL (decl);
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
gen_decl_die (decl, context_die);
|
||||
gen_decl_die (decl, NULL, context_die);
|
||||
DECL_EXTERNAL (decl) = saved_external_flag;
|
||||
break;
|
||||
|
||||
|
@ -15132,7 +15150,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die)
|
|||
if (is_fortran ())
|
||||
return ns_context;
|
||||
if (DECL_P (thing))
|
||||
gen_decl_die (thing, ns_context);
|
||||
gen_decl_die (thing, NULL, ns_context);
|
||||
else
|
||||
gen_type_die (thing, ns_context);
|
||||
}
|
||||
|
@ -15183,14 +15201,15 @@ gen_namespace_die (tree decl)
|
|||
/* Generate Dwarf debug information for a decl described by DECL. */
|
||||
|
||||
static void
|
||||
gen_decl_die (tree decl, dw_die_ref context_die)
|
||||
gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
|
||||
{
|
||||
tree origin;
|
||||
tree decl_or_origin = decl ? decl : origin;
|
||||
tree class_origin = NULL;
|
||||
|
||||
if (DECL_P (decl) && DECL_IGNORED_P (decl))
|
||||
if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
|
||||
return;
|
||||
|
||||
switch (TREE_CODE (decl))
|
||||
switch (TREE_CODE (decl_or_origin))
|
||||
{
|
||||
case ERROR_MARK:
|
||||
break;
|
||||
|
@ -15215,8 +15234,10 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
case FUNCTION_DECL:
|
||||
/* Don't output any DIEs to represent mere function declarations,
|
||||
unless they are class members or explicit block externs. */
|
||||
if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE
|
||||
&& (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
|
||||
if (DECL_INITIAL (decl_or_origin) == NULL_TREE
|
||||
&& DECL_CONTEXT (decl_or_origin) == NULL_TREE
|
||||
&& (current_function_decl == NULL_TREE
|
||||
|| DECL_ARTIFICIAL (decl_or_origin)))
|
||||
break;
|
||||
|
||||
#if 0
|
||||
|
@ -15228,8 +15249,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
#endif
|
||||
|
||||
/* If we're emitting a clone, emit info for the abstract instance. */
|
||||
if (DECL_ORIGIN (decl) != decl)
|
||||
dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl));
|
||||
if (origin || DECL_ORIGIN (decl) != decl)
|
||||
dwarf2out_abstract_function (origin ? origin : DECL_ABSTRACT_ORIGIN (decl));
|
||||
|
||||
/* If we're emitting an out-of-line copy of an inline function,
|
||||
emit info for the abstract instance and set up to refer to it. */
|
||||
|
@ -15257,7 +15278,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
gen_type_die (DECL_CONTEXT (decl), context_die);
|
||||
|
||||
/* And its containing type. */
|
||||
origin = decl_class_context (decl);
|
||||
if (!origin)
|
||||
origin = decl_class_context (decl);
|
||||
if (origin != NULL_TREE)
|
||||
gen_type_die_for_member (origin, decl, context_die);
|
||||
|
||||
|
@ -15266,7 +15288,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
}
|
||||
|
||||
/* Now output a DIE to represent the function itself. */
|
||||
gen_subprogram_die (decl, context_die);
|
||||
if (decl)
|
||||
gen_subprogram_die (decl, context_die);
|
||||
break;
|
||||
|
||||
case TYPE_DECL:
|
||||
|
@ -15309,28 +15332,30 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
|
||||
/* Output any DIEs that are needed to specify the type of this data
|
||||
object. */
|
||||
if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl))
|
||||
gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
|
||||
if (TREE_CODE (decl_or_origin) == RESULT_DECL
|
||||
&& DECL_BY_REFERENCE (decl_or_origin))
|
||||
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
|
||||
else
|
||||
gen_type_die (TREE_TYPE (decl), context_die);
|
||||
gen_type_die (TREE_TYPE (decl_or_origin), context_die);
|
||||
|
||||
/* And its containing type. */
|
||||
origin = decl_class_context (decl);
|
||||
if (origin != NULL_TREE)
|
||||
gen_type_die_for_member (origin, decl, context_die);
|
||||
class_origin = decl_class_context (decl_or_origin);
|
||||
if (class_origin != NULL_TREE)
|
||||
gen_type_die_for_member (class_origin, decl_or_origin, context_die);
|
||||
|
||||
/* And its containing namespace. */
|
||||
context_die = declare_in_namespace (decl, context_die);
|
||||
context_die = declare_in_namespace (decl_or_origin, context_die);
|
||||
|
||||
/* Now output the DIE to represent the data object itself. This gets
|
||||
complicated because of the possibility that the VAR_DECL really
|
||||
represents an inlined instance of a formal parameter for an inline
|
||||
function. */
|
||||
origin = decl_ultimate_origin (decl);
|
||||
if (!origin)
|
||||
origin = decl_ultimate_origin (decl);
|
||||
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
|
||||
gen_formal_parameter_die (decl, context_die);
|
||||
gen_formal_parameter_die (decl, origin, context_die);
|
||||
else
|
||||
gen_variable_die (decl, context_die);
|
||||
gen_variable_die (decl, origin, context_die);
|
||||
break;
|
||||
|
||||
case FIELD_DECL:
|
||||
|
@ -15346,11 +15371,11 @@ gen_decl_die (tree decl, dw_die_ref context_die)
|
|||
break;
|
||||
|
||||
case PARM_DECL:
|
||||
if (DECL_BY_REFERENCE (decl))
|
||||
gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
|
||||
if (DECL_BY_REFERENCE (decl_or_origin))
|
||||
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
|
||||
else
|
||||
gen_type_die (TREE_TYPE (decl), context_die);
|
||||
gen_formal_parameter_die (decl, context_die);
|
||||
gen_type_die (TREE_TYPE (decl_or_origin), context_die);
|
||||
gen_formal_parameter_die (decl, origin, context_die);
|
||||
break;
|
||||
|
||||
case NAMESPACE_DECL:
|
||||
|
@ -15641,7 +15666,7 @@ dwarf2out_decl (tree decl)
|
|||
return;
|
||||
}
|
||||
|
||||
gen_decl_die (decl, context_die);
|
||||
gen_decl_die (decl, NULL, context_die);
|
||||
}
|
||||
|
||||
/* Output a marker (i.e. a label) for the beginning of the generated code for
|
||||
|
@ -15676,11 +15701,19 @@ static bool
|
|||
dwarf2out_ignore_block (const_tree block)
|
||||
{
|
||||
tree decl;
|
||||
unsigned int i;
|
||||
|
||||
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
|
||||
return 0;
|
||||
for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++)
|
||||
{
|
||||
decl = BLOCK_NONLOCALIZED_VAR (block, i);
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,6 @@ eni_weights eni_time_weights;
|
|||
static tree declare_return_variable (copy_body_data *, tree, tree, tree *);
|
||||
static bool inlinable_function_p (tree);
|
||||
static void remap_block (tree *, copy_body_data *);
|
||||
static tree remap_decls (tree, copy_body_data *);
|
||||
static void copy_bind_expr (tree *, int *, copy_body_data *);
|
||||
static tree mark_local_for_remap_r (tree *, int *, void *);
|
||||
static void unsave_expr_1 (tree);
|
||||
|
@ -427,8 +426,43 @@ remap_type (tree type, copy_body_data *id)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
/* Decide if DECL can be put into BLOCK_NONLOCAL_VARs. */
|
||||
|
||||
static bool
|
||||
can_be_nonlocal (tree decl, copy_body_data *id)
|
||||
{
|
||||
/* We can not duplicate function decls. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
return true;
|
||||
|
||||
/* Local static vars must be non-local or we get multiple declaration
|
||||
problems. */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& !auto_var_in_fn_p (decl, id->src_fn))
|
||||
return true;
|
||||
|
||||
/* At the moment dwarf2out can handle only these types of nodes. We
|
||||
can support more later. */
|
||||
if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
|
||||
return false;
|
||||
|
||||
/* We must use global type. */
|
||||
if (TREE_TYPE (decl) != remap_type (TREE_TYPE (decl), id))
|
||||
return false;
|
||||
|
||||
/* Wihtout SSA we can't tell if variable is used. */
|
||||
if (!gimple_in_ssa_p (cfun))
|
||||
return false;
|
||||
|
||||
/* Live variables must be copied so we can attach DECL_RTL. */
|
||||
if (var_ann (decl))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static tree
|
||||
remap_decls (tree decls, copy_body_data *id)
|
||||
remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
|
||||
{
|
||||
tree old_var;
|
||||
tree new_decls = NULL_TREE;
|
||||
|
@ -437,16 +471,18 @@ remap_decls (tree decls, copy_body_data *id)
|
|||
for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
|
||||
{
|
||||
tree new_var;
|
||||
tree origin_var = DECL_ORIGIN (old_var);
|
||||
|
||||
/* We cannot chain the local static declarations into the local_decls
|
||||
as we can't duplicate them or break one decl rule. Go ahead
|
||||
and link them into local_decls. */
|
||||
|
||||
if (!auto_var_in_fn_p (old_var, id->src_fn)
|
||||
&& !DECL_EXTERNAL (old_var))
|
||||
if (can_be_nonlocal (old_var, id))
|
||||
{
|
||||
cfun->local_decls = tree_cons (NULL_TREE, old_var,
|
||||
cfun->local_decls);
|
||||
if (TREE_CODE (old_var) == VAR_DECL
|
||||
&& (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
|
||||
cfun->local_decls = tree_cons (NULL_TREE, old_var,
|
||||
cfun->local_decls);
|
||||
if (debug_info_level > DINFO_LEVEL_TERSE
|
||||
&& !DECL_IGNORED_P (old_var)
|
||||
&& nonlocalized_list)
|
||||
VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -456,8 +492,16 @@ remap_decls (tree decls, copy_body_data *id)
|
|||
/* If we didn't remap this variable, we can't mess with its
|
||||
TREE_CHAIN. If we remapped this variable to the return slot, it's
|
||||
already declared somewhere else, so don't declare it here. */
|
||||
if (!new_var || new_var == id->retvar)
|
||||
|
||||
if (new_var == id->retvar)
|
||||
;
|
||||
else if (!new_var)
|
||||
{
|
||||
if (debug_info_level > DINFO_LEVEL_TERSE
|
||||
&& !DECL_IGNORED_P (old_var)
|
||||
&& nonlocalized_list)
|
||||
VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (DECL_P (new_var));
|
||||
|
@ -485,10 +529,14 @@ remap_block (tree *block, copy_body_data *id)
|
|||
TREE_USED (new_block) = TREE_USED (old_block);
|
||||
BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
|
||||
BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
|
||||
BLOCK_NONLOCALIZED_VARS (new_block)
|
||||
= VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block));
|
||||
*block = new_block;
|
||||
|
||||
/* Remap its variables. */
|
||||
BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id);
|
||||
BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block),
|
||||
&BLOCK_NONLOCALIZED_VARS (new_block),
|
||||
id);
|
||||
|
||||
fn = id->dst_fn;
|
||||
|
||||
|
@ -549,7 +597,7 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id)
|
|||
if (BIND_EXPR_VARS (*tp))
|
||||
/* This will remap a lot of the same decls again, but this should be
|
||||
harmless. */
|
||||
BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), id);
|
||||
BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,7 +643,7 @@ copy_gimple_bind (gimple stmt, copy_body_data *id)
|
|||
harmless. */
|
||||
new_vars = gimple_bind_vars (stmt);
|
||||
if (new_vars)
|
||||
new_vars = remap_decls (new_vars, id);
|
||||
new_vars = remap_decls (new_vars, NULL, id);
|
||||
|
||||
new_bind = gimple_build_bind (new_vars, new_body, new_block);
|
||||
|
||||
|
@ -3317,11 +3365,9 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
|
|||
cfun->local_decls = tree_cons (NULL_TREE, var,
|
||||
cfun->local_decls);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
|
||||
cfun->local_decls);
|
||||
}
|
||||
else if (!can_be_nonlocal (var, id))
|
||||
cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
|
||||
cfun->local_decls);
|
||||
}
|
||||
|
||||
/* This is it. Duplicate the callee body. Assume callee is
|
||||
|
@ -3911,7 +3957,7 @@ replace_locals_stmt (gimple_stmt_iterator *gsip,
|
|||
/* This will remap a lot of the same decls again, but this should be
|
||||
harmless. */
|
||||
if (gimple_bind_vars (stmt))
|
||||
gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), id));
|
||||
gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), NULL, id));
|
||||
}
|
||||
|
||||
/* Keep iterating. */
|
||||
|
@ -4329,7 +4375,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
|
|||
tree var = TREE_VALUE (t_step);
|
||||
if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
|
||||
cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls);
|
||||
else
|
||||
else if (!can_be_nonlocal (var, &id))
|
||||
cfun->local_decls =
|
||||
tree_cons (NULL_TREE, remap_decl (var, &id),
|
||||
cfun->local_decls);
|
||||
|
|
|
@ -583,7 +583,7 @@ remove_unused_scope_block_p (tree scope)
|
|||
else if (debug_info_level == DINFO_LEVEL_NONE
|
||||
|| debug_info_level == DINFO_LEVEL_TERSE)
|
||||
;
|
||||
else if (BLOCK_VARS (scope))
|
||||
else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope))
|
||||
unused = false;
|
||||
/* See if this block is important for representation of inlined function.
|
||||
Inlined functions are always represented by block with
|
||||
|
@ -613,6 +613,7 @@ static void
|
|||
dump_scope_block (FILE *file, int indent, tree scope, int flags)
|
||||
{
|
||||
tree var, t;
|
||||
unsigned int i;
|
||||
|
||||
fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope),
|
||||
TREE_USED (scope) ? "" : " (unused)",
|
||||
|
@ -648,6 +649,13 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
|
|||
print_generic_decl (file, var, flags);
|
||||
fprintf (file, "%s\n", used ? "" : " (unused)");
|
||||
}
|
||||
for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
|
||||
{
|
||||
fprintf (file, "%*s",indent, "");
|
||||
print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i),
|
||||
flags);
|
||||
fprintf (file, " (nonlocalized)\n");
|
||||
}
|
||||
for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
|
||||
dump_scope_block (file, indent + 2, t, flags);
|
||||
fprintf (file, "\n%*s}\n",indent, "");
|
||||
|
|
|
@ -1968,6 +1968,9 @@ struct varray_head_tag;
|
|||
|
||||
/* In a BLOCK node. */
|
||||
#define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
|
||||
#define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars)
|
||||
#define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE))
|
||||
#define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
|
||||
#define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
|
||||
#define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
|
||||
/* Note: when changing this, make sure to find the places
|
||||
|
@ -2022,6 +2025,8 @@ struct tree_block GTY(())
|
|||
location_t locus;
|
||||
|
||||
tree vars;
|
||||
VEC(tree,gc) *nonlocalized_vars;
|
||||
|
||||
tree subblocks;
|
||||
tree supercontext;
|
||||
tree abstract_origin;
|
||||
|
|
Loading…
Reference in New Issue