Commit 0364adfd by Eric Botcazou Committed by Eric Botcazou

dwarf2out.c (function_possibly_abstracted_p): New static function.

	* dwarf2out.c (function_possibly_abstracted_p): New static function.
	(gen_subprogram_die): Use it function_possibly_abstracted_p in lieu of
	cgraph_function_possibly_inlined_p.
	(gen_inlined_subroutine_die): Return if the origin is to be ignored.
	(process_scope_var): Do not emit concrete instances of abstracted
	nested functions from here.
	(gen_decl_die): Emit the abstract instance if the function is possibly
	abstracted and not only possibly inlined.
	(dwarf2out_finish): Find the first non-abstract parent instance and
	attach concrete instances on the limbo list to it.

From-SVN: r188621
parent 8fcd8c83
2012-06-14 Eric Botcazou <ebotcazou@adacore.com>
* dwarf2out.c (function_possibly_abstracted_p): New static function.
(gen_subprogram_die): Use it function_possibly_abstracted_p in lieu of
cgraph_function_possibly_inlined_p.
(gen_inlined_subroutine_die): Return if the origin is to be ignored.
(process_scope_var): Do not emit concrete instances of abstracted
nested functions from here.
(gen_decl_die): Emit the abstract instance if the function is possibly
abstracted and not only possibly inlined.
(dwarf2out_finish): Find the first non-abstract parent instance and
attach concrete instances on the limbo list to it.
2012-06-14 Richard Earnshaw <rearnsha@arm.com> 2012-06-14 Richard Earnshaw <rearnsha@arm.com>
* arm.md (divsf3, divdf3): Remove FPA support. * arm.md (divsf3, divdf3): Remove FPA support.
......
...@@ -16722,6 +16722,30 @@ gen_call_site_die (tree decl, dw_die_ref subr_die, ...@@ -16722,6 +16722,30 @@ gen_call_site_die (tree decl, dw_die_ref subr_die,
return die; return die;
} }
/* Return true if an abstract instance of function DECL can be generated in
the debug information. */
static bool
function_possibly_abstracted_p (tree decl)
{
/* An abstract instance of DECL can be generated if DECL can be inlined or
is nested in a function that can be inlined, recursively. */
while (decl)
{
if (cgraph_function_possibly_inlined_p (decl))
return true;
decl = decl_function_context (decl);
/* Do not consider Fortran subroutines as nested in the main program. */
if (decl
&& is_fortran ()
&& !strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
"MAIN__"))
break;
}
return false;
}
/* Generate a DIE to represent a declared function (either file-scope or /* Generate a DIE to represent a declared function (either file-scope or
block-local). */ block-local). */
...@@ -16874,14 +16898,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -16874,14 +16898,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{ {
if (DECL_DECLARED_INLINE_P (decl)) if (DECL_DECLARED_INLINE_P (decl))
{ {
if (cgraph_function_possibly_inlined_p (decl)) if (function_possibly_abstracted_p (decl))
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined); add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined);
else else
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined); add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
} }
else else
{ {
if (cgraph_function_possibly_inlined_p (decl)) if (function_possibly_abstracted_p (decl))
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined); add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
else else
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined); add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined);
...@@ -17810,6 +17834,8 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -17810,6 +17834,8 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
gcc_assert (! BLOCK_ABSTRACT (stmt)); gcc_assert (! BLOCK_ABSTRACT (stmt));
decl = block_ultimate_origin (stmt); decl = block_ultimate_origin (stmt);
if (DECL_IGNORED_P (decl))
return;
/* Emit info for the abstract instance first, if we haven't yet. We /* Emit info for the abstract instance first, if we haven't yet. We
must emit this even if the block is abstract, otherwise when we must emit this even if the block is abstract, otherwise when we
...@@ -18751,6 +18777,7 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -18751,6 +18777,7 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
/* Process variable DECL (or variable with origin ORIGIN) within /* Process variable DECL (or variable with origin ORIGIN) within
block STMT and add it to CONTEXT_DIE. */ block STMT and add it to CONTEXT_DIE. */
static void static void
process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die) process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
{ {
...@@ -18768,8 +18795,15 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die) ...@@ -18768,8 +18795,15 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
if (die != NULL && die->die_parent == NULL) if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die); add_child_die (context_die, die);
else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL) else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin), dwarf2out_imported_module_or_decl_1 (decl_or_origin,
DECL_NAME (decl_or_origin),
stmt, context_die); stmt, context_die);
/* Do not emit concrete instances of abstracted nested functions within
concrete instances of parent functions. */
else if (TREE_CODE (decl_or_origin) == FUNCTION_DECL
&& die
&& get_AT (die, DW_AT_inline))
;
else else
gen_decl_die (decl, origin, context_die); gen_decl_die (decl, origin, context_die);
} }
...@@ -19116,11 +19150,11 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die) ...@@ -19116,11 +19150,11 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
? DECL_ORIGIN (origin) ? DECL_ORIGIN (origin)
: DECL_ABSTRACT_ORIGIN (decl)); : DECL_ABSTRACT_ORIGIN (decl));
/* If we're emitting an out-of-line copy of an inline function, /* If we're emitting an out-of-line copy of an abstracted function,
emit info for the abstract instance and set up to refer to it. */ emit info for the abstract instance and set up to refer to it. */
else if (cgraph_function_possibly_inlined_p (decl) else if (!DECL_ABSTRACT (decl)
&& ! DECL_ABSTRACT (decl) && function_possibly_abstracted_p (decl)
&& ! class_or_namespace_scope_p (context_die) && !class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just /* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */ that case, because that works only if we have a die. */
...@@ -22118,8 +22152,19 @@ dwarf2out_finish (const char *filename) ...@@ -22118,8 +22152,19 @@ dwarf2out_finish (const char *filename)
{ {
dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
if (origin && origin->die_parent) if (origin)
add_child_die (origin->die_parent, die); {
/* Find the first non-abstract parent instance. */
do
origin = origin->die_parent;
while (origin
&& (origin->die_tag != DW_TAG_subprogram
|| get_AT (origin, DW_AT_inline)));
if (origin)
add_child_die (origin, die);
else
add_child_die (comp_unit_die (), die);
}
else if (is_cu_die (die)) else if (is_cu_die (die))
; ;
else if (seen_error ()) else if (seen_error ())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment