This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Fix debug info of nested inline functions
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Joel Brobecker <brobecker at adacore dot com>
- Date: Mon, 14 May 2012 17:54:07 +0200
- Subject: Re: [patch] Fix debug info of nested inline functions
- References: <201203022129.30464.ebotcazou@adacore.com> <4FADC4E6.2070908@redhat.com>
> I notice that D.7 seems to suggest that if the nested function is not
> inlinable and shared between all instances of the containing function
> that we put a normal (non-abstract/concrete) instance of the nested
> function inside the abstract function for the containing function. But
> I agree that it's cleaner your way: put an abstract instance there
> instead so that the abstract instance of the containing function is all
> abstract.
Hum, yes, D.7 even tends to show that what GCC currently generates is as
expected. The problem arises when the containing function is itself inlined
into the nested function: in this case, we have the cycle in the debug info:
|-> AI (containing) -> OL (nested) -> CI (containing) --|
| |
------------------DW_AT_abstract_origin ------------------
that is problematic for GDB, and Joel said at the time that there was no easy
way to break the recursion in GDB.
AI: Abstract Instance
OL: Out-of-Line
CI: Concrete Instance
But if you think the patch is nevertheless reasonable, then let's go ahead.
> > + /* Emit an abstract instance of nested functions within an abstract
> > instance + of their parent. */
> > + int declaration = ((decl != current_function_decl
> > + && !(DECL_INITIAL (decl) != NULL_TREE
> > + && DECL_ABSTRACT (decl)
> > + && current_function_decl
> > + && DECL_ABSTRACT (current_function_decl)))
> >
> > || class_or_namespace_scope_p (context_die));
>
> Hmm, why isn't current_function_decl == decl when we're trying to emit
> the abstract instance of a nested function?
Because it is emitted when the first instance of the parent function is seen,
and in this case current_function_decl == parent_decl.
> > + /* Do not emit concrete instances of abstracted nested functions
> > without + actual instances. */
> > + else if (TREE_CODE (decl_or_origin) == FUNCTION_DECL
> > + && die
> > + && get_AT (die, DW_AT_inline))
> > + ;
>
> Should "without actual instances" be something like "within concrete
> instances of containing functions"?
Yes, that's probably clearer.
> > - if (origin && origin->die_parent)
> > + if (origin
> > + && origin->die_parent
> > + /* Skip an abtract parent instance. */
> > + && !(origin->die_parent->die_tag == DW_TAG_subprogram
> > + && get_AT (origin->die_parent, DW_AT_inline)))
> > add_child_die (origin->die_parent, die);
>
> What if the immediate parent is a DW_TAG_lexical_block or some other
> thing nested inside an abstract subprogram?
Indeed, there was a loop in the last revised version of the original thread:
http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01286.html
Not clear why I dropped it...
> In my earlier comments I seem to have been wrong about the behavior of
> gen_subprogram_die; now I see that if there is an abstract instance the
> concrete out-of-line instance is not associated with the decl number.
> So I guess your earlier limbo handling code was fine apart from the
> lexical_block issue above.
So the above last revised version is OK with you, modulo the comment in
process_scope_var?
--
Eric Botcazou