26#include <mlir/TableGen/EnumInfo.h>
27#include <mlir/TableGen/GenInfo.h>
29#include <llvm/ADT/StringExtras.h>
30#include <llvm/Support/CommandLine.h>
31#include <llvm/Support/FormatVariadic.h>
32#include <llvm/TableGen/Record.h>
33#include <llvm/TableGen/TableGenBackend.h>
47 EnumTestGenerator(llvm::raw_ostream &outputStream) : TestGenerator(
"Enum", outputStream) {}
49 void genExtraMethod(
const ExtraMethod & )
const override {
50 llvm_unreachable(
"Enums cannot have extra methods");
56 void genEnumUsageTest(StringRef cEnumName, StringRef firstCaseValue)
const {
57 static constexpr char fmt[] = R
"(
59TEST_F({0}EnumLinkTests, Enum_{1}_Usage) {{
60 // We create a variable and check that enum values can be assigned.
64 // Verify we can compare enum values
65 EXPECT_EQ(enumValue, {2});
68 os << llvm::formatv(fmt, dialectNameCapitalized, cEnumName, firstCaseValue);
74 void genWrapUnwrapTest(StringRef cEnumName, StringRef firstCaseValue)
const {
75 static constexpr char fmt[] = R
"(
77TEST_F({0}EnumLinkTests, Enum_{1}_WrapUnwrap) {{
78 // We use the first enum case value for testing.
81 // Test that wrap and unwrap are inverses (at compile/link time)
82 // The actual C++ type doesn't exist in test context, so we just
83 // verify the functions exist and link.
84 {1} roundTrip = wrap(unwrap(cValue));
85 EXPECT_EQ(cValue, roundTrip);
88 os << llvm::formatv(fmt, dialectNameCapitalized, cEnumName, firstCaseValue);
93 void genCompleteRecord(
const EnumInfo &enumInfo) {
96 !enumInfo.getCppNamespace().contains_insensitive(
getDialectName())) {
100 std::vector<EnumCase> enumCases = enumInfo.getAllCases();
101 if (enumCases.empty()) {
110 std::string firstCaseValue =
111 llvm::formatv(
"{0}_{1}", cEnumName, enumCases[0].getSymbol()).str();
114 this->genEnumUsageTest(cEnumName, firstCaseValue);
117 this->genWrapUnwrapTest(cEnumName, firstCaseValue);
124static bool emitEnumCAPITests(
const llvm::RecordKeeper &records, raw_ostream &os) {
126 emitSourceFileHeader(
"Enum C API Tests", os, records);
129 EnumTestGenerator generator(os);
132 generator.genTestClassPrologue();
135 for (
const auto *def : records.getAllDerivedDefinitionsIfDefined(
"EnumAttrInfo")) {
136 EnumInfo enumInfo(def);
137 generator.genCompleteRecord(enumInfo);
144 static mlir::GenRegistration genEnumCAPITests(
145 "gen-enum-capi-tests",
"Generate enum C API unit tests", &emitEnumCAPITests
llvm::cl::opt< std::string > & getFunctionPrefix()
Return the FunctionPrefix option, registering it on first access.
llvm::cl::opt< std::string > & getDialectName()
Return the DialectName option, registering it on first access.
std::string toPascalCase(mlir::StringRef str)
Convert names separated by underscore or colon to PascalCase.
void registerEnumCAPITestGenerator()
Register the enum C API test generator before command-line parsing.
Generator for common test implementation file elements.