[cfe-commits] r87083 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGCXXExpr.cpp CodeGenFunction.h
Anders Carlsson
andersca at mac.com
Thu Nov 12 20:45:42 PST 2009
Author: andersca
Date: Thu Nov 12 22:45:41 2009
New Revision: 87083
URL: http://llvm.org/viewvc/llvm-project?rev=87083&view=rev
Log:
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.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=87083&r1=87082&r2=87083&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Nov 12 22:45:41 2009
@@ -985,20 +985,35 @@
return VBaseOffset;
}
+static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, int64_t VtableIndex,
+ llvm::Value *This, const llvm::Type *Ty) {
+ Ty = Ty->getPointerTo()->getPointerTo()->getPointerTo();
+
+ llvm::Value *Vtable = CGF.Builder.CreateBitCast(This, Ty);
+ Vtable = CGF.Builder.CreateLoad(Vtable);
+
+ llvm::Value *VFuncPtr =
+ CGF.Builder.CreateConstInBoundsGEP1_64(Vtable, VtableIndex, "vfn");
+ return CGF.Builder.CreateLoad(VFuncPtr);
+}
+
llvm::Value *
-CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
+CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
const llvm::Type *Ty) {
- int64_t Index = CGM.getVtableInfo().getMethodVtableIndex(MD);
+ MD = MD->getCanonicalDecl();
+ int64_t VtableIndex = CGM.getVtableInfo().getMethodVtableIndex(MD);
- Ty = llvm::PointerType::get(Ty, 0);
- Ty = llvm::PointerType::get(Ty, 0);
- Ty = llvm::PointerType::get(Ty, 0);
- llvm::Value *vtbl = Builder.CreateBitCast(This, Ty);
- vtbl = Builder.CreateLoad(vtbl);
- llvm::Value *vfn = Builder.CreateConstInBoundsGEP1_64(vtbl,
- Index, "vfn");
- vfn = Builder.CreateLoad(vfn);
- return vfn;
+ return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
+}
+
+llvm::Value *
+CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
+ llvm::Value *&This, const llvm::Type *Ty) {
+ DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
+ int64_t VtableIndex =
+ CGM.getVtableInfo().getMethodVtableIndex(DD);
+
+ return ::BuildVirtualCall(*this, VtableIndex, This, Ty);
}
/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
Modified: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=87083&r1=87082&r2=87083&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp Thu Nov 12 22:45:41 2009
@@ -265,7 +265,9 @@
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 @@
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>();
-
- 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);
-
+ if (ShouldCallDelete) {
+ // Call delete.
+ FunctionDecl *DeleteFD = E->getOperatorDelete();
+ const FunctionProtoType *DeleteFTy =
+ DeleteFD->getType()->getAs<FunctionProtoType>();
+
+ 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);
+ }
+
EmitBlock(DeleteEnd);
}
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=87083&r1=87082&r2=87083&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Nov 12 22:45:41 2009
@@ -883,8 +883,11 @@
const Decl *TargetDecl = 0);
RValue EmitCallExpr(const CallExpr *E);
- llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
+ llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
const llvm::Type *Ty);
+ llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
+ llvm::Value *&This, const llvm::Type *Ty);
+
RValue EmitCXXMemberCall(const CXXMethodDecl *MD,
llvm::Value *Callee,
llvm::Value *This,
More information about the cfe-commits
mailing list