18#include <mlir/TableGen/EnumInfo.h>
19#include <mlir/TableGen/GenInfo.h>
21#include <llvm/Support/CommandLine.h>
22#include <llvm/Support/FormatVariadic.h>
23#include <llvm/TableGen/Record.h>
24#include <llvm/TableGen/TableGenBackend.h>
33 using HeaderGenerator::HeaderGenerator;
34 ~EnumHeaderGenerator()
override =
default;
36 void setEnumName(StringRef enumCppNamespace, StringRef enumClassName) {
37 std::string classNamePascal =
toPascalCase(enumClassName);
40 this->cEnumAltName =
toPascalCase(enumCppNamespace) + classNamePascal;
41 this->cppQualifiedPrefix = enumCppNamespace.str() +
"::" + enumClassName.str() +
"::";
46 void genCaseLabel(
const EnumCase &enumCase) {
47 static constexpr char fmt[] =
" /// `{0}{2}`\n {1}_{2} = {3}";
48 assert(!cEnumName.empty() &&
"cEnumName must be set");
49 assert(!cppQualifiedPrefix.empty() &&
"cppQualifiedPrefix must be set");
50 this->caseLabels.push_back(
51 llvm::formatv(fmt, cppQualifiedPrefix, cEnumName, enumCase.getSymbol(), enumCase.getValue())
56 void genEnumDeclaration()
const {
57 static constexpr char fmt[] = R
"(
61// type name based on prefix + dialect + enum class name
63// type name based on cpp namespace + enum class name
66 assert(!cEnumName.empty() && "cEnumName must be set");
67 os << llvm::formatv(fmt, cEnumName, cEnumAltName, llvm::join(caseLabels,
",\n"));
71 std::string cEnumName;
75 std::string cEnumAltName;
77 std::string cppQualifiedPrefix;
79 SmallVector<std::string> caseLabels;
84 using ImplementationGenerator::ImplementationGenerator;
85 ~EnumImplementationGenerator()
override =
default;
87 void setEnumName(StringRef , StringRef enumClassName) {
88 std::string classNamePascal =
toPascalCase(enumClassName);
95 void genWrapAndUnwrapDeclaration(StringRef enumCppNamespace, StringRef enumClassName)
const {
96 static constexpr char fmt[] = R
"(
97 static inline {0} wrap({1} cpp) {
100 static inline {1} unwrap({0} c) {
104 assert(!cEnumName.empty() && "cEnumName must be set");
105 os << llvm::formatv(fmt, cEnumName, enumCppNamespace +
"::" + enumClassName);
109 std::string cEnumName;
115static bool emitEnumCAPIHeader(
const llvm::RecordKeeper &records, raw_ostream &os) {
116 emitSourceFileHeader(
"Enum C API Declarations", os, records);
118 EnumHeaderGenerator generator(
"Enum", os);
119 generator.genPrologue();
122 for (
const auto *def : records.getAllDerivedDefinitionsIfDefined(
"EnumAttrInfo")) {
123 const EnumInfo enumInfo(def);
124 StringRef enumCppNamespace = enumInfo.getCppNamespace();
132 std::vector<EnumCase> enumCases = enumInfo.getAllCases();
133 if (enumCases.empty()) {
137 generator.setEnumName(enumCppNamespace, enumInfo.getEnumClassName());
138 for (EnumCase &enumCase : enumCases) {
139 generator.genCaseLabel(enumCase);
141 generator.genEnumDeclaration();
144 generator.genEpilogue();
149static bool emitEnumCAPIImpl(
const llvm::RecordKeeper &records, raw_ostream &os) {
150 emitSourceFileHeader(
"Enum C API Implementations", os, records);
152 EnumImplementationGenerator generator(
"Enum", os);
155 for (
const auto *def : records.getAllDerivedDefinitionsIfDefined(
"EnumAttrInfo")) {
156 const EnumInfo enumInfo(def);
157 StringRef enumCppNamespace = enumInfo.getCppNamespace();
165 std::vector<EnumCase> enumCases = enumInfo.getAllCases();
166 if (enumCases.empty()) {
170 generator.setEnumName(enumCppNamespace, enumInfo.getEnumClassName());
171 generator.genWrapAndUnwrapDeclaration(enumCppNamespace, enumInfo.getEnumClassName());
177 static mlir::GenRegistration genEnumCAPIHeader(
178 "gen-enum-capi-header",
"Generate C API enum declarations from EnumInfo definitions",
182 static mlir::GenRegistration genEnumCAPIImpl(
183 "gen-enum-capi-impl",
"Generate enum C API wrap/unwrap implementations", &emitEnumCAPIImpl
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 registerEnumCAPIGenerators()
Register the enum C API generators before command-line parsing.
Generator for common C implementation file elements.