From 9846c48ddb8d1f99a42dd429c491f120e18ad1f4 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Wed, 1 Jul 2020 10:57:45 -0700 Subject: [PATCH] [CodeGen] Add public function to emit C++ destructor call. Adds `CodeGen::getCXXDestructorImplicitParam`, to retrieve a C++ destructor's implicit parameter (after the "this" pointer) based on the ABI in the given CodeGenModule. This will allow other frontends (Swift, for example) to easily emit calls to object destructors with correct ABI semantics and calling convetions. This is needed for Swift C++ interop. Here's the corresponding Swift change: https://github.com/apple/swift/pull/32291 Differential Revision: https://reviews.llvm.org/D82392 --- clang/include/clang/CodeGen/CodeGenABITypes.h | 9 +++++++++ clang/lib/CodeGen/ABIInfo.h | 1 - clang/lib/CodeGen/CGCXXABI.h | 7 +++++++ clang/lib/CodeGen/CodeGenABITypes.cpp | 13 +++++++++++++ clang/lib/CodeGen/ItaniumCXXABI.cpp | 16 +++++++++++++++- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 17 ++++++++++++++++- 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 0b5031df0b5cb..7a21e8bcff358 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -25,7 +25,9 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/Type.h" +#include "clang/Basic/ABI.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "llvm/IR/BasicBlock.h" namespace llvm { class AttrBuilder; @@ -40,6 +42,7 @@ namespace llvm { namespace clang { class ASTContext; class CXXConstructorDecl; +class CXXDestructorDecl; class CXXRecordDecl; class CXXMethodDecl; class CodeGenOptions; @@ -90,6 +93,12 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, ImplicitCXXConstructorArgs getImplicitCXXConstructorArgs(CodeGenModule &CGM, const CXXConstructorDecl *D); +llvm::Value * +getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, + llvm::BasicBlock::iterator InsertPoint, + const CXXDestructorDecl *D, CXXDtorType Type, + bool ForVirtualBase, bool Delegating); + /// Returns null if the function type is incomplete and can't be lowered. llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD); diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index 0c3a076da0b58..3b6573f15e7aa 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -28,7 +28,6 @@ namespace clang { namespace CodeGen { class ABIArgInfo; - class Address; class CGCXXABI; class CGFunctionInfo; class CodeGenFunction; diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index f5f378510950b..83aaf50d4abba 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -400,6 +400,13 @@ class CGCXXABI { CXXCtorType Type, bool ForVirtualBase, bool Delegating, CallArgList &Args); + /// Get the implicit (second) parameter that comes after the "this" pointer, + /// or nullptr if there is isn't one. + virtual llvm::Value * + getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) = 0; + /// Emit the destructor call. virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp index 322cf45c47af8..d3a16a1d5accf 100644 --- a/clang/lib/CodeGen/CodeGenABITypes.cpp +++ b/clang/lib/CodeGen/CodeGenABITypes.cpp @@ -115,3 +115,16 @@ unsigned CodeGen::getLLVMFieldNumber(CodeGenModule &CGM, const FieldDecl *FD) { return CGM.getTypes().getCGRecordLayout(RD).getLLVMFieldNo(FD); } + +llvm::Value *CodeGen::getCXXDestructorImplicitParam( + CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, + llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, + CXXDtorType Type, bool ForVirtualBase, bool Delegating) { + CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); + CGF.CurCodeDecl = D; + CGF.CurFuncDecl = D; + CGF.CurFn = InsertBlock->getParent(); + CGF.Builder.SetInsertPoint(InsertBlock, InsertPoint); + return CGM.getCXXABI().getCXXDestructorImplicitParam( + CGF, D, Type, ForVirtualBase, Delegating); +} diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index e31285e6eaddc..a829a6d1deea3 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -229,6 +229,12 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { bool ForVirtualBase, bool Delegating) override; + llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, + CXXDtorType Type, + bool ForVirtualBase, + bool Delegating) override; + void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, @@ -1717,13 +1723,21 @@ CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs( return AddedStructorArgs::prefix({{VTT, VTTTy}}); } +llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam( + CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) { + GlobalDecl GD(DD, Type); + return CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); +} + void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy) { GlobalDecl GD(DD, Type); - llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); + llvm::Value *VTT = + getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating); QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); CGCallee Callee; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index f4281959a22cf..577980ba71ed7 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -259,6 +259,12 @@ class MicrosoftCXXABI : public CGCXXABI { bool ForVirtualBase, bool Delegating) override; + llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, + CXXDtorType Type, + bool ForVirtualBase, + bool Delegating) override; + void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, @@ -1577,6 +1583,12 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs( return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}}); } +llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam( + CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) { + return nullptr; +} + void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, @@ -1603,8 +1615,11 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF); } + llvm::Value *Implicit = + getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, + Delegating); // = nullptr CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, - /*ImplicitParam=*/nullptr, + /*ImplicitParam=*/Implicit, /*ImplicitParamTy=*/QualType(), nullptr); if (BaseDtorEndBB) { // Complete object handler should continue to be the remaining