1 //===- TypeDefGen.cpp - MLIR typeDef definitions generator ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache 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 //
9 // TypeDefGen uses the description of typeDefs to generate C++ definitions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "mlir/Support/LogicalResult.h"
14 #include "mlir/TableGen/CodeGenHelpers.h"
15 #include "mlir/TableGen/Format.h"
16 #include "mlir/TableGen/GenInfo.h"
17 #include "mlir/TableGen/TypeDef.h"
18 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/TableGen/Error.h"
21 #include "llvm/TableGen/TableGenBackend.h"
22
23 #define DEBUG_TYPE "mlir-tblgen-typedefgen"
24
25 using namespace mlir;
26 using namespace mlir::tblgen;
27
28 static llvm::cl::OptionCategory typedefGenCat("Options for -gen-typedef-*");
29 static llvm::cl::opt<std::string>
30 selectedDialect("typedefs-dialect",
31 llvm::cl::desc("Gen types for this dialect"),
32 llvm::cl::cat(typedefGenCat), llvm::cl::CommaSeparated);
33
34 /// Find all the TypeDefs for the specified dialect. If no dialect specified and
35 /// can only find one dialect's types, use that.
findAllTypeDefs(const llvm::RecordKeeper & recordKeeper,SmallVectorImpl<TypeDef> & typeDefs)36 static void findAllTypeDefs(const llvm::RecordKeeper &recordKeeper,
37 SmallVectorImpl<TypeDef> &typeDefs) {
38 auto recDefs = recordKeeper.getAllDerivedDefinitions("TypeDef");
39 auto defs = llvm::map_range(
40 recDefs, [&](const llvm::Record *rec) { return TypeDef(rec); });
41 if (defs.empty())
42 return;
43
44 StringRef dialectName;
45 if (selectedDialect.getNumOccurrences() == 0) {
46 if (defs.empty())
47 return;
48
49 llvm::SmallSet<Dialect, 4> dialects;
50 for (const TypeDef &typeDef : defs)
51 dialects.insert(typeDef.getDialect());
52 if (dialects.size() != 1)
53 llvm::PrintFatalError("TypeDefs belonging to more than one dialect. Must "
54 "select one via '--typedefs-dialect'");
55
56 dialectName = (*dialects.begin()).getName();
57 } else if (selectedDialect.getNumOccurrences() == 1) {
58 dialectName = selectedDialect.getValue();
59 } else {
60 llvm::PrintFatalError("Cannot select multiple dialects for which to "
61 "generate types via '--typedefs-dialect'.");
62 }
63
64 for (const TypeDef &typeDef : defs)
65 if (typeDef.getDialect().getName().equals(dialectName))
66 typeDefs.push_back(typeDef);
67 }
68
69 namespace {
70
71 /// Pass an instance of this class to llvm::formatv() to emit a comma separated
72 /// list of parameters in the format by 'EmitFormat'.
73 class TypeParamCommaFormatter : public llvm::detail::format_adapter {
74 public:
75 /// Choose the output format
76 enum EmitFormat {
77 /// Emit "parameter1Type parameter1Name, parameter2Type parameter2Name,
78 /// [...]".
79 TypeNamePairs,
80
81 /// Emit "parameter1(parameter1), parameter2(parameter2), [...]".
82 TypeNameInitializer,
83
84 /// Emit "param1Name, param2Name, [...]".
85 JustParams,
86 };
87
TypeParamCommaFormatter(EmitFormat emitFormat,ArrayRef<TypeParameter> params,bool prependComma=true)88 TypeParamCommaFormatter(EmitFormat emitFormat, ArrayRef<TypeParameter> params,
89 bool prependComma = true)
90 : emitFormat(emitFormat), params(params), prependComma(prependComma) {}
91
92 /// llvm::formatv will call this function when using an instance as a
93 /// replacement value.
format(raw_ostream & os,StringRef options)94 void format(raw_ostream &os, StringRef options) override {
95 if (params.size() && prependComma)
96 os << ", ";
97
98 switch (emitFormat) {
99 case EmitFormat::TypeNamePairs:
100 interleaveComma(params, os,
101 [&](const TypeParameter &p) { emitTypeNamePair(p, os); });
102 break;
103 case EmitFormat::TypeNameInitializer:
104 interleaveComma(params, os, [&](const TypeParameter &p) {
105 emitTypeNameInitializer(p, os);
106 });
107 break;
108 case EmitFormat::JustParams:
109 interleaveComma(params, os,
110 [&](const TypeParameter &p) { os << p.getName(); });
111 break;
112 }
113 }
114
115 private:
116 // Emit "paramType paramName".
emitTypeNamePair(const TypeParameter & param,raw_ostream & os)117 static void emitTypeNamePair(const TypeParameter ¶m, raw_ostream &os) {
118 os << param.getCppType() << " " << param.getName();
119 }
120 // Emit "paramName(paramName)"
emitTypeNameInitializer(const TypeParameter & param,raw_ostream & os)121 void emitTypeNameInitializer(const TypeParameter ¶m, raw_ostream &os) {
122 os << param.getName() << "(" << param.getName() << ")";
123 }
124
125 EmitFormat emitFormat;
126 ArrayRef<TypeParameter> params;
127 bool prependComma;
128 };
129
130 } // end anonymous namespace
131
132 //===----------------------------------------------------------------------===//
133 // GEN: TypeDef declarations
134 //===----------------------------------------------------------------------===//
135
136 /// Print this above all the other declarations. Contains type declarations used
137 /// later on.
138 static const char *const typeDefDeclHeader = R"(
139 namespace mlir {
140 class DialectAsmParser;
141 class DialectAsmPrinter;
142 } // namespace mlir
143 )";
144
145 /// The code block for the start of a typeDef class declaration -- singleton
146 /// case.
147 ///
148 /// {0}: The name of the typeDef class.
149 static const char *const typeDefDeclSingletonBeginStr = R"(
150 class {0}: public ::mlir::Type::TypeBase<{0}, ::mlir::Type, ::mlir::TypeStorage> {{
151 public:
152 /// Inherit some necessary constructors from 'TypeBase'.
153 using Base::Base;
154
155 )";
156
157 /// The code block for the start of a typeDef class declaration -- parametric
158 /// case.
159 ///
160 /// {0}: The name of the typeDef class.
161 /// {1}: The typeDef storage class namespace.
162 /// {2}: The storage class name.
163 /// {3}: The list of parameters with types.
164 static const char *const typeDefDeclParametricBeginStr = R"(
165 namespace {1} {
166 struct {2};
167 }
168 class {0}: public ::mlir::Type::TypeBase<{0}, ::mlir::Type,
169 {1}::{2}> {{
170 public:
171 /// Inherit some necessary constructors from 'TypeBase'.
172 using Base::Base;
173
174 )";
175
176 /// The snippet for print/parse.
177 static const char *const typeDefParsePrint = R"(
178 static ::mlir::Type parse(::mlir::MLIRContext* ctxt, ::mlir::DialectAsmParser& parser);
179 void print(::mlir::DialectAsmPrinter& printer) const;
180 )";
181
182 /// The code block for the verifyConstructionInvariants and getChecked.
183 ///
184 /// {0}: List of parameters, parameters style.
185 static const char *const typeDefDeclVerifyStr = R"(
186 static ::mlir::LogicalResult verifyConstructionInvariants(::mlir::Location loc{0});
187 static ::mlir::Type getChecked(::mlir::Location loc{0});
188 )";
189
190 /// Generate the declaration for the given typeDef class.
emitTypeDefDecl(const TypeDef & typeDef,raw_ostream & os)191 static void emitTypeDefDecl(const TypeDef &typeDef, raw_ostream &os) {
192 SmallVector<TypeParameter, 4> params;
193 typeDef.getParameters(params);
194
195 // Emit the beginning string template: either the singleton or parametric
196 // template.
197 if (typeDef.getNumParameters() == 0)
198 os << formatv(typeDefDeclSingletonBeginStr, typeDef.getCppClassName(),
199 typeDef.getStorageNamespace(), typeDef.getStorageClassName());
200 else
201 os << formatv(typeDefDeclParametricBeginStr, typeDef.getCppClassName(),
202 typeDef.getStorageNamespace(), typeDef.getStorageClassName());
203
204 // Emit the extra declarations first in case there's a type definition in
205 // there.
206 if (Optional<StringRef> extraDecl = typeDef.getExtraDecls())
207 os << *extraDecl << "\n";
208
209 TypeParamCommaFormatter emitTypeNamePairsAfterComma(
210 TypeParamCommaFormatter::EmitFormat::TypeNamePairs, params);
211 os << llvm::formatv(" static {0} get(::mlir::MLIRContext* ctxt{1});\n",
212 typeDef.getCppClassName(), emitTypeNamePairsAfterComma);
213
214 // Emit the verify invariants declaration.
215 if (typeDef.genVerifyInvariantsDecl())
216 os << llvm::formatv(typeDefDeclVerifyStr, emitTypeNamePairsAfterComma);
217
218 // Emit the mnenomic, if specified.
219 if (auto mnenomic = typeDef.getMnemonic()) {
220 os << " static ::llvm::StringRef getMnemonic() { return \"" << mnenomic
221 << "\"; }\n";
222
223 // If mnemonic specified, emit print/parse declarations.
224 os << typeDefParsePrint;
225 }
226
227 if (typeDef.genAccessors()) {
228 SmallVector<TypeParameter, 4> parameters;
229 typeDef.getParameters(parameters);
230
231 for (TypeParameter ¶meter : parameters) {
232 SmallString<16> name = parameter.getName();
233 name[0] = llvm::toUpper(name[0]);
234 os << formatv(" {0} get{1}() const;\n", parameter.getCppType(), name);
235 }
236 }
237
238 // End the typeDef decl.
239 os << " };\n";
240 }
241
242 /// Main entry point for decls.
emitTypeDefDecls(const llvm::RecordKeeper & recordKeeper,raw_ostream & os)243 static bool emitTypeDefDecls(const llvm::RecordKeeper &recordKeeper,
244 raw_ostream &os) {
245 emitSourceFileHeader("TypeDef Declarations", os);
246
247 SmallVector<TypeDef, 16> typeDefs;
248 findAllTypeDefs(recordKeeper, typeDefs);
249
250 IfDefScope scope("GET_TYPEDEF_CLASSES", os);
251
252 // Output the common "header".
253 os << typeDefDeclHeader;
254
255 if (typeDefs.size() > 0) {
256 NamespaceEmitter nsEmitter(os, typeDefs.begin()->getDialect());
257
258 // Well known print/parse dispatch function declarations. These are called
259 // from Dialect::parseType() and Dialect::printType() methods.
260 os << " ::mlir::Type generatedTypeParser(::mlir::MLIRContext* ctxt, "
261 "::mlir::DialectAsmParser& parser, ::llvm::StringRef mnenomic);\n";
262 os << " ::mlir::LogicalResult generatedTypePrinter(::mlir::Type type, "
263 "::mlir::DialectAsmPrinter& printer);\n";
264 os << "\n";
265
266 // Declare all the type classes first (in case they reference each other).
267 for (const TypeDef &typeDef : typeDefs)
268 os << " class " << typeDef.getCppClassName() << ";\n";
269
270 // Declare all the typedefs.
271 for (const TypeDef &typeDef : typeDefs)
272 emitTypeDefDecl(typeDef, os);
273 }
274
275 return false;
276 }
277
278 //===----------------------------------------------------------------------===//
279 // GEN: TypeDef list
280 //===----------------------------------------------------------------------===//
281
emitTypeDefList(SmallVectorImpl<TypeDef> & typeDefs,raw_ostream & os)282 static void emitTypeDefList(SmallVectorImpl<TypeDef> &typeDefs,
283 raw_ostream &os) {
284 IfDefScope scope("GET_TYPEDEF_LIST", os);
285 for (auto *i = typeDefs.begin(); i != typeDefs.end(); i++) {
286 os << i->getDialect().getCppNamespace() << "::" << i->getCppClassName();
287 if (i < typeDefs.end() - 1)
288 os << ",\n";
289 else
290 os << "\n";
291 }
292 }
293
294 //===----------------------------------------------------------------------===//
295 // GEN: TypeDef definitions
296 //===----------------------------------------------------------------------===//
297
298 /// Beginning of storage class.
299 /// {0}: Storage class namespace.
300 /// {1}: Storage class c++ name.
301 /// {2}: Parameters parameters.
302 /// {3}: Parameter initialzer string.
303 /// {4}: Parameter name list.
304 /// {5}: Parameter types.
305 static const char *const typeDefStorageClassBegin = R"(
306 namespace {0} {{
307 struct {1} : public ::mlir::TypeStorage {{
308 {1} ({2})
309 : {3} {{ }
310
311 /// The hash key for this storage is a pair of the integer and type params.
312 using KeyTy = std::tuple<{5}>;
313
314 /// Define the comparison function for the key type.
315 bool operator==(const KeyTy &key) const {{
316 return key == KeyTy({4});
317 }
318 )";
319
320 /// The storage class' constructor template.
321 /// {0}: storage class name.
322 static const char *const typeDefStorageClassConstructorBegin = R"(
323 /// Define a construction method for creating a new instance of this storage.
324 static {0} *construct(::mlir::TypeStorageAllocator &allocator, const KeyTy &key) {{
325 )";
326
327 /// The storage class' constructor return template.
328 /// {0}: storage class name.
329 /// {1}: list of parameters.
330 static const char *const typeDefStorageClassConstructorReturn = R"(
331 return new (allocator.allocate<{0}>())
332 {0}({1});
333 }
334 )";
335
336 /// The code block for the getChecked definition.
337 ///
338 /// {0}: List of parameters, parameters style.
339 /// {1}: C++ type class name.
340 /// {2}: Comma separated list of parameter names.
341 static const char *const typeDefDefGetCheckeStr = R"(
342 ::mlir::Type {1}::getChecked(Location loc{0}) {{
343 return Base::getChecked(loc{2});
344 }
345 )";
346
347 /// Use tgfmt to emit custom allocation code for each parameter, if necessary.
emitParameterAllocationCode(TypeDef & typeDef,raw_ostream & os)348 static void emitParameterAllocationCode(TypeDef &typeDef, raw_ostream &os) {
349 SmallVector<TypeParameter, 4> parameters;
350 typeDef.getParameters(parameters);
351 auto fmtCtxt = FmtContext().addSubst("_allocator", "allocator");
352 for (TypeParameter ¶meter : parameters) {
353 auto allocCode = parameter.getAllocator();
354 if (allocCode) {
355 fmtCtxt.withSelf(parameter.getName());
356 fmtCtxt.addSubst("_dst", parameter.getName());
357 os << " " << tgfmt(*allocCode, &fmtCtxt) << "\n";
358 }
359 }
360 }
361
362 /// Emit the storage class code for type 'typeDef'.
363 /// This includes (in-order):
364 /// 1) typeDefStorageClassBegin, which includes:
365 /// - The class constructor.
366 /// - The KeyTy definition.
367 /// - The equality (==) operator.
368 /// 2) The hashKey method.
369 /// 3) The construct method.
370 /// 4) The list of parameters as the storage class member variables.
emitStorageClass(TypeDef typeDef,raw_ostream & os)371 static void emitStorageClass(TypeDef typeDef, raw_ostream &os) {
372 SmallVector<TypeParameter, 4> parameters;
373 typeDef.getParameters(parameters);
374
375 // Initialize a bunch of variables to be used later on.
376 auto parameterNames = map_range(
377 parameters, [](TypeParameter parameter) { return parameter.getName(); });
378 auto parameterTypes = map_range(parameters, [](TypeParameter parameter) {
379 return parameter.getCppType();
380 });
381 auto parameterList = join(parameterNames, ", ");
382 auto parameterTypeList = join(parameterTypes, ", ");
383
384 // 1) Emit most of the storage class up until the hashKey body.
385 os << formatv(typeDefStorageClassBegin, typeDef.getStorageNamespace(),
386 typeDef.getStorageClassName(),
387 TypeParamCommaFormatter(
388 TypeParamCommaFormatter::EmitFormat::TypeNamePairs,
389 parameters, /*prependComma=*/false),
390 TypeParamCommaFormatter(
391 TypeParamCommaFormatter::EmitFormat::TypeNameInitializer,
392 parameters, /*prependComma=*/false),
393 parameterList, parameterTypeList);
394
395 // 2) Emit the haskKey method.
396 os << " static ::llvm::hash_code hashKey(const KeyTy &key) {\n";
397 // Extract each parameter from the key.
398 for (size_t i = 0, e = parameters.size(); i < e; ++i)
399 os << llvm::formatv(" const auto &{0} = std::get<{1}>(key);\n",
400 parameters[i].getName(), i);
401 // Then combine them all. This requires all the parameters types to have a
402 // hash_value defined.
403 os << llvm::formatv(
404 " return ::llvm::hash_combine({0});\n }\n",
405 TypeParamCommaFormatter(TypeParamCommaFormatter::EmitFormat::JustParams,
406 parameters, /* prependComma */ false));
407
408 // 3) Emit the construct method.
409 if (typeDef.hasStorageCustomConstructor())
410 // If user wants to build the storage constructor themselves, declare it
411 // here and then they can write the definition elsewhere.
412 os << " static " << typeDef.getStorageClassName()
413 << " *construct(::mlir::TypeStorageAllocator &allocator, const KeyTy "
414 "&key);\n";
415 else {
416 // If not, autogenerate one.
417
418 // First, unbox the parameters.
419 os << formatv(typeDefStorageClassConstructorBegin,
420 typeDef.getStorageClassName());
421 for (size_t i = 0; i < parameters.size(); ++i) {
422 os << formatv(" auto {0} = std::get<{1}>(key);\n",
423 parameters[i].getName(), i);
424 }
425 // Second, reassign the parameter variables with allocation code, if it's
426 // specified.
427 emitParameterAllocationCode(typeDef, os);
428
429 // Last, return an allocated copy.
430 os << formatv(typeDefStorageClassConstructorReturn,
431 typeDef.getStorageClassName(), parameterList);
432 }
433
434 // 4) Emit the parameters as storage class members.
435 for (auto parameter : parameters) {
436 os << " " << parameter.getCppType() << " " << parameter.getName()
437 << ";\n";
438 }
439 os << " };\n";
440
441 os << "} // namespace " << typeDef.getStorageNamespace() << "\n";
442 }
443
444 /// Emit the parser and printer for a particular type, if they're specified.
emitParserPrinter(TypeDef typeDef,raw_ostream & os)445 void emitParserPrinter(TypeDef typeDef, raw_ostream &os) {
446 // Emit the printer code, if specified.
447 if (auto printerCode = typeDef.getPrinterCode()) {
448 // Both the mnenomic and printerCode must be defined (for parity with
449 // parserCode).
450 os << "void " << typeDef.getCppClassName()
451 << "::print(::mlir::DialectAsmPrinter& printer) const {\n";
452 if (*printerCode == "") {
453 // If no code specified, emit error.
454 PrintFatalError(typeDef.getLoc(),
455 typeDef.getName() +
456 ": printer (if specified) must have non-empty code");
457 }
458 auto fmtCtxt = FmtContext().addSubst("_printer", "printer");
459 os << tgfmt(*printerCode, &fmtCtxt) << "\n}\n";
460 }
461
462 // emit a parser, if specified.
463 if (auto parserCode = typeDef.getParserCode()) {
464 // The mnenomic must be defined so the dispatcher knows how to dispatch.
465 os << "::mlir::Type " << typeDef.getCppClassName()
466 << "::parse(::mlir::MLIRContext* ctxt, ::mlir::DialectAsmParser& "
467 "parser) "
468 "{\n";
469 if (*parserCode == "") {
470 // if no code specified, emit error.
471 PrintFatalError(typeDef.getLoc(),
472 typeDef.getName() +
473 ": parser (if specified) must have non-empty code");
474 }
475 auto fmtCtxt =
476 FmtContext().addSubst("_parser", "parser").addSubst("_ctxt", "ctxt");
477 os << tgfmt(*parserCode, &fmtCtxt) << "\n}\n";
478 }
479 }
480
481 /// Print all the typedef-specific definition code.
emitTypeDefDef(TypeDef typeDef,raw_ostream & os)482 static void emitTypeDefDef(TypeDef typeDef, raw_ostream &os) {
483 NamespaceEmitter ns(os, typeDef.getDialect());
484 SmallVector<TypeParameter, 4> parameters;
485 typeDef.getParameters(parameters);
486
487 // Emit the storage class, if requested and necessary.
488 if (typeDef.genStorageClass() && typeDef.getNumParameters() > 0)
489 emitStorageClass(typeDef, os);
490
491 os << llvm::formatv(
492 "{0} {0}::get(::mlir::MLIRContext* ctxt{1}) {{\n"
493 " return Base::get(ctxt{2});\n}\n",
494 typeDef.getCppClassName(),
495 TypeParamCommaFormatter(
496 TypeParamCommaFormatter::EmitFormat::TypeNamePairs, parameters),
497 TypeParamCommaFormatter(TypeParamCommaFormatter::EmitFormat::JustParams,
498 parameters));
499
500 // Emit the parameter accessors.
501 if (typeDef.genAccessors())
502 for (const TypeParameter ¶meter : parameters) {
503 SmallString<16> name = parameter.getName();
504 name[0] = llvm::toUpper(name[0]);
505 os << formatv("{0} {3}::get{1}() const { return getImpl()->{2}; }\n",
506 parameter.getCppType(), name, parameter.getName(),
507 typeDef.getCppClassName());
508 }
509
510 // Generate getChecked() method.
511 if (typeDef.genVerifyInvariantsDecl()) {
512 os << llvm::formatv(
513 typeDefDefGetCheckeStr,
514 TypeParamCommaFormatter(
515 TypeParamCommaFormatter::EmitFormat::TypeNamePairs, parameters),
516 typeDef.getCppClassName(),
517 TypeParamCommaFormatter(TypeParamCommaFormatter::EmitFormat::JustParams,
518 parameters));
519 }
520
521 // If mnemonic is specified maybe print definitions for the parser and printer
522 // code, if they're specified.
523 if (typeDef.getMnemonic())
524 emitParserPrinter(typeDef, os);
525 }
526
527 /// Emit the dialect printer/parser dispatcher. User's code should call these
528 /// functions from their dialect's print/parse methods.
emitParsePrintDispatch(SmallVectorImpl<TypeDef> & typeDefs,raw_ostream & os)529 static void emitParsePrintDispatch(SmallVectorImpl<TypeDef> &typeDefs,
530 raw_ostream &os) {
531 if (typeDefs.size() == 0)
532 return;
533 const Dialect &dialect = typeDefs.begin()->getDialect();
534 NamespaceEmitter ns(os, dialect);
535
536 // The parser dispatch is just a list of if-elses, matching on the mnemonic
537 // and calling the class's parse function.
538 os << "::mlir::Type generatedTypeParser(::mlir::MLIRContext* ctxt, "
539 "::mlir::DialectAsmParser& parser, ::llvm::StringRef mnemonic) {\n";
540 for (const TypeDef &typeDef : typeDefs)
541 if (typeDef.getMnemonic())
542 os << formatv(" if (mnemonic == {0}::{1}::getMnemonic()) return "
543 "{0}::{1}::parse(ctxt, parser);\n",
544 typeDef.getDialect().getCppNamespace(),
545 typeDef.getCppClassName());
546 os << " return ::mlir::Type();\n";
547 os << "}\n\n";
548
549 // The printer dispatch uses llvm::TypeSwitch to find and call the correct
550 // printer.
551 os << "::mlir::LogicalResult generatedTypePrinter(::mlir::Type type, "
552 "::mlir::DialectAsmPrinter& printer) {\n"
553 << " ::mlir::LogicalResult found = ::mlir::success();\n"
554 << " ::llvm::TypeSwitch<::mlir::Type>(type)\n";
555 for (auto typeDef : typeDefs)
556 if (typeDef.getMnemonic())
557 os << formatv(" .Case<{0}::{1}>([&](::mlir::Type t) {{ "
558 "t.dyn_cast<{0}::{1}>().print(printer); })\n",
559 typeDef.getDialect().getCppNamespace(),
560 typeDef.getCppClassName());
561 os << " .Default([&found](::mlir::Type) { found = ::mlir::failure(); "
562 "});\n"
563 << " return found;\n"
564 << "}\n\n";
565 }
566
567 /// Entry point for typedef definitions.
emitTypeDefDefs(const llvm::RecordKeeper & recordKeeper,raw_ostream & os)568 static bool emitTypeDefDefs(const llvm::RecordKeeper &recordKeeper,
569 raw_ostream &os) {
570 emitSourceFileHeader("TypeDef Definitions", os);
571
572 SmallVector<TypeDef, 16> typeDefs;
573 findAllTypeDefs(recordKeeper, typeDefs);
574 emitTypeDefList(typeDefs, os);
575
576 IfDefScope scope("GET_TYPEDEF_CLASSES", os);
577 emitParsePrintDispatch(typeDefs, os);
578 for (auto typeDef : typeDefs)
579 emitTypeDefDef(typeDef, os);
580
581 return false;
582 }
583
584 //===----------------------------------------------------------------------===//
585 // GEN: TypeDef registration hooks
586 //===----------------------------------------------------------------------===//
587
588 static mlir::GenRegistration
589 genTypeDefDefs("gen-typedef-defs", "Generate TypeDef definitions",
__anon69b900310802(const llvm::RecordKeeper &records, raw_ostream &os) 590 [](const llvm::RecordKeeper &records, raw_ostream &os) {
591 return emitTypeDefDefs(records, os);
592 });
593
594 static mlir::GenRegistration
595 genTypeDefDecls("gen-typedef-decls", "Generate TypeDef declarations",
__anon69b900310902(const llvm::RecordKeeper &records, raw_ostream &os) 596 [](const llvm::RecordKeeper &records, raw_ostream &os) {
597 return emitTypeDefDecls(records, os);
598 });
599