diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-02-01 23:22:34 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-02-01 23:22:34 +0000 |
commit | ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309ea (patch) | |
tree | fbbf276e87148ef59204fd1cf98a467bccc3556d /lib/CodeGen/CGCXX.cpp | |
parent | 110a68e38bb37526f9bd1d4e8f1b941fe5410b27 (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.cpp | 42 |
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) { |