Author: Erick Velez
Date: 2026-01-02T10:15:45-08:00
New Revision: 5a9f34f16b90c29f3dd11914aef9f027edd51f83

URL: 
https://github.com/llvm/llvm-project/commit/5a9f34f16b90c29f3dd11914aef9f027edd51f83
DIFF: 
https://github.com/llvm/llvm-project/commit/5a9f34f16b90c29f3dd11914aef9f027edd51f83.diff

LOG: [clang-doc] Add typedefs and aliases to templates (#173957)

This patch also adds optional template information to the typedef info
struct.

Added: 
    clang-tools-extra/clang-doc/assets/alias-template.mustache
    clang-tools-extra/test/clang-doc/typedef-alias.cpp

Modified: 
    clang-tools-extra/clang-doc/BitcodeReader.cpp
    clang-tools-extra/clang-doc/BitcodeWriter.cpp
    clang-tools-extra/clang-doc/HTMLGenerator.cpp
    clang-tools-extra/clang-doc/JSONGenerator.cpp
    clang-tools-extra/clang-doc/Representation.cpp
    clang-tools-extra/clang-doc/Representation.h
    clang-tools-extra/clang-doc/Serialize.cpp
    clang-tools-extra/clang-doc/assets/class-template.mustache
    clang-tools-extra/clang-doc/assets/namespace-template.mustache
    clang-tools-extra/clang-doc/support/Utils.cpp
    clang-tools-extra/clang-doc/tool/CMakeLists.txt
    clang-tools-extra/test/clang-doc/json/class.cpp
    clang-tools-extra/test/clang-doc/json/namespace.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 731b6990cb697..cf2d5dedafb14 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -800,6 +800,9 @@ template <> void addTemplate(ConceptInfo *I, TemplateInfo 
&&P) {
 template <> void addTemplate(FriendInfo *I, TemplateInfo &&P) {
   I->Template.emplace(std::move(P));
 }
+template <> void addTemplate(TypedefInfo *I, TemplateInfo &&P) {
+  I->Template.emplace(std::move(P));
+}
 
 // Template specializations go only into template records.
 template <typename T>

diff  --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp 
b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index b7f60d88d96ff..e7537458d6e44 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -512,6 +512,8 @@ void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) 
{
     emitBlock(CI);
   if (T.DefLoc)
     emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION);
+  if (T.Template)
+    emitBlock(*T.Template);
   emitRecord(T.IsUsing, TYPEDEF_IS_USING);
   emitBlock(T.Underlying);
 }

diff  --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 1af555a5b772b..51b2d1f6a92f4 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -74,12 +74,12 @@ Error HTMLGenerator::setupTemplateFiles(const 
ClangDocContext &CDCtx) {
       ConvertToNative(CDCtx.MustacheTemplates.lookup("head-template"));
   std::string NavbarFilePath =
       ConvertToNative(CDCtx.MustacheTemplates.lookup("navbar-template"));
+  std::string AliasFilePath =
+      ConvertToNative(CDCtx.MustacheTemplates.lookup("alias-template"));
   std::vector<std::pair<StringRef, StringRef>> Partials = {
-      {"Comments", CommentFilePath},
-      {"FunctionPartial", FunctionFilePath},
-      {"EnumPartial", EnumFilePath},
-      {"HeadPartial", HeadFilePath},
-      {"NavbarPartial", NavbarFilePath}};
+      {"Comments", CommentFilePath},     {"FunctionPartial", FunctionFilePath},
+      {"EnumPartial", EnumFilePath},     {"HeadPartial", HeadFilePath},
+      {"NavbarPartial", NavbarFilePath}, {"AliasPartial", AliasFilePath}};
 
   if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, 
Partials))
     return Err;

diff  --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp 
b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 2887c5e7bc187..f4938b3460f53 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -349,8 +349,10 @@ serializeCommonChildren(const ScopeChildren &Children, 
json::Object &Obj,
     Obj["HasEnums"] = true;
   }
 
