[llvm-branch-commits] [clang-tools-extra] [clang-doc] Add class template to HTML (PR #171937)
Erick Velez via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Dec 12 10:39:23 PST 2025
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/171937
>From 58a5f5b96cb213d79d2f65fe4b8ebf5e8e4543b8 Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvelez7 at gmail.com>
Date: Thu, 11 Dec 2025 09:54:03 -0800
Subject: [PATCH] [clang-doc] Add class template to HTML
---
clang-tools-extra/clang-doc/JSONGenerator.cpp | 11 ++++-
.../clang-doc/assets/class-template.mustache | 3 ++
.../test/clang-doc/json/class-requires.cpp | 5 ++-
.../clang-doc/json/class-specialization.cpp | 10 ++++-
.../test/clang-doc/json/class-template.cpp | 5 ++-
.../test/clang-doc/json/class.cpp | 5 ++-
.../test/clang-doc/json/concept.cpp | 5 ++-
.../test/clang-doc/json/function-requires.cpp | 10 ++++-
.../test/clang-doc/json/method-template.cpp | 5 ++-
.../test/clang-doc/templates.cpp | 44 ++++++++++++++++---
.../unittests/clang-doc/JSONGeneratorTest.cpp | 5 ++-
11 files changed, 89 insertions(+), 19 deletions(-)
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 83fa556782793..327184afd7dc1 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -378,8 +378,15 @@ static void serializeInfo(const ArrayRef<TemplateParamInfo> &Params,
json::Value ParamsArray = Array();
auto &ParamsArrayRef = *ParamsArray.getAsArray();
ParamsArrayRef.reserve(Params.size());
- for (const auto &Param : Params)
- ParamsArrayRef.push_back(Param.Contents);
+ for (size_t Idx = 0; Idx < Params.size(); ++Idx) {
+ json::Value ParamObjVal = Object();
+ Object &ParamObj = *ParamObjVal.getAsObject();
+
+ ParamObj["Param"] = Params[Idx].Contents;
+ if (Idx == Params.size() - 1)
+ ParamObj["End"] = true;
+ ParamsArrayRef.push_back(ParamObjVal);
+ }
Obj["Parameters"] = ParamsArray;
}
diff --git a/clang-tools-extra/clang-doc/assets/class-template.mustache b/clang-tools-extra/clang-doc/assets/class-template.mustache
index 52caebb503e2d..ee1220071e24a 100644
--- a/clang-tools-extra/clang-doc/assets/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/class-template.mustache
@@ -107,6 +107,9 @@
<div class="resizer" id="resizer"></div>
<div class="content">
<section class="hero section-container">
+ {{#Template}}
+ <pre><code class="language-cpp code-clang-doc">template <{{#Parameters}}{{Param}}{{^End}}, {{/End}}{{/Parameters}}></code></pre>
+ {{/Template}}
<div class="hero__title">
<h1 class="hero__title-large">{{TagType}} {{Name}}</h1>
<p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
diff --git a/clang-tools-extra/test/clang-doc/json/class-requires.cpp b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
index 4e5ec3a5729cd..e10c5e89f6e17 100644
--- a/clang-tools-extra/test/clang-doc/json/class-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
@@ -29,7 +29,10 @@ struct MyClass;
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "typename T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "typename T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
diff --git a/clang-tools-extra/test/clang-doc/json/class-specialization.cpp b/clang-tools-extra/test/clang-doc/json/class-specialization.cpp
index 60f3b44eb69b0..6fd2f81e49b46 100644
--- a/clang-tools-extra/test/clang-doc/json/class-specialization.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-specialization.cpp
@@ -16,7 +16,10 @@ template<> struct MyClass<int> {};
// BASE-NEXT: "TagType": "struct",
// BASE-NEXT: "Template": {
// BASE-NEXT: "Parameters": [
-// BASE-NEXT: "typename T"
+// BASE-NEXT: {
+// BASE-NEXT: "End": true,
+// BASE-NEXT: "Param": "typename T"
+// BASE-NEXT: }
// BASE-NEXT: ]
// BASE-NEXT: },
@@ -30,7 +33,10 @@ template<> struct MyClass<int> {};
// SPECIALIZATION-NEXT: "Template": {
// SPECIALIZATION-NEXT: "Specialization": {
// SPECIALIZATION-NEXT: "Parameters": [
-// SPECIALIZATION-NEXT: "int"
+// SPECIALIZATION-NEXT: {
+// SPECIALIZATION-NEXT: "End": true,
+// SPECIALIZATION-NEXT: "Param": "int"
+// SPECIALIZATION-NEXT: }
// SPECIALIZATION-NEXT: ],
// SPECIALIZATION-NEXT: "SpecializationOf": "{{[0-9A-F]*}}"
// SPECIALIZATION-NEXT: }
diff --git a/clang-tools-extra/test/clang-doc/json/class-template.cpp b/clang-tools-extra/test/clang-doc/json/class-template.cpp
index de52064466140..9b0d4c4a9ba23 100644
--- a/clang-tools-extra/test/clang-doc/json/class-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-template.cpp
@@ -26,5 +26,8 @@ template<typename T> struct MyClass {
// CHECK: "Type": "T"
// CHECK: "Template": {
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "typename T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "typename T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index d57e8a990c3fe..1c0d5d5ab567a 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -108,7 +108,10 @@ struct MyClass {
// CHECK-NEXT: },
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "typename T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "typename T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: },
diff --git a/clang-tools-extra/test/clang-doc/json/concept.cpp b/clang-tools-extra/test/clang-doc/json/concept.cpp
index f4c4ad3946d47..fc440d095fc4c 100644
--- a/clang-tools-extra/test/clang-doc/json/concept.cpp
+++ b/clang-tools-extra/test/clang-doc/json/concept.cpp
@@ -25,7 +25,10 @@ concept Incrementable = requires(T x) {
// CHECK-NEXT: "Name": "Incrementable",
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "typename T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "typename T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
diff --git a/clang-tools-extra/test/clang-doc/json/function-requires.cpp b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
index 8ba6adc66a54b..931bb07edb836 100644
--- a/clang-tools-extra/test/clang-doc/json/function-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
@@ -43,7 +43,10 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "typename T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "typename T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
@@ -79,7 +82,10 @@ template<Incrementable T> Incrementable auto incrementTwo(T t);
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "Incrementable T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "Incrementable T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
diff --git a/clang-tools-extra/test/clang-doc/json/method-template.cpp b/clang-tools-extra/test/clang-doc/json/method-template.cpp
index f4885d956ad9b..a617f983d1269 100644
--- a/clang-tools-extra/test/clang-doc/json/method-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/method-template.cpp
@@ -36,7 +36,10 @@ struct MyClass {
// CHECK-NEXT: },
// CHECK-NEXT: "Template": {
// CHECK-NEXT: "Parameters": [
-// CHECK-NEXT: "class T"
+// CHECK-NEXT: {
+// CHECK-NEXT: "End": true,
+// CHECK-NEXT: "Param": "class T"
+// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp
index 171ff496ab8ef..addf7cbc63519 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -7,8 +7,9 @@
// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs --format=md
// RUN: cat %t/docs/GlobalNamespace/index.md | FileCheck %s --check-prefix=MD
-// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs --format=json
+// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs --format=html
// RUN: cat %t/docs/json/GlobalNamespace/index.json | FileCheck %s --check-prefix=JSON
+// RUN: cat %t/docs/html/GlobalNamespace/_ZTV5tuple.html | FileCheck %s --check-prefix=HTML-STRUCT
// YAML: ---
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
@@ -64,7 +65,10 @@ void ParamPackFunction(T... args);
// JSON-NEXT: },
// JSON-NEXT: "Template": {
// JSON-NEXT: "Parameters": [
-// JSON-NEXT: "class... T"
+// JSON-NEXT: {
+// JSON-NEXT: "End": true,
+// JSON-NEXT: "Param": "class... T"
+// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
@@ -111,10 +115,15 @@ void function(T x) {}
// JSON-NEXT: },
// JSON-NEXT: "Template": {
// JSON-NEXT: "Parameters": [
-// JSON-NEXT: "typename T",
-// JSON-NEXT: "int U = 1"
+// JSON-NEXT: {
+// JSON-NEXT: "Param": "typename T"
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "End": true,
+// JSON-NEXT: "Param": "int U = 1"
+// JSON-NEXT: }
// JSON-NEXT: ]
-// JSON-NEXT: },
+// JSON-NEXT: }
template <>
void function<bool, 0>(bool x) {}
@@ -162,8 +171,13 @@ void function<bool, 0>(bool x) {}
// JSON-NEXT: "Template": {
// JSON-NEXT: "Specialization": {
// JSON-NEXT: "Parameters": [
-// JSON-NEXT: "bool",
-// JSON-NEXT: "0"
+// JSON-NEXT: {
+// JSON-NEXT: "Param": "bool"
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "End": true,
+// JSON-NEXT: "Param": "0"
+// JSON-NEXT: }
// JSON-NEXT: ],
// JSON-NEXT: "SpecializationOf": "{{([0-9A-F]{40})}}"
// JSON-NEXT: }
@@ -175,6 +189,22 @@ void function<bool, 0>(bool x) {}
template <typename... Tys>
struct tuple {};
+// HTML-STRUCT: <section class="hero section-container">
+// HTML-STRUCT-NEXT: <pre><code class="language-cpp code-clang-doc">template <typename... Tys></code></pre>
+// HTML-STRUCT-NEXT: <div class="hero__title">
+// HTML-STRUCT-NEXT: <h1 class="hero__title-large">struct tuple</h1>
+// HTML-STRUCT-NEXT: <p>Defined at line [[# @LINE - 6]] of file {{.*}}templates.cpp</p>
+// HTML-STRUCT-NEXT: <div class="hero__subtitle">
+// HTML-STRUCT-NEXT: <div>
+// HTML-STRUCT-NEXT: <p> A Tuple type</p>
+// HTML-STRUCT-NEXT: </div>
+// HTML-STRUCT-NEXT: <div>
+// HTML-STRUCT-NEXT: <p> Does Tuple things.</p>
+// HTML-STRUCT-NEXT: </div>
+// HTML-STRUCT-NEXT: </div>
+// HTML-STRUCT-NEXT: </div>
+// HTML-STRUCT-NEXT: </section>
+
/// A function with a tuple parameter
///
/// \param t The input to func_with_tuple_param
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index b468964630d45..11ab969aa6b90 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -175,7 +175,10 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
"TagType": "class",
"Template": {
"Parameters": [
- "class T"
+ {
+ "End": true,
+ "Param": "class T"
+ }
]
},
"USR": "0000000000000000000000000000000000000000",
More information about the llvm-branch-commits
mailing list