<div dir="ltr">On Fri, Jul 19, 2013 at 1:46 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<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">On Jul 15, 2013, at 10:03 AM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:<br>


> <a href="http://llvm-reviews.chandlerc.com/D1066" target="_blank">http://llvm-reviews.chandlerc.com/D1066</a><br>
<br>
Okay, so what I'm understanding here is that, when MSVC emits a destructor<br>
(for example, when it's out of line), it emits a global symbol which evaluates<br>
the destructor body and also destroys the non-virtual-base subobjects, which<br>
is basically the behavior of Itanium base destructors.  If it needs a function<br>
that destroys the entire thing (the behavior of the Itanium complete destructor),<br>
it emits it ad hoc, using a symbol that'll be uniqued within the module.<br></blockquote><div><br></div><div>Yep, that's all correct.  This is the mapping from Itanium terminology to the names that native Windows tools emit:</div>

<div><br></div><div>Base -> this is just called ~Class</div><div>Complete -> vbase dtor (calls the base dtor and all vbase dtors)</div><div>Deleting -> scalar or vector deleting dtor<br></div><div><br></div><div>

This is documented in the mangler, which isn't the most obvious place to look I suppose.</div><div><br></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">


Meanwhile, the vf-table for a virtual destructor has entrypoints for what,<br>
exactly?  There seems to be a vector deleting destructor, presumably used<br>
for delete[] (which doesn't actually need to be virtually dispatched, but that<br>
decision may post-date MSVC's decision).  There's also a scalar deleting<br>
destructor, used for delete?  How do they generate direct calls to the destructor,<br>
i.e. foo->~Foo()?</blockquote><div><br></div><div>Timur answered that.</div><div><br></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">


Anyway, this should all be in a nice, detailed comment somewhere in<br>
MSCXXABI.cpp.<br></blockquote><div><br></div><div>Done.<br></div><div><br></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">


-bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {<br>
+bool CodeGenModule::MayDeferGeneration(GlobalDecl GD) {<br>
<br>
Instead of doing this, you should just make non-deferred generation only emit<br>
the variants that it actually guarantees, which seems to be just the base<br>
variant.<br></blockquote><div><br></div><div>OK.</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">

+  // XXX: In the Microsoft ABI, we want to emit a delegating complete dtor<br>
+  // without a definition, which means we won't be able to tell if the<br>
+  // definition is a try body.  In this case, MSVC simply delegates, so we do<br>
+  // the same.<br>
<br>
What is this XXX about?  Is this a FIXME?  It looks like we're actually doing it.<br></blockquote><div><br></div><div>I should remove that.  I'm still confused about why destructors defined as try bodies need to be a special case, but the current behavior should be compatible with cl.exe.</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">
+  // If the class has no virtual bases, then the complete and base destructors<br>
+  // are equivalent, for all C++ ABIs supported by clang.  We can save on code<br>
+  // size by calling the base dtor directly, especially if we'd have to emit a<br>
+  // thunk otherwise.<br>
+  // FIXME: We could do this for Itanium, but we should consult with John first.<br>
<br>
Okay, you can't put this in a comment. :)<br>
<br>
I'm fine with unconditionally emitting calls to base dtors in this case.<br></blockquote><div><br></div><div>It should even be a win on Darwin, since -mconstructor-aliases is disabled there.  I'll make that a separate change in case it breaks something.</div>
<div><br></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">
+  if (getCXXABI().useThunkForDtorVariant(dtorType) &&<br>
<div>+      dtorType == Dtor_Complete && dtor->getParent()->getNumVBases() == 0)<br>
<br>
</div>Checking dtorType and getNumVBases() are basically free because they<br>
don't require a real function call.  You should do those first.  Or actually, I<br>
guess you don't need the check.<br></blockquote><div><br></div><div>Reordered.  I'm leaving it for now, but planning to remove it.</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">

Otherwise this looks good.<br>
<span><font color="#888888"><br>
John.<br>
</font></span></blockquote></div><br></div></div>