r192312 - Initialize vtorDisp in class constructors and destructors
Timur Iskhodzhanov
timurrrr at google.com
Mon Oct 14 03:28:11 PDT 2013
Yep, disregard my previous suspicion :)
The vtorDisp for the vbase is at -4; it's just that B uses C's
vtorDisp in thunks.
2013/10/11 Warren Hunt <whunt at google.com>:
> When I run that through cl.exe with my test harness I get the following
> layouts:
>
> A : 4 : 4
> 0 : 00FC8144 vfp
>
> B : 4 : 4
> 0 : 00FC814C vfp
>
> C : 8 : 4
> 0 : 00FC815C A's vfp
> 4 : 00FC8154 B's vfp
>
> D : 20 : 4
> 0 : 00FC8174 vfp
> 4 : 00FC8178 vpb
> 8 : 00000000 C's vtordisp (A and B don't have vtordisps)
> c : 00FC816C C's (& A's) vfp
> 10 : 00FC8164 B's vfp
>
> By my understanding, the offset for C is -4, A and B don't have them.
>
> -Warren
>
>
>
> On Thu, Oct 10, 2013 at 10:38 AM, Timur Iskhodzhanov <timurrrr at google.com>
> wrote:
>>
>> This one requires -8.
>> We probably need to add something like getVtorDispOffset() to
>> ASTRecordLayout...
>> ------------------
>> struct A {
>> virtual void x();
>> };
>>
>> struct B {
>> virtual void f();
>> };
>>
>> struct C : A, B {};
>>
>> struct D : virtual C {
>> virtual void f();
>> virtual ~D();
>> };
>>
>> D d;
>> ------------------
>>
>> 2013/10/10 Warren Hunt <whunt at google.com>:
>> > 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!
>> >
>> > -Warren
>> >
>> >
>> > On Thu, Oct 10, 2013 at 7:52 AM, Timur Iskhodzhanov
>> > <timurrrr at google.com>
>> > wrote:
>> >>
>> >> 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