diff --git a/mlir/include/mlir/IR/EnumAttr.td b/mlir/include/mlir/IR/EnumAttr.td index 485c5266f3cfd..cb918b5eceb1a 100644 --- a/mlir/include/mlir/IR/EnumAttr.td +++ b/mlir/include/mlir/IR/EnumAttr.td @@ -113,6 +113,13 @@ class I64BitEnumAttrCaseGroup cases, class EnumAttrInfo< string name, list cases, Attr baseClass> : Attr { + + // Generate a description of this enums members for the MLIR docs. + let description = + "Enum cases:\n" # !interleave( + !foreach(case, cases, + "* " # case.str # " (`" # case.symbol # "`)"), "\n"); + // The C++ enum class name string className = name; @@ -381,6 +388,7 @@ class EnumAttr traits = []> : AttrDef { let summary = enumInfo.summary; + let description = enumInfo.description; // The backing enumeration. EnumAttrInfo enum = enumInfo; diff --git a/mlir/tools/mlir-tblgen/OpDocGen.cpp b/mlir/tools/mlir-tblgen/OpDocGen.cpp index c546763880a85..088d34597f315 100644 --- a/mlir/tools/mlir-tblgen/OpDocGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp @@ -173,6 +173,13 @@ static void emitOpTraitsDoc(const Operator &op, raw_ostream &os) { } } +static StringRef resolveAttrDescription(const Attribute &attr) { + StringRef description = attr.getDescription(); + if (description.empty()) + return attr.getBaseAttr().getDescription(); + return description; +} + static void emitOpDoc(const Operator &op, raw_ostream &os) { std::string classNameStr = op.getQualCppClassName(); StringRef className = classNameStr; @@ -192,16 +199,35 @@ static void emitOpDoc(const Operator &op, raw_ostream &os) { // Emit attributes. if (op.getNumAttributes() != 0) { - // TODO: Attributes are only documented by TableGen name, with no further - // info. This should be improved. os << "\n#### Attributes:\n\n"; - os << "| Attribute | MLIR Type | Description |\n" - << "| :-------: | :-------: | ----------- |\n"; + // Note: This table is HTML rather than markdown so the attribute's + // description can appear in an expandable region. The description may be + // multiple lines, which is not supported in a markdown table cell. + os << "\n"; + // Header. + os << "\n"; for (const auto &it : op.getAttributes()) { StringRef storageType = it.attr.getStorageType(); - os << "| `" << it.name << "` | " << storageType << " | " - << it.attr.getSummary() << "\n"; + // Name and storage type. + os << ""; + os << "\n"; } + os << "
AttributeMLIR TypeDescription
" << it.name << "" << storageType + << ""; + StringRef description = resolveAttrDescription(it.attr); + if (!description.empty()) { + // Expandable description. + // This appears as just the summary, but when clicked shows the full + // description. + os << "
" + << "" << it.attr.getSummary() << "" + << "{{% markdown %}}" << description << "{{% /markdown %}}" + << "
"; + } else { + // Fallback: Single-line summary. + os << it.attr.getSummary(); + } + os << "
\n"; } // Emit each of the operands.