https://github.com/adams381 created
https://github.com/llvm/llvm-project/pull/188092
Add LLVM type converter entries for `DataMemberType` (→ `i64`) and `MethodType`
(→ `{i64, i64}`) so that structs containing member pointers don't crash during
CIR-to-LLVM lowering.
Also fix `isZeroInitializable` for `MemberPointerType`. The old code
unconditionally emitted `errorNYI`. In the Itanium ABI, member function
pointers are zero-initializable (null is `{0, 0}`), but member data pointers
are not (null is `-1`).
>From 90cc52f68b5ec11038004393eca151276a994971 Mon Sep 17 00:00:00 2001
From: Adam Smith <[email protected]>
Date: Mon, 23 Mar 2026 10:49:45 -0700
Subject: [PATCH] [CIR][ABI] Add member pointer type lowering and fix
isZeroInitializable
Implement LLVM type conversions for DataMemberType (to i64) and
MethodType (to {i64, i64}) so that structs containing member pointers
can be lowered to LLVM IR.
Fix isZeroInitializable for MemberPointerType: member function
pointers are zero-initializable (null = {0, 0}), but member data
pointers are not (null = -1 in Itanium ABI).
Made-with: Cursor
---
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 9 ++++-----
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 8 ++++++++
clang/test/CIR/CodeGen/nonzeroinit-struct.cpp | 7 ++-----
clang/test/CIR/CodeGen/pointer-to-data-member.cpp | 6 ++++++
4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 2092964bac065..89004577e0570 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -652,11 +652,10 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) {
if (const auto *rd = t->getAsRecordDecl())
return isZeroInitializable(rd);
- if (t->getAs<MemberPointerType>()) {
- cgm.errorNYI(SourceLocation(), "isZeroInitializable for MemberPointerType",
- t);
- return false;
- }
+ // Itanium ABI: member function pointers are zero-initializable
+ // (null = {0, 0}), but member data pointers are not (null = -1).
+ if (const auto *mpt = t->getAs<MemberPointerType>())
+ return mpt->isMemberFunctionPointer();
return true;
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 9fa0e720e1591..7e4d2d74ce713 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3454,6 +3454,14 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter
&converter,
converter.addConversion([&](cir::VoidType type) -> mlir::Type {
return mlir::LLVM::LLVMVoidType::get(type.getContext());
});
+ converter.addConversion([&](cir::DataMemberType type) -> mlir::Type {
+ return mlir::IntegerType::get(type.getContext(), 64);
+ });
+ converter.addConversion([&](cir::MethodType type) -> mlir::Type {
+ auto i64 = mlir::IntegerType::get(type.getContext(), 64);
+ return mlir::LLVM::LLVMStructType::getLiteral(type.getContext(),
+ {i64, i64});
+ });
}
static void buildCtorDtorList(
diff --git a/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
b/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
index 871a028901947..d6dcc91004752 100644
--- a/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
+++ b/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
@@ -10,11 +10,8 @@ struct Trivial {
decltype(&Other::x) ptr;
};
-// This case has a trivial default constructor, but can't be zero-initialized.
+// This case has a trivial default constructor, but can't be zero-initialized
+// because it contains a data member pointer (null = -1 in Itanium ABI).
Trivial t;
-// Since the case above isn't handled yet, we want a test that verifies that
-// we're failing for the right reason.
-
-// expected-error@*:* {{ClangIR code gen Not Yet Implemented:
isZeroInitializable for MemberPointerType}}
// expected-error@*:* {{ClangIR code gen Not Yet Implemented:
tryEmitPrivateForVarInit: non-zero-initializable cxx record}}
diff --git a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
index 3d88b989d23cb..0251f33528b60 100644
--- a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
@@ -349,3 +349,9 @@ auto test_null_incomplete() -> int Incomplete::* {
// OGCG: define {{.*}} i64 @_Z20test_null_incompletev()
// OGCG: ret i64 -1
+
+// Struct containing a member data pointer can be lowered.
+struct StructWithMDP { char *a; int Point::* b; };
+void take_struct_mdp(StructWithMDP s) { (void)s; }
+// LLVM: define {{.*}} void
@_Z15take_struct_mdp13StructWithMDP(%struct.StructWithMDP %{{.*}})
+// OGCG: define {{.*}} void @_Z15take_struct_mdp13StructWithMDP(ptr %{{.*}},
i64 %{{.*}})
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits