Skip to content

Commit

Permalink
[CodeGen] Add public function to emit C++ destructor call.
Browse files Browse the repository at this point in the history
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: swiftlang/swift#32291

Differential Revision: https://reviews.llvm.org/D82392
  • Loading branch information
zoecarver authored and memfrob committed Oct 4, 2022
1 parent fe77b58 commit 64eab5f
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 3 deletions.
9 changes: 9 additions & 0 deletions clang/include/clang/CodeGen/CodeGenABITypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -40,6 +42,7 @@ class Type;
namespace clang {
class ASTContext;
class CXXConstructorDecl;
class CXXDestructorDecl;
class CXXRecordDecl;
class CXXMethodDecl;
class CodeGenOptions;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion clang/lib/CodeGen/ABIInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ namespace clang {

namespace CodeGen {
class ABIArgInfo;
class Address;
class CGCXXABI;
class CGFunctionInfo;
class CodeGenFunction;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/CGCXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,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,
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CodeGen/CodeGenABITypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
16 changes: 15 additions & 1 deletion clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,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,
Expand Down Expand Up @@ -1693,13 +1699,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;
Expand Down
17 changes: 16 additions & 1 deletion clang/lib/CodeGen/MicrosoftCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down

0 comments on commit 64eab5f

Please sign in to comment.