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