diff options
author | Anders Carlsson <andersca@mac.com> | 2009-11-13 04:45:41 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-11-13 04:45:41 +0000 |
commit | 566abee1e9828a7700b51e4d17ea08234fde3bb4 (patch) | |
tree | c92f80b56e260884fbbf1cb43a57fe80853051b7 /lib/CodeGen/CGCXXExpr.cpp | |
parent | 03d8ed439f55b692634f9c71721ecfabbe347c4d (diff) |
Add a special BuildVirtualCall that's going to be used for building calls to destructors. This is needed because when compiling:
struct A {
virtual ~A();
};
void f(A* a) {
delete a;
}
A's deleting destructor should be called.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXXExpr.cpp')
-rw-r--r-- | lib/CodeGen/CGCXXExpr.cpp | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/lib/CodeGen/CGCXXExpr.cpp b/lib/CodeGen/CGCXXExpr.cpp index 8b0490fe32..a21149973d 100644 --- a/lib/CodeGen/CGCXXExpr.cpp +++ b/lib/CodeGen/CGCXXExpr.cpp @@ -265,7 +265,9 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); EmitBlock(DeleteNotNull); - + + bool ShouldCallDelete = true; + // Call the destructor if necessary. if (const RecordType *RT = DeleteTy->getAs<RecordType>()) { if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { @@ -276,30 +278,35 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor), /*isVariadic=*/false); - llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty); + llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty); EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0); + + // The dtor took care of deleting the object. + ShouldCallDelete = false; } else EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr); } } } - // Call delete. - FunctionDecl *DeleteFD = E->getOperatorDelete(); - const FunctionProtoType *DeleteFTy = - DeleteFD->getType()->getAs<FunctionProtoType>(); + if (ShouldCallDelete) { + // Call delete. + FunctionDecl *DeleteFD = E->getOperatorDelete(); + const FunctionProtoType *DeleteFTy = + DeleteFD->getType()->getAs<FunctionProtoType>(); - CallArgList DeleteArgs; + CallArgList DeleteArgs; - QualType ArgTy = DeleteFTy->getArgType(0); - llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy)); - DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy)); - - // Emit the call to delete. - EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(), - DeleteArgs), - CGM.GetAddrOfFunction(DeleteFD), - DeleteArgs, DeleteFD); + QualType ArgTy = DeleteFTy->getArgType(0); + llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy)); + DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy)); + // Emit the call to delete. + EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(), + DeleteArgs), + CGM.GetAddrOfFunction(DeleteFD), + DeleteArgs, DeleteFD); + } + EmitBlock(DeleteEnd); } |