Skip to content

Commit 8f26a30

Browse files
authored
[CIR] Add complete destructor handling (#149552)
The initial implementation for emitting destructors emitted the complete destructor body for both D1 and D2 destructors. This change updates the code to have the D1 destructor call the D2 destructor.
1 parent 5e8e03d commit 8f26a30

File tree

8 files changed

+77
-8
lines changed

8 files changed

+77
-8
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,6 @@ struct MissingFeatures {
252252
static bool writebacks() { return false; }
253253
static bool appleKext() { return false; }
254254
static bool dtorCleanups() { return false; }
255-
static bool completeDtors() { return false; }
256255
static bool vtableInitialization() { return false; }
257256
static bool msvcBuiltins() { return false; }
258257

clang/lib/CIR/CodeGen/CIRGenCXXABI.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ class CIRGenCXXABI {
7575
/// Emit dtor variants required by this ABI.
7676
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d) = 0;
7777

78+
virtual void emitDestructorCall(CIRGenFunction &cgf,
79+
const CXXDestructorDecl *dd, CXXDtorType type,
80+
bool forVirtualBase, bool delegating,
81+
Address thisAddr, QualType thisTy) = 0;
82+
7883
/// Returns true if the given destructor type should be emitted as a linkonce
7984
/// delegating thunk, regardless of whether the dtor is defined in this TU or
8085
/// not.

clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,29 @@ static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e,
246246
}
247247
}
248248

249+
RValue CIRGenFunction::emitCXXDestructorCall(
250+
GlobalDecl dtor, const CIRGenCallee &callee, mlir::Value thisVal,
251+
QualType thisTy, mlir::Value implicitParam, QualType implicitParamTy,
252+
const CallExpr *ce) {
253+
const CXXMethodDecl *dtorDecl = cast<CXXMethodDecl>(dtor.getDecl());
254+
255+
assert(!thisTy.isNull());
256+
assert(thisTy->getAsCXXRecordDecl() == dtorDecl->getParent() &&
257+
"Pointer/Object mixup");
258+
259+
assert(!cir::MissingFeatures::addressSpace());
260+
261+
CallArgList args;
262+
commonBuildCXXMemberOrOperatorCall(*this, dtorDecl, thisVal, implicitParam,
263+
implicitParamTy, ce, args, nullptr);
264+
assert((ce || dtor.getDecl()) && "expected source location provider");
265+
assert(!cir::MissingFeatures::opCallMustTail());
266+
return emitCall(cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,
267+
ReturnValueSlot(), args, nullptr,
268+
ce ? getLoc(ce->getExprLoc())
269+
: getLoc(dtor.getDecl()->getSourceRange()));
270+
}
271+
249272
/// Emit a call to an operator new or operator delete function, as implicitly
250273
/// created by new-expressions and delete-expressions.
251274
static RValue emitNewDeleteCall(CIRGenFunction &cgf,

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,14 @@ void CIRGenFunction::emitDelegatingCXXConstructorCall(
392392
}
393393
}
394394

