aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-06-14 14:09:05 +0000
committerEric Botcazou <ebotcazou@adacore.com>2012-06-14 14:09:05 +0000
commit686ea0275b3269e6fc6d9a339482851f9d760fa4 (patch)
tree483f1b13f1045f868174d5a9bf379855188a002f /gcc/dwarf2out.c
parent1a2a7b421b3d1556774e474e2904f643b80660c1 (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@188621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c63
1 files changed, 54 insertions, 9 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3fd51fdb3b8..e77fecf8808 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -16722,6 +16722,30 @@ gen_call_site_die (tree decl, dw_die_ref subr_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
block-local). */
@@ -16874,14 +16898,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
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);
else
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
}
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);
else
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)
gcc_assert (! BLOCK_ABSTRACT (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
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)
/* 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)
{
@@ -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)
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),
+ dwarf2out_imported_module_or_decl_1 (decl_or_origin,
+ DECL_NAME (decl_or_origin),
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
gen_decl_die (decl, origin, context_die);
}
@@ -19116,11 +19150,11 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
? DECL_ORIGIN (origin)
: 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. */
- else if (cgraph_function_possibly_inlined_p (decl)
- && ! DECL_ABSTRACT (decl)
- && ! class_or_namespace_scope_p (context_die)
+ else if (!DECL_ABSTRACT (decl)
+ && function_possibly_abstracted_p (decl)
+ && !class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */
@@ -22118,8 +22152,19 @@ dwarf2out_finish (const char *filename)
{
dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
- if (origin && origin->die_parent)
- add_child_die (origin->die_parent, die);
+ if (origin)
+ {
+ /* 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 (seen_error ())