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

Reply via email to