<div dir="ltr">In all of the tests I have run the vtorDisp is at -4. RecordlayoutBuilder puts it there (there are weird padding rules when vtordisps are present, but the location of a vtordisp with respect to its virtual base has always been constant to my testing). If you have any counterexamples I would love to see them!<div>
<br></div><div>-Warren</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Oct 10, 2013 at 7:52 AM, Timur Iskhodzhanov <span dir="ltr"><<a href="mailto:timurrrr@google.com" target="_blank">timurrrr@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">2013/10/9 Timur Iskhodzhanov <<a href="mailto:timurrrr@google.com">timurrrr@google.com</a>>:<br>
<div class="im">> Author: timurrrr<br>
> Date: Wed Oct 9 13:16:58 2013<br>
> New Revision: 192312<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=192312&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=192312&view=rev</a><br>
> Log:<br>
> Initialize vtorDisp in class constructors and destructors<br>
><br>
> Reviewed at <a href="http://llvm-reviews.chandlerc.com/D1867" target="_blank">http://llvm-reviews.chandlerc.com/D1867</a><br>
><br>
</div>> ...<br>
<div class="im">> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192312&r1=192311&r2=192312&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192312&r1=192311&r2=192312&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Oct 9 13:16:58 2013<br>
</div><div><div class="h5">> @@ -456,6 +459,61 @@ MicrosoftCXXABI::EmitCtorCompleteObjectH<br>
> return SkipVbaseCtorsBB;<br>
> }<br>
><br>
> +void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(<br>
> + CodeGenFunction &CGF, const CXXRecordDecl *RD) {<br>
> + // In most cases, an override for a vbase virtual method can adjust<br>
> + // the "this" parameter by applying a constant offset.<br>
> + // However, this is not enough while a constructor or a destructor of some<br>
> + // class X is being executed if all the following conditions are met:<br>
> + // - X has virtual bases, (1)<br>
> + // - X overrides a virtual method M of a vbase Y, (2)<br>
> + // - X itself is a vbase of the most derived class.<br>
> + //<br>
> + // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X<br>
> + // which holds the extra amount of "this" adjustment we must do when we use<br>
> + // the X vftables (i.e. during X ctor or dtor).<br>
> + // Outside the ctors and dtors, the values of vtorDisps are zero.<br>
> +<br>
> + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);<br>
> + typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets;<br>
> + const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap();<br>
> + CGBuilderTy &Builder = CGF.Builder;<br>
> +<br>
> + unsigned AS =<br>
> + cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace();<br>
> + llvm::Value *Int8This = 0; // Initialize lazily.<br>
> +<br>
> + for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end();<br>
> + I != E; ++I) {<br>
> + if (!I->second.hasVtorDisp())<br>
> + continue;<br>
> +<br>
> + llvm::Value *VBaseOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(<br>
> + CGF, getThisValue(CGF), RD, I->first);<br>
> + // FIXME: it doesn't look right that we SExt in GetVirtualBaseClassOffset()<br>
> + // just to Trunc back immediately.<br>
> + VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.Int32Ty);<br>
> + uint64_t ConstantVBaseOffset =<br>
> + Layout.getVBaseClassOffset(I->first).getQuantity();<br>
> +<br>
> + // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase).<br>
> + llvm::Value *VtorDispValue = Builder.CreateSub(<br>
> + VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset),<br>
> + "vtordisp.value");<br>
> +<br>
> + if (!Int8This)<br>
> + Int8This = Builder.CreateBitCast(getThisValue(CGF),<br>
> + CGF.Int8Ty->getPointerTo(AS));<br>
> + llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);<br>
> + // vtorDisp is always the 32-bits before the vbase in the class layout.<br>
> + VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);<br>
<br>
</div></div>After investigating some other tests, I'm pretty sure the "-4"<br>
vtordisp offset is not constant but rather might have a different<br>
value for more complex record layouts.<br>
<br>
Warren, do you have any insight to share on the vtordisp location in a<br>
record layout?<br>
<div class="HOEnZb"><div class="h5"><br>
> + VtorDispPtr = Builder.CreateBitCast(<br>
> + VtorDispPtr, CGF.Int32Ty->getPointerTo(AS), "vtordisp.ptr");<br>
> +<br>
> + Builder.CreateStore(VtorDispValue, VtorDispPtr);<br>
> + }<br>
> +}<br>
> +<br>
> void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {<br>
> // There's only one constructor type in this ABI.<br>
> CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));<br>
><br>
</div></div></blockquote></div><br></div>