[cfe-commits] r123922 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/apple-kext-indirect-call.C
Fariborz Jahanian
fjahanian at apple.com
Thu Jan 20 09:19:02 PST 2011
Author: fjahanian
Date: Thu Jan 20 11:19:02 2011
New Revision: 123922
URL: http://llvm.org/viewvc/llvm-project?rev=123922&view=rev
Log:
apple kext abi requires all vf calls, including qualified
vf calls, be made indirect. This patch is towards that goal.
Added:
cfe/trunk/test/CodeGenCXX/apple-kext-indirect-call.C
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.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=123922&r1=123921&r2=123922&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Jan 20 11:19:02 2011
@@ -306,6 +306,35 @@
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) {
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=123922&r1=123921&r2=123922&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Jan 20 11:19:02 2011
@@ -172,8 +172,12 @@
//
// We also don't emit a virtual call if the base expression has a record type
// because then we know what the type is.
- bool UseVirtualCall = MD->isVirtual() && !ME->hasQualifier()
+ bool UseVirtualCall;
+ if (!getContext().getLangOptions().AppleKext)
+ UseVirtualCall = MD->isVirtual() && !ME->hasQualifier()
&& !canDevirtualizeMemberFunctionCalls(ME->getBase(), MD);
+ else
+ UseVirtualCall = MD->isVirtual();
llvm::Value *Callee;
if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
@@ -186,7 +190,12 @@
dyn_cast<CXXConstructorDecl>(MD)) {
Callee = CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty);
} else if (UseVirtualCall) {
- Callee = BuildVirtualCall(MD, This, Ty);
+ if (getContext().getLangOptions().AppleKext &&
+ ME->hasQualifier()) {
+ Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), This, Ty);
+ }
+ else
+ Callee = BuildVirtualCall(MD, This, Ty);
} else {
Callee = CGM.GetAddrOfFunction(MD, Ty);
}
@@ -267,7 +276,9 @@
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
FPT->isVariadic());
llvm::Value *Callee;
- if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0), MD))
+ if (MD->isVirtual() &&
+ (getContext().getLangOptions().AppleKext ||
+ !canDevirtualizeMemberFunctionCalls(E->getArg(0), MD)))
Callee = BuildVirtualCall(MD, This, Ty);
else
Callee = CGM.GetAddrOfFunction(MD, Ty);
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=123922&r1=123921&r2=123922&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jan 20 11:19:02 2011
@@ -1500,6 +1500,10 @@
const llvm::Type *Ty);
llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
llvm::Value *This, const llvm::Type *Ty);
+ llvm::Value *BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
+ NestedNameSpecifier *Qual,
+ llvm::Value *This,
+ const llvm::Type *Ty);
RValue EmitCXXMemberCall(const CXXMethodDecl *MD,
llvm::Value *Callee,
Added: cfe/trunk/test/CodeGenCXX/apple-kext-indirect-call.C
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/apple-kext-indirect-call.C?rev=123922&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/apple-kext-indirect-call.C (added)
+++ cfe/trunk/test/CodeGenCXX/apple-kext-indirect-call.C Thu Jan 20 11:19:02 2011
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
+
+struct Base {
+ virtual void abc1(void) const;
+ virtual void abc2(void) const;
+ virtual void abc(void) const;
+};
+
+void Base::abc(void) const {}
+
+void FUNC(Base* p) {
+ p->Base::abc();
+}
+
+// CHECK-NOT: call void @_ZNK4Base3abcEv
More information about the cfe-commits
mailing list