[Mlir-commits] [mlir] [mlir][ODS] Add EnumInfo accessors for the bit enum separator (NFC) (PR #237962)
Henrich Lauko
llvmlistbot at llvm.org
Mon Nov 2 07:53:57 PST 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/237962
>From c13512239e22f7d9f3de3d6d85482b57bda972f1 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Mon, 2 Nov 2026 12:20:13 +0000
Subject: [PATCH] [mlir][ODS] Add EnumInfo accessors for the bit enum separator
(NFC)
The generators read the bit enum `separator` field through
getValueAsString in nine places, and EnumsGen and OpFormatGen each carry
a copy of the StringSwitch that maps it to the AsmParser method parsing
it. Add EnumInfo::getBitEnumSeparator, getBitEnumSeparatorKind and
getBitEnumSeparatorParser, and use them at every site; the comma checks
now compare the kind. A separator other than '|' or ',' used to produce
C++ that did not compile and is now a TableGen error instead.
Assisted-by: Claude Code (Claude Opus 5.5).
---
mlir/include/mlir/TableGen/EnumInfo.h | 12 +++++++++
mlir/lib/TableGen/EnumInfo.cpp | 25 +++++++++++++++++++
.../tools/mlir-tblgen/AttrOrTypeFormatGen.cpp | 3 ++-
.../mlir-tblgen/EnumPythonBindingGen.cpp | 2 +-
mlir/tools/mlir-tblgen/EnumsGen.cpp | 21 +++++++---------
mlir/tools/mlir-tblgen/OpFormatGen.cpp | 13 +++-------
6 files changed, 53 insertions(+), 23 deletions(-)
diff --git a/mlir/include/mlir/TableGen/EnumInfo.h b/mlir/include/mlir/TableGen/EnumInfo.h
index d8dfd3489cf6bd..9a46ac0c3cdb7d 100644
--- a/mlir/include/mlir/TableGen/EnumInfo.h
+++ b/mlir/include/mlir/TableGen/EnumInfo.h
@@ -134,6 +134,18 @@ class EnumInfo {
bool printBitEnumPrimaryGroups() const;
bool printBitEnumQuoted() const;
+ // Returns the string printed between the cases of a bit enum.
+ StringRef getBitEnumSeparator() const;
+
+ // The token that separates the cases of a bit enum, ignoring the spaces
+ // around it.
+ enum class BitEnumSeparatorKind { VerticalBar, Comma };
+ BitEnumSeparatorKind getBitEnumSeparatorKind() const;
+
+ // Returns the name of the `AsmParser` method that parses the separator
+ // between the cases of a bit enum.
+ StringRef getBitEnumSeparatorParser() const;
+
// Returns the TableGen definition this EnumAttrCase was constructed from.
const llvm::Record &getDef() const;
diff --git a/mlir/lib/TableGen/EnumInfo.cpp b/mlir/lib/TableGen/EnumInfo.cpp
index 99960c8df29d2c..54c6f7320f09a2 100644
--- a/mlir/lib/TableGen/EnumInfo.cpp
+++ b/mlir/lib/TableGen/EnumInfo.cpp
@@ -8,6 +8,7 @@
#include "mlir/TableGen/EnumInfo.h"
#include "mlir/TableGen/Attribute.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
using namespace mlir;
@@ -147,4 +148,28 @@ bool EnumInfo::printBitEnumQuoted() const {
return def->getValueAsBit("printBitEnumQuoted");
}
+StringRef EnumInfo::getBitEnumSeparator() const {
+ return def->getValueAsString("separator");
+}
+
+EnumInfo::BitEnumSeparatorKind EnumInfo::getBitEnumSeparatorKind() const {
+ StringRef separator = getBitEnumSeparator().trim();
+ if (separator == "|")
+ return BitEnumSeparatorKind::VerticalBar;
+ if (separator == ",")
+ return BitEnumSeparatorKind::Comma;
+ PrintFatalError(def->getLoc(), "bit enum separator must be '|' or ',', "
+ "optionally surrounded by spaces");
+}
+
+StringRef EnumInfo::getBitEnumSeparatorParser() const {
+ switch (getBitEnumSeparatorKind()) {
+ case BitEnumSeparatorKind::VerticalBar:
+ return "parseOptionalVerticalBar";
+ case BitEnumSeparatorKind::Comma:
+ return "parseOptionalComma";
+ }
+ llvm_unreachable("unknown bit enum separator kind");
+}
+
const Record &EnumInfo::getDef() const { return *def; }
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
index 853ba5b0d0c71d..f8296749a03cb2 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
@@ -126,7 +126,8 @@ static bool isUndelimitedCommaBitEnumParam(const ParameterElement *el) {
return false;
EnumInfo enumInfo(enumAttr->getValueAsDef("enum"));
return enumInfo.isNewStyleBitEnum() &&
- enumInfo.getDef().getValueAsString("separator").trim() == ",";
+ enumInfo.getBitEnumSeparatorKind() ==
+ EnumInfo::BitEnumSeparatorKind::Comma;
}
/// Returns true if a non-final struct parameter needs brackets to separate its
diff --git a/mlir/tools/mlir-tblgen/EnumPythonBindingGen.cpp b/mlir/tools/mlir-tblgen/EnumPythonBindingGen.cpp
index 6cef09d9958c7a..eeaa9e342f82bf 100644
--- a/mlir/tools/mlir-tblgen/EnumPythonBindingGen.cpp
+++ b/mlir/tools/mlir-tblgen/EnumPythonBindingGen.cpp
@@ -79,7 +79,7 @@ static void emitEnumClass(EnumInfo enumInfo, raw_ostream &os) {
if (enumInfo.isBitEnum())
os << formatv(" if len(self) > 1:\n"
" return \"{0}\".join(map(str, self))\n",
- enumInfo.getDef().getValueAsString("separator"));
+ enumInfo.getBitEnumSeparator());
for (const EnumCase &enumCase : enumInfo.getAllCases()) {
os << formatv(" if self is {0}.{1}:\n", enumInfo.getEnumClassName(),
makePythonEnumCaseName(enumCase.getSymbol()));
diff --git a/mlir/tools/mlir-tblgen/EnumsGen.cpp b/mlir/tools/mlir-tblgen/EnumsGen.cpp
index c83ed3cf42fcd7..dba18803c86969 100644
--- a/mlir/tools/mlir-tblgen/EnumsGen.cpp
+++ b/mlir/tools/mlir-tblgen/EnumsGen.cpp
@@ -107,10 +107,12 @@ struct FieldParser<std::optional<{0}>, std::optional<{0}>> {{
std::string isKeyValueCompositional;
if (enumInfo.isNewStyleBitEnum()) {
- StringRef separator = enumInfo.getDef().getValueAsString("separator");
isKeyValueCompositional =
formatv("\n static constexpr bool isKeyValueCompositional = {0};\n",
- separator.trim() == "," ? "false" : "true");
+ enumInfo.getBitEnumSeparatorKind() ==
+ EnumInfo::BitEnumSeparatorKind::Comma
+ ? "false"
+ : "true");
}
os << formatv(fieldParserDecls, qualName, isKeyValueCompositional);
}
@@ -226,14 +228,10 @@ FieldParser<std::optional<{0}>, std::optional<{0}>>::parse(AsmParser &parser) {{
)";
if (enumInfo.isNewStyleBitEnum()) {
- StringRef separator = enumInfo.getDef().getValueAsString("separator");
- StringRef parseSeparatorFn =
- llvm::StringSwitch<StringRef>(separator.trim())
- .Case("|", "parseOptionalVerticalBar")
- .Case(",", "parseOptionalComma")
- .Default("error, enum separator must be '|' or ','");
+ StringRef parseSeparatorFn = enumInfo.getBitEnumSeparatorParser();
os << formatv(fieldParserDefsUnquotedBitEnum, qualName, cppNamespace,
- enumInfo.getSummary(), casesList, separator, parseSeparatorFn,
+ enumInfo.getSummary(), casesList,
+ enumInfo.getBitEnumSeparator(), parseSeparatorFn,
casesInitList);
} else {
os << formatv(fieldParserDefs, qualName, cppNamespace,
@@ -468,7 +466,7 @@ static void emitSymToStrFnForBitEnum(const Record &enumDef, raw_ostream &os) {
StringRef enumName = enumInfo.getEnumClassName();
StringRef symToStrFnName = enumInfo.getSymbolToStringFnName();
StringRef symToStrFnRetType = enumInfo.getSymbolToStringFnRetType();
- StringRef separator = enumDef.getValueAsString("separator");
+ StringRef separator = enumInfo.getBitEnumSeparator();
auto enumerants = enumInfo.getAllCases();
auto allBitsUnsetCase = getAllBitsUnsetCase(enumerants);
@@ -562,8 +560,7 @@ static void emitStrToSymFnForBitEnum(const Record &enumDef, raw_ostream &os) {
StringRef enumName = enumInfo.getEnumClassName();
std::string underlyingType = std::string(enumInfo.getUnderlyingType());
StringRef strToSymFnName = enumInfo.getStringToSymbolFnName();
- StringRef separator = enumDef.getValueAsString("separator");
- StringRef separatorTrimmed = separator.trim();
+ StringRef separatorTrimmed = enumInfo.getBitEnumSeparator().trim();
auto enumerants = enumInfo.getAllCases();
auto allBitsUnsetCase = getAllBitsUnsetCase(enumerants);
diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index 1fd993cc197a9a..dadbfc6222ada9 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -509,8 +509,8 @@ static bool needsPropDictEnumBrackets(const NamedAttribute *attr) {
if (!shouldStripEnumAttrInPropDict(attr))
return false;
EnumInfo enumInfo(getEnumInfoRecord(attr->attr.getBaseAttr()));
- return enumInfo.isBitEnum() &&
- enumInfo.getDef().getValueAsString("separator").trim() == ",";
+ return enumInfo.isBitEnum() && enumInfo.getBitEnumSeparatorKind() ==
+ EnumInfo::BitEnumSeparatorKind::Comma;
}
/// Returns if we should format the given attribute as an SymbolNameAttr.
@@ -1311,11 +1311,7 @@ static void genEnumAttrParser(const NamedAttribute *var, MethodBody &body,
if (formatAsEnumDirective && enumInfo.isBitEnum() &&
(formatBitEnumAsUnquoted || !enumInfo.printBitEnumQuoted())) {
- StringRef separator = enumInfo.getDef().getValueAsString("separator");
- StringRef parseSeparatorFn = llvm::StringSwitch<StringRef>(separator.trim())
- .Case("|", "parseOptionalVerticalBar")
- .Case(",", "parseOptionalComma")
- .Default("invalid bit enum separator");
+ StringRef parseSeparatorFn = enumInfo.getBitEnumSeparatorParser();
std::string enumType =
(enumInfo.getCppNamespace() + "::" + enumInfo.getEnumClassName()).str();
body << formatv(unquotedBitEnumAttrParserCode, var->name,
@@ -4002,8 +3998,7 @@ OpFormatParser::verifyEnumAdjacentLiterals(SMLoc loc,
if (!literal)
continue;
- StringRef separator =
- enumInfo.getDef().getValueAsString("separator").trim();
+ StringRef separator = enumInfo.getBitEnumSeparator().trim();
if (literal->getSpelling() == separator) {
return emitError(loc, "unquoted bit enum cannot be followed by its '" +
separator + "' separator literal");
More information about the Mlir-commits
mailing list