r182870 - [ms-cxxabi] Implement MSVC virtual base adjustment
Reid Kleckner
rnk at google.com
Tue Jun 4 14:33:32 PDT 2013
Thanks, done in r183251.
On Tue, Jun 4, 2013 at 1:45 PM, John McCall <rjmccall at apple.com> wrote:
> On May 29, 2013, at 11:02 AM, Reid Kleckner <reid at kleckner.net> wrote:
> > Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=182870&r1=182869&r2=182870&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed May 29 13:02:47 2013
> > @@ -48,6 +48,11 @@ public:
> > llvm::Value *ptr,
> > QualType type);
> >
> > + llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
> > + llvm::Value *This,
> > + const CXXRecordDecl *ClassDecl,
> > + const CXXRecordDecl
> *BaseClassDecl);
> > +
> > void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
> > CXXCtorType Type,
> > CanQualType &ResTy,
> > @@ -142,6 +147,22 @@ private:
> > GetNullMemberPointerFields(const MemberPointerType *MPT,
> > llvm::SmallVectorImpl<llvm::Constant *>
> &fields);
> >
> > + /// \brief Finds the offset from the base of RD to the vbptr it uses,
> even if
> > + /// it is reusing a vbptr from a non-virtual base. RD must have
> morally
> > + /// virtual bases.
> > + CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD);
> > +
> > + /// \brief Shared code for virtual base adjustment. Returns the
> offset from
> > + /// the vbptr to the virtual base. Optionally returns the address of
> the
> > + /// vbptr itself.
> > + llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
> > + llvm::Value *Base,
> > + llvm::Value *VBPtrOffset,
> > + llvm::Value *VBTableOffset,
> > + llvm::Value **VBPtr = 0);
> > +
> > + /// \brief Performs a full virtual base adjustment. Used to
> dereference
> > + /// pointers to members of virtual bases.
> > llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const
> CXXRecordDecl *RD,
> > llvm::Value *Base,
> > llvm::Value
> *VirtualBaseAdjustmentOffset,
> > @@ -212,6 +233,68 @@ llvm::Value *MicrosoftCXXABI::adjustToCo
> > return ptr;
> > }
> >
> > +CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl
> *RD) {
> > + assert(RD->getNumVBases());
> > + CharUnits Total = CharUnits::Zero();
> > + while (RD) {
> > + const ASTRecordLayout &RDLayout =
> getContext().getASTRecordLayout(RD);
> > + CharUnits VBPtrOffset = RDLayout.getVBPtrOffset();
> > + // -1 is the sentinel for no vbptr.
> > + if (VBPtrOffset != CharUnits::fromQuantity(-1)) {
> > + Total += VBPtrOffset;
> > + break;
> > + }
> > +
> > + // RD is reusing the vbptr of a non-virtual base. Find it and
> continue.
> > + const CXXRecordDecl *FirstNVBaseWithVBases = 0;
> > + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
> > + E = RD->bases_end(); I != E; ++I) {
> > + const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
> > + if (!I->isVirtual() && Base->getNumVBases() > 0) {
> > + FirstNVBaseWithVBases = Base;
> > + break;
> > + }
> > + }
> > + assert(FirstNVBaseWithVBases);
>
> Please break this out into a function and use llvm_unreachable in the
> fall-out case.
>
> > + Total += RDLayout.getBaseClassOffset(FirstNVBaseWithVBases);
> > + RD = FirstNVBaseWithVBases;
> > + }
> > + return Total;
> > +}
> > +
> > +llvm::Value *
> > +MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
> > + llvm::Value *This,
> > + const CXXRecordDecl
> *ClassDecl,
> > + const CXXRecordDecl
> *BaseClassDecl) {
> > + int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity();
> > + llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy,
> VBPtrChars);
> > +
> > + // The vbtable is an array of i32 offsets. The first entry is a self
> entry,
> > + // and the rest are offsets from the vbptr to virtual bases. The
> bases are
> > + // ordered the same way our vbases are ordered: as they appear in a
> > + // left-to-right depth-first search of the hierarchy.
> > + unsigned VBTableIndex = 1; // Start with one to skip the self entry.
> > + for (CXXRecordDecl::base_class_const_iterator I =
> ClassDecl->vbases_begin(),
> > + E = ClassDecl->vbases_end(); I != E; ++I) {
> > + if (I->getType()->getAsCXXRecordDecl() == BaseClassDecl)
> > + break;
> > + VBTableIndex++;
> > + }
> > + assert(VBTableIndex != 1 + ClassDecl->getNumVBases() &&
> > + "BaseClassDecl must be a vbase of ClassDecl");
>
> Same.
>
> Otherwise looks fine.
>
> John.
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130604/e6eda777/attachment.html>
More information about the cfe-commits
mailing list