-  if (!Children.Typedefs.empty())
+  if (!Children.Typedefs.empty()) {
     serializeArray(Children.Typedefs, Obj, "Typedefs", SerializeInfo);
+    Obj["HasTypedefs"] = true;
+  }
 
   if (!Children.Records.empty()) {
     serializeArray(Children.Records, Obj, "Records", SerializeReferenceLambda);
@@ -494,6 +496,8 @@ static void serializeInfo(const TypedefInfo &I, 
json::Object &Obj,
   auto &TypeObj = *TypeVal.getAsObject();
   serializeInfo(I.Underlying, TypeObj);
   Obj["Underlying"] = TypeVal;
+  if (I.Template)
+    serializeInfo(I.Template.value(), Obj);
 }
 
 static void serializeInfo(const BaseRecordInfo &I, Object &Obj,

diff  --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index 8eab5fb992ebc..d840350ba8426 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -368,6 +368,8 @@ void TypedefInfo::merge(TypedefInfo &&Other) {
     IsUsing = Other.IsUsing;
   if (Underlying.Type.Name == "")
     Underlying = Other.Underlying;
+  if (!Template)
+    Template = Other.Template;
   SymbolInfo::merge(std::move(Other));
 }
 

diff  --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index a3e779aa39bc4..7685d17bb033d 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -498,12 +498,12 @@ struct TypedefInfo : public SymbolInfo {
 
   TypeInfo Underlying;
 
+  // Only type aliases can be templates.
+  std::optional<TemplateInfo> Template;
+
   // Underlying type declaration
   SmallString<16> TypeDeclaration;
 
-  /// Comment description for the typedef.
-  std::vector<CommentInfo> Description;
-
   // Indicates if this is a new C++ "using"-style typedef:
   //   using MyVector = std::vector<int>
   // False means it's a C-style typedef:

diff  --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 29f8faf94713d..c52106b11f84b 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -1114,6 +1114,9 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, 
Location Loc,
   Info.DefLoc = Loc;
   auto &LO = D->getLangOpts();
   Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
+  populateTemplateParameters(Info.Template, D);
+  if (Info.Template)
+    populateConstraints(Info.Template.value(), D->getDescribedTemplate());
 
   if (Info.Underlying.Type.Name.empty()) {
     // Typedef for an unnamed type. This is like "typedef struct { } Foo;"
@@ -1144,6 +1147,9 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, 
Location Loc,
   Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
   Info.TypeDeclaration = getTypeAlias(D);
   Info.IsUsing = true;
+  populateTemplateParameters(Info.Template, D);
+  if (Info.Template)
+    populateConstraints(Info.Template.value(), D->getDescribedAliasTemplate());
 
   extractCommentFromDecl(D, Info);
 

diff  --git a/clang-tools-extra/clang-doc/assets/alias-template.mustache 
b/clang-tools-extra/clang-doc/assets/alias-template.mustache
new file mode 100644
index 0000000000000..9b32f132e9ef3
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/alias-template.mustache
@@ -0,0 +1,12 @@
+<div id="{{USR}}" class="delimiter-container">
+    {{#Template}}
+    <pre><code class="language-cpp code-clang-doc">template 
&lt;{{#Parameters}}{{Param}}{{^End}}, {{/End}}{{/Parameters}}&gt;</code></pre>
+    {{/Template}}
+    <pre><code class="language-cpp 
code-clang-doc">{{#IsUsing}}using{{/IsUsing}}{{^IsUsing}}typedef{{/IsUsing}} 
{{Name}}{{#IsUsing}} ={{/Isusing}} 
{{#Underlying}}{{Name}}{{/Underlying}}</code></pre>
+    {{#Description}}
+    {{>Comments}}
+    {{/Description}}
+    {{#Location}}
+    <p>Defined at line {{LineNumber}} of file {{Filename}}</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 ee1220071e24a..9c7b06d7e7117 100644
--- a/clang-tools-extra/clang-doc/assets/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/class-template.mustache
@@ -85,9 +85,20 @@
                         </ul>
                     </li>
                     {{/Enums}}
-                    {{#Typedef}}
-                    <li class="sidebar-section">Typedef</li>
-                    {{/Typedef}}
+                    {{#HasTypedefs}}
+                    <li class="sidebar-section">
+                        <a class="sidebar-item" href="#Typedefs">Typedefs</a>
+                    </li>
+                    <li>
+                        <ul>
+                            {{#Typedefs}}
+                            <li class="sidebar-item-container">
+                                <a class="sidebar-item" 
href="#{{USR}}">{{Name}}</a>
+                            </li>
+                            {{/Typedefs}}
+                        </ul>
+                    </li>
+                    {{/HasTypedefs}}
                     {{#Record}}
                     <li class="sidebar-section">
                         <a class="sidebar-item" href="#Classes">Inner 
Classes</a>
@@ -200,11 +211,14 @@
                     </ul>
                 </section>
                 {{/Record}}
-                {{#Typedef}}
-                <section class="section-container">
-                    <h2 id="Enums">Enums</h2>
+                {{#HasTypedefs}}
+                <section id="Typedefs" class="section-container">
+                    <h2>Typedefs</h2>
+                    {{#Typedefs}}
+                    {{>AliasPartial}}
+                    {{/Typedefs}}
                 </section>
-                {{/Typedef}}
+                {{/HasTypedefs}}
             </div>
         </div>
     </main>

diff  --git a/clang-tools-extra/clang-doc/assets/namespace-template.mustache 
b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
index 3588ecf30b3f9..2d8381a9ea6e3 100644
--- a/clang-tools-extra/clang-doc/assets/namespace-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
@@ -85,6 +85,20 @@
                         </ul>
                     </li>
                     {{/HasConcepts}}
+                    {{#HasTypedefs}}
+                    <li class="sidebar-section">
+                        <a class="sidebar-item" href="#Typedefs">Typedefs</a>
+                    </li>
+                    <li>
+                        <ul>
+                            {{#Typedefs}}
+                            <li class="sidebar-item-container">
+                                <a class="sidebar-item" 
href="#{{USR}}">{{Name}}</a>
+                            </li>
+                            {{/Typedefs}}
+                        </ul>
+                    </li>
+                    {{/HasTypedefs}}
                 </ul>
             </div>
             <div class="resizer" id="resizer"></div>
@@ -155,6 +169,14 @@
                     {{/Concepts}}
                 </section>
                 {{/HasConcepts}}
+                {{#HasTypedefs}}
+                <section id="Typedefs" class="section-container">
+                    <h2>Typedefs</h2>
+                    {{#Typedefs}}
+                    {{>AliasPartial}}
+                    {{/Typedefs}}
+                </section>
+                {{/HasTypedefs}}
             </div>
         </div>
     </main>

diff  --git a/clang-tools-extra/clang-doc/support/Utils.cpp 
b/clang-tools-extra/clang-doc/support/Utils.cpp
index e0d92d23b045e..1dce98f06d144 100644
--- a/clang-tools-extra/clang-doc/support/Utils.cpp
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -62,6 +62,8 @@ void getHtmlFiles(StringRef AssetsPath, 
clang::doc::ClangDocContext &CDCtx) {
       appendPathPosix(AssetsPath, "navbar-template.mustache");
   SmallString<128> IndexTemplate =
       appendPathPosix(AssetsPath, "index-template.mustache");
+  SmallString<128> AliasTemplate =
+      appendPathPosix(AssetsPath, "alias-template.mustache");
 
   CDCtx.MustacheTemplates.insert(
       {"namespace-template", NamespaceTemplate.c_str()});
@@ -73,4 +75,5 @@ void getHtmlFiles(StringRef AssetsPath, 
clang::doc::ClangDocContext &CDCtx) {
   CDCtx.MustacheTemplates.insert({"head-template", HeadTemplate.c_str()});
   CDCtx.MustacheTemplates.insert({"navbar-template", NavbarTemplate.c_str()});
   CDCtx.MustacheTemplates.insert({"index-template", IndexTemplate.c_str()});
+  CDCtx.MustacheTemplates.insert({"alias-template", AliasTemplate.c_str()});
 }

diff  --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt 
b/clang-tools-extra/clang-doc/tool/CMakeLists.txt
index 6d8665379e750..aef2acfde0ca3 100644
--- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt
@@ -34,6 +34,7 @@ set(assets
   head-template.mustache
   navbar-template.mustache
   index-template.mustache
+  alias-template.mustache
 )
 
 set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets")

diff  --git a/clang-tools-extra/test/clang-doc/json/class.cpp 
b/clang-tools-extra/test/clang-doc/json/class.cpp
index 79ac20f954f7a..6ec86ff1efeed 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -130,6 +130,7 @@ struct MyClass {
 // CHECK-NEXT:    "HasPublicFunctions": true,
 // CHECK-NEXT:    "HasPublicMembers": true,
 // CHECK-NEXT:    "HasRecords": true,
+// CHECK-NEXT:    "HasTypedefs": true,
 // CHECK-NEXT:    "InfoType": "record",
 // CHECK-NEXT:    "IsTypedef": false,
 // CHECK-NEXT:    "Location": {

diff  --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp 
b/clang-tools-extra/test/clang-doc/json/namespace.cpp
index 2f79cfa404f07..1337efe3f268d 100644
--- a/clang-tools-extra/test/clang-doc/json/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp
@@ -76,6 +76,7 @@ typedef int MyTypedef;
 // CHECK-NEXT:   "HasFunctions": true,
 // CHECK-NEXT:   "HasNamespaces": true,
 // CHECK-NEXT:   "HasRecords": true,
+// CHECK-NEXT:   "HasTypedefs": true,
 // CHECK-NEXT:   "InfoType": "namespace",
 // CHECK-NEXT:   "Name": "Global Namespace",
 // CHECK-NEXT:   "Namespaces": [

diff  --git a/clang-tools-extra/test/clang-doc/typedef-alias.cpp 
b/clang-tools-extra/test/clang-doc/typedef-alias.cpp
new file mode 100644
index 0000000000000..dec2bc5883a09
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/typedef-alias.cpp
@@ -0,0 +1,87 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: clang-doc --format=html --output=%t --executor=standalone %s
+// RUN: FileCheck %s < %t/html/GlobalNamespace/index.html 
-check-prefix=HTML-GLOBAL
+// RUN: FileCheck %s < %t/html/GlobalNamespace/index.html 
-check-prefix=HTML-GLOBAL
+// RUN: FileCheck %s < %t/html/GlobalNamespace/_ZTV6Vector.html 
-check-prefix=HTML-VECTOR
+
+/// \brief This is u_long
+using u_long = unsigned long;
+
+/// \brief This is IntPtr
+typedef int* IntPtr;
+
+template<typename T>
+class Vector {
+  /// \brief This is a Ptr
+  using Ptr = IntPtr;
+};
+
+template<typename T> using Vec = Vector<T>;
+
+using IntVec = Vector<int>;
+
+// HTML-GLOBAL:              <a class="sidebar-item" 
href="#Typedefs">Typedefs</a>
+// HTML-GLOBAL-NEXT:     </li>
+// HTML-GLOBAL-NEXT:     <li>
+// HTML-GLOBAL-NEXT:         <ul>
+// HTML-GLOBAL-NEXT:             <li class="sidebar-item-container">
+// HTML-GLOBAL-NEXT:                 <a class="sidebar-item" 
href="#{{([0-9A-F]{40})}}">u_long</a>
+// HTML-GLOBAL-NEXT:             </li>
+// HTML-GLOBAL-NEXT:             <li class="sidebar-item-container">
+// HTML-GLOBAL-NEXT:                 <a class="sidebar-item" 
href="#{{([0-9A-F]{40})}}">IntPtr</a>
+// HTML-GLOBAL-NEXT:             </li>
+// HTML-GLOBAL-NEXT:             <li class="sidebar-item-container">
+// HTML-GLOBAL-NEXT:                 <a class="sidebar-item" 
href="#{{([0-9A-F]{40})}}">Vec</a>
+// HTML-GLOBAL-NEXT:             </li>
+// HTML-GLOBAL-NEXT:             <li class="sidebar-item-container">
+// HTML-GLOBAL-NEXT:                 <a class="sidebar-item" 
href="#{{([0-9A-F]{40})}}">IntVec</a>
+// HTML-GLOBAL-NEXT:             </li>
+// HTML-GLOBAL-NEXT:         </ul>
+// HTML-GLOBAL-NEXT:     </li>
+// HTML-GLOBAL:      <section id="Typedefs" class="section-container">
+// HTML-GLOBAL-NEXT:     <h2>Typedefs</h2>
+// HTML-GLOBAL-NEXT:     <div id="{{([0-9A-F]{40})}}" 
class="delimiter-container">
+// HTML-GLOBAL-NEXT:         <pre><code class="language-cpp 
code-clang-doc">using u_long = unsigned long</code></pre>
+// HTML-GLOBAL-NEXT:         <div>
+// HTML-GLOBAL-NEXT:             <p> This is u_long</p>
+// HTML-GLOBAL-NEXT:         </div>
+// HTML-GLOBAL-NEXT:         <p>Defined at line 8 of file 
{{.*}}typedef-alias.cpp</p>
+// HTML-GLOBAL-NEXT:     </div>
+// HTML-GLOBAL-NEXT:     <div id="{{([0-9A-F]{40})}}" 
class="delimiter-container">
+// HTML-GLOBAL-NEXT:         <pre><code class="language-cpp 
code-clang-doc">typedef IntPtr int *</code></pre>
+// HTML-GLOBAL-NEXT:         <div>
+// HTML-GLOBAL-NEXT:             <p> This is IntPtr</p>
+// HTML-GLOBAL-NEXT:         </div>
+// HTML-GLOBAL-NEXT:         <p>Defined at line 11 of file 
{{.*}}typedef-alias.cpp</p>
+// HTML-GLOBAL-NEXT:     </div>
+// HTML-GLOBAL-NEXT:     <div id="{{([0-9A-F]{40})}}" 
class="delimiter-container">
+// HTML-GLOBAL-NEXT:         <pre><code class="language-cpp 
code-clang-doc">template &lt;typename T&gt;</code></pre>
+// HTML-GLOBAL-NEXT:         <pre><code class="language-cpp 
code-clang-doc">using Vec = Vector&lt;T&gt;</code></pre>
+// HTML-GLOBAL-NEXT:         <p>Defined at line 19 of file 
{{.*}}typedef-alias.cpp</p>
+// HTML-GLOBAL-NEXT:     </div>
+// HTML-GLOBAL-NEXT:     <div id="{{([0-9A-F]{40})}}" 
class="delimiter-container">
+// HTML-GLOBAL-NEXT:         <pre><code class="language-cpp 
code-clang-doc">using IntVec = Vector&lt;int&gt;</code></pre>
+// HTML-GLOBAL-NEXT:         <p>Defined at line 21 of file 
{{.*}}typedef-alias.cpp</p>
+// HTML-GLOBAL-NEXT:     </div>
+// HTML-GLOBAL-NEXT: </section>
+
+// HTML-VECTOR:                  <a class="sidebar-item" 
href="#Typedefs">Typedefs</a>
+// HTML-VECTOR-NEXT:         </li>
+// HTML-VECTOR-NEXT:         <li>
+// HTML-VECTOR-NEXT:             <ul>
+// HTML-VECTOR-NEXT:                 <li class="sidebar-item-container">
+// HTML-VECTOR-NEXT:                     <a class="sidebar-item" 
href="#{{([0-9A-F]{40})}}">Ptr</a>
+// HTML-VECTOR-NEXT:                 </li>
+// HTML-VECTOR-NEXT:             </ul>
+// HTML-VECTOR-NEXT:         </li>
+// HTML-VECTOR-NEXT:     </ul>
+// HTML-VECTOR:      <section id="Typedefs" class="section-container">
+// HTML-VECTOR-NEXT:     <h2>Typedefs</h2>
+// HTML-VECTOR-NEXT:     <div id="{{([0-9A-F]{40})}}" 
class="delimiter-container">
+// HTML-VECTOR-NEXT:         <pre><code class="language-cpp 
code-clang-doc">using Ptr = IntPtr</code></pre>
+// HTML-VECTOR-NEXT:         <div>
+// HTML-VECTOR-NEXT:             <p> This is a Ptr</p>
+// HTML-VECTOR-NEXT:         </div>
+// HTML-VECTOR-NEXT:         <p>Defined at line 16 of file 
{{.*}}typedef-alias.cpp</p>
+// HTML-VECTOR-NEXT:     </div>
+// HTML-VECTOR-NEXT: </section>


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

Reply via email to