diff --git a/mlir/include/mlir/Support/IndentedOstream.h b/mlir/include/mlir/Support/IndentedOstream.h --- a/mlir/include/mlir/Support/IndentedOstream.h +++ b/mlir/include/mlir/Support/IndentedOstream.h @@ -59,8 +59,10 @@ /// Prints a string re-indented to the current indent. Re-indents by removing /// the leading whitespace from the first non-empty line from every line of - /// the string, skipping over empty lines at the start. - raw_indented_ostream &printReindented(StringRef str); + /// the string, skipping over empty lines at the start. Prefixes each line + /// with extraPrefix after the indentation. + raw_indented_ostream &printReindented(StringRef str, + StringRef extraPrefix = ""); /// Increases the indent and returning this raw_indented_ostream. raw_indented_ostream &indent() { @@ -92,16 +94,19 @@ /// Constant indent added/removed. static constexpr int indentSize = 2; - // Tracker for current indentation. + /// Tracker for current indentation. int currentIndent = 0; - // The leading whitespace of the string being printed, if reindent is used. + /// The leading whitespace of the string being printed, if reindent is used. int leadingWs = 0; - // Tracks whether at start of line and so indent is required or not. + /// The extra prefix to be printed, if reindent is used. + StringRef currentExtraPrefix; + + /// Tracks whether at start of line and so indent is required or not. bool atStartOfLine = true; - // The underlying raw_ostream. + /// The underlying raw_ostream. raw_ostream &os; }; diff --git a/mlir/lib/Support/IndentedOstream.cpp b/mlir/lib/Support/IndentedOstream.cpp --- a/mlir/lib/Support/IndentedOstream.cpp +++ b/mlir/lib/Support/IndentedOstream.cpp @@ -16,7 +16,8 @@ using namespace mlir; raw_indented_ostream & -mlir::raw_indented_ostream::printReindented(StringRef str) { +mlir::raw_indented_ostream::printReindented(StringRef str, + StringRef extraPrefix) { StringRef output = str; // Skip empty lines. while (!output.empty()) { @@ -39,7 +40,9 @@ remaining = split.second; } // Print, skipping the empty lines. + std::swap(currentExtraPrefix, extraPrefix); *this << output; + std::swap(currentExtraPrefix, extraPrefix); leadingWs = 0; return *this; } @@ -49,7 +52,7 @@ // Print out indented. auto print = [this](StringRef str) { if (atStartOfLine) - os.indent(currentIndent) << str.substr(leadingWs); + os.indent(currentIndent) << currentExtraPrefix << str.substr(leadingWs); else os << str.substr(leadingWs); }; @@ -66,8 +69,9 @@ auto split = std::make_pair(str.slice(0, idx), str.slice(idx + 1, StringRef::npos)); - // Print empty new line without spaces if line only has spaces. - if (!split.first.ltrim().empty()) + // Print empty new line without spaces if line only has spaces and no extra + // prefix is requested. + if (!split.first.ltrim().empty() || !currentExtraPrefix.empty()) print(split.first); os << '\n'; atStartOfLine = true; diff --git a/mlir/test/mlir-tblgen/op-interface.td b/mlir/test/mlir-tblgen/op-interface.td --- a/mlir/test/mlir-tblgen/op-interface.td +++ b/mlir/test/mlir-tblgen/op-interface.td @@ -73,6 +73,7 @@ // DECL-LABEL: TestOpInterfaceInterfaceTraits // DECL: class TestOpInterface : public ::mlir::OpInterface +// DECL: /// some function comment // DECL: int foo(int input); // DECL: template diff --git a/mlir/tools/mlir-tblgen/DocGenUtilities.h b/mlir/tools/mlir-tblgen/DocGenUtilities.h --- a/mlir/tools/mlir-tblgen/DocGenUtilities.h +++ b/mlir/tools/mlir-tblgen/DocGenUtilities.h @@ -14,9 +14,10 @@ #ifndef MLIR_TOOLS_MLIRTBLGEN_DOCGENUTILITIES_H_ #define MLIR_TOOLS_MLIRTBLGEN_DOCGENUTILITIES_H_ +#include "llvm/ADT/StringRef.h" + namespace llvm { class raw_ostream; -class StringRef; } // namespace llvm namespace mlir { @@ -30,6 +31,10 @@ // nested. void emitDescription(llvm::StringRef description, llvm::raw_ostream &os); +// Emit the description as a C++ comment while realigning it. +void emitDescriptionComment(llvm::StringRef description, llvm::raw_ostream &os, + llvm::StringRef prefix = ""); + } // namespace tblgen } // namespace mlir diff --git a/mlir/tools/mlir-tblgen/OpDocGen.cpp b/mlir/tools/mlir-tblgen/OpDocGen.cpp --- a/mlir/tools/mlir-tblgen/OpDocGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp @@ -48,6 +48,17 @@ ros.printReindented(description.rtrim(" \t")); } +void mlir::tblgen::emitDescriptionComment(StringRef description, + raw_ostream &os, StringRef prefix) { + if (description.empty()) + return; + raw_indented_ostream ros(os); + StringRef trimmed = description.rtrim(" \t"); + ros.printReindented(trimmed, (Twine(prefix) + "/// ").str()); + if (!trimmed.endswith("\n")) + ros << "\n"; +} + // Emits `str` with trailing newline if not empty. static void emitIfNotEmpty(StringRef str, raw_ostream &os) { if (!str.empty()) { diff --git a/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp b/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp --- a/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp +++ b/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp @@ -158,6 +158,12 @@ // GEN: Interface definitions //===----------------------------------------------------------------------===// +static void emitInterfaceMethodDoc(const InterfaceMethod &method, + raw_ostream &os, StringRef prefix = "") { + if (Optional description = method.getDescription()) + tblgen::emitDescriptionComment(*description, os, prefix); +} + static void emitInterfaceDef(const Interface &interface, StringRef valueType, raw_ostream &os) { StringRef interfaceName = interface.getName(); @@ -167,6 +173,7 @@ // Insert the method definitions. bool isOpInterface = isa(interface); for (auto &method : interface.getMethods()) { + emitInterfaceMethodDoc(method, os); emitCPPType(method.getReturnType(), os); if (!cppNamespace.empty()) os << cppNamespace << "::"; @@ -401,6 +408,7 @@ if (!defaultImpl) continue; + emitInterfaceMethodDoc(method, os, " "); os << " " << (method.isStatic() ? "static " : ""); emitCPPType(method.getReturnType(), os); emitMethodNameAndArgs(method, os, valueType, /*addThisArg=*/false, @@ -470,6 +478,7 @@ // Insert the method declarations. bool isOpInterface = isa(interface); for (auto &method : interface.getMethods()) { + emitInterfaceMethodDoc(method, os, " "); emitCPPType(method.getReturnType(), os << " "); emitMethodNameAndArgs(method, os, valueType, /*addThisArg=*/false, /*addConst=*/!isOpInterface);