[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add nested records to template (PR #173959)
Erick Velez via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 29 22:21:30 PST 2025
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/173959
Nested records already had some tags, but they weren't
compatible with the current JSON scheme.
>From 7d7791c154cefb697d06c9b3a144eae1da576e70 Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvelez7 at gmail.com>
Date: Wed, 24 Dec 2025 13:21:53 -0800
Subject: [PATCH] [clang-doc] Add nested records to template
Nested records already had some tags, but they weren't
compatible with the current JSON scheme.
---
clang-tools-extra/clang-doc/JSONGenerator.cpp | 8 ++++-
.../clang-doc/assets/class-template.mustache | 24 +++++++--------
.../test/clang-doc/json/class.cpp | 30 ++++++++++++++++---
3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index f4938b3460f53..b7cc390d1e634 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -330,8 +330,14 @@ static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
ReferenceObj["Name"] = Ref.Name;
ReferenceObj["QualName"] = Ref.QualName;
ReferenceObj["USR"] = toHex(toStringRef(Ref.USR));
- if (!Ref.DocumentationFileName.empty())
+ if (!Ref.DocumentationFileName.empty()) {
ReferenceObj["DocumentationFileName"] = Ref.DocumentationFileName;
+
+ // If the reference is a nested class, the
+ if (Ref.Path != "GlobalNamespace") {
+ ReferenceObj["PathStem"] = sys::path::stem(Ref.Path);
+ }
+ }
}
// Although namespaces and records both have ScopeChildren, they serialize them
diff --git a/clang-tools-extra/clang-doc/assets/class-template.mustache b/clang-tools-extra/clang-doc/assets/class-template.mustache
index 8555d1bbffae5..a539671f52e6d 100644
--- a/clang-tools-extra/clang-doc/assets/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/class-template.mustache
@@ -99,20 +99,20 @@
</ul>
</li>
{{/HasTypedefs}}
- {{#Record}}
+ {{#HasRecords}}
<li class="sidebar-section">
<a class="sidebar-item" href="#Classes">Inner Classes</a>
</li>
<li>
<ul>
- {{#Links}}
+ {{#Records}}
<li class="sidebar-item-container">
- <a class="sidebar-item" href="#{{ID}}">{{Name}}</a>
+ <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
</li>
- {{/Links}}
+ {{/Records}}
</ul>
</li>
- {{/Record}}
+ {{/HasRecords}}
</ul>
</div>
<div class="resizer" id="resizer"></div>
@@ -195,20 +195,20 @@
{{/Enums}}
</section>
{{/HasEnums}}
- {{#Record}}
+ {{#HasRecords}}
<section id="Classes" class="section-container">
<h2>Inner Classes</h2>
<ul class="class-container">
- {{#Links}}
- <li id="{{ID}}" style="max-height: 40px;">
- <a href="{{Link}}">
- <pre><code class="language-cpp code-clang-doc" >class {{Name}}</code></pre>
+ {{#Records}}
+ <li id="{{USR}}" style="max-height: 40px;">
+ <a href="{{PathStem}}/{{DocumentationFileName}}.html">
+ <pre><code class="language-cpp code-clang-doc">class {{Name}}</code></pre>
</a>
</li>
- {{/Links}}
+ {{/Records}}
</ul>
</section>
- {{/Record}}
+ {{/HasRecords}}
{{#HasTypedefs}}
<section id="Typedefs" class="section-container">
<h2>Typedefs</h2>
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index 6ec86ff1efeed..43aa8df187c07 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -1,6 +1,7 @@
// RUN: rm -rf %t && mkdir -p %t
-// RUN: clang-doc --output=%t --format=json --executor=standalone %s
+// RUN: clang-doc --output=%t --format=html --executor=standalone %s
// RUN: FileCheck %s < %t/json/GlobalNamespace/_ZTV7MyClass.json
+// RUN: FileCheck %s < %t/html/GlobalNamespace/_ZTV7MyClass.html -check-prefix=HTML
struct Foo;
@@ -57,7 +58,7 @@ struct MyClass {
// CHECK-NEXT: "InfoType": "enum",
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
-// CHECK-NEXT: "LineNumber": 17
+// CHECK-NEXT: "LineNumber": 18
// CHECK-NEXT: },
// CHECK-NEXT: "Members": [
// CHECK-NEXT: {
@@ -135,7 +136,7 @@ struct MyClass {
// CHECK-NEXT: "IsTypedef": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
-// CHECK-NEXT: "LineNumber": 10
+// CHECK-NEXT: "LineNumber": 11
// CHECK-NEXT: },
// CHECK-NEXT: "MangledName": "_ZTV7MyClass",
// CHECK-NEXT: "Name": "MyClass",
@@ -223,6 +224,7 @@ struct MyClass {
// CHECK-NEXT: "End": true,
// CHECK-NEXT: "Name": "NestedClass",
// CHECK-NEXT: "Path": "GlobalNamespace{{[\/]+}}MyClass",
+// CHECK-NEXT: "PathStem": "MyClass",
// CHECK-NEXT: "QualName": "NestedClass",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
@@ -235,7 +237,7 @@ struct MyClass {
// CHECK-NEXT: "IsUsing": false,
// CHECK-NEXT: "Location": {
// CHECK-NEXT: "Filename": "{{.*}}class.cpp",
-// CHECK-NEXT: "LineNumber": 23
+// CHECK-NEXT: "LineNumber": 24
// CHECK-NEXT: },
// CHECK-NEXT: "Name": "MyTypedef",
// CHECK-NEXT: "Namespace": [
@@ -252,3 +254,23 @@ struct MyClass {
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
+
+// HTML: <a class="sidebar-item" href="#Classes">Inner Classes</a>
+// HTML-NEXT: </li>
+// HTML-NEXT: <li>
+// HTML-NEXT: <ul>
+// HTML-NEXT: <li class="sidebar-item-container">
+// HTML-NEXT: <a class="sidebar-item" href="#{{([0-9A-F]{40})}}">NestedClass</a>
+// HTML-NEXT: </li>
+// HTML-NEXT: </ul>
+// HTML-NEXT: </li>
+// HTML: <section id="Classes" class="section-container">
+// HTML-NEXT: <h2>Inner Classes</h2>
+// HTML-NEXT: <ul class="class-container">
+// HTML-NEXT: <li id="{{([0-9A-F]{40})}}" style="max-height: 40px;">
+// HTML-NEXT: <a href="MyClass/_ZTVN7MyClass11NestedClassE.html">
+// HTML-NEXT: <pre><code class="language-cpp code-clang-doc">class NestedClass</code></pre>
+// HTML-NEXT: </a>
+// HTML-NEXT: </li>
+// HTML-NEXT: </ul>
+// HTML-NEXT: </section>
More information about the llvm-branch-commits
mailing list