https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/171938

>From 103242be294fb1bfe326db89fc66fe0843486219 Mon Sep 17 00:00:00 2001
From: Erick Velez <[email protected]>
Date: Thu, 11 Dec 2025 14:07:40 -0800
Subject: [PATCH] [clang-doc] Serialize namespace-level functions

---
 clang-tools-extra/clang-doc/JSONGenerator.cpp |  4 +-
 .../assets/function-template.mustache         |  6 +-
 .../assets/namespace-template.mustache        | 26 +++++++
 .../test/clang-doc/json/namespace.cpp         |  1 +
 .../test/clang-doc/namespace.cpp              | 70 ++++++++++++-------
 .../test/clang-doc/templates.cpp              | 43 ++++++++++++
 .../unittests/clang-doc/JSONGeneratorTest.cpp |  1 +
 7 files changed, 124 insertions(+), 27 deletions(-)

diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp 
b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 327184afd7dc1..8828414cb3925 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -629,8 +629,10 @@ static void serializeInfo(const NamespaceInfo &I, 
json::Object &Obj,
     serializeInfo(Info, Object, RepositoryUrl);
   };
 
-  if (!I.Children.Functions.empty())
+  if (!I.Children.Functions.empty()) {
     serializeArray(I.Children.Functions, Obj, "Functions", SerializeInfo);
+    Obj["HasFunctions"] = true;
+  }
 
   if (!I.Children.Concepts.empty())
     serializeArray(I.Children.Concepts, Obj, "Concepts", SerializeInfo);
diff --git a/clang-tools-extra/clang-doc/assets/function-template.mustache 
b/clang-tools-extra/clang-doc/assets/function-template.mustache
index dc787bf0c8694..5e02257f86de8 100644
--- a/clang-tools-extra/clang-doc/assets/function-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/function-template.mustache
@@ -7,13 +7,17 @@
 }}
 <div class="delimiter-container">
     <div id="{{USR}}">
