[Mlir-commits] [mlir] 2e2ad53 - [mlir] Generate C++ doc comments for interfaces

Alex Zinenko llvmlistbot at llvm.org
Wed Aug 10 06:12:38 PDT 2022


Author: Alex Zinenko
Date: 2022-08-10T15:12:29+02:00
New Revision: 2e2ad53979045cb18d1c5924af8cb7cc75de5c77

URL: https://github.com/llvm/llvm-project/commit/2e2ad53979045cb18d1c5924af8cb7cc75de5c77
DIFF: https://github.com/llvm/llvm-project/commit/2e2ad53979045cb18d1c5924af8cb7cc75de5c77.diff

LOG: [mlir] Generate C++ doc comments for interfaces

When emitting the declarations for interface methods defined in ODS,
also emit their descriptions as C++ comments. This makes the
documentation accessible to C++ tooling such as IDEs that offers better
usability than reading it form the .td or the website.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D130478

Added: 
    

Modified: 
    mlir/include/mlir/Support/IndentedOstream.h
    mlir/lib/Support/IndentedOstream.cpp
    mlir/test/mlir-tblgen/op-interface.td
    mlir/tools/mlir-tblgen/DocGenUtilities.h
    mlir/tools/mlir-tblgen/OpDocGen.cpp
    mlir/tools/mlir-tblgen/OpInterfacesGen.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Support/IndentedOstream.h b/mlir/include/mlir/Support/IndentedOstream.h
index 79c66995c67ae..3d19a1e1ede37 100644
--- a/mlir/include/mlir/Support/IndentedOstream.h
+++ b/mlir/include/mlir/Support/IndentedOstream.h
@@ -59,8 +59,10 @@ class raw_indented_ostream : public raw_ostream {
 
   /// 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 @@ class raw_indented_ostream : public raw_ostream {
   /// 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
index 470147cd5c526..4e2cad11712f8 100644
--- 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 @@ mlir::raw_indented_ostream::printReindented(StringRef str) {
     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 @@ void mlir::raw_indented_ostream::write_impl(const char *ptr, size_t size) {
   // 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 @@ void mlir::raw_indented_ostream::write_impl(const char *ptr, size_t size) {
 
     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
index 51403fb286a8e..901d9ea773011 100644
--- a/mlir/test/mlir-tblgen/op-interface.td
+++ b/mlir/test/mlir-tblgen/op-interface.td
@@ -73,6 +73,7 @@ def DeclareMethodsWithDefaultOp : Op<TestDialect, "declare_methods_op",
 // DECL-LABEL: TestOpInterfaceInterfaceTraits
 // DECL: class TestOpInterface : public ::mlir::OpInterface<TestOpInterface, detail::TestOpInterfaceInterfaceTraits>
 
+// DECL: /// some function comment
 // DECL: int foo(int input);
 
 // DECL: template<typename ConcreteOp>

diff  --git a/mlir/tools/mlir-tblgen/DocGenUtilities.h b/mlir/tools/mlir-tblgen/DocGenUtilities.h
index 8132a776a9c63..a1fbbb3c3e11e 100644
--- 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 @@ namespace tblgen {
 // 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
index 13bd4a8bad2f1..ed9e514695644 100644
--- a/mlir/tools/mlir-tblgen/OpDocGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp
@@ -48,6 +48,17 @@ void mlir::tblgen::emitDescription(StringRef description, raw_ostream &os) {
   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
index a6d3cccdd8770..340759d1a3b19 100644
--- a/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpInterfacesGen.cpp
@@ -158,6 +158,12 @@ struct TypeInterfaceGenerator : public InterfaceGenerator {
 // GEN: Interface definitions
 //===----------------------------------------------------------------------===//
 
+static void emitInterfaceMethodDoc(const InterfaceMethod &method,
+                                   raw_ostream &os, StringRef prefix = "") {
+  if (Optional<StringRef> 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 @@ static void emitInterfaceDef(const Interface &interface, StringRef valueType,
   // Insert the method definitions.
   bool isOpInterface = isa<OpInterface>(interface);
   for (auto &method : interface.getMethods()) {
+    emitInterfaceMethodDoc(method, os);
     emitCPPType(method.getReturnType(), os);
     if (!cppNamespace.empty())
       os << cppNamespace << "::";
@@ -401,6 +408,7 @@ void InterfaceGenerator::emitTraitDecl(const Interface &interface,
     if (!defaultImpl)
       continue;
 
+    emitInterfaceMethodDoc(method, os, "    ");
     os << "    " << (method.isStatic() ? "static " : "");
     emitCPPType(method.getReturnType(), os);
     emitMethodNameAndArgs(method, os, valueType, /*addThisArg=*/false,
@@ -470,6 +478,7 @@ void InterfaceGenerator::emitInterfaceDecl(const Interface &interface) {
   // Insert the method declarations.
   bool isOpInterface = isa<OpInterface>(interface);
   for (auto &method : interface.getMethods()) {
+    emitInterfaceMethodDoc(method, os, "  ");
     emitCPPType(method.getReturnType(), os << "  ");
     emitMethodNameAndArgs(method, os, valueType, /*addThisArg=*/false,
                           /*addConst=*/!isOpInterface);


        


More information about the Mlir-commits mailing list