Skip to content

[clang-doc] Serialize repository URL in Mustache templates#174914

Merged
evelez7 merged 1 commit intomainfrom
users/evelez7/clang-doc-repository-url-templates
Jan 10, 2026
Merged

[clang-doc] Serialize repository URL in Mustache templates#174914
evelez7 merged 1 commit intomainfrom
users/evelez7/clang-doc-repository-url-templates

Conversation

@evelez7
Copy link
Member

@evelez7 evelez7 commented Jan 8, 2026

Location tags didn't handle possible FileURL fields when a repository
URL was specified in a clang-doc invocation. This also cleans up all
location occurences to use <p> instead of <div> and allows linking
to the repository URL.

@llvmbot
Copy link
Member

llvmbot commented Jan 8, 2026

@llvm/pr-subscribers-clang-tools-extra

Author: Erick Velez (evelez7)

Changes

Location tags didn't handle possible FileURL fields when a repository
URL was specified in a clang-doc invocation. This also cleans up all
location occurences to use &lt;p&gt; instead of &lt;div&gt; and allows linking
to the repository URL.


Full diff: https://github.com/llvm/llvm-project/pull/174914.diff

10 Files Affected:

  • (modified) clang-tools-extra/clang-doc/JSONGenerator.cpp (+1-1)
  • (modified) clang-tools-extra/clang-doc/assets/alias-template.mustache (+1-1)
  • (modified) clang-tools-extra/clang-doc/assets/class-template.mustache (+3-1)
  • (modified) clang-tools-extra/clang-doc/assets/enum-template.mustache (+1-3)
  • (modified) clang-tools-extra/clang-doc/assets/function-template.mustache (+2-1)
  • (modified) clang-tools-extra/clang-doc/assets/namespace-template.mustache (+3-1)
  • (modified) clang-tools-extra/test/clang-doc/enum.cpp (+4-6)
  • (modified) clang-tools-extra/test/clang-doc/json/class.cpp (-2)
  • (modified) clang-tools-extra/test/clang-doc/mustache-index.cpp (+1-3)
  • (modified) clang-tools-extra/test/clang-doc/templates.cpp (+1-2)
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index ad76c40d49db8..1621c76df1d0b 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -84,7 +84,7 @@ serializeLocation(const Location &Loc,
     return LocationObj;
   SmallString<128> FileURL(*RepositoryUrl);
   sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
-  FileURL += "#" + std::to_string(Loc.StartLineNumber);
+  FileURL += "#L" + std::to_string(Loc.StartLineNumber);
   LocationObj["FileURL"] = FileURL;
   return LocationObj;
 }
