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 <[email protected]>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 <[email protected]>: > > 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 <[email protected] > > > > wrote: > >> > >> 2013/10/9 Timur Iskhodzhanov <[email protected]>: > >> > 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)); > >> > > > > > >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
