16
16
#include " OpGenHelpers.h"
17
17
#include " mlir/Support/IndentedOstream.h"
18
18
#include " mlir/TableGen/AttrOrTypeDef.h"
19
+ #include " mlir/TableGen/Attribute.h"
19
20
#include " mlir/TableGen/GenInfo.h"
20
21
#include " mlir/TableGen/Operator.h"
21
22
#include " llvm/ADT/DenseMap.h"
37
38
// Commandline Options
38
39
// ===----------------------------------------------------------------------===//
39
40
static llvm::cl::OptionCategory
40
- docCat (" Options for -gen-(attrdef|typedef|op|dialect)-doc" );
41
+ docCat (" Options for -gen-(attrdef|typedef|enum| op|dialect)-doc" );
41
42
llvm::cl::opt<std::string>
42
43
stripPrefix (" strip-prefix" ,
43
44
llvm::cl::desc (" Strip prefix of the fully qualified names" ),
@@ -228,8 +229,7 @@ static void emitOpDoc(const Operator &op, raw_ostream &os) {
228
229
// Expandable description.
229
230
// This appears as just the summary, but when clicked shows the full
230
231
// description.
231
- os << " <details>"
232
- << " <summary>" << it.attr .getSummary () << " </summary>"
232
+ os << " <details>" << " <summary>" << it.attr .getSummary () << " </summary>"
233
233
<< " {{% markdown %}}" << description << " {{% /markdown %}}"
234
234
<< " </details>" ;
235
235
} else {
@@ -381,6 +381,39 @@ static void emitAttrOrTypeDefDoc(const RecordKeeper &recordKeeper,
381
381
emitAttrOrTypeDefDoc (AttrOrTypeDef (def), os);
382
382
}
383
383
384
+ // ===----------------------------------------------------------------------===//
385
+ // Enum Documentation
386
+ // ===----------------------------------------------------------------------===//
387
+
388
+ static void emitEnumDoc (const EnumAttr &def, raw_ostream &os) {
389
+ os << llvm::formatv (" ### {0}\n " , def.getEnumClassName ());
390
+
391
+ // Emit the summary if present.
392
+ if (!def.getSummary ().empty ())
393
+ os << " \n " << def.getSummary () << " \n " ;
394
+
395
+ // Emit case documentation.
396
+ std::vector<EnumAttrCase> cases = def.getAllCases ();
397
+ os << " \n #### Cases:\n\n " ;
398
+ os << " | Symbol | Value | String |\n "
399
+ << " | :----: | :---: | ------ |\n " ;
400
+ for (const auto &it : cases) {
401
+ os << " | " << it.getSymbol () << " | `" << it.getValue () << " ` | "
402
+ << it.getStr () << " |\n " ;
403
+ }
404
+
405
+ os << " \n " ;
406
+ }
407
+
408
+ static void emitEnumDoc (const RecordKeeper &recordKeeper, raw_ostream &os) {
409
+ std::vector<llvm::Record *> defs =
410
+ recordKeeper.getAllDerivedDefinitions (" EnumAttr" );
411
+
412
+ os << " <!-- Autogenerated by mlir-tblgen; don't manually edit -->\n " ;
413
+ for (const llvm::Record *def : defs)
414
+ emitEnumDoc (EnumAttr (def), os);
415
+ }
416
+
384
417
// ===----------------------------------------------------------------------===//
385
418
// Dialect Documentation
386
419
// ===----------------------------------------------------------------------===//
@@ -413,7 +446,7 @@ static void maybeNest(bool nest, llvm::function_ref<void(raw_ostream &os)> fn,
413
446
static void emitBlock (ArrayRef<Attribute> attributes, StringRef inputFilename,
414
447
ArrayRef<AttrDef> attrDefs, ArrayRef<OpDocGroup> ops,
415
448
ArrayRef<Type> types, ArrayRef<TypeDef> typeDefs,
416
- raw_ostream &os) {
449
+ ArrayRef<EnumAttr> enums, raw_ostream &os) {
417
450
if (!ops.empty ()) {
418
451
os << " ## Operations\n\n " ;
419
452
emitSourceLink (inputFilename, os);
@@ -459,13 +492,19 @@ static void emitBlock(ArrayRef<Attribute> attributes, StringRef inputFilename,
459
492
for (const TypeDef &def : typeDefs)
460
493
emitAttrOrTypeDefDoc (def, os);
461
494
}
495
+
496
+ if (!enums.empty ()) {
497
+ os << " ## Enums\n\n " ;
498
+ for (const EnumAttr &def : enums)
499
+ emitEnumDoc (def, os);
500
+ }
462
501
}
463
502
464
503
static void emitDialectDoc (const Dialect &dialect, StringRef inputFilename,
465
504
ArrayRef<Attribute> attributes,
466
505
ArrayRef<AttrDef> attrDefs, ArrayRef<OpDocGroup> ops,
467
506
ArrayRef<Type> types, ArrayRef<TypeDef> typeDefs,
468
- raw_ostream &os) {
507
+ ArrayRef<EnumAttr> enums, raw_ostream &os) {
469
508
os << " # '" << dialect.getName () << " ' Dialect\n\n " ;
470
509
emitIfNotEmpty (dialect.getSummary (), os);
471
510
emitIfNotEmpty (dialect.getDescription (), os);
@@ -475,7 +514,8 @@ static void emitDialectDoc(const Dialect &dialect, StringRef inputFilename,
475
514
if (!r.match (dialect.getDescription ()))
476
515
os << " [TOC]\n\n " ;
477
516
478
- emitBlock (attributes, inputFilename, attrDefs, ops, types, typeDefs, os);
517
+ emitBlock (attributes, inputFilename, attrDefs, ops, types, typeDefs, enums,
518
+ os);
479
519
}
480
520
481
521
static bool emitDialectDoc (const RecordKeeper &recordKeeper, raw_ostream &os) {
@@ -495,21 +535,27 @@ static bool emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
495
535
recordKeeper.getAllDerivedDefinitionsIfDefined (" TypeDef" );
496
536
std::vector<Record *> attrDefDefs =
497
537
recordKeeper.getAllDerivedDefinitionsIfDefined (" AttrDef" );
538
+ std::vector<Record *> enumDefs =
539
+ recordKeeper.getAllDerivedDefinitionsIfDefined (" EnumAttrInfo" );
498
540
499
541
std::vector<Attribute> dialectAttrs;
500
542
std::vector<AttrDef> dialectAttrDefs;
501
543
std::vector<OpDocGroup> dialectOps;
502
544
std::vector<Type> dialectTypes;
503
545
std::vector<TypeDef> dialectTypeDefs;
546
+ std::vector<EnumAttr> dialectEnums;
504
547
505
548
llvm::SmallDenseSet<Record *> seen;
506
- auto addIfInDialect = [&](llvm::Record *record, const auto &def, auto &vec) {
507
- if (seen.insert (record).second && def. getDialect () == *dialect ) {
549
+ auto addIfNotSeen = [&](llvm::Record *record, const auto &def, auto &vec) {
550
+ if (seen.insert (record).second ) {
508
551
vec.push_back (def);
509
552
return true ;
510
553
}
511
554
return false ;
512
555
};
556
+ auto addIfInDialect = [&](llvm::Record *record, const auto &def, auto &vec) {
557
+ return def.getDialect () == *dialect && addIfNotSeen (record, def, vec);
558
+ };
513
559
514
560
SmallDenseMap<Record *, OpDocGroup> opDocGroup;
515
561
@@ -539,6 +585,9 @@ static bool emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
539
585
addIfInDialect (def, TypeDef (def), dialectTypeDefs);
540
586
for (Record *def : typeDefs)
541
587
addIfInDialect (def, Type (def), dialectTypes);
588
+ dialectEnums.reserve (enumDefs.size ());
589
+ for (Record *def : enumDefs)
590
+ addIfNotSeen (def, EnumAttr (def), dialectEnums);
542
591
543
592
// Sort alphabetically ignorning dialect for ops and section name for
544
593
// sections.
@@ -557,7 +606,7 @@ static bool emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
557
606
os << " <!-- Autogenerated by mlir-tblgen; don't manually edit -->\n " ;
558
607
emitDialectDoc (*dialect, recordKeeper.getInputFilename (), dialectAttrs,
559
608
dialectAttrDefs, dialectOps, dialectTypes, dialectTypeDefs,
560
- os);
609
+ dialectEnums, os);
561
610
return false ;
562
611
}
563
612
@@ -587,6 +636,13 @@ static mlir::GenRegistration
587
636
return false ;
588
637
});
589
638
639
+ static mlir::GenRegistration
640
+ genEnumRegister (" gen-enum-doc" , " Generate dialect enum documentation" ,
641
+ [](const RecordKeeper &records, raw_ostream &os) {
642
+ emitEnumDoc (records, os);
643
+ return false ;
644
+ });
645
+
590
646
static mlir::GenRegistration
591
647
genRegister (" gen-dialect-doc" , " Generate dialect documentation" ,
592
648
[](const RecordKeeper &records, raw_ostream &os) {
0 commit comments