aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-11-30 22:07:18 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-11-30 22:07:18 +0000
commitba2253f234d27d3ecc5b2b88e9cd9198658eb312 (patch)
tree1f12f22c1b316407cd56803231eac3876f1f0486 /lib/CodeGen/CGCXX.cpp
parent37909808416da93703cecc83091e2b9eab0053d6 (diff)
More support for virtual destructor calls.
Fixes pr5619 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 437fed7478..34d1c8d984 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -603,16 +603,7 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
Counter = Builder.CreateLoad(IndexPtr);
Counter = Builder.CreateSub(Counter, One);
llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
- if (D->isVirtual()) {
- const llvm::Type *Ty =
- CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D),
- /*isVariadic=*/false);
-
- llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, Address, Ty);
- EmitCXXMemberCall(D, Callee, Address, 0, 0);
- }
- else
- EmitCXXDestructorCall(D, Dtor_Complete, Address);
+ EmitCXXDestructorCall(D, Dtor_Complete, Address);
EmitBlock(ContinueBlock);
@@ -703,6 +694,15 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
CXXDtorType Type,
llvm::Value *This) {
+ if (D->isVirtual()) {
+ const llvm::Type *Ty =
+ CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D),
+ /*isVariadic=*/false);
+
+ llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, This, Ty);
+ EmitCXXMemberCall(D, Callee, This, 0, 0);
+ return;
+ }
llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
EmitCXXMemberCall(D, Callee, This, 0, 0);
@@ -1777,12 +1777,12 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
// Ignore trivial destructors.
if (BaseClassDecl->hasTrivialDestructor())
continue;
-
+ const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
+
llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
ClassDecl, BaseClassDecl,
/*NullCheckValue=*/false);
- EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
- Dtor_Base, V);
+ EmitCXXDestructorCall(D, Dtor_Base, V);
}
// If we're emitting a base destructor, we don't want to emit calls to the
@@ -1790,10 +1790,21 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
if (DtorType == Dtor_Base)
return;
- // FIXME: Handle virtual bases.
+ // Handle virtual bases.
for (CXXRecordDecl::reverse_base_class_const_iterator I =
ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) {
- assert(false && "FIXME: Handle virtual bases.");
+ const CXXBaseSpecifier &Base = *I;
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+
+ // Ignore trivial destructors.
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
+ llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
+ ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
+ EmitCXXDestructorCall(D, Dtor_Base, V);
}
// If we have a deleting destructor, emit a call to the delete operator.