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
