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