[clang] [CIR] Fix emission of functions referenced by member-pointer (PR #181452)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 13 18:46:23 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Erich Keane (erichkeane)
<details>
<summary>Changes</summary>
While working on attributes for these, I discovered that when a function was referenced only via a member function pointer (see no-odr-use.cpp test for the example that failed!), that we were incorrectly generating the type of the function to not include the 'this' pointer. This restores that behavior by making sure we generate the type for the member-pointer type correctly.
---
Patch is 21.34 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/181452.diff
6 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+2-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+8-3)
- (modified) clang/test/CIR/CodeGen/no-odr-use.cpp (+17)
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp (+10-10)
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp (+6-6)
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func.cpp (+25-25)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 3b88856f09842..462e73b3acc8d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -1895,7 +1895,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
if (cxxDecl->isVirtual())
return cgm.getCXXABI().buildVirtualMethodAttr(ty, cxxDecl);
- cir::FuncOp methodFuncOp = cgm.getAddrOfFunction(cxxDecl);
+ cir::FuncOp methodFuncOp =
+ cgm.getAddrOfFunction(cxxDecl, ty.getMemberFuncTy());
return cgm.getBuilder().getMethodAttr(ty, methodFuncOp);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 03d5eb860ab81..6a88cda7bf2c5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -540,13 +540,18 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
case Type::MemberPointer: {
const auto *mpt = cast<MemberPointerType>(ty);
- mlir::Type memberTy = convertType(mpt->getPointeeType());
+ NestedNameSpecifier mptNNS = mpt->getQualifier();
auto clsTy = mlir::cast<cir::RecordType>(
- convertType(QualType(mpt->getQualifier().getAsType(), 0)));
+ convertType(QualType(mptNNS.getAsType(), 0)));
if (mpt->isMemberDataPointer()) {
+ mlir::Type memberTy = convertType(mpt->getPointeeType());
resultType = cir::DataMemberType::get(memberTy, clsTy);
} else {
- auto memberFuncTy = mlir::cast<cir::FuncType>(memberTy);
+ auto memberFuncTy =
+ getFunctionType(cgm.getTypes().arrangeCXXMethodType(
+ mptNNS.getAsRecordDecl(),
+ mpt->getPointeeType()->getAs<clang::FunctionProtoType>(),
+ /*methodDecl=*/nullptr));
resultType = cir::MethodType::get(memberFuncTy, clsTy);
}
break;
diff --git a/clang/test/CIR/CodeGen/no-odr-use.cpp b/clang/test/CIR/CodeGen/no-odr-use.cpp
index 5c3476164d8f7..0458183750e68 100644
--- a/clang/test/CIR/CodeGen/no-odr-use.cpp
+++ b/clang/test/CIR/CodeGen/no-odr-use.cpp
@@ -95,6 +95,14 @@ namespace PR42276 {
using l = void (State::*)();
static constexpr l m[]{&State::f1, &State::f2};
};
+ // CIR-CXX11-LABEL: cir.func {{.*}} @_ZN7PR422765State2f1Ev(!cir.ptr<!rec_PR422763A3AState>)
+ // CIR-CXX11-LABEL: cir.func {{.*}} @_ZN7PR422765State2f2Ev(!cir.ptr<!rec_PR422763A3AState>)
+ //
+ // LLVM-CXX11-LABEL: declare{{.*}} @_ZN7PR422765State2f1Ev(ptr)
+ // LLVM-CXX11-LABEL: declare{{.*}} @_ZN7PR422765State2f2Ev(ptr)
+ //
+ // OG-Codegen always generates these deferred, not only if they are non-const.
+ //
// CIR-LABEL: cir.func {{.*}} @_ZN7PR422765State16syncDirtyObjectsEv(
// LLVM-LABEL: define{{.*}} void @_ZN7PR422765State16syncDirtyObjectsEv(
// OGCG-LABEL: define{{.*}} void @_ZN7PR422765State16syncDirtyObjectsEv(
@@ -110,4 +118,13 @@ namespace PR42276 {
// OGCG-CXX2A: getelementptr inbounds [2 x { i64, i64 }], ptr @_ZN7PR422765State1mE, i64 0, i64 %{{.*}}
(this->*m[i])();
}
+ // CIR-CXX2A-LABEL: cir.func {{.*}} @_ZN7PR422765State2f1Ev(!cir.ptr<!rec_PR422763A3AState>)
+ // CIR-CXX2A-LABEL: cir.func {{.*}} @_ZN7PR422765State2f2Ev(!cir.ptr<!rec_PR422763A3AState>)
+ //
+ // LLVM-CXX2A-LABEL: declare{{.*}} @_ZN7PR422765State2f1Ev(ptr)
+ // LLVM-CXX2A-LABEL: declare{{.*}} @_ZN7PR422765State2f2Ev(ptr)
+ //
+ // OGCG-LABEL: declare{{.*}} @_ZN7PR422765State2f1Ev(ptr{{.*}})
+ // OGCG-LABEL: declare{{.*}} @_ZN7PR422765State2f2Ev(ptr{{.*}})
+ //
}
diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp
index 1abb5241f8af9..acc77081a5bc8 100644
--- a/clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp
@@ -21,7 +21,7 @@ bool memfunc_to_bool(void (Foo::*func)(int)) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z15memfunc_to_boolM3FooFviE
-// CIR-BEFORE: %{{.*}} = cir.cast member_ptr_to_bool %{{.*}} : !cir.method<!cir.func<(!s32i)> in !rec_Foo> -> !cir.bool
+// CIR-BEFORE: %{{.*}} = cir.cast member_ptr_to_bool %{{.*}} : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo> -> !cir.bool
// CIR-AFTER: cir.func {{.*}} @_Z15memfunc_to_boolM3FooFviE
// CIR-AFTER: %[[FUNC:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!rec_anon_struct>, !rec_anon_struct
@@ -50,7 +50,7 @@ auto memfunc_reinterpret(void (Foo::*func)(int)) -> void (Bar::*)() {
}
// CIR-BEFORE: cir.func {{.*}} @_Z19memfunc_reinterpretM3FooFviE
-// CIR-BEFORE: %{{.*}} = cir.cast bitcast %{{.*}} : !cir.method<!cir.func<(!s32i)> in !rec_Foo> -> !cir.method<!cir.func<()> in !rec_Bar>
+// CIR-BEFORE: %{{.*}} = cir.cast bitcast %{{.*}} : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo> -> !cir.method<!cir.func<(!cir.ptr<!rec_Bar>)> in !rec_Bar>
// CIR-AFTER: cir.func {{.*}} @_Z19memfunc_reinterpretM3FooFviE
// CIR-AFTER: %[[FUNC:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!rec_anon_struct>, !rec_anon_struct
@@ -93,8 +93,8 @@ DerivedMemFunc base_to_derived_zero_offset(Base1MemFunc ptr) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z27base_to_derived_zero_offsetM5Base1FviE
-// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Base1>>, !cir.method<!cir.func<(!s32i)> in !rec_Base1>
-// CIR-BEFORE: %{{.*}} = cir.derived_method %[[PTR]][0] : !cir.method<!cir.func<(!s32i)> in !rec_Base1> -> !cir.method<!cir.func<(!s32i)> in !rec_Derived>
+// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Base1>, !s32i)> in !rec_Base1>>, !cir.method<!cir.func<(!cir.ptr<!rec_Base1>, !s32i)> in !rec_Base1>
+// CIR-BEFORE: %{{.*}} = cir.derived_method %[[PTR]][0] : !cir.method<!cir.func<(!cir.ptr<!rec_Base1>, !s32i)> in !rec_Base1> -> !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>
// CIR-AFTER: cir.func {{.*}} @_Z27base_to_derived_zero_offsetM5Base1FviE
// CIR-AFTER: %[[PTR:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["ptr", init]
@@ -125,8 +125,8 @@ DerivedMemFunc base_to_derived(Base2MemFunc ptr) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z15base_to_derivedM5Base2FviE
-// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Base2>>, !cir.method<!cir.func<(!s32i)> in !rec_Base2>
-// CIR-BEFORE: %{{.*}} = cir.derived_method %[[PTR]][16] : !cir.method<!cir.func<(!s32i)> in !rec_Base2> -> !cir.method<!cir.func<(!s32i)> in !rec_Derived>
+// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Base2>, !s32i)> in !rec_Base2>>, !cir.method<!cir.func<(!cir.ptr<!rec_Base2>, !s32i)> in !rec_Base2>
+// CIR-BEFORE: %{{.*}} = cir.derived_method %[[PTR]][16] : !cir.method<!cir.func<(!cir.ptr<!rec_Base2>, !s32i)> in !rec_Base2> -> !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>
// CIR-AFTER: cir.func {{.*}} @_Z15base_to_derivedM5Base2FviE
// CIR-AFTER: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!rec_anon_struct>, !rec_anon_struct
@@ -154,8 +154,8 @@ Base1MemFunc derived_to_base_zero_offset(DerivedMemFunc ptr) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z27derived_to_base_zero_offsetM7DerivedFviE
-// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Derived>>, !cir.method<!cir.func<(!s32i)> in !rec_Derived>
-// CIR-BEFORE: %{{.*}} = cir.base_method %[[PTR]][0] : !cir.method<!cir.func<(!s32i)> in !rec_Derived> -> !cir.method<!cir.func<(!s32i)> in !rec_Base1>
+// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>>, !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>
+// CIR-BEFORE: %{{.*}} = cir.base_method %[[PTR]][0] : !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived> -> !cir.method<!cir.func<(!cir.ptr<!rec_Base1>, !s32i)> in !rec_Base1>
// CIR-AFTER: cir.func {{.*}} @_Z27derived_to_base_zero_offsetM7DerivedFviE
// CIR-AFTER: %[[PTR:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["ptr", init]
@@ -186,8 +186,8 @@ Base2MemFunc derived_to_base(DerivedMemFunc ptr) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z15derived_to_baseM7DerivedFviE
-// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Derived>>, !cir.method<!cir.func<(!s32i)> in !rec_Derived>
-// CIR-BEFORE: %{{.*}} = cir.base_method %[[PTR]][16] : !cir.method<!cir.func<(!s32i)> in !rec_Derived> -> !cir.method<!cir.func<(!s32i)> in !rec_Base2>
+// CIR-BEFORE: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>>, !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived>
+// CIR-BEFORE: %{{.*}} = cir.base_method %[[PTR]][16] : !cir.method<!cir.func<(!cir.ptr<!rec_Derived>, !s32i)> in !rec_Derived> -> !cir.method<!cir.func<(!cir.ptr<!rec_Base2>, !s32i)> in !rec_Base2>
// CIR-AFTER: cir.func {{.*}} @_Z15derived_to_baseM7DerivedFviE
// CIR-AFTER: %[[PTR:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!rec_anon_struct>, !rec_anon_struct
diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp
index f00d227e97fe7..a268886d34634 100644
--- a/clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp
@@ -17,9 +17,9 @@ bool cmp_eq(void (Foo::*lhs)(int), void (Foo::*rhs)(int)) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z6cmp_eqM3FooFviES1_
-// CIR-BEFORE: %[[LHS:.*]] = cir.load{{.*}} %0 : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>
-// CIR-BEFORE: %[[RHS:.*]] = cir.load{{.*}} %1 : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>
-// CIR-BEFORE: %[[CMP:.*]] = cir.cmp(eq, %[[LHS]], %[[RHS]]) : !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.bool
+// CIR-BEFORE: %[[LHS:.*]] = cir.load{{.*}} %0 : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>
+// CIR-BEFORE: %[[RHS:.*]] = cir.load{{.*}} %1 : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>
+// CIR-BEFORE: %[[CMP:.*]] = cir.cmp(eq, %[[LHS]], %[[RHS]]) : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.bool
// CIR-BEFORE: cir.store %[[CMP]], %{{.*}} : !cir.bool, !cir.ptr<!cir.bool>
// CIR-AFTER: @_Z6cmp_eqM3FooFviES1_
@@ -71,9 +71,9 @@ bool cmp_ne(void (Foo::*lhs)(int), void (Foo::*rhs)(int)) {
}
// CIR-BEFORE: cir.func {{.*}} @_Z6cmp_neM3FooFviES1_
-// CIR-BEFORE: %[[LHS:.*]] = cir.load{{.*}} %0 : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>
-// CIR-BEFORE: %[[RHS:.*]] = cir.load{{.*}} %1 : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>
-// CIR-BEFORE: %[[CMP:.*]] = cir.cmp(ne, %[[LHS]], %[[RHS]]) : !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.bool
+// CIR-BEFORE: %[[LHS:.*]] = cir.load{{.*}} %0 : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>
+// CIR-BEFORE: %[[RHS:.*]] = cir.load{{.*}} %1 : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>
+// CIR-BEFORE: %[[CMP:.*]] = cir.cmp(ne, %[[LHS]], %[[RHS]]) : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.bool
// CIR-BEFORE: cir.store %[[CMP]], %{{.*}} : !cir.bool, !cir.ptr<!cir.bool>
// CIR-AFTER: cir.func {{.*}} @_Z6cmp_neM3FooFviES1_
diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
index 21238f2eda859..3f6f67f44ed4c 100644
--- a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
@@ -15,7 +15,7 @@ struct Foo {
// 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-BEFORE: cir.global external @m1_ptr = #cir.method<@_ZN3Foo2m1Ei> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !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 }
@@ -23,7 +23,7 @@ void (Foo::*m1_ptr)(int) = &Foo::m1;
// 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-BEFORE: cir.global external @m2_ptr = #cir.method<vtable_offset = 0> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !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 }
@@ -32,12 +32,12 @@ auto make_non_virtual() -> void (Foo::*)(int) {
return &Foo::m1;
}
-// CIR-BEFORE: cir.func {{.*}} @_Z16make_non_virtualv() -> !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, ["__retval"]
-// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<@_ZN3Foo2m1Ei> : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.func {{.*}} @_Z16make_non_virtualv() -> !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
+// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>, ["__retval"]
+// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<@_ZN3Foo2m1Ei> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-BEFORE: cir.store %[[METHOD_PTR]], %[[RETVAL]]
// CIR-BEFORE: %[[RET:.*]] = cir.load %[[RETVAL]]
-// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-AFTER: cir.func {{.*}} @_Z16make_non_virtualv() -> !rec_anon_struct {
// CIR-AFTER: %[[RETVAL:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["__retval"]
@@ -59,12 +59,12 @@ auto make_virtual() -> void (Foo::*)(int) {
return &Foo::m3;
}
-// CIR-BEFORE: cir.func {{.*}} @_Z12make_virtualv() -> !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, ["__retval"]
-// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<vtable_offset = 8> : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.func {{.*}} @_Z12make_virtualv() -> !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
+// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>, ["__retval"]
+// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<vtable_offset = 8> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-BEFORE: cir.store %[[METHOD_PTR]], %[[RETVAL]]
-// CIR-BEFORE: %[[RET:.*]] = cir.load %[[RETVAL]] : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: %[[RET:.*]] = cir.load %[[RETVAL]] : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>, !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-AFTER: cir.func {{.*}} @_Z12make_virtualv() -> !rec_anon_struct
// CIR-AFTER: %[[RETVAL:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["__retval"]
@@ -86,12 +86,12 @@ auto make_null() -> void (Foo::*)(int) {
return nullptr;
}
-// CIR-BEFORE: cir.func {{.*}} @_Z9make_nullv() -> !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, ["__retval"]
-// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<null> : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.func {{.*}} @_Z9make_nullv() -> !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
+// CIR-BEFORE: %[[RETVAL:.*]] = cir.alloca !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>, ["__retval"]
+// CIR-BEFORE: %[[METHOD_PTR:.*]] = cir.const #cir.method<null> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-BEFORE: cir.store %[[METHOD_PTR]], %[[RETVAL]]
// CIR-BEFORE: %[[RET:.*]] = cir.load %[[RETVAL]]
-// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
+// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
// CIR-AFTER: cir.func {{.*}} @_Z9make_nullv() -> !rec_anon_struct
// CIR-AFTER: %[[RETVAL:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["__retval"]
@@ -115,10 +115,10 @@ void call(Foo *obj, void (Foo::*func)(int), int arg) {
// CIR-BEFORE: cir.func {{.*}} @_Z4callP3FooMS_FviEi
// CIR-BEFORE: %[[OBJ:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.ptr<!rec_Foo>>, !cir.ptr<!rec_Foo>
-// CIR-BEFORE: %[[FUNC:.*]] = cir.load{{.*}} : !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-BEFORE: %[[CALLEE:.*]], %[[THIS:.*]] = cir.get_method %[[FUNC]], %[[OBJ]] : (!cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.ptr<!rec_Foo>) -> (!cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>, !cir.ptr<!void>)
+// CIR-BEFORE: %[[FUNC:.*]] = cir.load{{.*}} : !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>>, !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>
+// CIR-BEFORE: %[[CALLEE:.*]], %[[THIS:.*]] = cir.get_method %[[FUNC]], %[[OBJ]] : (!cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo>, !cir.ptr<!rec_Foo>) -> (!cir.ptr<!cir.func<(!cir.ptr<!void>, !cir.ptr<!rec_Foo>, !s32i)>>, !cir.ptr<!void>)
// CIR-BEFORE: %[[ARG:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
-// CIR-BEFORE: cir.call %[[CALLEE]](%[[THIS]], %[[ARG]]) : (!cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>, !cir.ptr<!void>, !s32i) -> ()
+// CIR-BEFORE: cir.call %[[CALLEE]](%[[THIS]], %[[ARG]]) : (!cir.ptr<!cir.func<(!cir.ptr<!void>, !cir.ptr<!rec_Foo>, !s32i)>>, !cir.ptr<!void>, !s32i) -> ()
// CIR-AFTER: cir.func {{.*}} @_Z4callP3FooMS_FviEi
// CIR-AFTER: %[[OBJ:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.ptr<!rec_Foo>>, !cir.ptr<!rec_Foo>
@@ -135,15 +135,15 @@ void call(Foo *obj, void (Foo::*func)(int), int arg) {
// CIR-AFTER: %[[VTABLE:.*]] = cir.load %[[VTABLE_PTR]] : !cir.ptr<!cir.ptr<!s8i>>, !cir.ptr<!s8i>
// CIR-AFTER: %[[OFFSET:.*]] = cir.binop(sub, %[[METHOD_PTR]], %[[VIRT_BIT]]) : !s64i
// CIR-AFTER: %[[VTABLE_SLOT:.*]] = cir.ptr_stride %[[VTABLE]], %[[OFFSET]] : (!cir.ptr<!s8i>, !s64i) -> !cir.ptr<!s8i>
-// CIR-AFTER: %[[VIRTUAL_FN_PTR:.*]] = cir.cast bitcast %[[VTABLE_SLOT]] : !cir.ptr<!s8i> -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>>
-// CIR-AFTER: %[[VIRTUAL_FN_PTR_LOAD:.*]] = cir.load %[[VIRTUAL_FN_PTR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>>, !cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>
-// CIR-AFTER: cir.yield %[[VIRTUAL_FN_PTR_LOAD]] : !cir.ptr<!cir.func<(!cir.ptr<!void>, !s32i)>>
+// CIR-AFTER: %[[VIRTUAL_FN_PTR:.*]] = cir.cast bitcast %[[VTABLE_SLOT]] : !cir.ptr<!s8i> -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!void>, !cir.ptr<!rec_Foo>, !s32i)>>>
+// CIR-AFTER: %[[VIRTUAL_FN_PTR_LOAD:.*]] = cir.load %[[VIRTUAL_FN_PTR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!void>, !cir.ptr<!rec_Foo>, !s32i)>>>, !cir.ptr<!cir.f...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/181452
More information about the cfe-commits
mailing list