https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/178074

>From 8488600bed78dae304e8a21457bb7e1ef8e89a7d Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Mon, 26 Jan 2026 14:36:12 -0800
Subject: [PATCH 1/2] [CIR] Add support for member pointer constants

This adds support for initializing global variables of type pointer-to-member
that pointer to member functions.
---
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp     | 10 +++++++---
 .../CIR/Dialect/Transforms/CXXABILowering.cpp    |  5 +++++
 .../test/CIR/CodeGen/pointer-to-member-func.cpp  | 16 ++++++++++++++++
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index ecb65d901de54..ceacf4180591f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -1884,9 +1884,13 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
       return {};
     }
 
-    if (isa<CXXMethodDecl>(memberDecl)) {
-      cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer to 
method");
-      return {};
+    if (auto cxxDecl = dyn_cast<CXXMethodDecl>(memberDecl)) {
+      auto ty = mlir::cast<cir::MethodType>(cgm.convertType(destType));
+      if (cxxDecl->isVirtual())
+        return cgm.getCXXABI().buildVirtualMethodAttr(ty, cxxDecl);
+
+      cir::FuncOp methodFuncOp = cgm.getAddrOfFunction(cxxDecl);
+      return cgm.getBuilder().getMethodAttr(ty, methodFuncOp);
     }
 
     auto cirTy = mlir::cast<cir::DataMemberType>(cgm.convertType(destType));
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp 
b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
index c8e06fed50cf9..dff0484a53d73 100644
--- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -264,6 +264,11 @@ mlir::LogicalResult 
CIRGlobalOpABILowering::matchAndRewrite(
         mlir::cast_if_present<cir::DataMemberAttr>(op.getInitialValueAttr());
     loweredInit = lowerModule->getCXXABI().lowerDataMemberConstant(
         init, layout, *getTypeConverter());
+  } else if (mlir::isa<cir::MethodType>(ty)) {
+    cir::MethodAttr init =
+        mlir::cast_if_present<cir::MethodAttr>(op.getInitialValueAttr());
+    loweredInit = lowerModule->getCXXABI().lowerMethodConstant(
+        init, layout, *getTypeConverter());
   } else {
     llvm_unreachable(
         "inputs to cir.global in ABI lowering must be data member or method");
diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp 
b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
index 4dedee3e48c45..21238f2eda859 100644
--- a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
@@ -12,6 +12,22 @@ struct Foo {
   virtual void m3(int);
 };
 
+// Global pointer to non-virtual method
+void (Foo::*m1_ptr)(int) = &Foo::m1;
+
+// CIR-BEFORE: cir.global external @m1_ptr = #cir.method<@_ZN3Foo2m1Ei> : 
!cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-AFTER: cir.global external @m1_ptr = 
#cir.const_record<{#cir.global_view<@_ZN3Foo2m1Ei> : !s64i, #cir.int<0> : 
!s64i}> : !rec_anon_struct
+// LLVM: @m1_ptr = global { i64, i64 } { i64 ptrtoint (ptr @_ZN3Foo2m1Ei to 
i64), i64 0 }
+// OGCG: @m1_ptr = global { i64, i64 } { i64 ptrtoint (ptr @_ZN3Foo2m1Ei to 
i64), i64 0 }
+
+// Global pointer to virtual method
+void (Foo::*m2_ptr)(int) = &Foo::m2;
+
+// CIR-BEFORE: cir.global external @m2_ptr = #cir.method<vtable_offset = 0> : 
!cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-AFTER: cir.global external @m2_ptr = #cir.const_record<{#cir.int<1> : 
!s64i, #cir.int<0> : !s64i}> : !rec_anon_struct
+// LLVM: @m2_ptr = global { i64, i64 } { i64 1, i64 0 }
+// OGCG: @m2_ptr = global { i64, i64 } { i64 1, i64 0 }
+
 auto make_non_virtual() -> void (Foo::*)(int) {
   return &Foo::m1;
 }

>From 903699036f29bff1dc3aafbd022297ec2d6e2b15 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Mon, 26 Jan 2026 16:48:33 -0800
Subject: [PATCH 2/2] Address review feedback

---
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index ceacf4180591f..0c756d8456682 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -1884,7 +1884,7 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
       return {};
     }
 
-    if (auto cxxDecl = dyn_cast<CXXMethodDecl>(memberDecl)) {
+    if (auto const *cxxDecl = dyn_cast<CXXMethodDecl>(memberDecl)) {
       auto ty = mlir::cast<cir::MethodType>(cgm.convertType(destType));
       if (cxxDecl->isVirtual())
         return cgm.getCXXABI().buildVirtualMethodAttr(ty, cxxDecl);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to