[Mlir-commits] [mlir] [mlir] Add struct parsing and printing utilities (PR #133939)
Jorn Tuyls
llvmlistbot at llvm.org
Thu Apr 3 07:50:15 PDT 2025
================
@@ -316,6 +316,41 @@ static ParseResult parseCustomFloatAttr(AsmParser &p, StringAttr &typeStrAttr,
return success();
}
+//===----------------------------------------------------------------------===//
+// TestCustomStructAttr
+//===----------------------------------------------------------------------===//
+
+Attribute TestCustomStructAttr::parse(AsmParser &p, Type type) {
+ std::string typeStr;
+ int64_t value;
+ FailureOr<ArrayAttr> optParam;
+ if (failed(p.parseStruct(AsmParser::Delimiter::LessGreater,
+ {"type_str", "value", "opt_param"},
+ {[&]() { return p.parseString(&typeStr); },
+ [&]() { return p.parseInteger(value); },
+ [&]() {
+ optParam = mlir::FieldParser<ArrayAttr>::parse(p);
+ return success(succeeded(optParam));
+ }}))) {
+ p.emitError(p.getCurrentLocation())
+ << "failed parsing `TestCustomStructAttr`";
+ return {};
+ }
+ return get(p.getContext(), StringAttr::get(p.getContext(), typeStr), value,
+ optParam.value_or(ArrayAttr()));
+}
+
+void TestCustomStructAttr::print(AsmPrinter &p) const {
+ p << "<";
+ p.printStruct(std::make_pair("type_str", getTypeStr()),
+ std::make_pair("value", getValue()));
----------------
jtuyls wrote:
Yeah, you can use interleaveComma instead, and am I happy to just remove the printStruct utility, but I think interleaveComma is a bit more bloated with different types of the operands:
```
SmallVector<StringRef> keywords = {"type_str", "value"};
llvm::interleaveComma(keywords, p, [&](StringRef kw) {
p << kw << " = ";
if (kw == "type_str") {
p.printStrippedAttrOrType(getTypeStr()); //StringAttr
} else if (kw == "value") {
p.printStrippedAttrOrType(getValue()); // int64_t
}
});
if (getOptParam() != ArrayAttr()) {
p << ", opt_param = ";
p.printStrippedAttrOrType(getOptParam());
}
```
Of course, you could just print the list manually as well, which might even be the most compact in a lot of instances:
```
p << "type_str = ";
p.printStrippedAttrOrType(getTypeStr());
p << ", value = ";
p.printStrippedAttrOrType(getValue());
if (getOptParam() != ArrayAttr()) {
p << ", opt_param = ";
p.printStrippedAttrOrType(getOptParam());
}
```
Alternatively, I could implement printStruct more in line with parseStruct like this:
```
void printStruct(ArrayRef<StringRef> keywords,
ArrayRef<llvm::function_ref<void(AsmPrinter &p)>> printFuncs) {
DenseMap<StringRef, llvm::function_ref<void(AsmPrinter &p)>> keywordToFunc;
for (auto &&[kw, printFunc] : llvm::zip(keywords, printFuncs))
keywordToFunc[kw] = printFunc;
auto &os = getStream();
llvm::interleaveComma(keywords, os, [&](StringRef kw) {
os << kw << " = ";
keywordToFunc[kw](*this);
});
}
```
And use it like this:
```
SmallVector<StringRef> keywords = {"type_str", "value"};
p.printStruct(keywords, {
[&](AsmPrinter &p) { p.printStrippedAttrOrType(getTypeStr()); },
[&](AsmPrinter &p) { p.printStrippedAttrOrType(getValue()); }
});
if (getOptParam() != ArrayAttr()) {
p << ", opt_param = ";
p.printStrippedAttrOrType(getOptParam());
}
```
Upon reconsideration, I like this latter approach or removing the printStruct utility the most. Let me know what you prefer?
https://github.com/llvm/llvm-project/pull/133939
More information about the Mlir-commits
mailing list