[clang-tools-extra] [Clang-doc] Display values and comments in MD (PR #183754)
Samrudh Nelli via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 01:13:22 PST 2026
https://github.com/SamrudhNelli updated https://github.com/llvm/llvm-project/pull/183754
>From d9e58f68ad9fa377e91d1778d2393c3bc8451c55 Mon Sep 17 00:00:00 2001
From: Samrudh Nelli <samrudhnelli at gmail.com>
Date: Fri, 27 Feb 2026 21:07:37 +0530
Subject: [PATCH] display in a table format
---
clang-tools-extra/clang-doc/MDGenerator.cpp | 63 ++++-
clang-tools-extra/test/clang-doc/enum.cpp | 284 +++++++++++++++-----
2 files changed, 277 insertions(+), 70 deletions(-)
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index fcb75af80f9e9..6fd0bf2df038a 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -67,6 +67,30 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L,
OS << "\n\n";
}
+static std::string genRawText(const std::vector<CommentInfo> &Comments) {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ std::queue<const CommentInfo *> Q;
+ for (const auto &CI : Comments)
+ Q.push(&CI);
+ const CommentInfo *Comment;
+ bool First = true;
+ while (Q.size()) {
+ Comment = Q.front();
+ Q.pop();
+ if (!Comment->Text.empty())
+ {
+ if (!First)
+ OS << "<br>";
+ OS << Comment->Text;
+ First = false;
+ }
+ for (const auto &CI : Comment->Children)
+ Q.push(CI.get());
+ }
+ return Result;
+}
+
static void maybeWriteSourceFileRef(llvm::raw_ostream &OS,
const ClangDocContext &CDCtx,
const std::optional<Location> &DefLoc) {
@@ -157,16 +181,41 @@ static void writeNameLink(const StringRef &CurrentPath, const Reference &R,
static void genMarkdown(const ClangDocContext &CDCtx, const EnumInfo &I,
llvm::raw_ostream &OS) {
if (I.Scoped)
- writeLine("| enum class " + I.Name + " |", OS);
- else
- writeLine("| enum " + I.Name + " |", OS);
- writeLine("--", OS);
+ OS << "class ";
+ OS << (I.Name.empty() ? "(unnamed)" : StringRef(I.Name)) << " ";
+ if (I.BaseType && !I.BaseType->Type.QualName.empty()) {
+ OS << ": " << I.BaseType->Type.QualName << " ";
+ }
+ OS << "|\n\n";
std::string Buffer;
llvm::raw_string_ostream Members(Buffer);
- if (!I.Members.empty())
- for (const auto &N : I.Members)
- Members << "| " << N.Name << " |\n";
+ Members << "| Name | Value |";
+ if (!I.Members.empty()) {
+ bool HasComments = false;
+ for (const auto &Member : I.Members) {
+ if (!Member.Description.empty()) {
+ HasComments = true;
+ Members << " Comments |";
+ break;
+ }
+ }
+ Members << "\n";
+ Members << "|:-:|:-:|";
+ if (HasComments)
+ Members << ":-:|";
+ Members << "\n";
+ for (const auto &N : I.Members) {
+ Members << "| " << N.Name << " ";
+ if (!N.Value.empty())
+ Members << "| " << N.Value << " ";
+ if (HasComments) {
+ std::string RawComment = StringRef(genRawText(N.Description)).trim().str();
+ Members << "| " << (RawComment.empty() ? "--" : RawComment) << " ";
+ }
+ Members << "|\n";
+ }
+ }
writeLine(Members.str(), OS);
maybeWriteSourceFileRef(OS, CDCtx, I.DefLoc);
diff --git a/clang-tools-extra/test/clang-doc/enum.cpp b/clang-tools-extra/test/clang-doc/enum.cpp
index 6e11bbf065f25..c58d94404fcdc 100644
--- a/clang-tools-extra/test/clang-doc/enum.cpp
+++ b/clang-tools-extra/test/clang-doc/enum.cpp
@@ -30,9 +30,9 @@ enum Color {
// MD-INDEX: ## Enums
// MD-INDEX: | enum Color |
// MD-INDEX: --
-// MD-INDEX: | Red |
-// MD-INDEX: | Green |
-// MD-INDEX: | Blue |
+// MD-INDEX: | Red | 0 | Comment 1 |
+// MD-INDEX: | Green | Comment 2 |
+// MD-INDEX: | Blue | Comment 3 |
// MD-INDEX: **brief** For specifying RGB colors
// HTML-INDEX: <div>
@@ -73,37 +73,192 @@ enum class Shapes {
/// Comment 3
Triangle
};
+
// MD-INDEX: | enum class Shapes |
// MD-INDEX: --
-// MD-INDEX: | Circle |
-// MD-INDEX: | Rectangle |
-// MD-INDEX: | Triangle |
+// MD-INDEX: | Circle | 0 | Comment 1 |
+// MD-INDEX: | Rectangle | 1 | Comment 2 |
+// MD-INDEX: | Triangle | 2 | Comment 3 |
// MD-INDEX: **brief** Shape Types
-// COM: FIXME: Serialize "enum class" in template
-// HTML-INDEX: <div>
-// HTML-INDEX: <pre><code class="language-cpp code-clang-doc">enum Shapes</code></pre>
-// HTML-INDEX: </div>
-// HTML-INDEX: <table class="table-wrapper">
-// HTML-INDEX: <tbody>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <th>Name</th>
-// HTML-INDEX: <th>Value</th>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>Circle</td>
-// HTML-INDEX: <td>0</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>Rectangle</td>
-// HTML-INDEX: <td>1</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>Triangle</td>
-// HTML-INDEX: <td>2</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: </tbody>
-// HTML-INDEX: </table>
+// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
+// HTML-INDEX-NEXT: <div>
+// HTML-INDEX-NEXT: <pre><code class="language-cpp code-clang-doc">enum class Shapes</code></pre>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <table class="table-wrapper">
+// HTML-INDEX-NEXT: <tbody>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <th>Name</th>
+// HTML-INDEX-NEXT: <th>Value</th>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Circle</td>
+// HTML-INDEX-NEXT: <td>0</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Rectangle</td>
+// HTML-INDEX-NEXT: <td>1</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Triangle</td>
+// HTML-INDEX-NEXT: <td>2</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: </tbody>
+// HTML-INDEX-NEXT: </table>
+// HTML-INDEX-NEXT: <div class="doc-card">
+// HTML-INDEX-NEXT: <div class="nested-delimiter-container">
+// HTML-INDEX-NEXT: <p> Shape Types</p>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-48]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: </div>
+
+typedef unsigned char uint8_t;
+/**
+ * @brief Specify the size
+ */
+enum Size : uint8_t {
+ // MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
+ // HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ Small, ///< A pearl
+ Medium, ///< A tennis ball
+ Large ///< A football
+};
+
+// MD-INDEX: | enum Size : uint8_t |
+// MD-INDEX: --
+// MD-INDEX: | Small | 0 | A pearl |
+// MD-INDEX: | Medium | 1 | A tennis ball |
+// MD-INDEX: | Large | 2 | A football |
+// MD-INDEX: **brief** Specify the size
+
+// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
+// HTML-INDEX-NEXT: <div>
+// HTML-INDEX-NEXT: <pre><code class="language-cpp code-clang-doc">enum Size : uint8_t</code></pre>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <table class="table-wrapper">
+// HTML-INDEX-NEXT: <tbody>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <th>Name</th>
+// HTML-INDEX-NEXT: <th>Value</th>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Small</td>
+// HTML-INDEX-NEXT: <td>0</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Medium</td>
+// HTML-INDEX-NEXT: <td>1</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>Large</td>
+// HTML-INDEX-NEXT: <td>2</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: </tbody>
+// HTML-INDEX-NEXT: </table>
+// HTML-INDEX-NEXT: <div class="doc-card">
+// HTML-INDEX-NEXT: <div class="nested-delimiter-container">
+// HTML-INDEX-NEXT: <p> Specify the size</p>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-44]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: </div>
+
+/**
+ * @brief Very long number
+ */
+enum : long long {
+ // MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
+ // HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ BigVal = 999999999999 ///< A very large value
+};
+
+// MD-INDEX: | enum (unnamed) : long long |
+// MD-INDEX: --
+// MD-INDEX: | BigVal | 999999999999 | A very large value |
+// MD-INDEX: **brief** Very long number
+
+// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
+// HTML-INDEX-NEXT: <div>
+// HTML-INDEX-NEXT: <pre><code class="language-cpp code-clang-doc">enum (unnamed) : long long</code></pre>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <table class="table-wrapper">
+// HTML-INDEX-NEXT: <tbody>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <th>Name</th>
+// HTML-INDEX-NEXT: <th>Value</th>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>BigVal</td>
+// HTML-INDEX-NEXT: <td>999999999999</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: </tbody>
+// HTML-INDEX-NEXT: </table>
+// HTML-INDEX-NEXT: <div class="doc-card">
+// HTML-INDEX-NEXT: <div class="nested-delimiter-container">
+// HTML-INDEX-NEXT: <p> Very long number</p>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-32]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: </div>
+
+class FilePermissions {
+// MD-PERM-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
+// HTML-PERM-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+public:
+ /**
+ * @brief File permission flags
+ */
+ enum {
+ // MD-PERM-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
+ // HTML-PERM-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ Read = 1, ///> Permission to READ r
+ Write = 2, ///> Permission to WRITE w
+ Execute = 4 ///> Permission to EXECUTE x
+ };
+};
+
+// MD-PERM: | enum (unnamed) |
+// MD-PERM: --
+// MD-PERM: | Read | 1 | Permission to READ r |
+// MD-PERM: | Write | 2 | Permission to WRITE w |
+// MD-PERM: | Execute | 4 | Permission to EXECUTE x |
+// MD-PERM: **brief** File permission flags
+
+// HTML-PERM-LABEL: <section id="Enums" class="section-container">
+// HTML-PERM-NEXT: <h2>Enumerations</h2>
+// HTML-PERM-NEXT: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
+// HTML-PERM-NEXT: <div>
+// HTML-PERM-NEXT: <pre><code class="language-cpp code-clang-doc">enum (unnamed)</code></pre>
+// HTML-PERM-NEXT: </div>
+// HTML-PERM-NEXT: <table class="table-wrapper">
+// HTML-PERM-NEXT: <tbody>
+// HTML-PERM-NEXT: <tr>
+// HTML-PERM-NEXT: <th>Name</th>
+// HTML-PERM-NEXT: <th>Value</th>
+// HTML-PERM-NEXT: </tr>
+// HTML-PERM-NEXT: <tr>
+// HTML-PERM-NEXT: <td>Read</td>
+// HTML-PERM-NEXT: <td>1</td>
+// HTML-PERM-NEXT: </tr>
+// HTML-PERM-NEXT: <tr>
+// HTML-PERM-NEXT: <td>Write</td>
+// HTML-PERM-NEXT: <td>2</td>
+// HTML-PERM-NEXT: </tr>
+// HTML-PERM-NEXT: <tr>
+// HTML-PERM-NEXT: <td>Execute</td>
+// HTML-PERM-NEXT: <td>4</td>
+// HTML-PERM-NEXT: </tr>
+// HTML-PERM-NEXT: </tbody>
+// HTML-PERM-NEXT: </table>
+// HTML-PERM-NEXT: <div class="doc-card">
+// HTML-PERM-NEXT: <div class="nested-delimiter-container">
+// HTML-PERM-NEXT: <p> File permission flags</p>
+// HTML-PERM-NEXT: </div>
+// HTML-PERM-NEXT: </div>
+// HTML-PERM-NEXT: <p>Defined at line [[@LINE-47]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-PERM-NEXT: </div>
+// HTML-PERM-NEXT: </section>
// COM: FIXME: Add enums declared inside of classes to class template
class Animals {
@@ -161,9 +316,9 @@ class Animals {
// MD-ANIMAL: ## Enums
// MD-ANIMAL: | enum AnimalType |
// MD-ANIMAL: --
-// MD-ANIMAL: | Dog |
-// MD-ANIMAL: | Cat |
-// MD-ANIMAL: | Iguana |
+// MD-ANIMAL: | Dog | 0 | Man's best friend |
+// MD-ANIMAL: | Cat | 1 | Man's other best friend |
+// MD-ANIMAL: | Iguana | 2 | A lizard |
// MD-ANIMAL: **brief** specify what animal the class is
namespace Vehicles {
@@ -185,10 +340,10 @@ enum Car {
// MD-VEHICLES: ## Enums
// MD-VEHICLES: | enum Car |
// MD-VEHICLES: --
-// MD-VEHICLES: | Sedan |
-// MD-VEHICLES: | SUV |
-// MD-VEHICLES: | Pickup |
-// MD-VEHICLES: | Hatchback |
+// MD-VEHICLES: | Sedan | 0 | Comment 1 |
+// MD-VEHICLES: | SUV | 1 | Comment 2 |
+// MD-VEHICLES: | Pickup | 2 | Comment 3 |
+// MD-VEHICLES: | Hatchback | 3 | Comment 4 |
// MD-VEHICLES: **brief** specify type of car
// HTML-VEHICLES: <div>
@@ -227,30 +382,33 @@ enum ColorUserSpecified {
// MD-INDEX: | enum ColorUserSpecified |
// MD-INDEX: --
-// MD-INDEX: | RedUserSpecified |
-// MD-INDEX: | GreenUserSpecified |
-// MD-INDEX: | BlueUserSpecified |
+// MD-INDEX: | RedUserSpecified | 65 |
+// MD-INDEX: | GreenUserSpecified | 2 |
+// MD-INDEX: | BlueUserSpecified | 67 |
-// HTML-INDEX: <div>
-// HTML-INDEX: <pre><code class="language-cpp code-clang-doc">enum ColorUserSpecified</code></pre>
-// HTML-INDEX: </div>
-// HTML-INDEX: <table class="table-wrapper">
-// HTML-INDEX: <tbody>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <th>Name</th>
-// HTML-INDEX: <th>Value</th>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>RedUserSpecified</td>
-// HTML-INDEX: <td>'A'</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>GreenUserSpecified</td>
-// HTML-INDEX: <td>2</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: <tr>
-// HTML-INDEX: <td>BlueUserSpecified</td>
-// HTML-INDEX: <td>'C'</td>
-// HTML-INDEX: </tr>
-// HTML-INDEX: </tbody>
-// HTML-INDEX: </table>
+// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
+// HTML-INDEX-NEXT: <div>
+// HTML-INDEX-NEXT: <pre><code class="language-cpp code-clang-doc">enum ColorUserSpecified</code></pre>
+// HTML-INDEX-NEXT: </div>
+// HTML-INDEX-NEXT: <table class="table-wrapper">
+// HTML-INDEX-NEXT: <tbody>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <th>Name</th>
+// HTML-INDEX-NEXT: <th>Value</th>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>RedUserSpecified</td>
+// HTML-INDEX-NEXT: <td>'A'</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>GreenUserSpecified</td>
+// HTML-INDEX-NEXT: <td>2</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: <tr>
+// HTML-INDEX-NEXT: <td>BlueUserSpecified</td>
+// HTML-INDEX-NEXT: <td>'C'</td>
+// HTML-INDEX-NEXT: </tr>
+// HTML-INDEX-NEXT: </tbody>
+// HTML-INDEX-NEXT: </table>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-36]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: </div>
More information about the cfe-commits
mailing list