diff options
author | Andy Kaylor <akaylor@nvidia.com> | 2025-07-21 15:34:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-21 15:34:46 -0700 |
commit | 8f26a301bc7caf3d11d1f03818dae77a24e266e9 (patch) | |
tree | 050e441313238715c1b334626013b62cd42506b5 /clang/lib | |
parent | 5e8e03d859f4367b68ad08311ae0b3f8bf8eea4f (diff) | |
download | llvm-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.h | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp | 23 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenClass.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 9 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 24 |
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: |