[Mlir-commits] [mlir] [mlir][tblgen] Define enum `FieldParser` specializations out-of-line (PR #233730)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Oct 20 00:47:50 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-core
Author: Markus Böck (zero9178)
<details>
<summary>Changes</summary>
The `FieldParser` specializations generated for every enum were defined inline in the enum declarations header. Since their bodies do not depend on the `ParserT` template parameter, they are type-checked eagerly in every translation unit including the header, which instantiates `FailureOr<E>`, `FailureOr<std::optional<E>>` and their `std::optional` bases and type traits for every enum. Only a small fraction of these specializations is ever used, and only from the generated attribute and op parsers of the dialect itself.
This patch changes `parse` to a non-template taking an `AsmParser &`, declares it in the header and emits its definition into the enum definitions file instead.
Compiling all of MLIR (clang 18 with 64 cores) takes 4.5% less CPU time, with the median translation unit compiling 2.8% faster and some up to 15% faster. The summed peak memory usage of all translation units drops by 4.5% and the largest peak memory usage of a single translation unit (`mlir/lib/CAPI/Conversion/Passes.cpp`) drops by 13% (1710 MB -> 1492 MB). A translation unit only including `NVVMDialect.h` compiles 12% faster with 14% lower peak memory usage.
---
Patch is 25.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/233730.diff
7 Files Affected:
- (modified) mlir/include/mlir/TableGen/EnumInfo.h (+10)
- (modified) mlir/lib/TableGen/EnumInfo.cpp (+14)
- (modified) mlir/test/mlir-tblgen/enums-gen.td (+42-31)
- (modified) mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp (+1-1)
- (modified) mlir/tools/mlir-tblgen/EnumsGen.cpp (+188-150)
- (modified) mlir/tools/mlir-tblgen/OpFormatGen.cpp (+1-1)
- (modified) mlir/unittests/TableGen/EnumsGenTest.cpp (+1)
``````````diff
diff --git a/mlir/include/mlir/TableGen/EnumInfo.h b/mlir/include/mlir/TableGen/EnumInfo.h
index aea76c01e7e7a..d8dfd3489cf6b 100644
--- a/mlir/include/mlir/TableGen/EnumInfo.h
+++ b/mlir/include/mlir/TableGen/EnumInfo.h
@@ -72,12 +72,22 @@ class EnumInfo {
// Returns true if this is a bit enum.
bool isBitEnum() const;
+ // Returns true if this is a bit enum whose cases are parsed and printed as
+ // separate, unquoted keywords.
+ bool isNewStyleBitEnum() const;
+
+ // Returns true if a 'FieldParser' and a printer are generated for the enum.
+ bool hasParserPrinter() const;
+
// Returns the enum class name.
StringRef getEnumClassName() const;
// Returns the C++ namespaces this enum class should be placed in.
StringRef getCppNamespace() const;
+ // Returns the fully qualified C++ name of the enum class.
+ std::string getQualifiedName() const;
+
// Returns the summary of the enum.
StringRef getSummary() const;
diff --git a/mlir/lib/TableGen/EnumInfo.cpp b/mlir/lib/TableGen/EnumInfo.cpp
index 6128c53557cc4..99960c8df29d2 100644
--- a/mlir/lib/TableGen/EnumInfo.cpp
+++ b/mlir/lib/TableGen/EnumInfo.cpp
@@ -57,6 +57,16 @@ std::optional<Attribute> EnumInfo::asEnumAttr() const {
bool EnumInfo::isBitEnum() const { return isSubClassOf("BitEnumBase"); }
+bool EnumInfo::isNewStyleBitEnum() const {
+ return isBitEnum() && !printBitEnumQuoted();
+}
+
+bool EnumInfo::hasParserPrinter() const {
+ std::optional<Attribute> enumAttrInfo = asEnumAttr();
+ return !getUnderlyingType().empty() &&
+ (!enumAttrInfo || !enumAttrInfo->getConstBuilderTemplate().empty());
+}
+
StringRef EnumInfo::getEnumClassName() const {
return def->getValueAsString("className");
}
@@ -73,6 +83,10 @@ StringRef EnumInfo::getCppNamespace() const {
return def->getValueAsString("cppNamespace");
}
+std::string EnumInfo::getQualifiedName() const {
+ return (getCppNamespace() + "::" + getEnumClassName()).str();
+}
+
int64_t EnumInfo::getBitwidth() const { return def->getValueAsInt("bitwidth"); }
StringRef EnumInfo::getUnderlyingType() const {
diff --git a/mlir/test/mlir-tblgen/enums-gen.td b/mlir/test/mlir-tblgen/enums-gen.td
index e64e50b2382cb..dc0caab3652d9 100644
--- a/mlir/test/mlir-tblgen/enums-gen.td
+++ b/mlir/test/mlir-tblgen/enums-gen.td
@@ -32,21 +32,13 @@ def MyBitEnum: I32BitEnumAttr<"MyBitEnum", "An example bit enum",
// DECL: ::std::optional<MyBitEnum> symbolizeMyBitEnum(::llvm::StringRef);
// DECL: struct FieldParser<::MyBitEnum, ::MyBitEnum> {
-// DECL: template <typename ParserT>
-// DECL: static FailureOr<::MyBitEnum> parse(ParserT &parser) {
-// DECL: // Parse the keyword/string containing the enum.
-// DECL: std::string enumKeyword;
-// DECL: auto loc = parser.getCurrentLocation();
-// DECL: if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
-// DECL: return parser.emitError(loc, "expected keyword for An example bit enum");
-// DECL: // Symbolize the keyword.
-// DECL: if (::std::optional<::MyBitEnum> attr = ::symbolizeEnum<::MyBitEnum>(enumKeyword))
-// DECL: return *attr;
-// DECL: return parser.emitError(loc, "expected one of [none, tagged, Bit1, Bit2, Bit3, BitGroup] for An example bit enum, got: ") << enumKeyword;
-// DECL: }
+// DECL-NEXT: static FailureOr<::MyBitEnum> parse(AsmParser &parser);
+// DECL-NEXT: };
// DECL: struct FieldParser<std::optional<::MyBitEnum>, std::optional<::MyBitEnum>> {
// DECL: static constexpr bool isKeyValueCompositional = false;
+// DECL: static FailureOr<std::optional<::MyBitEnum>> parse(AsmParser &parser);
+// DECL-NEXT: };
// DECL: inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, ::MyBitEnum value) {
// DECL: auto valueStr = stringifyEnum(value);
@@ -101,6 +93,23 @@ def MyBitEnum: I32BitEnumAttr<"MyBitEnum", "An example bit enum",
// DEF: .Case("tagged", 1)
// DEF: .Case("Bit1", 2)
+// DEF-LABEL: FailureOr<::MyBitEnum> FieldParser<::MyBitEnum, ::MyBitEnum>::parse(AsmParser &parser) {
+// DEF: // Parse the keyword/string containing the enum.
+// DEF: std::string enumKeyword;
+// DEF: auto loc = parser.getCurrentLocation();
+// DEF: if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
+// DEF: return parser.emitError(loc, "expected keyword for An example bit enum");
+// DEF: // Symbolize the keyword.
+// DEF: if (::std::optional<::MyBitEnum> attr = ::symbolizeEnum<::MyBitEnum>(enumKeyword))
+// DEF: return *attr;
+// DEF: return parser.emitError(loc, "expected one of [none, tagged, Bit1, Bit2, Bit3, BitGroup] for An example bit enum, got: ") << enumKeyword;
+// DEF: }
+
+// DEF-LABEL: FailureOr<std::optional<::MyBitEnum>>
+// DEF-NEXT: FieldParser<std::optional<::MyBitEnum>, std::optional<::MyBitEnum>>::parse(AsmParser &parser) {
+// DEF: if (failed(parser.parseOptionalKeywordOrString(&enumKeyword, {"none", "tagged", "Bit1", "Bit2", "Bit3", "BitGroup"})))
+// DEF-NEXT: return std::optional<::MyBitEnum>{};
+
// Test enum printer generation for non non-keyword enums.
def NonKeywordBit: I32BitEnumCaseBit<"Bit0", 0, "tag-ged">;
@@ -138,25 +147,27 @@ def MyNonQuotedPrintBitEnum
// DECL: struct FieldParser<::MyNonQuotedPrintBitEnum, ::MyNonQuotedPrintBitEnum> {
// DECL: static constexpr bool isKeyValueCompositional = true;
-// DECL: template <typename ParserT>
-// DECL: static FailureOr<::MyNonQuotedPrintBitEnum> parse(ParserT &parser) {
-// DECL: ::MyNonQuotedPrintBitEnum flags = {};
-// DECL: do {
- // DECL: // Parse the keyword containing a part of the enum.
-// DECL: ::llvm::StringRef enumKeyword;
-// DECL: auto loc = parser.getCurrentLocation();
-// DECL: if (failed(parser.parseOptionalKeyword(&enumKeyword))) {
-// DECL: return parser.emitError(loc, "expected keyword for Example new-style bit enum");
-// DECL: }
-// DECL: // Symbolize the keyword.
-// DECL: if (::std::optional<::MyNonQuotedPrintBitEnum> flag = ::symbolizeEnum<::MyNonQuotedPrintBitEnum>(enumKeyword))
-// DECL: flags = flags | *flag;
-// DECL: } else {
-// DECL: return parser.emitError(loc, "expected one of [none, tagged, Bit1, Bit2, Bit3, BitGroup] for Example new-style bit enum, got: ") << enumKeyword;
-// DECL: }
-// DECL: } while (::mlir::succeeded(parser.parseOptionalVerticalBar()));
-// DECL: return flags;
-// DECL: }
+// DECL: static FailureOr<::MyNonQuotedPrintBitEnum> parse(AsmParser &parser);
+// DECL-NEXT: };
+
+// DEF-LABEL: FailureOr<::MyNonQuotedPrintBitEnum> FieldParser<::MyNonQuotedPrintBitEnum, ::MyNonQuotedPrintBitEnum>::parse(AsmParser &parser) {
+// DEF: ::MyNonQuotedPrintBitEnum flags = {};
+// DEF: do {
+// DEF: // Parse the keyword containing a part of the enum.
+// DEF: ::llvm::StringRef enumKeyword;
+// DEF: auto loc = parser.getCurrentLocation();
+// DEF: if (failed(parser.parseOptionalKeyword(&enumKeyword))) {
+// DEF: return parser.emitError(loc, "expected keyword for Example new-style bit enum");
+// DEF: }
+// DEF: // Symbolize the keyword.
+// DEF: if (::std::optional<::MyNonQuotedPrintBitEnum> flag = ::symbolizeEnum<::MyNonQuotedPrintBitEnum>(enumKeyword)) {
+// DEF: flags = flags | *flag;
+// DEF: } else {
+// DEF: return parser.emitError(loc, "expected one of [none, tagged, Bit1, Bit2, Bit3, BitGroup] for Example new-style bit enum, got: ") << enumKeyword;
+// DEF: }
+// DEF: } while (::mlir::succeeded(parser.parseOptionalVerticalBar()));
+// DEF: return flags;
+// DEF: }
def MyCommaSeparatedBitEnum
: I32BitEnum<"MyCommaSeparatedBitEnum", "Comma-separated bit enum",
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
index eed05558447de..853ba5b0d0c71 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
@@ -125,7 +125,7 @@ static bool isUndelimitedCommaBitEnumParam(const ParameterElement *el) {
if (!enumAttr)
return false;
EnumInfo enumInfo(enumAttr->getValueAsDef("enum"));
- return enumInfo.isBitEnum() && !enumInfo.printBitEnumQuoted() &&
+ return enumInfo.isNewStyleBitEnum() &&
enumInfo.getDef().getValueAsString("separator").trim() == ",";
}
diff --git a/mlir/tools/mlir-tblgen/EnumsGen.cpp b/mlir/tools/mlir-tblgen/EnumsGen.cpp
index 845f1ef46cf35..c83ed3cf42fcd 100644
--- a/mlir/tools/mlir-tblgen/EnumsGen.cpp
+++ b/mlir/tools/mlir-tblgen/EnumsGen.cpp
@@ -66,26 +66,71 @@ static void emitEnumClass(const Record &enumDef, StringRef enumName,
os << "};\n\n";
}
-static void emitParserPrinter(const EnumInfo &enumInfo, StringRef qualName,
- StringRef cppNamespace, raw_ostream &os) {
- std::optional<Attribute> enumAttrInfo = enumInfo.asEnumAttr();
- if (enumInfo.getUnderlyingType().empty() ||
- (enumAttrInfo && enumAttrInfo->getConstBuilderTemplate().empty()))
- return;
+/// Returns a bit vector with a bit set for every case that cannot be printed
+/// as a keyword.
+static BitVector getNonKeywordCases(ArrayRef<EnumCase> cases) {
+ BitVector nonKeywordCases(cases.size());
+ for (auto [index, enumerant] : llvm::enumerate(cases))
+ if (!tblgen::canFormatStringAsKeyword(enumerant.getStr()))
+ nonKeywordCases.set(index);
+ return nonKeywordCases;
+}
+
+/// Emits the declarations of the 'FieldParser' specializations of the enum.
+/// The definitions are emitted by 'emitFieldParserDefs' into the enum
+/// definitions file instead of inline in the header. The bodies would otherwise
+/// be type-checked and require instantiating the 'FailureOr' and
+/// 'std::optional' types in every translation unit including the header,
+/// despite rarely being used. The forward declarations of 'AsmParser' and
+/// 'FieldParser' are emitted once per file by 'emitEnumDecls'.
+static void emitFieldParserDecls(const EnumInfo &enumInfo, StringRef qualName,
+ raw_ostream &os) {
+ const char *const fieldParserDecls = R"(
+namespace mlir {
+template<>
+struct FieldParser<{0}, {0}> {{{1}
+ static FailureOr<{0}> parse(AsmParser &parser);
+};
+
+/// Support for std::optional, useful in attribute/type definition where the enum is
+/// used as:
+///
+/// let parameters = (ins OptionalParameter<"std::optional<TheEnumName>">:$value);
+template<>
+struct FieldParser<std::optional<{0}>, std::optional<{0}>> {{
+ static constexpr bool isKeyValueCompositional = false;
+
+ static FailureOr<std::optional<{0}>> parse(AsmParser &parser);
+};
+} // namespace mlir
+)";
+
+ 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");
+ }
+ os << formatv(fieldParserDecls, qualName, isKeyValueCompositional);
+}
+
+/// Emits the definitions of the 'FieldParser' specializations declared by
+/// 'emitFieldParserDecls'.
+static void emitFieldParserDefs(const EnumInfo &enumInfo, raw_ostream &os) {
+ std::string qualName = enumInfo.getQualifiedName();
+ StringRef cppNamespace = enumInfo.getCppNamespace();
auto cases = enumInfo.getAllCases();
+ BitVector nonKeywordCases = getNonKeywordCases(cases);
- // Check which cases shouldn't be printed using a keyword.
- llvm::BitVector nonKeywordCases(cases.size());
std::string casesList;
llvm::raw_string_ostream caseListOs(casesList);
caseListOs << "[";
llvm::interleaveComma(llvm::enumerate(cases), caseListOs,
[&](auto enumerant) {
StringRef name = enumerant.value().getStr();
- if (!mlir::tblgen::canFormatStringAsKeyword(name)) {
- nonKeywordCases.set(enumerant.index());
+ if (nonKeywordCases.test(enumerant.index()))
caseListOs << "\\\"" << name << "\\\"";
- }
caseListOs << name;
});
caseListOs << "]";
@@ -99,151 +144,125 @@ static void emitParserPrinter(const EnumInfo &enumInfo, StringRef qualName,
});
casesInitListOs << "}";
- // Generate the parser and the start of the printer for the enum, excluding
- // non-quoted bit enums.
- const char *parsedAndPrinterStart = R"(
+ // Generate the parser for the enum, excluding non-quoted bit enums.
+ const char *const fieldParserDefs = R"(
namespace mlir {
-template <typename T, typename>
-struct FieldParser;
+FailureOr<{0}> FieldParser<{0}, {0}>::parse(AsmParser &parser) {{
+ // Parse the keyword/string containing the enum.
+ std::string enumKeyword;
+ auto loc = parser.getCurrentLocation();
+ if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
+ return parser.emitError(loc, "expected keyword for {2}");
+
+ // Symbolize the keyword.
+ if (::std::optional<{0}> attr = {1}::symbolizeEnum<{0}>(enumKeyword))
+ return *attr;
+ return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
+}
-template<>
-struct FieldParser<{0}, {0}> {{
- template <typename ParserT>
- static FailureOr<{0}> parse(ParserT &parser) {{
- // Parse the keyword/string containing the enum.
- std::string enumKeyword;
+FailureOr<std::optional<{0}>>
+FieldParser<std::optional<{0}>, std::optional<{0}>>::parse(AsmParser &parser) {{
+ // Parse the keyword/string containing the enum.
+ std::string enumKeyword;
+ auto loc = parser.getCurrentLocation();
+ if (failed(parser.parseOptionalKeywordOrString(&enumKeyword, {4})))
+ return std::optional<{0}>{{};
+
+ // Symbolize the keyword.
+ if (::std::optional<{0}> attr = {1}::symbolizeEnum<{0}>(enumKeyword))
+ return attr;
+ return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
+}
+} // namespace mlir
+)";
+
+ const char *const fieldParserDefsUnquotedBitEnum = R"(
+namespace mlir {
+FailureOr<{0}> FieldParser<{0}, {0}>::parse(AsmParser &parser) {{
+ {0} flags = {{};
+ do {{
+ // Parse the keyword containing a part of the enum.
+ ::llvm::StringRef enumKeyword;
auto loc = parser.getCurrentLocation();
- if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
+ if (failed(parser.parseOptionalKeyword(&enumKeyword))) {{
return parser.emitError(loc, "expected keyword for {2}");
+ }
// Symbolize the keyword.
- if (::std::optional<{0}> attr = {1}::symbolizeEnum<{0}>(enumKeyword))
- return *attr;
- return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
- }
-};
-
-/// Support for std::optional, useful in attribute/type definition where the enum is
-/// used as:
-///
-/// let parameters = (ins OptionalParameter<"std::optional<TheEnumName>">:$value);
-template<>
-struct FieldParser<std::optional<{0}>, std::optional<{0}>> {{
- static constexpr bool isKeyValueCompositional = false;
+ if (::std::optional<{0}> flag = {1}::symbolizeEnum<{0}>(enumKeyword)) {{
+ flags = flags | *flag;
+ } else {{
+ return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
+ }
+ } while (::mlir::succeeded(parser.{5}()));
+ return flags;
+}
- template <typename ParserT>
- static FailureOr<std::optional<{0}>> parse(ParserT &parser) {{
- // Parse the keyword/string containing the enum.
- std::string enumKeyword;
+FailureOr<std::optional<{0}>>
+FieldParser<std::optional<{0}>, std::optional<{0}>>::parse(AsmParser &parser) {{
+ {0} flags = {{};
+ bool firstIter = true;
+ do {{
+ // Parse the keyword containing a part of the enum.
+ ::llvm::StringRef enumKeyword;
auto loc = parser.getCurrentLocation();
- if (failed(parser.parseOptionalKeywordOrString(&enumKeyword, {4})))
- return std::optional<{0}>{{};
+ if (failed(parser.parseOptionalKeyword(&enumKeyword, {6}))) {{
+ if (firstIter)
+ return std::optional<{0}>{{};
+ return parser.emitError(loc, "expected keyword for {2} after '{4}'");
+ }
+ firstIter = false;
// Symbolize the keyword.
- if (::std::optional<{0}> attr = {1}::symbolizeEnum<{0}>(enumKeyword))
- return attr;
- return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
- }
-};
+ if (::std::optional<{0}> flag = {1}::symbolizeEnum<{0}>(enumKeyword)) {{
+ flags = flags | *flag;
+ } else {{
+ return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
+ }
+ } while(::mlir::succeeded(parser.{5}()));
+ return std::optional<{0}>{{flags};
+}
} // namespace mlir
-
-namespace llvm {
-inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, {0} value) {{
- auto valueStr = stringifyEnum(value);
)";
- const char *parsedAndPrinterStartUnquotedBitEnum = R"(
- namespace mlir {
- template <typename T, typename>
- struct FieldParser;
-
- template<>
- struct FieldParser<{0}, {0}> {{
- static constexpr bool isKeyValueCompositional = {7};
-
- template <typename ParserT>
- static FailureOr<{0}> parse(ParserT &parser) {{
- {0} flags = {{};
- do {{
- // Parse the keyword containing a part of the enum.
- ::llvm::StringRef enumKeyword;
- auto loc = parser.getCurrentLocation();
- if (failed(parser.parseOptionalKeyword(&enumKeyword))) {{
- return parser.emitError(loc, "expected keyword for {2}");
- }
-
- // Symbolize the keyword.
- if (::std::optional<{0}> flag = {1}::symbolizeEnum<{0}>(enumKeyword)) {{
- flags = flags | *flag;
- } else {{
- return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
- }
- } while (::mlir::succeeded(parser.{5}()));
- return flags;
- }
- };
-
- /// Support for std::optional, useful in attribute/type definition where the enum is
- /// used as:
- ///
- /// let parameters = (ins OptionalParameter<"std::optional<TheEnumName>">:$value);
- template<>
- struct FieldParser<std::optional<{0}>, std::optional<{0}>> {{
- static constexpr bool isKeyValueCompositional = false;
-
- template <typename ParserT>
- static FailureOr<std::optional<{0}>> parse(ParserT &parser) {{
- {0} flags = {{};
- bool firstIter = true;
- do {{
- // Parse the keyword containing a part of the enum.
- ::llvm::StringRef enumKeyword;
- auto loc = parser.getCurrentLocation();
- if (failed(parser.parseOptionalKeyword(&enumKeyword, {6}))) {{
- if (firstIter)
- return std::optional<{0}>{{};
- return parser.emitError(loc, "expected keyword for {2} after '{4}'");
- }
- firstIter = false;
-
- // Symbolize the keyword.
- if (::std::optional<{0}> flag = {1}::symbolizeEnum<{0}>(enumKeyword)) {{
- flags = flags | *flag;
- } else {{
- return parser.emitError(loc, "expected one of {3} for {2}, got: ") << enumKeyword;
- }
- } while(::mlir::succeeded(parser.{5}()));
- return std::optional<{0}>{{flags};
- }
- };
- } // namespace mlir
-
- namespace llvm {
- inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, {0} value) {{
- auto valueStr = stringifyEnum(value);
- )";
-
- bool isNewStyleBitEnum =
- enumInfo.isBitEnum() && !enumInfo.printBitEnumQuoted();
-
- if (isNewStyleBitEnum) {
- if (nonKeywordCases.any())
- return PrintFatalError(
- "bit enum " + qualName +
- " cannot be printed unquoted with cases that cannot be keywords");
+ 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 ','");
- os << formatv(parsedAndPrinterStartUnquotedBitEnum, qualName, cppNamespace,
+ os << formatv(fieldParserDefsUnquotedBitEnum, qualName, cppNamespace,
enumInfo.getSummary(), casesList, separator, parseSeparatorFn,
- casesInitList, separator.trim() == "," ? "false" : "true");
+ casesInitList);...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/233730
More information about the Mlir-commits
mailing list