aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorAndy Kaylor <akaylor@nvidia.com>2025-07-21 15:34:46 -0700
committerGitHub <noreply@github.com>2025-07-21 15:34:46 -0700
commit8f26a301bc7caf3d11d1f03818dae77a24e266e9 (patch)
tree050e441313238715c1b334626013b62cd42506b5 /clang/lib
parent5e8e03d859f4367b68ad08311ae0b3f8bf8eea4f (diff)
downloadllvm-8f26a301bc7caf3d11d1f03818dae77a24e266e9.zip
llvm-8f26a301bc7caf3d11d1f03818dae77a24e266e9.tar.gz
llvm-8f26a301bc7caf3d11d1f03818dae77a24e266e9.tar.bz2
[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.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXABI.h5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp23
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenClass.cpp8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp11
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h9
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp24
6 files changed, 75 insertions, 5 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index eb079b8..5929568 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -75,6 +75,11 @@ public:
/// Emit dtor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d) = 0;
+ virtual void emitDestructorCall(CIRGenFunction &cgf,
+ const CXXDestructorDecl *dd, CXXDtorType type,
+ bool forVirtualBase, bool delegating,
+ Address thisAddr, QualType thisTy) = 0;
+
/// Returns true if the given destructor type should be emitted as a linkonce
/// delegating thunk, regardless of whether the dtor is defined in this TU or
/// not.
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
index 8da832d..67d8988 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp
@@ -246,6 +246,29 @@ static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e,
}
}
+RValue CIRGenFunction::emitCXXDestructorCall(
+ GlobalDecl dtor, const CIRGenCallee &callee, mlir::Value thisVal,
+ QualType thisTy, mlir::Value implicitParam, QualType implicitParamTy,
+ const CallExpr *ce) {
+ const CXXMethodDecl *dtorDecl = cast<CXXMethodDecl>(dtor.getDecl());
+
+ assert(!thisTy.isNull());
+ assert(thisTy->getAsCXXRecordDecl() == dtorDecl->getParent() &&
+ "Pointer/Object mixup");
+
+ assert(!cir::MissingFeatures::addressSpace());
+
+ CallArgList args;
+ commonBuildCXXMemberOrOperatorCall(*this, dtorDecl, thisVal, implicitParam,
+ implicitParamTy, ce, args, nullptr);
+ assert((ce || dtor.getDecl()) && "expected source location provider");
+ assert(!cir::MissingFeatures::opCallMustTail());
+ return emitCall(cgm.getTypes().arrangeCXXStructorDeclaration(dtor), callee,
+ ReturnValueSlot(), args, nullptr,
+ ce ? getLoc(ce->getExprLoc())
+ : getLoc(dtor.getDecl()->getSourceRange()));
+}
+
/// Emit a call to an operator new or operator delete function, as implicitly
/// created by new-expressions and delete-expressions.
static RValue emitNewDeleteCall(CIRGenFunction &cgf,
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 8667bb6..fbf53db 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -392,6 +392,14 @@ void CIRGenFunction::emitDelegatingCXXConstructorCall(
}
}
+void CIRGenFunction::emitCXXDestructorCall(const CXXDestructorDecl *dd,
+ CXXDtorType type,
+ bool forVirtualBase, bool delegating,
+ Address thisAddr, QualType thisTy) {
+ cgm.getCXXABI().emitDestructorCall(*this, dd, type, forVirtualBase,
+ delegating, thisAddr, thisTy);
+}
+
Address CIRGenFunction::getAddressOfBaseClass(
Address value, const CXXRecordDecl *derived,
llvm::iterator_range<CastExpr::path_const_iterator> path,
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 7e1a44c..3e69e56 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -593,11 +593,12 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
assert(!cir::MissingFeatures::dtorCleanups());
- // TODO(cir): A complete destructor is supposed to call the base destructor.
- // Since we have to emit both dtor kinds we just fall through for now and.
- // As long as we don't support virtual bases this should be functionally
- // equivalent.
- assert(!cir::MissingFeatures::completeDtors());
+ if (!isTryBody) {
+ QualType thisTy = dtor->getFunctionObjectParameterType();
+ emitCXXDestructorCall(dtor, Dtor_Base, /*forVirtualBase=*/false,
+ /*delegating=*/false, loadCXXThisAddress(), thisTy);
+ break;
+ }
// Fallthrough: act like we're in the base variant.
[[fallthrough]];
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 12484196..2aceeef 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -853,6 +853,15 @@ public:
bool delegating, Address thisAddr,
CallArgList &args, clang::SourceLocation loc);
+ void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type,
+ bool forVirtualBase, bool delegating,
+ Address thisAddr, QualType thisTy);
+
+ RValue emitCXXDestructorCall(GlobalDecl dtor, const CIRGenCallee &callee,
+ mlir::Value thisVal, QualType thisTy,
+ mlir::Value implicitParam,
+ QualType implicitParamTy, const CallExpr *e);
+
mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s,
llvm::ArrayRef<const Attr *> attrs);
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 1496d87..6577f5f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -46,6 +46,11 @@ public:
void emitCXXDestructors(const clang::CXXDestructorDecl *d) override;
void emitCXXStructor(clang::GlobalDecl gd) override;
+ void emitDestructorCall(CIRGenFunction &cgf, const CXXDestructorDecl *dd,
+ CXXDtorType type, bool forVirtualBase,
+ bool delegating, Address thisAddr,
+ QualType thisTy) override;
+
bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
CXXDtorType dt) const override {
// Itanium does not emit any destructor variant as an inline thunk.
@@ -240,6 +245,25 @@ bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
return false;
}
+void CIRGenItaniumCXXABI::emitDestructorCall(
+ CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type,
+ bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy) {
+ GlobalDecl gd(dd, type);
+ if (needsVTTParameter(gd)) {
+ cgm.errorNYI(dd->getSourceRange(), "emitDestructorCall: VTT");
+ }
+
+ mlir::Value vtt = nullptr;
+ ASTContext &astContext = cgm.getASTContext();
+ QualType vttTy = astContext.getPointerType(astContext.VoidPtrTy);
+ assert(!cir::MissingFeatures::appleKext());
+ CIRGenCallee callee =
+ CIRGenCallee::forDirect(cgm.getAddrOfCXXStructor(gd), gd);
+
+ cgf.emitCXXDestructorCall(gd, callee, thisAddr.getPointer(), thisTy, vtt,
+ vttTy, nullptr);
+}
+
CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &cgm) {
switch (cgm.getASTContext().getCXXABIKind()) {
case TargetCXXABI::GenericItanium: