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

David Blaikie dblaikie at gmail.com
Sat Aug 10 12:51:38 PDT 2013


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.

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.

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.

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



> --paulr
>
> >
> > Modified:
> >     llvm/trunk/include/llvm/DebugInfo.h
> >     llvm/trunk/lib/IR/DebugInfo.cpp
> >
> > Modified: llvm/trunk/include/llvm/DebugInfo.h
> > URL: http://llvm.org/viewvc/llvm-
> > project/llvm/trunk/include/llvm/DebugInfo.h?rev=188082&r1=188081&r2=1880
> > 82&view=diff
> > ========================================================================
> > ======
> > --- llvm/trunk/include/llvm/DebugInfo.h (original)
> > +++ llvm/trunk/include/llvm/DebugInfo.h Fri Aug  9 12:17:12 2013
> > @@ -323,6 +323,7 @@ namespace llvm {
> >
> >      DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
> >      void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
> > +    void addMember(DISubprogram S);
> >      unsigned getRunTimeLang() const { return getUnsignedField(11); }
> >      DICompositeType getContainingType() const {
> >        return getFieldAs<DICompositeType>(12);
> >
> > Modified: llvm/trunk/lib/IR/DebugInfo.cpp
> > URL: http://llvm.org/viewvc/llvm-
> > project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=188082&r1=188081&r2=188082&v
> > iew=diff
> > ========================================================================
> > ======
> > --- llvm/trunk/lib/IR/DebugInfo.cpp (original)
> > +++ llvm/trunk/lib/IR/DebugInfo.cpp Fri Aug  9 12:17:12 2013
> > @@ -647,6 +647,19 @@ void DICompositeType::setTypeArray(DIArr
> >    DbgNode = N;
> >  }
> >
> > +void DICompositeType::addMember(DISubprogram S) {
> > +  SmallVector<llvm::Value *, 16> M;
> > +  DIArray OrigM = getTypeArray();
> > +  unsigned Elements = OrigM.getNumElements();
> > +  if (Elements == 1 && !OrigM.getElement(0))
> > +    Elements = 0;
> > +  M.reserve(Elements + 1);
> > +  for (unsigned i = 0; i != Elements; ++i)
> > +    M.push_back(OrigM.getElement(i));
> > +  M.push_back(S);
> > +  setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));
> > +}
> > +
> >  /// \brief Set the containing type.
> >  void DICompositeType::setContainingType(DICompositeType ContainingType)
> > {
> >    TrackingVH<MDNode> N(*this);
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130810/69758776/attachment.html>


More information about the llvm-commits mailing list