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