+        {{#Template}}
+        <pre><code class="language-cpp code-clang-doc">template 
&lt;{{#Parameters}}{{Param}}{{^End}}, {{/End}}{{/Parameters}}&gt;</code></pre>
+        {{/Template}}
         {{! Function Prototype }}
-        <pre><code class="language-cpp code-clang-doc">{{ReturnType.Name}} 
{{Name}} ({{#Params}}{{^End}}{{Type}} {{Name}}, {{/End}}{{#End}}{{Type}} 
{{Name}}{{/End}}{{/Params}})</code></pre>
+        <pre><code class="language-cpp code-clang-doc">{{ReturnType.Name}} 
{{Name}}{{#Template}}{{#Specialization}}&lt;{{#Parameters}}{{Param}}{{^End}}, 
{{/End}}{{/Parameters}}&gt;{{/Specialization}}{{/Template}} 
({{#Params}}{{^End}}{{Type}} {{Name}}, {{/End}}{{#End}}{{Type}} 
{{Name}}{{/End}}{{/Params}})</code></pre>
         {{! Function Comments }}
         {{#Description}}
         <div>
             {{>Comments}}
         </div>
         {{/Description}}
+        <p>Defined at line {{Location.LineNumber}} of file 
{{Location.Filename}}</p>
     </div>
 </div>
diff --git a/clang-tools-extra/clang-doc/assets/namespace-template.mustache 
b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
index 7e00821c4914f..5edce48cee6d8 100644
--- a/clang-tools-extra/clang-doc/assets/namespace-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
@@ -43,6 +43,20 @@
                         </ul>
                     </li>
                     {{/HasRecords}}
+                    {{#HasFunctions}}
+                    <li class="sidebar-section">
+                        <a class="sidebar-item" href="#Functions">Functions</a>
+                    </li>
+                    <li>
+                        <ul>
+                            {{#Functions}}
+                            <li class="sidebar-item-container">
+                                <a class="sidebar-item" 
href="#{{USR}}">{{Name}}{{#Template}}{{#Specialization}}&lt;{{#Parameters}}{{Param}}{{^End}},
 {{/End}}{{/Parameters}}&gt;{{/Specialization}}{{/Template}}</a>
+                            </li>
+                            {{/Functions}}
+                        </ul>
+                    </li>
+                    {{/HasFunctions}}
                 </ul>
             </div>
             <div class="resizer" id="resizer"></div>
@@ -71,6 +85,18 @@
                     </ul>
                 </section>
                 {{/HasRecords}}
+                {{#HasFunctions}}
+                <section id="Functions" class="section-container">
+                    <h2>Functions</h2>
+                    <ul class="class-container">
+                        {{#Functions}}
+                        <li>
+                            {{>FunctionPartial}}
+                        </li>
+                        {{/Functions}}
+                    </ul>
+                </section>
+                {{/HasFunctions}}
             </div>
         </div>
     </main>
diff --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp 
b/clang-tools-extra/test/clang-doc/json/namespace.cpp
index c1370d9fe379f..3beb6b91010d6 100644
--- a/clang-tools-extra/test/clang-doc/json/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp
@@ -73,6 +73,7 @@ typedef int MyTypedef;
 // CHECK-NEXT:     }
 // CHECK-NEXT:   ],
 // CHECK-NEXT:   "HasEnums": true,
+// CHECK-NEXT:   "HasFunctions": true,
 // CHECK-NEXT:   "HasRecords": true,
 // CHECK-NEXT:   "InfoType": "namespace",
 // CHECK-NEXT:   "Name": "Global Namespace",
diff --git a/clang-tools-extra/test/clang-doc/namespace.cpp 
b/clang-tools-extra/test/clang-doc/namespace.cpp
index 8580ea6739a21..a8267d34efd59 100644
--- a/clang-tools-extra/test/clang-doc/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/namespace.cpp
@@ -45,7 +45,7 @@
 namespace {
 void anonFunction() {}
 // MD-ANON-INDEX-LINE: *Defined at 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-ANON-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-ANON-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
 
 class AnonClass {};
 // MD-ANON-CLASS-LINE: *Defined at 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
@@ -80,7 +80,7 @@ namespace PrimaryNamespace {
 // Function in PrimaryNamespace
 void functionInPrimaryNamespace() {}
 // MD-PRIMARY-INDEX-LINE: *Defined at 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-PRIMARY-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-PRIMARY-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
 
 // Class in PrimaryNamespace
 class ClassInPrimaryNamespace {};
@@ -97,7 +97,7 @@ namespace NestedNamespace {
 // Function in NestedNamespace
 void functionInNestedNamespace() {}
 // MD-NESTED-INDEX-LINE: *Defined at 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-NESTED-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-NESTED-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
 
 // Class in NestedNamespace
 class ClassInNestedNamespace {};
@@ -128,10 +128,17 @@ class ClassInNestedNamespace {};
 // HTML-NESTED-INDEX:             </a>
 // HTML-NESTED-INDEX:         </li>
 // HTML-NESTED-INDEX:     </ul>
-// HTML-NESTED-INDEX-NOT: <h2 id="Functions">Functions</h2>
-// HTML-NESTED-INDEX-NOT: <h3 
id="{{([0-9A-F]{40})}}">functionInNestedNamespace</h3>
-// HTML-NESTED-INDEX-NOT: <p>void functionInNestedNamespace()</p>
-// HTML-NESTED-INDEX-NOT: <p> Function in NestedNamespace</p>
+// HTML-NESTED-INDEX:     <div class="delimiter-container">
+// HTML-NESTED-INDEX:         <div id="{{([0-9A-F]{40})}}">
+// HTML-NESTED-INDEX:             <pre><code class="language-cpp 
code-clang-doc">void functionInNestedNamespace ()</code></pre>
+// HTML-NESTED-INDEX:             <div>
+// HTML-NESTED-INDEX:                 <div>
+// HTML-NESTED-INDEX:                     <p> Function in NestedNamespace</p>
+// HTML-NESTED-INDEX:                 </div>
+// HTML-NESTED-INDEX:             </div>
+// HTML-NESTED-INDEX:             <p>Defined at line 98 of file 
{{.*}}namespace.cpp</p>
+// HTML-NESTED-INDEX:         </div>
+// HTML-NESTED-INDEX:     </div>
 } // namespace PrimaryNamespace
 
 // MD-PRIMARY-INDEX: # namespace PrimaryNamespace
@@ -148,25 +155,31 @@ class ClassInNestedNamespace {};
 // HTML-PRIMARY-INDEX: <h2>PrimaryNamespace</h2>
 // HTML-PRIMARY-INDEX-NOT: <h2 id="Namespaces">Namespaces</h2>
 // HTML-PRIMARY-INDEX-NOT: <a 
href="NestedNamespace{{[\/]}}index.html">NestedNamespace</a>
-// HTML-PRIMARY-INDEX      <h2>Inner Classes</h2>
-// HTML-PRIMARY-INDEX          <ul class="class-container">
-// HTML-PRIMARY-INDEX              <li id="{{([0-9A-F]{40})}}" 
style="max-height: 40px;">
-// HTML-PRIMARY-INDEX                  <a 
href="_ZTVN16PrimaryNamespace23ClassInPrimaryNamespaceE.html">
-// HTML-PRIMARY-INDEX                      <pre><code class="language-cpp 
code-clang-doc">class ClassInPrimaryNamespace</code></pre>
-// HTML-PRIMARY-INDEX                  </a>
-// HTML-PRIMARY-INDEX              </li>
-// HTML-PRIMARY-INDEX          </ul>
-// HTML-PRIMARY-INDEX-NOT: <h2 id="Functions">Functions</h2>
-// HTML-PRIMARY-INDEX-NOT: <h3 
id="{{([0-9A-F]{40})}}">functionInPrimaryNamespace</h3>
-// HTML-PRIMARY-INDEX-NOT: <p>void functionInPrimaryNamespace()</p>
-// HTML-PRIMARY-INDEX-NOT: <p> Function in PrimaryNamespace</p>
-
+// HTML-PRIMARY-INDEX:      <h2>Inner Classes</h2>
+// HTML-PRIMARY-INDEX:          <ul class="class-container">
+// HTML-PRIMARY-INDEX:              <li id="{{([0-9A-F]{40})}}" 
style="max-height: 40px;">
+// HTML-PRIMARY-INDEX:                  <a 
href="_ZTVN16PrimaryNamespace23ClassInPrimaryNamespaceE.html">
+// HTML-PRIMARY-INDEX:                      <pre><code class="language-cpp 
code-clang-doc">class ClassInPrimaryNamespace</code></pre>
+// HTML-PRIMARY-INDEX:                 </a>
+// HTML-PRIMARY-INDEX:              </li>
+// HTML-PRIMARY-INDEX:          </ul>
+// HTML-PRIMARY-INDEX:      <div class="delimiter-container">
+// HTML-PRIMARY-INDEX:          <div id="{{([0-9A-F]{40})}}">
+// HTML-PRIMARY-INDEX:              <pre><code class="language-cpp 
code-clang-doc">void functionInPrimaryNamespace ()</code></pre>
+// HTML-PRIMARY-INDEX:              <div>
+// HTML-PRIMARY-INDEX:                  <div>
+// HTML-PRIMARY-INDEX:                      <p> Function in 
PrimaryNamespace</p>
+// HTML-PRIMARY-INDEX:                  </div>
+// HTML-PRIMARY-INDEX:              </div>
+// HTML-PRIMARY-INDEX:              <p>Defined at line 81 of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-PRIMARY-INDEX:          </div>
+// HTML-PRIMARY-INDEX:      </div>
 // AnotherNamespace
 namespace AnotherNamespace {
 // Function in AnotherNamespace
 void functionInAnotherNamespace() {}
 // MD-ANOTHER-INDEX-LINE: *Defined at 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-ANOTHER-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-ANOTHER-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
 
 // Class in AnotherNamespace
 class ClassInAnotherNamespace {};
@@ -198,10 +211,17 @@ class ClassInAnotherNamespace {};
 // HTML-ANOTHER-INDEX:             </a>
 // HTML-ANOTHER-INDEX:         </li>
 // HTML-ANOTHER-INDEX:     </ul>
-// HTML-ANOTHER-INDEX-NOT: <h2 id="Functions">Functions</h2>
-// HTML-ANOTHER-INDEX-NOT: <h3 
id="{{([0-9A-F]{40})}}">functionInAnotherNamespace</h3>
-// HTML-ANOTHER-INDEX-NOT: <p>void functionInAnotherNamespace()</p>
-// HTML-ANOTHER-INDEX-NOT: <p> Function in AnotherNamespace</p>
+// HTML-ANOTHER-INDEX:     <div class="delimiter-container">
+// HTML-ANOTHER-INDEX:         <div id="{{([0-9A-F]{40})}}">
+// HTML-ANOTHER-INDEX:             <pre><code class="language-cpp 
code-clang-doc">void functionInAnotherNamespace ()</code></pre>
+// HTML-ANOTHER-INDEX:             <div>
+// HTML-ANOTHER-INDEX:                 <div>
+// HTML-ANOTHER-INDEX:                     <p> Function in AnotherNamespace</p>
+// HTML-ANOTHER-INDEX:                 </div>
+// HTML-ANOTHER-INDEX:             </div>
+// HTML-ANOTHER-INDEX:             <p>Defined at line 180 of file 
{{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-ANOTHER-INDEX:         </div>
+// HTML-ANOTHER-INDEX:     </div>
 
 // COM: FIXME: Add namespaces to namespace template
 // HTML-GLOBAL-INDEX-NOT: <div id="main-content" class="col-xs-12 col-sm-9 
col-md-8 main-content">
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp 
b/clang-tools-extra/test/clang-doc/templates.cpp
index addf7cbc63519..e76ccb240dcfc 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -10,6 +10,7 @@
 // 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
+// RUN: cat %t/docs/html/GlobalNamespace/index.html | FileCheck %s 
--check-prefix=HTML
 
 // YAML: ---
 // YAML-NEXT: USR:             '{{([0-9A-F]{40})}}'
@@ -72,6 +73,15 @@ void ParamPackFunction(T... args);
 // JSON-NEXT:        ]
 // JSON-NEXT:      },
 
+// HTML:       <div class="delimiter-container">
+// HTML-NEXT:      <div id="{{([0-9A-F]{40})}}">
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">template 
&lt;class... T&gt;</code></pre>
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">void 
ParamPackFunction (T... args)</code></pre>
+// COM:                FIXME: Omit defined line if not defined, or emit 
declaration line.
+// HTML-NEXT:          <p>Defined at line of file </p>
+// HTML-NEXT:      </div>
+// HTML-NEXT:  </div>
+
 template <typename T, int U = 1>
 void function(T x) {}
 
@@ -125,6 +135,15 @@ void function(T x) {}
 // JSON-NEXT:        ]
 // JSON-NEXT:      }
 
+// HTML:       <div class="delimiter-container">
+// HTML-NEXT:      <div id="{{([0-9A-F]{40})}}">
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">template 
&lt;typename T, int U = 1&gt;</code></pre>
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">void 
function (T x)</code></pre>
+// HTML-NEXT:          <p>Defined at line [[# @LINE - 56]] of file 
{{.*}}templates.cpp</p>
+// HTML-NEXT:      </div>
+// HTML-NEXT:  </div>
+
+
 template <>
 void function<bool, 0>(bool x) {}
 
@@ -183,6 +202,14 @@ void function<bool, 0>(bool x) {}
 // JSON-NEXT:        }
 // JSON-NEXT:      },
 
+// HTML:       <div class="delimiter-container">
+// HTML-NEXT:      <div id="{{([0-9A-F]{40})}}">
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">template 
&lt;&gt;</code></pre>
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">void 
function&lt;bool, 0&gt; (bool x)</code></pre>
+// HTML-NEXT:          <p>Defined at line [[# @LINE - 62]] of file 
{{.*}}templates.cpp</p>
+// HTML-NEXT:      </div>
+// HTML-NEXT:  </div>
+
 /// A Tuple type
 ///
 /// Does Tuple things.
@@ -272,3 +299,19 @@ tuple<int, int, bool> func_with_tuple_param(tuple<int, 
int, bool> t) { return t;
 // JSON-NEXT:        "QualName": "tuple<int, int, bool>",
 // JSON-NEXT:        "USR": "{{([0-9A-F]{40})}}"
 // JSON-NEXT:      },
+
+// HTML:       <div class="delimiter-container">
+// HTML-NEXT:      <div id="{{([0-9A-F]{40})}}">
+// HTML-NEXT:          <pre><code class="language-cpp code-clang-doc">tuple 
func_with_tuple_param (tuple t)</code></pre>
+// HTML-NEXT:          <div>
+// HTML-NEXT:              <div>
+// HTML-NEXT:                  <p> A function with a tuple parameter</p>
+// HTML-NEXT:              </div>
+// HTML-NEXT:              <h3>Parameters</h3>
+// HTML-NEXT:              <div>
+// HTML-NEXT:                  <b>t</b>   The input to func_with_tuple_param
+// HTML-NEXT:              </div> 
+// HTML-NEXT:          </div>
+// HTML-NEXT:          <p>Defined at line [[# @LINE - 77]] of file 
{{.*}}templates.cpp</p>
+// HTML-NEXT:      </div>
+// HTML-NEXT:  </div>
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index 11ab969aa6b90..e6eaabcb8127c 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -246,6 +246,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) {
     }
   ],
   "HasEnums": true,
+  "HasFunctions": true,
   "HasRecords": true,
   "InfoType": "namespace",
   "Name": "Global Namespace",

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to