diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-01-20 17:19:02 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-01-20 17:19:02 +0000 |
commit | 2726267f094a0c1f5ac5b501ec5a9898c58876bf (patch) | |
tree | dc61f39188448cc2b42cd6ddd6351b3c2466f3d8 /lib/CodeGen/CGCXX.cpp | |
parent | 14cc9451de4a9539bf79e4e5d63248c2377426db (diff) |
apple kext abi requires all vf calls, including qualified
vf calls, be made indirect. This patch is towards that goal.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index bb217fbcc9..b6381de027 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -306,6 +306,35 @@ CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This, return ::BuildVirtualCall(*this, VTableIndex, This, Ty); } +/// BuildVirtualCall - This routine is to support gcc's kext ABI making +/// indirect call to virtual functions. It makes the call through indexing +/// into the vtable. +llvm::Value * +CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, + NestedNameSpecifier *Qual, + llvm::Value *This, + const llvm::Type *Ty) { + llvm::Value *VTable = 0; + assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) && + "BuildAppleKextVirtualCall - bad Qual kind"); + + const Type *QTy = Qual->getAsType(); + QualType T = QualType(QTy, 0); + const RecordType *RT = T->getAs<RecordType>(); + assert(RT && "BuildAppleKextVirtualCall - Qual type must be record"); + const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); + VTable = CGM.getVTables().GetAddrOfVTable(RD); + Ty = Ty->getPointerTo()->getPointerTo(); + VTable = Builder.CreateBitCast(VTable, Ty); + assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); + MD = MD->getCanonicalDecl(); + uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD); + VTableIndex += 2; + llvm::Value *VFuncPtr = + CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); + return CGF.Builder.CreateLoad(VFuncPtr); +} + llvm::Value * CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, llvm::Value *This, const llvm::Type *Ty) { |