// RUN: mlir-tblgen -gen-enum-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL // RUN: mlir-tblgen -gen-enum-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF include "mlir/IR/EnumAttr.td" include "mlir/IR/OpBase.td" // Test bit enums def None: I32BitEnumAttrCaseNone<"None", "none">; def Bit0: I32BitEnumAttrCaseBit<"Bit0", 0, "tagged">; def Bit1: I32BitEnumAttrCaseBit<"Bit1", 1>; def Bit2: I32BitEnumAttrCaseBit<"Bit2", 2>; def Bit3: I32BitEnumAttrCaseBit<"Bit3", 3>; def BitGroup: I32BitEnumAttrCaseGroup<"BitGroup", [ Bit0, Bit1 ]>; def MyBitEnum: I32BitEnumAttr<"MyBitEnum", "An example bit enum", [None, Bit0, Bit1, Bit2, Bit3, BitGroup]> { let genSpecializedAttr = 0; } // DECL-LABEL: enum class MyBitEnum : uint32_t // DECL: None = 0, // DECL: Bit0 = 1, // DECL: Bit1 = 2, // DECL: Bit2 = 4, // DECL: Bit3 = 8, // DECL: } // DECL: ::std::optional symbolizeMyBitEnum(uint32_t); // DECL: std::string stringifyMyBitEnum(MyBitEnum); // DECL: ::std::optional symbolizeMyBitEnum(::llvm::StringRef); // DECL: struct FieldParser<::MyBitEnum, ::MyBitEnum> { // DECL: template // 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, "invalid An example bit enum specification: ") << enumKeyword; // DECL: } // DECL: inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, ::MyBitEnum value) { // DECL: auto valueStr = stringifyEnum(value); // DECL: switch (value) { // DECL: case ::MyBitEnum::BitGroup: // DECL: return p << valueStr; // DECL: default: // DECL: break; // DECL: } // DECL: auto underlyingValue = static_cast>(value); // DECL: if (underlyingValue && !llvm::has_single_bit(underlyingValue)) // DECL: return p << '"' << valueStr << '"'; // DECL: return p << valueStr; // DEF-LABEL: std::string stringifyMyBitEnum // DEF: auto val = static_cast // DEF: if (val == 0) return "none"; // DEF: if (1u == (1u & val)) // DEF-NEXT: push_back("tagged") // DEF: if (2u == (2u & val)) // DEF-NEXT: push_back("Bit1") // DEF-LABEL: ::std::optional symbolizeMyBitEnum(::llvm::StringRef str) // DEF: if (str == "none") return MyBitEnum::None; // DEF: .Case("tagged", 1) // DEF: .Case("Bit1", 2) // Test enum printer generation for non non-keyword enums. def NonKeywordBit: I32BitEnumAttrCaseBit<"Bit0", 0, "tag-ged">; def MyMixedNonKeywordBitEnum: I32BitEnumAttr<"MyMixedNonKeywordBitEnum", "An example bit enum", [ NonKeywordBit, Bit1 ]> { let genSpecializedAttr = 0; } def MyNonKeywordBitEnum: I32BitEnumAttr<"MyNonKeywordBitEnum", "An example bit enum", [ NonKeywordBit ]> { let genSpecializedAttr = 0; } // DECL: inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, ::MyMixedNonKeywordBitEnum value) { // DECL: auto valueStr = stringifyEnum(value); // DECL: switch (value) { // DECL: case ::MyMixedNonKeywordBitEnum::Bit1: // DECL: break; // DECL: default: // DECL: return p << '"' << valueStr << '"'; // DECL: } // DECL: return p << valueStr; // DECL: } // DECL: inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, ::MyNonKeywordBitEnum value) { // DECL: auto valueStr = stringifyEnum(value); // DECL: return p << '"' << valueStr << '"';