https://github.com/Lancern created https://github.com/llvm/llvm-project/pull/153014
This patch adds CIRGen support for C++ pseudo destructor call expressions. >From 8d567b71514b64222c67937e5fda907af87b7855 Mon Sep 17 00:00:00 2001 From: Sirui Mu <msrlanc...@gmail.com> Date: Mon, 11 Aug 2025 22:29:39 +0800 Subject: [PATCH] [CIR] Add CIRGen for pseudo destructor calls --- clang/include/clang/CIR/MissingFeatures.h | 1 - clang/lib/CIR/CodeGen/CIRGenCall.h | 21 ++++++++++++++ clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 10 +++---- clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 34 +++++++++++++++++++++++ clang/lib/CIR/CodeGen/CIRGenFunction.h | 4 ++- clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/test/CIR/CodeGen/call.cpp | 16 ++++++++++- 7 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index fcc8ce7caf111..f410be4293aef 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -87,7 +87,6 @@ struct MissingFeatures { static bool setFunctionAttributes() { return false; } // CallOp handling - static bool opCallPseudoDtor() { return false; } static bool opCallAggregateArgs() { return false; } static bool opCallPaddingArgs() { return false; } static bool opCallABIExtendArg() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h index 28576a15068fa..47d998ae25838 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.h +++ b/clang/lib/CIR/CodeGen/CIRGenCall.h @@ -46,6 +46,7 @@ class CIRGenCallee { enum class SpecialKind : uintptr_t { Invalid, Builtin, + PseudoDestructor, Last = Builtin, }; @@ -54,12 +55,16 @@ class CIRGenCallee { const clang::FunctionDecl *decl; unsigned id; }; + struct PseudoDestructorInfoStorage { + const clang::CXXPseudoDestructorExpr *expr; + }; SpecialKind kindOrFunctionPtr; union { CIRGenCalleeInfo abstractInfo; BuiltinInfoStorage builtinInfo; + PseudoDestructorInfoStorage pseudoDestructorInfo; }; explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {} @@ -98,6 +103,22 @@ class CIRGenCallee { return result; } + static CIRGenCallee + forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr) { + CIRGenCallee result(SpecialKind::PseudoDestructor); + result.pseudoDestructorInfo.expr = expr; + return result; + } + + bool isPseudoDestructor() const { + return kindOrFunctionPtr == SpecialKind::PseudoDestructor; + } + + const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const { + assert(isPseudoDestructor()); + return pseudoDestructorInfo.expr; + } + bool isOrdinary() const { return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index c437b14dd8d1c..54f8cd8859b7b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -1543,10 +1543,10 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) { cgm.errorNYI(e->getSourceRange(), "emitCallee: call to member function is NYI"); return {}; + } else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) { + return CIRGenCallee::forPseudoDestructor(pde); } - assert(!cir::MissingFeatures::opCallPseudoDtor()); - // Otherwise, we have an indirect reference. mlir::Value calleePtr; QualType functionType; @@ -1598,10 +1598,8 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e, return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e, returnValue); - if (isa<CXXPseudoDestructorExpr>(e->getCallee())) { - cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor"); - } - assert(!cir::MissingFeatures::opCallPseudoDtor()); + if (callee.isPseudoDestructor()) + return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr()); return emitCall(e->getCallee()->getType(), callee, e, returnValue); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp new file mode 100644 index 0000000000000..55847da7c9493 --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -0,0 +1,34 @@ +//===--- CIRGenExprCXX.cpp - Emit CIR Code for C++ expressions ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This contains code dealing with code generation of C++ expressions +// +//===----------------------------------------------------------------------===// + +#include "CIRGenFunction.h" +#include "clang/AST/ExprCXX.h" + +using namespace clang; +using namespace clang::CIRGen; + +RValue CIRGenFunction::emitCXXPseudoDestructorExpr( + const CXXPseudoDestructorExpr *expr) { + QualType destroyedType = expr->getDestroyedType(); + if (destroyedType.hasStrongOrWeakObjCLifetime()) { + assert(!cir::MissingFeatures::objCLifetime()); + } else { + // C++ [expr.pseudo]p1: + // The result shall only be used as the operand for the function call + // operator (), and the result of such a call has type void. The only + // effect is the evaluation of the postfix-expression before the dot or + // arrow. + emitIgnoredExpr(expr->getBase()); + } + + return RValue::get(nullptr); +} diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 065039ec041e0..a6cb958de4130 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1032,6 +1032,8 @@ class CIRGenFunction : public CIRGenTypeCache { const CXXMethodDecl *md, ReturnValueSlot returnValue); + RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr); + void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args); @@ -1197,7 +1199,7 @@ class CIRGenFunction : public CIRGenTypeCache { /// reasonable to just ignore the returned alignment when it isn't from an /// explicit source. Address emitPointerWithAlignment(const clang::Expr *expr, - LValueBaseInfo *baseInfo); + LValueBaseInfo *baseInfo = nullptr); /// Emits a reference binding to the passed in expression. RValue emitReferenceBindingToExpr(const Expr *e); diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt index ca3a329d0c56d..a095b896cb0a8 100644 --- a/clang/lib/CIR/CodeGen/CMakeLists.txt +++ b/clang/lib/CIR/CodeGen/CMakeLists.txt @@ -22,6 +22,7 @@ add_clang_library(clangCIR CIRGenExprAggregate.cpp CIRGenExprComplex.cpp CIRGenExprConstant.cpp + CIRGenExprCXX.cpp CIRGenExprScalar.cpp CIRGenFunction.cpp CIRGenItaniumCXXABI.cpp diff --git a/clang/test/CIR/CodeGen/call.cpp b/clang/test/CIR/CodeGen/call.cpp index 43e5d150a949f..3e8cfc1cceb51 100644 --- a/clang/test/CIR/CodeGen/call.cpp +++ b/clang/test/CIR/CodeGen/call.cpp @@ -116,4 +116,18 @@ void f14() { // LLVM: call void @_Z3f13v() #[[LLVM_ATTR_0:.+]] // LLVM: } -// LLLVM: attributes #[[LLVM_ATTR_0]] = { nounwind } +int f15(); +void f16() { + using T = int; + f15().~T(); +} + +// CIR-LABEL: @_Z3f16v +// CIR-NEXT: %{{.+}} = cir.call @_Z3f15v() : () -> !s32i +// CIR: } + +// LLVM-LABEL: define{{.+}} void @_Z3f16v() { +// LLVM-NEXT: %{{.+}} = call i32 @_Z3f15v() +// LLVM: } + +// LLVM: attributes #[[LLVM_ATTR_0]] = { nounwind } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits