[llvm] r188082 - DebugInfo: provide the ability to add members to a class after it has been constructed

Robinson, Paul Paul_Robinson at playstation.sony.com
Mon Aug 12 11:19:05 PDT 2013


> 
>
> From: David Blaikie [mailto:dblaikie at gmail.com] 
> Sent: Saturday, August 10, 2013 12:52 PM
> To: Robinson, Paul
> Cc: llvm-commits at cs.uiuc.edu
> Subject: Re: [llvm] r188082 - DebugInfo: provide the ability to add members to a class after it has been constructed
>
>
>
> On Fri, Aug 9, 2013 at 11:23 AM, Robinson, Paul
>  <Paul_Robinson at playstation.sony.com> wrote:
> > > -----Original Message-----
> > > From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> > > bounces at cs.uiuc.edu] On Behalf Of David Blaikie
> > > Sent: Friday, August 09, 2013 10:17 AM
> > > To: llvm-commits at cs.uiuc.edu
> > > Subject: [llvm] r188082 - DebugInfo: provide the ability to add members
> > > to a class after it has been constructed
> > >
> > > Author: dblaikie
> > > Date: Fri Aug  9 12:17:12 2013
> > > New Revision: 188082
> > >
> > > URL: http://llvm.org/viewvc/llvm-project?rev=188082&view=rev
> > > Log:
> > > DebugInfo: provide the ability to add members to a class after it has
> > > been constructed
> > >
> > > This is necessary to allow Clang to only emit implicit members when
> > > there is code generated for them, rather than whenever they are ODR
> > > used.
> > Um, so classes could have different member lists in different TUs,
> > meaning if you're using type units, the type units won't match?
>
> This has always been true of C++ due to 
>
> 1) nested types:
>
> struct foo {
>  struct bar;
> };
>
> One TU has struct foo::bar { }; and another TU doesn't (this is common
> in the pimpl idiom) - the DIE for 'foo' can't be the same between those
> TUs since one will contain a declaration of 'bar' and another a definition
> (& in fact both Clang and GCC don't even emit the declaration of 'bar'
> if it's unreferenced in the current TU - so you'll get 3 versions: no
> mention of 'bar', a declaration of 'bar', and a definition of 'bar'). We
> could possibly use out-of-line definitions the same way we do for function
> definitions, but I doubt GDB/debuggers could handle that just yet.

With pimpl I'd expect only one TU with a definition so not matching the
declaration is okay. That is, yes, you get two copies in different TUs.

>
> 2) implicit special members, as mentioned in the Clang side of this change:
>
> struct foo { };
>
> in a TU with only that code, 'foo' does not contain a declaration for any
> of the 5 special members (default ctor, copy ctor, move ctor, copy assign,
> move assign, dtor). Only in a TU that references those special members
> would they be declared and then possibly defined (if they are ODR-used (eg:
> used from an evaluated context, not just "sizeof", etc))). The compiler
> isn't allowed to speculate about the existence/viability of creating
> declarations of those special members in a TU that doesn't reference them
> in any way.
>
> This was already true of Clang prior to this change - a TU that never used
> the special members would not have declarations of them, some other TU that
> did reference them would have them.

Makes me think these artificial members should not contribute to the type
signature. They are of little to no value in the debugger anyhow.  Maybe
ALL artificial members should not contribute to the type signature...

>
> 3) member function template specializations
>
> struct foo { template<typename T> void func(); };
>
> In this case it's completely unbounded - 'func' could be instantiated with
> any number of types. There's no way we could even speculate about which
> members 'foo'f might have in total.
>
> GCC and Clang both simply emit declarations (and, optionally, definitions)
> of any specializations that 'func' has in this TU. GCC already only did
> this for specializations that actually generated code (because they were
> used by code that was being emitted) but Clang emitted it for every
> specialization.
>
> eg:
>
> inline void f() {
>  foo().func<int>();
> }
>
> int main() {
>  foo().func<float>();
> }
>
> produced two specializations (foo<int> only as a declaration with no
> definition, foo<float> with both declaration and definition) from Clang,
> but only one from GCC. Clang now produces only one in the above program.
> But as you can see, there could be any number of other instances of this
> member function template (foo<bool>, foo<string>, foo<bar>, etc) in other
> translation units.

I knew about member templates, I think such classes shouldn't be considered
candidates for type units.  They aren't common.

>
> Here's the Clang side of the patch: http://llvm.org/viewvc/llvm-project?rev=188085&view=rev 
>
>
> > --paulr






More information about the llvm-commits mailing list