[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
Douglas Gregor
dgregor at apple.com
Thu Jan 20 16:06:29 PST 2011
On Jan 20, 2011, at 9:19 AM, Fariborz Jahanian wrote:
> 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);
> +}
I'm really confused about something... why can't we just use BuildVirtualCall for kext calls? And where does the +2 adjustment for VTableIndex come from?
> 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();
I'd rather update canDevirtualizeMemberFunctionCalls() with a getLangOptions().AppleKext check, rather than updating all of the potentially-devirtualizing callers of canDevirtualizeMemberFunctionCalls().
> 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
I'd feel a little more comfortable if this check looked for the indirect call, rather than looking for the absence of a direct call. Plus, we should be checking for that +2 adjustment in the generated IR.
- Doug
More information about the cfe-commits
mailing list