<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Aug 9, 2013 at 11:23 AM, Robinson, Paul <span dir="ltr"><<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>> -----Original Message-----<br>
> From: <a href="mailto:llvm-commits-bounces@cs.uiuc.edu" target="_blank">llvm-commits-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:llvm-commits-" target="_blank">llvm-commits-</a><br>
> <a href="mailto:bounces@cs.uiuc.edu" target="_blank">bounces@cs.uiuc.edu</a>] On Behalf Of David Blaikie<br>
> Sent: Friday, August 09, 2013 10:17 AM<br>
> To: <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
> Subject: [llvm] r188082 - DebugInfo: provide the ability to add members<br>
> to a class after it has been constructed<br>
><br>
> Author: dblaikie<br>
> Date: Fri Aug  9 12:17:12 2013<br>
> New Revision: 188082<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=188082&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=188082&view=rev</a><br>
> Log:<br>
> DebugInfo: provide the ability to add members to a class after it has<br>
> been constructed<br>
><br>
> This is necessary to allow Clang to only emit implicit members when<br>
> there is code generated for them, rather than whenever they are ODR<br>
> used.<br>
<br>
</div>Um, so classes could have different member lists in different TUs,<br>
meaning if you're using type units, the type units won't match?<br></blockquote><div><br></div><div>This has always been true of C++ due to <br><br>1) nested types:<br><br>struct foo {<br>  struct bar;<br>};<br><br>

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.<br>

<br>2) implicit special members, as mentioned in the Clang side of this change:<br><br></div><div>struct foo { };<br><br>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.<br>

<br>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.<br><br>3) member function template specializations<br>

<br>struct foo { template<typename T> void func(); };<br><br>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.<br>

<br>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.<br>

<br>eg:<br><br>inline void f() {<br>  foo().func<int>();<br>}<br><br>int main() {<br>  foo().func<float>();<br>}<br><br>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.<br>
<br>Here's the Clang side of the patch: <a href="http://llvm.org/viewvc/llvm-project?rev=188085&view=rev">http://llvm.org/viewvc/llvm-project?rev=188085&view=rev</a>
</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
--paulr<br>
<div><div><br>
><br>
> Modified:<br>
>     llvm/trunk/include/llvm/DebugInfo.h<br>
>     llvm/trunk/lib/IR/DebugInfo.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/include/llvm/DebugInfo.h?rev=188082&r1=188081&r2=1880<br>
> 82&view=diff<br>
> ========================================================================<br>
> ======<br>
> --- llvm/trunk/include/llvm/DebugInfo.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo.h Fri Aug  9 12:17:12 2013<br>
> @@ -323,6 +323,7 @@ namespace llvm {<br>
><br>
>      DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }<br>
>      void setTypeArray(DIArray Elements, DIArray TParams = DIArray());<br>
> +    void addMember(DISubprogram S);<br>
>      unsigned getRunTimeLang() const { return getUnsignedField(11); }<br>
>      DICompositeType getContainingType() const {<br>
>        return getFieldAs<DICompositeType>(12);<br>
><br>
> Modified: llvm/trunk/lib/IR/DebugInfo.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=188082&r1=188081&r2=188082&v<br>
> iew=diff<br>
> ========================================================================<br>
> ======<br>
> --- llvm/trunk/lib/IR/DebugInfo.cpp (original)<br>
> +++ llvm/trunk/lib/IR/DebugInfo.cpp Fri Aug  9 12:17:12 2013<br>
> @@ -647,6 +647,19 @@ void DICompositeType::setTypeArray(DIArr<br>
>    DbgNode = N;<br>
>  }<br>
><br>
> +void DICompositeType::addMember(DISubprogram S) {<br>
> +  SmallVector<llvm::Value *, 16> M;<br>
> +  DIArray OrigM = getTypeArray();<br>
> +  unsigned Elements = OrigM.getNumElements();<br>
> +  if (Elements == 1 && !OrigM.getElement(0))<br>
> +    Elements = 0;<br>
> +  M.reserve(Elements + 1);<br>
> +  for (unsigned i = 0; i != Elements; ++i)<br>
> +    M.push_back(OrigM.getElement(i));<br>
> +  M.push_back(S);<br>
> +  setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));<br>
> +}<br>
> +<br>
>  /// \brief Set the containing type.<br>
>  void DICompositeType::setContainingType(DICompositeType ContainingType)<br>
> {<br>
>    TrackingVH<MDNode> N(*this);<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div></blockquote></div><br></div></div>