395+
void CIRGenFunction::emitCXXDestructorCall(const CXXDestructorDecl *dd,
396+
CXXDtorType type,
397+
bool forVirtualBase, bool delegating,
398+
Address thisAddr, QualType thisTy) {
399+
cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
400+
delegating, thisAddr, thisTy);
401+
}
402+
395403
Address CIRGenFunction::getAddressOfBaseClass(
396404
Address value, const CXXRecordDecl *derived,
397405
llvm::iterator_range<CastExpr::path_const_iterator> path,

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,12 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
593593

594594
assert(!cir::MissingFeatures::dtorCleanups());
595595

596-
// TODO(cir): A complete destructor is supposed to call the base destructor.
597-
// Since we have to emit both dtor kinds we just fall through for now and.
598-
// As long as we don't support virtual bases this should be functionally
599-
// equivalent.
600-
assert(!cir::MissingFeatures::completeDtors());
596+
if (!isTryBody) {
597+
QualType thisTy = dtor->getFunctionObjectParameterType();
598+
emitCXXDestructorCall(dtor, Dtor_Base, /*forVirtualBase=*/false,
599+
/*delegating=*/false, loadCXXThisAddress(), thisTy);
600+
break;
601+
}
601602

602603
// Fallthrough: act like we're in the base variant.
603604
[[fallthrough]];

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,15 @@ class CIRGenFunction : public CIRGenTypeCache {
853853
bool delegating, Address thisAddr,
854854
CallArgList &args, clang::SourceLocation loc);
855855

856+
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type,
857+
bool forVirtualBase, bool delegating,
858+
Address thisAddr, QualType thisTy);
859+
860+
RValue emitCXXDestructorCall(GlobalDecl dtor, const CIRGenCallee &callee,
861+
mlir::Value thisVal, QualType thisTy,
862+
mlir::Value implicitParam,
863+
QualType implicitParamTy, const CallExpr *e);
864+
856865
mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s,
857866
llvm::ArrayRef<const Attr *> attrs);
858867

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
4646
void emitCXXDestructors(const clang::CXXDestructorDecl *d) override;
4747
void emitCXXStructor(clang::GlobalDecl gd) override;
4848

49+
void emitDestructorCall(CIRGenFunction &cgf, const CXXDestructorDecl *dd,
50+
CXXDtorType type, bool forVirtualBase,
51+
bool delegating, Address thisAddr,
52+
QualType thisTy) override;
53+
4954
bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
5055
CXXDtorType dt) const override {
5156
// Itanium does not emit any destructor variant as an inline thunk.
@@ -240,6 +245,25 @@ bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
240245
return false;
241246
}
242247

248+
void CIRGenItaniumCXXABI::emitDestructorCall(
249+
CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type,
250+
bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy) {
251+
GlobalDecl gd(dd, type);
252+
if (needsVTTParameter(gd)) {
253+
cgm.errorNYI(dd->getSourceRange(), "emitDestructorCall: VTT");
254+
}
255+
256+
mlir::Value vtt = nullptr;
257+
ASTContext &astContext = cgm.getASTContext();
258+
QualType vttTy = astContext.getPointerType(astContext.VoidPtrTy);
259+
assert(!cir::MissingFeatures::appleKext());
260+
CIRGenCallee callee =
261+
CIRGenCallee::forDirect(cgm.getAddrOfCXXStructor(gd), gd);
262+
263+
cgf.emitCXXDestructorCall(gd, callee, thisAddr.getPointer(), thisTy, vtt,
264+
vttTy, nullptr);
265+
}
266+
243267
CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &cgm) {
244268
switch (cgm.getASTContext().getCXXABIKind()) {
245269
case TargetCXXABI::GenericItanium:

clang/test/CIR/CodeGen/destructors.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ out_of_line_destructor::~out_of_line_destructor() {
3131
// OGCG: ret void
3232

3333
// CIR: cir.func dso_local @_ZN22out_of_line_destructorD1Ev(%{{.+}}: !cir.ptr<!rec_out_of_line_destructor>
34-
// CIR: cir.call @_Z13some_functionv() nothrow : () -> ()
34+
// CIR: cir.call @_ZN22out_of_line_destructorD2Ev(%{{.*}}) nothrow : (!cir.ptr<!rec_out_of_line_destructor>)
3535
// CIR: cir.return
3636

3737
// LLVM: define dso_local void @_ZN22out_of_line_destructorD1Ev(ptr %{{.+}})
38-
// LLVM: call void @_Z13some_functionv()
38+
// LLVM: call void @_ZN22out_of_line_destructorD2Ev
3939
// LLVM: ret void
4040

4141
// OGCG: define dso_local void @_ZN22out_of_line_destructorD1Ev(ptr {{.*}}%{{.+}})

0 commit comments

Comments
 (0)