aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-01-02 01:01:18 +0000
committerAnders Carlsson <andersca@mac.com>2010-01-02 01:01:18 +0000
commitc997d4278d329e18891aac9698fb991b2d4622eb (patch)
treef44c1c11f2654154146fbbfec44a1993b8deea91 /lib/CodeGen/CGClass.cpp
parent3b5ad2283c999f6edf7d42332a655447b7386b2e (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.cpp83
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");
+}