diff options
Diffstat (limited to 'clang/lib/CodeGen/ItaniumCXXABI.cpp')
| -rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 24d187f2330..b8dec54a4e3 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -114,7 +114,7 @@ public: llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; - llvm::Value * + CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, @@ -263,9 +263,9 @@ public: llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) override; - llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, - Address This, llvm::Type *Ty, - SourceLocation Loc) override; + CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, + Address This, llvm::Type *Ty, + SourceLocation Loc) override; llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, @@ -520,7 +520,7 @@ ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { /// /// If the member is non-virtual, memptr.ptr is the address of /// the function to call. -llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( +CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CodeGenFunction &CGF, const Expr *E, Address ThisAddr, llvm::Value *&ThisPtrForCall, llvm::Value *MemFnPtr, const MemberPointerType *MPT) { @@ -609,9 +609,11 @@ llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // We're done. CGF.EmitBlock(FnEnd); - llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2); - Callee->addIncoming(VirtualFn, FnVirtual); - Callee->addIncoming(NonVirtualFn, FnNonVirtual); + llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2); + CalleePtr->addIncoming(VirtualFn, FnVirtual); + CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual); + + CGCallee Callee(FPT, CalleePtr); return Callee; } @@ -1448,12 +1450,14 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); - llvm::Value *Callee = nullptr; - if (getContext().getLangOpts().AppleKext) + CGCallee Callee; + if (getContext().getLangOpts().AppleKext && + Type != Dtor_Base && DD->isVirtual()) Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent()); - - if (!Callee) - Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)); + else + Callee = + CGCallee::forDirect(CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)), + DD); CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(), This.getPointer(), VTT, VTTTy, @@ -1598,19 +1602,20 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, return VTable; } -llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, - GlobalDecl GD, - Address This, - llvm::Type *Ty, - SourceLocation Loc) { +CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, + GlobalDecl GD, + Address This, + llvm::Type *Ty, + SourceLocation Loc) { GD = GD.getCanonicalDecl(); Ty = Ty->getPointerTo()->getPointerTo(); auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl()); llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent()); uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); + llvm::Value *VFunc; if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) { - return CGF.EmitVTableTypeCheckedLoad( + VFunc = CGF.EmitVTableTypeCheckedLoad( MethodDecl->getParent(), VTable, VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8); } else { @@ -1618,8 +1623,11 @@ llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); - return CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); + VFunc = CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); } + + CGCallee Callee(MethodDecl, VFunc); + return Callee; } llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( @@ -1631,7 +1639,7 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration( Dtor, getFromDtorType(DtorType)); llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); - llvm::Value *Callee = + CGCallee Callee = getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty, CE ? CE->getLocStart() : SourceLocation()); |

