diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-02 01:01:18 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-02 01:01:18 +0000 |
commit | c997d4278d329e18891aac9698fb991b2d4622eb (patch) | |
tree | f44c1c11f2654154146fbbfec44a1993b8deea91 /lib/CodeGen/CGClass.cpp | |
parent | 3b5ad2283c999f6edf7d42332a655447b7386b2e (diff) |
Correctly pass VTT parameters to constructors and destructors. The VTTs aren't yet used in the ctors/dtors, but that will follow.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92409 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index b4f964fb5c..64568d2e6f 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -431,6 +431,37 @@ void CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest, EmitBlock(AfterFor, true); } +/// GetVTTParameter - Return the VTT parameter that should be passed to a +/// base constructor/destructor with virtual bases. +static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) { + if (!CGVtableInfo::needsVTTParameter(GD)) { + // This constructor/destructor does not need a VTT parameter. + return 0; + } + + const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); + const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); + + llvm::Value *VTT; + + uint64_t SubVTTIndex = + CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base); + assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); + + if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) { + // A VTT parameter was passed to the constructor, use it. + VTT = CGF.LoadCXXVTT(); + VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); + } else { + // We're the complete constructor, so get the VTT by name. + VTT = CGF.CGM.getVtableInfo().getVTT(RD); + VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); + } + + return VTT; +} + + /// EmitClassMemberwiseCopy - This routine generates code to copy a class /// object from SrcValue to DestValue. Copying can be either a bitwise copy /// or via a copy constructor call. @@ -438,11 +469,16 @@ void CodeGenFunction::EmitClassMemberwiseCopy( llvm::Value *Dest, llvm::Value *Src, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl, QualType Ty) { + CXXCtorType CtorType = Ctor_Complete; + if (ClassDecl) { Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl, /*NullCheckValue=*/false); Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl, /*NullCheckValue=*/false); + + // We want to call the base constructor. + CtorType = Ctor_Base; } if (BaseClassDecl->hasTrivialCopyConstructor()) { EmitAggregateCopy(Dest, Src, Ty); @@ -451,13 +487,19 @@ void CodeGenFunction::EmitClassMemberwiseCopy( if (CXXConstructorDecl *BaseCopyCtor = BaseClassDecl->getCopyConstructor(getContext(), 0)) { - llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, - Ctor_Complete); + llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType); CallArgList CallArgs; // Push the this (Dest) ptr. CallArgs.push_back(std::make_pair(RValue::get(Dest), BaseCopyCtor->getThisType(getContext()))); + // Push the VTT parameter, if necessary. + if (llvm::Value *VTT = + GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) { + QualType T = getContext().getPointerType(getContext().VoidPtrTy); + CallArgs.push_back(std::make_pair(RValue::get(VTT), T)); + } + // Push the Src ptr. CallArgs.push_back(std::make_pair(RValue::get(Src), BaseCopyCtor->getParamDecl(0)->getType())); @@ -787,10 +829,8 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset/8); V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo()); - // FIXME: This should always use Ctor_Base as the ctor type! (But that - // causes crashes in tests.) CGF.EmitCXXConstructorCall(BaseInit->getConstructor(), - CtorType, V, + Ctor_Base, V, BaseInit->const_arg_begin(), BaseInit->const_arg_end()); } @@ -1248,6 +1288,7 @@ CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, return m; } + void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, @@ -1271,35 +1312,19 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, return; } + llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type)); llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); - EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, ArgBeg, ArgEnd); + EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); } void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, llvm::Value *This) { + llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type)); llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); - CallArgList Args; - - // Push the this ptr. - Args.push_back(std::make_pair(RValue::get(This), - DD->getThisType(getContext()))); - - // Add a VTT parameter if necessary. - // FIXME: This should not be a dummy null parameter! - if (Type == Dtor_Base && DD->getParent()->getNumVBases() != 0) { - QualType T = getContext().getPointerType(getContext().VoidPtrTy); - - Args.push_back(std::make_pair(RValue::get(CGM.EmitNullConstant(T)), T)); - } - - // FIXME: We should try to share this code with EmitCXXMemberCall. - - QualType ResultType = DD->getType()->getAs<FunctionType>()->getResultType(); - EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, - ReturnValueSlot(), Args, DD); + EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); } llvm::Value * @@ -1395,3 +1420,11 @@ void CodeGenFunction::InitializeVtablePtrsRecursive( // Store address point Builder.CreateStore(VtableAddressPoint, VtableField); } + +llvm::Value *CodeGenFunction::LoadCXXVTT() { + assert((isa<CXXConstructorDecl>(CurFuncDecl) || + isa<CXXDestructorDecl>(CurFuncDecl)) && + "Must be in a C++ ctor or dtor to load the vtt parameter"); + + return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); +} |