aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-02-01 23:22:34 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-02-01 23:22:34 +0000
commitccd5259d33cbbdd6f5fbf7ccab4cb4a2702309ea (patch)
treefbbf276e87148ef59204fd1cf98a467bccc3556d /lib/CodeGen/CGCXX.cpp
parent110a68e38bb37526f9bd1d4e8f1b941fe5410b27 (diff)
-fapple-kext support for indirect call to virtuals dtors - wip.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124701 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index c9c95883c7..a4145675b3 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -323,6 +323,10 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
const RecordType *RT = T->getAs<RecordType>();
assert(RT && "BuildAppleKextVirtualCall - Qual type must be record");
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
+ return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD);
+
VTable = CGM.getVTables().GetAddrOfVTable(RD);
Ty = Ty->getPointerTo()->getPointerTo();
VTable = Builder.CreateBitCast(VTable, Ty);
@@ -337,6 +341,44 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
return CGF.Builder.CreateLoad(VFuncPtr);
}
+/// BuildVirtualCall - This routine makes indirect vtable call for
+/// call to virtual destructors. It returns 0 if it could not do it.
+llvm::Value *
+CodeGenFunction::BuildAppleKextVirtualDestructorCall(
+ const CXXDestructorDecl *DD,
+ CXXDtorType Type,
+ const CXXRecordDecl *RD) {
+ llvm::Value * Callee = 0;
+ const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD);
+ // FIXME. Dtor_Base dtor is always direct!!
+ // It need be somehow inline expanded into the caller.
+ // -O does that. But need to support -O0 as well.
+ if (MD->isVirtual() && Type != Dtor_Base) {
+ DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
+ // Compute the function type we're calling.
+ const CGFunctionInfo *FInfo =
+ &CGM.getTypes().getFunctionInfo(cast<CXXDestructorDecl>(MD),
+ Dtor_Complete);
+ const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+ const llvm::Type *Ty
+ = CGM.getTypes().GetFunctionType(*FInfo, FPT->isVariadic());
+ if (!RD)
+ RD = DD->getParent();
+ llvm::Value *VTable = CGM.getVTables().GetAddrOfVTable(RD);
+ Ty = Ty->getPointerTo()->getPointerTo();
+ VTable = Builder.CreateBitCast(VTable, Ty);
+ uint64_t VTableIndex =
+ CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
+ uint64_t AddressPoint =
+ CGM.getVTables().getAddressPoint(BaseSubobject(RD, 0), RD);
+ VTableIndex += AddressPoint;
+ llvm::Value *VFuncPtr =
+ CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
+ Callee = CGF.Builder.CreateLoad(VFuncPtr);
+ }
+ return Callee;
+}
+
llvm::Value *
CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
llvm::Value *This, const llvm::Type *Ty) {