MLIR  21.0.0git
IRDLToCpp.cpp
Go to the documentation of this file.
1 //===- IRDLToCpp.cpp - Converts IRDL definitions to C++ -------------------===//
2 //
3 // Part of the LLVM Project, under the A0ache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "mlir/Support/LLVM.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/ADT/TypeSwitch.h"
17 #include "llvm/Support/FormatVariadic.h"
18 #include "llvm/Support/raw_ostream.h"
19 
20 #include "TemplatingUtils.h"
21 
22 using namespace mlir;
23 
24 constexpr char headerTemplateText[] =
25 #include "Templates/Header.txt"
26  ;
27 
28 constexpr char declarationMacroFlag[] = "GEN_DIALECT_DECL_HEADER";
29 constexpr char definitionMacroFlag[] = "GEN_DIALECT_DEF";
30 
31 namespace {
32 
33 /// The set of strings that can be generated from a Dialect declaraiton
34 struct DialectStrings {
35  std::string dialectName;
36  std::string dialectCppName;
37  std::string dialectCppShortName;
38  std::string dialectBaseTypeName;
39 
40  std::string namespaceOpen;
41  std::string namespaceClose;
42  std::string namespacePath;
43 };
44 
45 /// The set of strings that can be generated from a Type declaraiton
46 struct TypeStrings {
47  StringRef typeName;
48  std::string typeCppName;
49 };
50 
51 /// The set of strings that can be generated from an Operation declaraiton
52 struct OpStrings {
53  StringRef opName;
54  std::string opCppName;
55  SmallVector<std::string> opResultNames;
56  SmallVector<std::string> opOperandNames;
57 };
58 
59 static std::string joinNameList(llvm::ArrayRef<std::string> names) {
60  std::string nameArray;
61  llvm::raw_string_ostream nameArrayStream(nameArray);
62  nameArrayStream << "{\"" << llvm::join(names, "\", \"") << "\"}";
63 
64  return nameArray;
65 }
66 
67 /// Generates the C++ type name for a TypeOp
68 static std::string typeToCppName(irdl::TypeOp type) {
69  return llvm::formatv("{0}Type",
70  convertToCamelFromSnakeCase(type.getSymName(), true));
71 }
72 
73 /// Generates the C++ class name for an OperationOp
74 static std::string opToCppName(irdl::OperationOp op) {
75  return llvm::formatv("{0}Op",
76  convertToCamelFromSnakeCase(op.getSymName(), true));
77 }
78 
79 /// Generates TypeStrings from a TypeOp
80 static TypeStrings getStrings(irdl::TypeOp type) {
81  TypeStrings strings;
82  strings.typeName = type.getSymName();
83  strings.typeCppName = typeToCppName(type);
84  return strings;
85 }
86 
87 /// Generates OpStrings from an OperatioOp
88 static OpStrings getStrings(irdl::OperationOp op) {
89  auto operandOp = op.getOp<irdl::OperandsOp>();
90 
91  auto resultOp = op.getOp<irdl::ResultsOp>();
92 
93  OpStrings strings;
94  strings.opName = op.getSymName();
95  strings.opCppName = opToCppName(op);
96 
97  if (operandOp) {
98  strings.opOperandNames = SmallVector<std::string>(
99  llvm::map_range(operandOp->getNames(), [](Attribute attr) {
100  return llvm::formatv("{0}", cast<StringAttr>(attr));
101  }));
102  }
103 
104  if (resultOp) {
105  strings.opResultNames = SmallVector<std::string>(
106  llvm::map_range(resultOp->getNames(), [](Attribute attr) {
107  return llvm::formatv("{0}", cast<StringAttr>(attr));
108  }));
109  }
110 
111  return strings;
112 }
113 
114 /// Fills a dictionary with values from TypeStrings
115 static void fillDict(irdl::detail::dictionary &dict,
116  const TypeStrings &strings) {
117  dict["TYPE_NAME"] = strings.typeName;
118  dict["TYPE_CPP_NAME"] = strings.typeCppName;
119 }
120 
121 /// Fills a dictionary with values from OpStrings
122 static void fillDict(irdl::detail::dictionary &dict, const OpStrings &strings) {
123  const auto operandCount = strings.opOperandNames.size();
124  const auto resultCount = strings.opResultNames.size();
125 
126  dict["OP_NAME"] = strings.opName;
127  dict["OP_CPP_NAME"] = strings.opCppName;
128  dict["OP_OPERAND_COUNT"] = std::to_string(strings.opOperandNames.size());
129  dict["OP_RESULT_COUNT"] = std::to_string(strings.opResultNames.size());
130  dict["OP_OPERAND_INITIALIZER_LIST"] =
131  operandCount ? joinNameList(strings.opOperandNames) : "{\"\"}";
132  dict["OP_RESULT_INITIALIZER_LIST"] =
133  resultCount ? joinNameList(strings.opResultNames) : "{\"\"}";
134 }
135 
136 /// Fills a dictionary with values from DialectStrings
137 static void fillDict(irdl::detail::dictionary &dict,
138  const DialectStrings &strings) {
139  dict["DIALECT_NAME"] = strings.dialectName;
140  dict["DIALECT_BASE_TYPE_NAME"] = strings.dialectBaseTypeName;
141  dict["DIALECT_CPP_NAME"] = strings.dialectCppName;
142  dict["DIALECT_CPP_SHORT_NAME"] = strings.dialectCppShortName;
143  dict["NAMESPACE_OPEN"] = strings.namespaceOpen;
144  dict["NAMESPACE_CLOSE"] = strings.namespaceClose;
145  dict["NAMESPACE_PATH"] = strings.namespacePath;
146 }
147 
148 static LogicalResult generateTypedefList(irdl::DialectOp &dialect,
149  SmallVector<std::string> &typeNames) {
150  auto typeOps = dialect.getOps<irdl::TypeOp>();
151  auto range = llvm::map_range(typeOps, typeToCppName);
152  typeNames = SmallVector<std::string>(range);
153  return success();
154 }
155 
156 static LogicalResult generateOpList(irdl::DialectOp &dialect,
157  SmallVector<std::string> &opNames) {
158  auto operationOps = dialect.getOps<irdl::OperationOp>();
159  auto range = llvm::map_range(operationOps, opToCppName);
160  opNames = SmallVector<std::string>(range);
161  return success();
162 }
163 
164 } // namespace
165 
166 static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output,
167  irdl::detail::dictionary &dict) {
168  static const auto typeDeclTemplate = irdl::detail::Template(
169 #include "Templates/TypeDecl.txt"
170  );
171 
172  fillDict(dict, getStrings(type));
173  typeDeclTemplate.render(output, dict);
174 
175  return success();
176 }
177 
179  const OpStrings &opStrings) {
180  auto opGetters = std::string{};
181  auto resGetters = std::string{};
182 
183  for (size_t i = 0, end = opStrings.opOperandNames.size(); i < end; ++i) {
184  const auto op =
185  llvm::convertToCamelFromSnakeCase(opStrings.opOperandNames[i], true);
186  opGetters += llvm::formatv("::mlir::Value get{0}() { return "
187  "getStructuredOperands({1}).front(); }\n ",
188  op, i);
189  }
190  for (size_t i = 0, end = opStrings.opResultNames.size(); i < end; ++i) {
191  const auto op =
192  llvm::convertToCamelFromSnakeCase(opStrings.opResultNames[i], true);
193  resGetters += llvm::formatv(
194  R"(::mlir::Value get{0}() { return ::llvm::cast<::mlir::Value>(getStructuredResults({1}).front()); }
195  )",
196  op, i);
197  }
198 
199  dict["OP_OPERAND_GETTER_DECLS"] = opGetters;
200  dict["OP_RESULT_GETTER_DECLS"] = resGetters;
201 }
202 
204  const OpStrings &opStrings) {
205  std::string buildDecls;
206  llvm::raw_string_ostream stream{buildDecls};
207 
208  auto resultParams =
209  llvm::join(llvm::map_range(opStrings.opResultNames,
210  [](StringRef name) -> std::string {
211  return llvm::formatv(
212  "::mlir::Type {0}, ",
213  llvm::convertToCamelFromSnakeCase(name));
214  }),
215  "");
216 
217  auto operandParams =
218  llvm::join(llvm::map_range(opStrings.opOperandNames,
219  [](StringRef name) -> std::string {
220  return llvm::formatv(
221  "::mlir::Value {0}, ",
222  llvm::convertToCamelFromSnakeCase(name));
223  }),
224  "");
225 
226  stream << llvm::formatv(
227  R"(static void build(::mlir::OpBuilder &opBuilder, ::mlir::OperationState &opState, {0} {1} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {{});)",
228  resultParams, operandParams);
229  dict["OP_BUILD_DECLS"] = buildDecls;
230 }
231 
232 static LogicalResult generateOperationInclude(irdl::OperationOp op,
233  raw_ostream &output,
234  irdl::detail::dictionary &dict) {
235  static const auto perOpDeclTemplate = irdl::detail::Template(
236 #include "Templates/PerOperationDecl.txt"
237  );
238  const auto opStrings = getStrings(op);
239  fillDict(dict, opStrings);
240 
241  generateOpGetterDeclarations(dict, opStrings);
242  generateOpBuilderDeclarations(dict, opStrings);
243 
244  perOpDeclTemplate.render(output, dict);
245  return success();
246 }
247 
248 static LogicalResult generateInclude(irdl::DialectOp dialect,
249  raw_ostream &output,
250  DialectStrings &dialectStrings) {
251  static const auto dialectDeclTemplate = irdl::detail::Template(
252 #include "Templates/DialectDecl.txt"
253  );
254  static const auto typeHeaderDeclTemplate = irdl::detail::Template(
255 #include "Templates/TypeHeaderDecl.txt"
256  );
257 
259  fillDict(dict, dialectStrings);
260 
261  dialectDeclTemplate.render(output, dict);
262  typeHeaderDeclTemplate.render(output, dict);
263 
264  auto typeOps = dialect.getOps<irdl::TypeOp>();
265  auto operationOps = dialect.getOps<irdl::OperationOp>();
266 
267  for (auto &&typeOp : typeOps) {
268  if (failed(generateTypeInclude(typeOp, output, dict)))
269  return failure();
270  }
271 
272  SmallVector<std::string> opNames;
273  if (failed(generateOpList(dialect, opNames)))
274  return failure();
275 
276  auto classDeclarations =
277  llvm::join(llvm::map_range(opNames,
278  [](llvm::StringRef name) -> std::string {
279  return llvm::formatv("class {0};", name);
280  }),
281  "\n");
282  const auto forwardDeclarations = llvm::formatv(
283  "{1}\n{0}\n{2}", std::move(classDeclarations),
284  dialectStrings.namespaceOpen, dialectStrings.namespaceClose);
285 
286  output << forwardDeclarations;
287  for (auto &&operationOp : operationOps) {
288  if (failed(generateOperationInclude(operationOp, output, dict)))
289  return failure();
290  }
291 
292  return success();
293 }
294 
295 static std::string generateOpDefinition(irdl::detail::dictionary &dict,
296  irdl::OperationOp op) {
297  static const auto perOpDefTemplate = mlir::irdl::detail::Template{
298 #include "Templates/PerOperationDef.txt"
299  };
300 
301  auto opStrings = getStrings(op);
302  fillDict(dict, opStrings);
303 
304  const auto operandCount = opStrings.opOperandNames.size();
305  const auto operandNames =
306  operandCount ? joinNameList(opStrings.opOperandNames) : "{\"\"}";
307 
308  const auto resultNames = joinNameList(opStrings.opResultNames);
309 
310  auto resultTypes = llvm::join(
311  llvm::map_range(opStrings.opResultNames,
312  [](StringRef attr) -> std::string {
313  return llvm::formatv("::mlir::Type {0}, ", attr);
314  }),
315  "");
316  auto operandTypes = llvm::join(
317  llvm::map_range(opStrings.opOperandNames,
318  [](StringRef attr) -> std::string {
319  return llvm::formatv("::mlir::Value {0}, ", attr);
320  }),
321  "");
322  auto operandAdder =
323  llvm::join(llvm::map_range(opStrings.opOperandNames,
324  [](StringRef attr) -> std::string {
325  return llvm::formatv(
326  " opState.addOperands({0});", attr);
327  }),
328  "\n");
329  auto resultAdder = llvm::join(
330  llvm::map_range(opStrings.opResultNames,
331  [](StringRef attr) -> std::string {
332  return llvm::formatv(" opState.addTypes({0});", attr);
333  }),
334  "\n");
335 
336  const auto buildDefinition = llvm::formatv(
337  R"(
338 void {0}::build(::mlir::OpBuilder &opBuilder, ::mlir::OperationState &opState, {1} {2} ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {{
339 {3}
340 {4}
341 }
342 )",
343  opStrings.opCppName, std::move(resultTypes), std::move(operandTypes),
344  std::move(operandAdder), std::move(resultAdder));
345 
346  dict["OP_BUILD_DEFS"] = buildDefinition;
347 
348  std::string str;
349  llvm::raw_string_ostream stream{str};
350  perOpDefTemplate.render(stream, dict);
351  return str;
352 }
353 
354 static std::string
355 generateTypeVerifierCase(StringRef name, const DialectStrings &dialectStrings) {
356  return llvm::formatv(
357  R"(.Case({1}::{0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {
358 value = {1}::{0}::get(parser.getContext());
359 return ::mlir::success(!!value);
360 }))",
361  name, dialectStrings.namespacePath);
362 }
363 
364 static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output,
365  DialectStrings &dialectStrings) {
366 
367  static const auto typeHeaderDefTemplate = mlir::irdl::detail::Template{
368 #include "Templates/TypeHeaderDef.txt"
369  };
370  static const auto typeDefTemplate = mlir::irdl::detail::Template{
371 #include "Templates/TypeDef.txt"
372  };
373  static const auto dialectDefTemplate = mlir::irdl::detail::Template{
374 #include "Templates/DialectDef.txt"
375  };
376 
378  fillDict(dict, dialectStrings);
379 
380  typeHeaderDefTemplate.render(output, dict);
381 
382  SmallVector<std::string> typeNames;
383  if (failed(generateTypedefList(dialect, typeNames)))
384  return failure();
385 
386  dict["TYPE_LIST"] = llvm::join(
387  llvm::map_range(typeNames,
388  [&dialectStrings](llvm::StringRef name) -> std::string {
389  return llvm::formatv(
390  "{0}::{1}", dialectStrings.namespacePath, name);
391  }),
392  ",\n");
393 
394  auto typeVerifierGenerator =
395  [&dialectStrings](llvm::StringRef name) -> std::string {
396  return generateTypeVerifierCase(name, dialectStrings);
397  };
398 
399  auto typeCase =
400  llvm::join(llvm::map_range(typeNames, typeVerifierGenerator), "\n");
401 
402  dict["TYPE_PARSER"] = llvm::formatv(
403  R"(static ::mlir::OptionalParseResult generatedTypeParser(::mlir::AsmParser &parser, ::llvm::StringRef *mnemonic, ::mlir::Type &value) {
404  return ::mlir::AsmParser::KeywordSwitch<::mlir::OptionalParseResult>(parser)
405  {0}
406  .Default([&](llvm::StringRef keyword, llvm::SMLoc) {{
407  *mnemonic = keyword;
408  return std::nullopt;
409  });
410 })",
411  std::move(typeCase));
412 
413  auto typePrintCase =
414  llvm::join(llvm::map_range(typeNames,
415  [&](llvm::StringRef name) -> std::string {
416  return llvm::formatv(
417  R"(.Case<{1}::{0}>([&](auto t) {
418  printer << {1}::{0}::getMnemonic();
419  return ::mlir::success();
420  }))",
421  name, dialectStrings.namespacePath);
422  }),
423  "\n");
424  dict["TYPE_PRINTER"] = llvm::formatv(
425  R"(static ::llvm::LogicalResult generatedTypePrinter(::mlir::Type def, ::mlir::AsmPrinter &printer) {
426  return ::llvm::TypeSwitch<::mlir::Type, ::llvm::LogicalResult>(def)
427  {0}
428  .Default([](auto) {{ return ::mlir::failure(); });
429 })",
430  std::move(typePrintCase));
431 
432  dict["TYPE_DEFINES"] =
433  join(map_range(typeNames,
434  [&](StringRef name) -> std::string {
435  return formatv("MLIR_DEFINE_EXPLICIT_TYPE_ID({1}::{0})",
436  name, dialectStrings.namespacePath);
437  }),
438  "\n");
439 
440  typeDefTemplate.render(output, dict);
441 
442  auto operations = dialect.getOps<irdl::OperationOp>();
443  SmallVector<std::string> opNames;
444  if (failed(generateOpList(dialect, opNames)))
445  return failure();
446 
447  const auto commaSeparatedOpList = llvm::join(
448  map_range(opNames,
449  [&dialectStrings](llvm::StringRef name) -> std::string {
450  return llvm::formatv("{0}::{1}", dialectStrings.namespacePath,
451  name);
452  }),
453  ",\n");
454 
455  const auto opDefinitionGenerator = [&dict](irdl::OperationOp op) {
456  return generateOpDefinition(dict, op);
457  };
458 
459  const auto perOpDefinitions =
460  llvm::join(llvm::map_range(operations, opDefinitionGenerator), "\n");
461 
462  dict["OP_LIST"] = commaSeparatedOpList;
463  dict["OP_CLASSES"] = perOpDefinitions;
464  output << perOpDefinitions;
465  dialectDefTemplate.render(output, dict);
466 
467  return success();
468 }
469 
470 static LogicalResult verifySupported(irdl::DialectOp dialect) {
471  LogicalResult res = success();
472  dialect.walk([&](mlir::Operation *op) {
473  res =
475  .Case<irdl::DialectOp>(([](irdl::DialectOp) { return success(); }))
476  .Case<irdl::OperationOp>(
477  ([](irdl::OperationOp) { return success(); }))
478  .Case<irdl::TypeOp>(([](irdl::TypeOp) { return success(); }))
479  .Case<irdl::OperandsOp>(([](irdl::OperandsOp op) -> LogicalResult {
480  if (llvm::all_of(
481  op.getVariadicity(), [](irdl::VariadicityAttr attr) {
482  return attr.getValue() == irdl::Variadicity::single;
483  }))
484  return success();
485  return op.emitError("IRDL C++ translation does not yet support "
486  "variadic operations");
487  }))
488  .Case<irdl::ResultsOp>(([](irdl::ResultsOp op) -> LogicalResult {
489  if (llvm::all_of(
490  op.getVariadicity(), [](irdl::VariadicityAttr attr) {
491  return attr.getValue() == irdl::Variadicity::single;
492  }))
493  return success();
494  return op.emitError(
495  "IRDL C++ translation does not yet support variadic results");
496  }))
497  .Case<irdl::AnyOp>(([](irdl::AnyOp) { return success(); }))
498  .Default([](mlir::Operation *op) -> LogicalResult {
499  return op->emitError("IRDL C++ translation does not yet support "
500  "translation of ")
501  << op->getName() << " operation";
502  });
503 
504  if (failed(res))
505  return WalkResult::interrupt();
506 
507  return WalkResult::advance();
508  });
509 
510  return res;
511 }
512 
513 LogicalResult
515  raw_ostream &output) {
516  static const auto typeDefTempl = detail::Template(
517 #include "Templates/TypeDef.txt"
518  );
519 
520  llvm::SmallMapVector<DialectOp, DialectStrings, 2> dialectStringTable;
521 
522  for (auto dialect : dialects) {
523  if (failed(verifySupported(dialect)))
524  return failure();
525 
526  StringRef dialectName = dialect.getSymName();
527 
528  SmallVector<SmallString<8>> namespaceAbsolutePath{{"mlir"}, dialectName};
529  std::string namespaceOpen;
530  std::string namespaceClose;
531  std::string namespacePath;
532  llvm::raw_string_ostream namespaceOpenStream(namespaceOpen);
533  llvm::raw_string_ostream namespaceCloseStream(namespaceClose);
534  llvm::raw_string_ostream namespacePathStream(namespacePath);
535  for (auto &pathElement : namespaceAbsolutePath) {
536  namespaceOpenStream << "namespace " << pathElement << " {\n";
537  namespaceCloseStream << "} // namespace " << pathElement << "\n";
538  namespacePathStream << "::" << pathElement;
539  }
540 
541  std::string cppShortName =
542  llvm::convertToCamelFromSnakeCase(dialectName, true);
543  std::string dialectBaseTypeName = llvm::formatv("{0}Type", cppShortName);
544  std::string cppName = llvm::formatv("{0}Dialect", cppShortName);
545 
546  DialectStrings dialectStrings;
547  dialectStrings.dialectName = dialectName;
548  dialectStrings.dialectBaseTypeName = dialectBaseTypeName;
549  dialectStrings.dialectCppName = cppName;
550  dialectStrings.dialectCppShortName = cppShortName;
551  dialectStrings.namespaceOpen = namespaceOpen;
552  dialectStrings.namespaceClose = namespaceClose;
553  dialectStrings.namespacePath = namespacePath;
554 
555  dialectStringTable[dialect] = std::move(dialectStrings);
556  }
557 
558  // generate the actual header
559  output << headerTemplateText;
560 
561  output << llvm::formatv("#ifdef {0}\n#undef {0}\n", declarationMacroFlag);
562  for (auto dialect : dialects) {
563 
564  auto &dialectStrings = dialectStringTable[dialect];
565  auto &dialectName = dialectStrings.dialectName;
566 
567  if (failed(generateInclude(dialect, output, dialectStrings)))
568  return dialect->emitError("Error in Dialect " + dialectName +
569  " while generating headers");
570  }
571  output << llvm::formatv("#endif // #ifdef {}\n", declarationMacroFlag);
572 
573  output << llvm::formatv("#ifdef {0}\n#undef {0}\n ", definitionMacroFlag);
574  for (auto &dialect : dialects) {
575  auto &dialectStrings = dialectStringTable[dialect];
576  auto &dialectName = dialectStrings.dialectName;
577 
578  if (failed(generateLib(dialect, output, dialectStrings)))
579  return dialect->emitError("Error in Dialect " + dialectName +
580  " while generating library");
581  }
582  output << llvm::formatv("#endif // #ifdef {}\n", definitionMacroFlag);
583 
584  return success();
585 }
static LogicalResult verifySupported(irdl::DialectOp dialect)
Definition: IRDLToCpp.cpp:447
static LogicalResult generateInclude(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings)
Definition: IRDLToCpp.cpp:247
static LogicalResult generateOperationInclude(irdl::OperationOp op, raw_ostream &output, irdl::detail::dictionary &dict)
Definition: IRDLToCpp.cpp:231
static void generateOpGetterDeclarations(irdl::detail::dictionary &dict, const OpStrings &opStrings)
Definition: IRDLToCpp.cpp:178
static void generateOpBuilderDeclarations(irdl::detail::dictionary &dict, const OpStrings &opStrings)
Definition: IRDLToCpp.cpp:202
constexpr char declarationMacroFlag[]
Definition: IRDLToCpp.cpp:28
constexpr char headerTemplateText[]
Definition: IRDLToCpp.cpp:24
static std::string generateTypeVerifierCase(StringRef name, const DialectStrings &dialectStrings)
Definition: IRDLToCpp.cpp:349
static LogicalResult generateTypeInclude(irdl::TypeOp type, raw_ostream &output, irdl::detail::dictionary &dict)
Definition: IRDLToCpp.cpp:166
static LogicalResult generateLib(irdl::DialectOp dialect, raw_ostream &output, DialectStrings &dialectStrings)
Definition: IRDLToCpp.cpp:355
constexpr char definitionMacroFlag[]
Definition: IRDLToCpp.cpp:29
static std::string generateOpDefinition(irdl::detail::dictionary &dict, irdl::OperationOp op)
Definition: IRDLToCpp.cpp:294
Attributes are known-constant values of operations.
Definition: Attributes.h:25
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:268
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:119
static WalkResult advance()
Definition: Visitors.h:51
static WalkResult interrupt()
Definition: Visitors.h:50
Template Code as used by IRDL-to-Cpp.
llvm::StringMap< llvm::SmallString< 8 > > dictionary
A dictionary stores a mapping of template variable names to their assigned string values.
LogicalResult translateIRDLDialectToCpp(llvm::ArrayRef< irdl::DialectOp > dialects, raw_ostream &output)
Translates an IRDL dialect definition to a C++ definition that can be used with MLIR.
Definition: IRDLToCpp.cpp:491
Include the generated interface declarations.