r192312 - Initialize vtorDisp in class constructors and destructors

Timur Iskhodzhanov timurrrr at google.com
Thu Oct 10 07:52:17 PDT 2013


2013/10/9 Timur Iskhodzhanov <timurrrr at google.com>:
> Author: timurrrr
> Date: Wed Oct  9 13:16:58 2013
> New Revision: 192312
>
> URL: http://llvm.org/viewvc/llvm-project?rev=192312&view=rev
> Log:
> Initialize vtorDisp in class constructors and destructors
>
> Reviewed at http://llvm-reviews.chandlerc.com/D1867
>
> ...
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192312&r1=192311&r2=192312&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Oct  9 13:16:58 2013
> @@ -456,6 +459,61 @@ MicrosoftCXXABI::EmitCtorCompleteObjectH
>    return SkipVbaseCtorsBB;
>  }
>
> +void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
> +    CodeGenFunction &CGF, const CXXRecordDecl *RD) {
> +  // In most cases, an override for a vbase virtual method can adjust
> +  // the "this" parameter by applying a constant offset.
> +  // However, this is not enough while a constructor or a destructor of some
> +  // class X is being executed if all the following conditions are met:
> +  //  - X has virtual bases, (1)
> +  //  - X overrides a virtual method M of a vbase Y, (2)
> +  //  - X itself is a vbase of the most derived class.
> +  //
> +  // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X
> +  // which holds the extra amount of "this" adjustment we must do when we use
> +  // the X vftables (i.e. during X ctor or dtor).
> +  // Outside the ctors and dtors, the values of vtorDisps are zero.
> +
> +  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
> +  typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets;
> +  const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap();
> +  CGBuilderTy &Builder = CGF.Builder;
> +
> +  unsigned AS =
> +      cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace();
> +  llvm::Value *Int8This = 0;  // Initialize lazily.
> +
> +  for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end();
> +        I != E; ++I) {
> +    if (!I->second.hasVtorDisp())
> +      continue;
> +
> +    llvm::Value *VBaseOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
> +        CGF, getThisValue(CGF), RD, I->first);
> +    // FIXME: it doesn't look right that we SExt in GetVirtualBaseClassOffset()
> +    // just to Trunc back immediately.
> +    VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.Int32Ty);
> +    uint64_t ConstantVBaseOffset =
> +        Layout.getVBaseClassOffset(I->first).getQuantity();
> +
> +    // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase).
> +    llvm::Value *VtorDispValue = Builder.CreateSub(
> +        VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset),
> +        "vtordisp.value");
> +
> +    if (!Int8This)
> +      Int8This = Builder.CreateBitCast(getThisValue(CGF),
> +                                       CGF.Int8Ty->getPointerTo(AS));
> +    llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
> +    // vtorDisp is always the 32-bits before the vbase in the class layout.
> +    VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);

After investigating some other tests, I'm pretty sure the "-4"
vtordisp offset is not constant but rather might have a different
value for more complex record layouts.

Warren, do you have any insight to share on the vtordisp location in a
record layout?

> +    VtorDispPtr = Builder.CreateBitCast(
> +        VtorDispPtr, CGF.Int32Ty->getPointerTo(AS), "vtordisp.ptr");
> +
> +    Builder.CreateStore(VtorDispValue, VtorDispPtr);
> +  }
> +}
> +
>  void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
>    // There's only one constructor type in this ABI.
>    CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
>



More information about the cfe-commits mailing list