diff --git a/clang-tools-extra/clang-doc/assets/alias-template.mustache b/clang-tools-extra/clang-doc/assets/alias-template.mustache
index 9b32f132e9ef3..835d9aab1417e 100644
--- a/clang-tools-extra/clang-doc/assets/alias-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/alias-template.mustache
@@ -7,6 +7,6 @@
     {{>Comments}}
     {{/Description}}
     {{#Location}}
-    <p>Defined at line {{LineNumber}} of file {{Filename}}</p>
+    <p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
     {{/Location}}
 </div>
diff --git a/clang-tools-extra/clang-doc/assets/class-template.mustache b/clang-tools-extra/clang-doc/assets/class-template.mustache
index ef5a7572a3f48..71ed1abd1016d 100644
--- a/clang-tools-extra/clang-doc/assets/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/class-template.mustache
@@ -153,7 +153,9 @@
                     {{/Template}}
                     <div class="hero__title">
                         <h1 class="hero__title-large">{{TagType}} {{Name}}</h1>
-                        <p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
+                        {{#Location}}
+                        <p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
+                        {{/Location}}
                         {{#Description}}
                         <div class="doc-card">
                             {{>Comments}}
diff --git a/clang-tools-extra/clang-doc/assets/enum-template.mustache b/clang-tools-extra/clang-doc/assets/enum-template.mustache
index af1364c4d37f6..22661c69f9c22 100644
--- a/clang-tools-extra/clang-doc/assets/enum-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/enum-template.mustache
@@ -42,8 +42,6 @@
     </div>
     {{/EnumComments}}
     {{#Location}}
-    <div>
-        Defined at line {{LineNumber}} of file {{Filename}}
-    </div>
+    <p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
     {{/Location}}
 </div>
diff --git a/clang-tools-extra/clang-doc/assets/function-template.mustache b/clang-tools-extra/clang-doc/assets/function-template.mustache
index 354e26b7b05b0..837c59e05f864 100644
--- a/clang-tools-extra/clang-doc/assets/function-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/function-template.mustache
@@ -18,6 +18,7 @@
         </div>
         {{/Description}}
         {{#Location}}
-        <p>Defined at line {{LineNumber}} of file {{Filename}}</p>
+        <p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
         {{/Location}}
+    </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 567af626714ef..fc0b9e2c388d9 100644
--- a/clang-tools-extra/clang-doc/assets/namespace-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
@@ -176,7 +176,9 @@
                         {{#Description}}
                         {{>Comments}}
                         {{/Description}}
-                        <p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
+                        {{#Location}}
+                        <p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
+                        {{/Location}}
                     </div>
                     {{/Concepts}}
                 </section>
diff --git a/clang-tools-extra/test/clang-doc/enum.cpp b/clang-tools-extra/test/clang-doc/enum.cpp
index ce844ec072564..f10d8808f185e 100644
--- a/clang-tools-extra/test/clang-doc/enum.cpp
+++ b/clang-tools-extra/test/clang-doc/enum.cpp
@@ -21,7 +21,7 @@
  */
 enum Color {
   // MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
-  // HTML-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+  // HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
   Red,   ///< Comment 1
   Green, ///< Comment 2
   Blue   ///< Comment 3
@@ -64,7 +64,7 @@ enum Color {
  */
 enum class Shapes {
   // MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
-  // HTML-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+  // HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
 
   /// Comment 1
   Circle,
@@ -115,7 +115,7 @@ class Animals {
    */
   enum AnimalType {
     // MD-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
-    // HTML-ANIMAL-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+    // HTML-ANIMAL-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
     Dog,   ///< Man's best friend
     Cat,   ///< Man's other best friend
     Iguana ///< A lizard
@@ -148,9 +148,7 @@ class Animals {
 // HTML-ANIMAL-NEXT:                 </tr>
 // HTML-ANIMAL-NEXT:             </tbody>
 // HTML-ANIMAL-NEXT:         </table>
-// HTML-ANIMAL-NEXT:         <div>
-// HTML-ANIMAL-NEXT:             Defined at line 116 of file {{.*}}enum.cpp
-// HTML-ANIMAL-NEXT:         </div>
+// HTML-ANIMAL-NEXT:         <p>Defined at line 116 of file {{.*}}enum.cpp</p>
 // HTML-ANIMAL-NEXT:     </div>
 // HTML-ANIMAL-NEXT: </section>
 
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index c4f0b2166a3f8..7614b38567814 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -336,8 +336,6 @@ struct MyClass {
 // HTML-NEXT:         <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
 // HTML-NEXT:                 <pre><code class="language-cpp code-clang-doc">int protectedMethod ()</code></pre>
 // HTML-NEXT:         </div>
-// HTML-NEXT:     </div>
-// HTML-NEXT: </section>
 // HTML:      <section id="Classes" class="section-container">
 // HTML-NEXT:     <h2>Inner Classes</h2>
 // HTML-NEXT:     <ul class="class-container">
diff --git a/clang-tools-extra/test/clang-doc/mustache-index.cpp b/clang-tools-extra/test/clang-doc/mustache-index.cpp
index 9706307287f9b..caaa932d3e02f 100644
--- a/clang-tools-extra/test/clang-doc/mustache-index.cpp
+++ b/clang-tools-extra/test/clang-doc/mustache-index.cpp
@@ -54,9 +54,7 @@ class Foo;
 // CHECK-NEXT:                      </tr>
 // CHECK-NEXT:                  </tbody>
 // CHECK-NEXT:              </table>
-// CHECK-NEXT:              <div>
-// CHECK-NEXT:                  Defined at line 5 of file {{.*}}mustache-index.cpp
-// CHECK-NEXT:              </div>
+// CHECK-NEXT:              <p>Defined at line 5 of file {{.*}}mustache-index.cpp</p>
 // CHECK-NEXT:          </div>
 // CHECK-NEXT:      </div>
 // CHECK-NEXT:  </section>
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp
index 27fff6ed5a09d..8c9b0b53a8b3d 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -78,8 +78,7 @@ void ParamPackFunction(T... args);
 // JSON-NEXT:      },
 
 // HTML:        <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>
-// HTML-NEXT:  </div>
+// HTML-NEXT:   <pre><code class="language-cpp code-clang-doc">void ParamPackFunction (T... args)</code></pre>
 
 template <typename T, int U = 1>
 void function(T x) {}

Copy link
Member Author

evelez7 commented Jan 8, 2026

@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-empty-locations branch from 008f9df to 0c46055 Compare January 8, 2026 06:14
@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-repository-url-templates branch from 6164eef to ec66cd7 Compare January 8, 2026 06:14
Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great patch. LGTM, modulo a few comments.

We may want to style those links somehow to make it more obvious that they're something you can follow. At least in dark mode they're just white text like the rest of the line.

SmallString<128> FileURL(*RepositoryUrl);
sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
FileURL += "#" + std::to_string(Loc.StartLineNumber);
FileURL += "#L" + std::to_string(Loc.StartLineNumber);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FileURL += "#L" + std::to_string(Loc.StartLineNumber);
FileURL += Ctx.RepositoryLinePrefix + std::to_string(Loc.StartLineNumber);

This should be something we can get from the ClangDocContext, and will allow the user to change the default prefix. We added that, since not every code hosting site uses the github convention.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this, but the method of passing around an optional in JSONGenerator seems to be reaching its limit. It seems like it would make more sense to create a class with all of these static functions as methods that can access a ClangDocContext as a field. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, sounds good. Lets not conflate that refactoring and this patch though. Just add a TODO/FIXME, and we can remove it once the class becomes a thing. I imagine its a mixed bag about which APIs will get simpler and which won't w/ a change to a class, but its probably nicer in any case.

@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-empty-locations branch from 0c46055 to be256e4 Compare January 9, 2026 01:03
@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-repository-url-templates branch from ec66cd7 to da383e7 Compare January 9, 2026 01:04
Base automatically changed from users/evelez7/clang-doc-empty-locations to main January 9, 2026 01:29
@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-repository-url-templates branch 2 times, most recently from 36d8658 to 085d7a3 Compare January 9, 2026 05:07
@evelez7 evelez7 force-pushed the users/evelez7/clang-doc-repository-url-templates branch from 085d7a3 to aa58492 Compare January 10, 2026 03:31
Copy link
Member Author

evelez7 commented Jan 10, 2026

Merge activity

  • Jan 10, 4:05 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jan 10, 4:06 AM UTC: @evelez7 merged this pull request with Graphite.

@evelez7 evelez7 merged commit 2723e9a into main Jan 10, 2026
10 checks passed
@evelez7 evelez7 deleted the users/evelez7/clang-doc-repository-url-templates branch January 10, 2026 04:07
Priyanshu3820 pushed a commit to Priyanshu3820/llvm-project that referenced this pull request Jan 18, 2026
Location tags didn't handle possible `FileURL` fields when a repository
URL was specified in a clang-doc invocation. This also cleans up all
location occurences to use `<p>` instead of `<div>` and allows linking
to the repository URL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants