[clang] [CIR] Upstream CIR method attribute handling (PR #174640)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 7 09:13:44 PST 2026
https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/174640
>From ebdb617d94b778e7d0466aec9be37e993858d893 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Thu, 11 Dec 2025 10:48:09 -0800
Subject: [PATCH 1/2] [CIR] Upstream CIR method attribute handling
This adds code for generating cir.method attributes and lowering them to
LLVM IR to implement support the C++ method pointer variables.
---
.../CIR/Dialect/Builder/CIRBaseBuilder.h | 5 ++
.../include/clang/CIR/Dialect/IR/CIRAttrs.td | 43 +++++++++++++++++
clang/include/clang/CIR/MissingFeatures.h | 1 +
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 15 ++++--
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 44 +++++++++++++++++
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 +-
.../CIR/Dialect/Transforms/CXXABILowering.cpp | 9 ++++
.../Transforms/TargetLowering/CIRCXXABI.h | 6 +++
.../TargetLowering/LowerItaniumCXXABI.cpp | 48 +++++++++++++++++++
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 15 +++---
.../CIR/CodeGen/pointer-to-member-func.cpp | 41 ++++++++--------
11 files changed, 200 insertions(+), 31 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index cc28941aaa079..eadf3dd6ee0f0 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -179,6 +179,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return getPointerTo(cir::VoidType::get(getContext()), as);
}
+ cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
+ auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
+ return cir::MethodAttr::get(ty, methodFuncSymbolRef);
+ }
+
cir::BoolAttr getCIRBoolAttr(bool state) {
return cir::BoolAttr::get(getContext(), state);
}
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index c0279a0b20670..74ca19fb329b3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -498,6 +498,49 @@ def CIR_DataMemberAttr : CIR_Attr<"DataMember", "data_member", [
}];
}
+//===----------------------------------------------------------------------===//
+// MethodAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_MethodAttr : CIR_Attr<"Method", "method", [TypedAttrInterface]> {
+ let summary = "Holds a constant pointer-to-member-function value";
+ let description = [{
+ A method attribute is a literal attribute that represents a constant
+ pointer-to-member-function value.
+
+ If the member function is a non-virtual function, the `symbol` parameter
+ gives the global symbol for the non-virtual member function.
+
+ Virtual function handling is not yet implemented.
+
+ If `symbol` is not present, the attribute represents a null pointer
+ constant.
+ }];
+
+ let parameters = (ins AttributeSelfTypeParameter<
+ "", "cir::MethodType">:$type,
+ OptionalParameter<
+ "std::optional<mlir::FlatSymbolRefAttr>">:$symbol);
+
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "cir::MethodType":$type), [{
+ return $_get(type.getContext(), type, std::nullopt);
+ }]>,
+ AttrBuilderWithInferredContext<(ins "cir::MethodType":$type,
+ "mlir::FlatSymbolRefAttr":$symbol), [{
+ return $_get(type.getContext(), type, symbol);
+ }]>,
+ ];
+
+ let hasCustomAssemblyFormat = 1;
+
+ let extraClassDeclaration = [{
+ bool isNull() const {
+ return !getSymbol().has_value();
+ }
+ }];
+}
+
//===----------------------------------------------------------------------===//
// GlobalViewAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index acfc937a11993..e7b2d7ebbe113 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -345,6 +345,7 @@ struct MissingFeatures {
static bool useEHCleanupForArray() { return false; }
static bool vaArgABILowering() { return false; }
static bool vectorConstants() { return false; }
+ static bool virtualMethodAttr() { return false; }
static bool vlas() { return false; }
static bool vtableInitialization() { return false; }
static bool vtableEmitMetadata() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 42df6304628dc..a995a4ceb601d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1527,9 +1527,18 @@ mlir::Value CIRGenModule::emitMemberPointerConstant(const UnaryOperator *e) {
const auto *decl = cast<DeclRefExpr>(e->getSubExpr())->getDecl();
// A member function pointer.
- if (isa<CXXMethodDecl>(decl)) {
- errorNYI(e->getSourceRange(), "emitMemberPointerConstant: method pointer");
- return {};
+ if (const auto *methodDecl = dyn_cast<CXXMethodDecl>(decl)) {
+ auto ty = mlir::cast<cir::MethodType>(convertType(e->getType()));
+ if (methodDecl->isVirtual()) {
+ assert(!cir::MissingFeatures::virtualMethodAttr());
+ errorNYI(e->getSourceRange(),
+ "emitMemberPointerConstant: virtual method pointer");
+ return {};
+ }
+
+ auto methodFuncOp = getAddrOfFunction(methodDecl);
+ return cir::ConstantOp::create(builder, loc,
+ builder.getMethodAttr(ty, methodFuncOp));
}
// Otherwise, a member data pointer.
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 59d7765198f9e..c69335ccf7960 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -301,6 +301,50 @@ DataMemberAttr::verify(function_ref<InFlightDiagnostic()> emitError,
return success();
}
+//===----------------------------------------------------------------------===//
+// MethodAttr definitions
+//===----------------------------------------------------------------------===//
+
+Attribute MethodAttr::parse(AsmParser &parser, Type odsType) {
+ auto ty = mlir::cast<cir::MethodType>(odsType);
+
+ if (parser.parseLess().failed())
+ return {};
+
+ // Try to parse the null pointer constant.
+ if (parser.parseOptionalKeyword("null").succeeded()) {
+ if (parser.parseGreater())
+ return {};
+ return get(ty);
+ }
+
+ // Try to parse a flat symbol ref for a pointer to non-virtual member
+ // function.
+ FlatSymbolRefAttr symbol;
+ auto parseSymbolRefResult = parser.parseOptionalAttribute(symbol);
+ if (parseSymbolRefResult.has_value()) {
+ if (parseSymbolRefResult.value().failed())
+ return {};
+ if (parser.parseGreater())
+ return {};
+ return get(ty, symbol);
+ }
+
+ return {};
+}
+
+void MethodAttr::print(AsmPrinter &printer) const {
+ auto symbol = getSymbol();
+
+ printer << '<';
+ if (symbol.has_value()) {
+ printer << *symbol;
+ } else {
+ printer << "null";
+ }
+ printer << '>';
+}
+
//===----------------------------------------------------------------------===//
// CIR ConstArrayAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 8f0dc705181e6..0f1997ff8af6e 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -357,9 +357,9 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
return success();
}
- if (isa<cir::DataMemberAttr>(attrType)) {
+ if (isa<cir::DataMemberAttr, cir::MethodAttr>(attrType)) {
// More detailed type verifications are already done in
- // DataMemberAttr::verify. Don't need to repeat here.
+ // DataMemberAttr::verify or MethodAttr::verify. Don't need to repeat here.
return success();
}
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
index 49087ca38d948..4ef277be8ce08 100644
--- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -171,6 +171,15 @@ mlir::LogicalResult CIRConstantOpABILowering::matchAndRewrite(
return mlir::success();
}
+ if (mlir::isa<cir::MethodType>(op.getType())) {
+ auto method = mlir::cast<cir::MethodAttr>(op.getValue());
+ mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+ mlir::TypedAttr abiValue = lowerModule->getCXXABI().lowerMethodConstant(
+ method, layout, *getTypeConverter());
+ rewriter.replaceOpWithNewOp<ConstantOp>(op, abiValue);
+ return mlir::success();
+ }
+
llvm_unreachable("constant operand is not an CXXABI-dependent type");
}
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
index edfe29f1471cb..bcbda7b94a56f 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h
@@ -59,6 +59,12 @@ class CIRCXXABI {
lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
mlir::Value loweredAddr, mlir::Value loweredMember,
mlir::OpBuilder &builder) const = 0;
+
+ /// Lower the given member function pointer constant to a constant of the ABI
+ /// type. The returned constant is represented as an attribute as well.
+ virtual mlir::TypedAttr
+ lowerMethodConstant(cir::MethodAttr attr, const mlir::DataLayout &layout,
+ const mlir::TypeConverter &typeConverter) const = 0;
};
/// Creates an Itanium-family ABI.
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
index 323ecc46909d4..b3a858a072f8b 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
@@ -51,6 +51,10 @@ class LowerItaniumCXXABI : public CIRCXXABI {
lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
mlir::Value loweredAddr, mlir::Value loweredMember,
mlir::OpBuilder &builder) const override;
+
+ mlir::TypedAttr
+ lowerMethodConstant(cir::MethodAttr attr, const mlir::DataLayout &layout,
+ const mlir::TypeConverter &typeConverter) const override;
};
} // namespace
@@ -133,4 +137,48 @@ mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
cir::CastKind::bitcast, memberBytesPtr);
}
+mlir::TypedAttr LowerItaniumCXXABI::lowerMethodConstant(
+ cir::MethodAttr attr, const mlir::DataLayout &layout,
+ const mlir::TypeConverter &typeConverter) const {
+ cir::IntType ptrdiffCIRTy = getPtrDiffCIRTy(lm);
+ auto loweredMethodTy = mlir::cast<cir::RecordType>(
+ lowerMethodType(attr.getType(), typeConverter));
+
+ auto zero = cir::IntAttr::get(ptrdiffCIRTy, 0);
+
+ // Itanium C++ ABI 2.3.2:
+ // In all representations, the basic ABI properties of member function
+ // pointer types are those of the following class, where fnptr_t is the
+ // appropriate function-pointer type for a member function of this type:
+ //
+ // struct {
+ // fnptr_t ptr;
+ // ptrdiff_t adj;
+ // };
+
+ if (attr.isNull()) {
+ // Itanium C++ ABI 2.3.2:
+ //
+ // In the standard representation, a null member function pointer is
+ // represented with ptr set to a null pointer. The value of adj is
+ // unspecified for null member function pointers.
+ //
+ // clang CodeGen emits struct{null, null} for null member function pointers.
+ // Let's do the same here.
+ return cir::ConstRecordAttr::get(
+ loweredMethodTy, mlir::ArrayAttr::get(attr.getContext(), {zero, zero}));
+ }
+
+ assert(!cir::MissingFeatures::virtualMethodAttr());
+
+ // Itanium C++ ABI 2.3.2:
+ //
+ // A member function pointer for a non-virtual member function is
+ // represented with ptr set to a pointer to the function, using the base
+ // ABI's representation of function pointers.
+ auto ptr = cir::GlobalViewAttr::get(ptrdiffCIRTy, attr.getSymbol().value());
+ return cir::ConstRecordAttr::get(
+ loweredMethodTy, mlir::ArrayAttr::get(attr.getContext(), {ptr, zero}));
+}
+
} // namespace cir
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7686add38250e..03245cc6963e9 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -577,11 +577,11 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
mlir::LLVM::GEPNoWrapFlags::none);
}
- // The incubator has handling here for the attribute having integer type, but
- // the only test case I could find that reaches it is a direct CIR-to-LLVM IR
- // lowering with no clear indication of how the CIR might have been generated.
- // We'll hit the unreachable below if this happens.
- assert(!cir::MissingFeatures::globalViewIntLowering());
+ if (auto intTy = mlir::dyn_cast<cir::IntType>(globalAttr.getType())) {
+ auto llvmDstTy = converter->convertType(globalAttr.getType());
+ return mlir::LLVM::PtrToIntOp::create(rewriter, parentOp->getLoc(),
+ llvmDstTy, addrOp);
+ }
if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(globalAttr.getType())) {
mlir::Type llvmEltTy =
@@ -1801,7 +1801,10 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
} else if (mlir::isa<cir::IntType>(op.getType())) {
// Lower GlobalViewAttr to llvm.mlir.addressof + llvm.mlir.ptrtoint
if (auto ga = mlir::dyn_cast<cir::GlobalViewAttr>(op.getValue())) {
- // See the comment in visitCirAttr for why this isn't implemented.
+ // We can have a global view with an integer type in the case of method
+ // pointers, but the lowering of those doesn't go through this path.
+ // They are handled in the visitCirAttr. This is left as an error until
+ // we have a test case that reaches it.
assert(!cir::MissingFeatures::globalViewIntLowering());
op.emitError() << "global view with integer type";
return mlir::failure();
diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
index e3fe05dfa34fa..47c5871e72290 100644
--- a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp
@@ -12,28 +12,29 @@ struct Foo {
virtual void m3(int);
};
-void unused_pointer_to_member_func(void (Foo::*func)(int)) {
+auto make_non_virtual() -> void (Foo::*)(int) {
+ return &Foo::m1;
}
-// CIR-BEFORE: cir.func {{.*}} @_Z29unused_pointer_to_member_funcM3FooFviE(%[[ARG:.*]]: !cir.method<!cir.func<(!s32i)> in !rec_Foo>)
-// CIR-BEFORE: %[[FUNC:.*]] = cir.alloca !cir.method<!cir.func<(!s32i)> in !rec_Foo>, !cir.ptr<!cir.method<!cir.func<(!s32i)> in !rec_Foo>>, ["func", init]
+// 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.store %[[METHOD_PTR]], %[[RETVAL]]
+// CIR-BEFORE: %[[RET:.*]] = cir.load %[[RETVAL]]
+// CIR-BEFORE: cir.return %[[RET]] : !cir.method<!cir.func<(!s32i)> in !rec_Foo>
-// CIR-AFTER: !rec_anon_struct = !cir.record<struct {!s64i, !s64i}>
-// CIR-AFTER: cir.func {{.*}} @_Z29unused_pointer_to_member_funcM3FooFviE(%[[ARG:.*]]: !rec_anon_struct {{.*}})
-// CIR-AFTER %[[FUNC:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["func", init]
+// CIR-AFTER: cir.func {{.*}} @_Z16make_non_virtualv() -> !rec_anon_struct {
+// CIR-AFTER: %[[RETVAL:.*]] = cir.alloca !rec_anon_struct, !cir.ptr<!rec_anon_struct>, ["__retval"]
+// CIR-AFTER: %[[METHOD_PTR:.*]] = cir.const #cir.const_record<{#cir.global_view<@_ZN3Foo2m1Ei> : !s64i, #cir.int<0> : !s64i}> : !rec_anon_struct
+// CIR-AFTER: cir.store %[[METHOD_PTR]], %[[RETVAL]]
+// CIR-AFTER: %[[RET:.*]] = cir.load %[[RETVAL]]
+// CIR-AFTER: cir.return %[[RET]] : !rec_anon_struct
-// NOTE: The difference between LLVM and OGCG are due to the lack of calling convention handling in CIR.
+// LLVM: define {{.*}} { i64, i64 } @_Z16make_non_virtualv()
+// LLVM: %[[RETVAL:.*]] = alloca { i64, i64 }
+// LLVM: store { i64, i64 } { i64 ptrtoint (ptr @_ZN3Foo2m1Ei to i64), i64 0 }, ptr %[[RETVAL]]
+// LLVM: %[[RET:.*]] = load { i64, i64 }, ptr %[[RETVAL]]
+// LLVM: ret { i64, i64 } %[[RET]]
-// LLVM: define {{.*}} void @_Z29unused_pointer_to_member_funcM3FooFviE({ i64, i64 } %[[ARG:.*]])
-// LLVM: %[[FUNC:.*]] = alloca { i64, i64 }
-// LLVM: store { i64, i64 } %[[ARG]], ptr %[[FUNC]]
-
-// OGCG: define {{.*}} void @_Z29unused_pointer_to_member_funcM3FooFviE(i64 %[[FUNC_COERCE0:.*]], i64 %[[FUNC_COERCE1:.*]])
-// OGCG: %[[FUNC:.*]] = alloca { i64, i64 }
-// OGCG: %[[FUNC_ADDR:.*]] = alloca { i64, i64 }
-// OGCG: %[[FUNC_0:.*]] = getelementptr inbounds nuw { i64, i64 }, ptr %[[FUNC]], i32 0, i32 0
-// OGCG: store i64 %[[FUNC_COERCE0]], ptr %[[FUNC_0]]
-// OGCG: %[[FUNC_1:.*]] = getelementptr inbounds nuw { i64, i64 }, ptr %[[FUNC]], i32 0, i32 1
-// OGCG: store i64 %[[FUNC_COERCE1]], ptr %[[FUNC_1]]
-// OGCG: %[[FUNC1:.*]] = load { i64, i64 }, ptr %[[FUNC]]
-// OGCG: store { i64, i64 } %[[FUNC1]], ptr %[[FUNC_ADDR]]
+// OGCG: define {{.*}} { i64, i64 } @_Z16make_non_virtualv()
+// OGCG: ret { i64, i64 } { i64 ptrtoint (ptr @_ZN3Foo2m1Ei to i64), i64 0 }
>From 4b7cbd929db46063f830c7be607278d2ee8eff61 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Wed, 7 Jan 2026 09:12:46 -0800
Subject: [PATCH 2/2] Address review feedback
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 2 +-
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 7 ++++---
.../Transforms/TargetLowering/LowerItaniumCXXABI.cpp | 4 ++++
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +-
4 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index a995a4ceb601d..fcd3f105807ca 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1536,7 +1536,7 @@ mlir::Value CIRGenModule::emitMemberPointerConstant(const UnaryOperator *e) {
return {};
}
- auto methodFuncOp = getAddrOfFunction(methodDecl);
+ cir::FuncOp methodFuncOp = getAddrOfFunction(methodDecl);
return cir::ConstantOp::create(builder, loc,
builder.getMethodAttr(ty, methodFuncOp));
}
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index c69335ccf7960..2f4240c385cab 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -313,7 +313,7 @@ Attribute MethodAttr::parse(AsmParser &parser, Type odsType) {
// Try to parse the null pointer constant.
if (parser.parseOptionalKeyword("null").succeeded()) {
- if (parser.parseGreater())
+ if (parser.parseGreater().failed())
return {};
return get(ty);
}
@@ -321,11 +321,12 @@ Attribute MethodAttr::parse(AsmParser &parser, Type odsType) {
// Try to parse a flat symbol ref for a pointer to non-virtual member
// function.
FlatSymbolRefAttr symbol;
- auto parseSymbolRefResult = parser.parseOptionalAttribute(symbol);
+ mlir::OptionalParseResult parseSymbolRefResult =
+ parser.parseOptionalAttribute(symbol);
if (parseSymbolRefResult.has_value()) {
if (parseSymbolRefResult.value().failed())
return {};
- if (parser.parseGreater())
+ if (parser.parseGreater().failed())
return {};
return get(ty, symbol);
}
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
index b3a858a072f8b..7a9620c2cc7e3 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp
@@ -141,6 +141,10 @@ mlir::TypedAttr LowerItaniumCXXABI::lowerMethodConstant(
cir::MethodAttr attr, const mlir::DataLayout &layout,
const mlir::TypeConverter &typeConverter) const {
cir::IntType ptrdiffCIRTy = getPtrDiffCIRTy(lm);
+
+ // lowerMethodType returns the CIR type used to represent the method pointer
+ // in an ABI-specific way. That's why lowerMethodType returns cir::RecordType
+ // here.
auto loweredMethodTy = mlir::cast<cir::RecordType>(
lowerMethodType(attr.getType(), typeConverter));
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 03245cc6963e9..982adaaa79a3f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -578,7 +578,7 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
}
if (auto intTy = mlir::dyn_cast<cir::IntType>(globalAttr.getType())) {
- auto llvmDstTy = converter->convertType(globalAttr.getType());
+ mlir::Type llvmDstTy = converter->convertType(globalAttr.getType());
return mlir::LLVM::PtrToIntOp::create(rewriter, parentOp->getLoc(),
llvmDstTy, addrOp);
}
More information about the cfe-commits
mailing list