https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/144617

None

>From bd5747e542e23078a98a830da191e5f1f72bd85b Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvel...@gmail.com>
Date: Tue, 17 Jun 2025 15:11:02 -0700
Subject: [PATCH] [clang-doc] mangle specialization file names

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp     |  9 +++++++++
 clang-tools-extra/clang-doc/BitcodeWriter.cpp     |  7 ++++++-
 clang-tools-extra/clang-doc/BitcodeWriter.h       |  1 +
 clang-tools-extra/clang-doc/JSONGenerator.cpp     |  9 ++++++++-
 clang-tools-extra/clang-doc/Representation.h      |  3 +++
 clang-tools-extra/clang-doc/Serialize.cpp         |  8 ++++++++
 .../json/specialization-mangled-name.cpp          | 15 +++++++++++++++
 7 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-doc/json/specialization-mangled-name.cpp

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 35058abab0663..9227cf2bf51a2 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -83,6 +83,13 @@ static llvm::Error decodeRecord(const Record &R, 
std::optional<Location> &Field,
   return llvm::Error::success();
 }
 
+static llvm::Error decodeRecord(const Record &R,
+                                std::optional<SmallString<16>> &Field,
+                                llvm::StringRef Blob) {
+  Field.emplace(Blob);
+  return llvm::Error::success();
+}
+
 static llvm::Error decodeRecord(const Record &R, InfoType &Field,
                                 llvm::StringRef Blob) {
   switch (auto IT = static_cast<InfoType>(R[0])) {
@@ -379,6 +386,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID,
                                TemplateSpecializationInfo *I) {
   if (ID == TEMPLATE_SPECIALIZATION_OF)
     return decodeRecord(R, I->SpecializationOf, Blob);
+  if (ID == TEMPLATE_SPECIALIZATION_MANGLED_NAME)
+    return decodeRecord(R, I->MangledName, Blob);
   return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                  "invalid field for TemplateParamInfo");
 }
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp 
b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index f8a6859169b01..e2c58731fbc67 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -202,6 +202,8 @@ static const llvm::IndexedMap<RecordIdDsc, 
RecordIdToIndexFunctor>
           {TEMPLATE_PARAM_CONTENTS, {"Contents", &genStringAbbrev}},
           {TEMPLATE_SPECIALIZATION_OF,
            {"SpecializationOf", &genSymbolIdAbbrev}},
+          {TEMPLATE_SPECIALIZATION_MANGLED_NAME,
+           {"MangledName", &genStringAbbrev}},
           {TYPEDEF_USR, {"USR", &genSymbolIdAbbrev}},
           {TYPEDEF_NAME, {"Name", &genStringAbbrev}},
           {TYPEDEF_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
@@ -263,7 +265,8 @@ static const std::vector<std::pair<BlockId, 
std::vector<RecordId>>>
         // Template Blocks.
         {BI_TEMPLATE_BLOCK_ID, {}},
         {BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}},
-        {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}};
+        {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID,
+         {TEMPLATE_SPECIALIZATION_OF, TEMPLATE_SPECIALIZATION_MANGLED_NAME}}};
 
 // AbbreviationMap
 
@@ -638,6 +641,8 @@ void ClangDocBitcodeWriter::emitBlock(const TemplateInfo 
&T) {
 void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) {
   StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID);
   emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF);
+  if (T.MangledName)
+    emitRecord(T.MangledName->str(), TEMPLATE_SPECIALIZATION_MANGLED_NAME);
   for (const auto &P : T.Params)
     emitBlock(P);
 }
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h 
b/clang-tools-extra/clang-doc/BitcodeWriter.h
index e33a1aece883c..c0b879af59194 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.h
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -131,6 +131,7 @@ enum RecordId {
   REFERENCE_FIELD,
   TEMPLATE_PARAM_CONTENTS,
   TEMPLATE_SPECIALIZATION_OF,
+  TEMPLATE_SPECIALIZATION_MANGLED_NAME,
   TYPEDEF_USR,
   TYPEDEF_NAME,
   TYPEDEF_DEFLOCATION,
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp 
b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 0f7cbafcf5135..ca56e669038b4 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -491,7 +491,14 @@ Error JSONGenerator::generateDocs(
       CreatedDirs.insert(Path);
     }
 
-    sys::path::append(Path, Info->getFileBaseName() + ".json");
+    SmallString<16> FileBaseName = Info->getFileBaseName();
+    if (Info->IT == InfoType::IT_record) {
+      if (auto Template = static_cast<RecordInfo *>(Info)->Template;
+          Template && Template->Specialization &&
+          Template->Specialization->MangledName)
+        FileBaseName = Template->Specialization->MangledName.value();
+    }
+    sys::path::append(Path, FileBaseName + ".json");
     FileToInfos[Path].push_back(Info);
   }
 
diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 75da500645819..6c88712706dc0 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -209,6 +209,9 @@ struct TemplateSpecializationInfo {
 
   // Template parameters applying to the specialized record/function.
   std::vector<TemplateParamInfo> Params;
+
+  // Used to distinguish class specialization file names.
+  std::optional<SmallString<16>> MangledName;
 };
 
 // Records the template information for a struct or function that is a template
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index e8f1a9cee2675..d82d2cd2c9eeb 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -10,6 +10,7 @@
 #include "BitcodeWriter.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
+#include "clang/AST/Mangle.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringExtras.h"
@@ -909,6 +910,13 @@ emitInfo(const RecordDecl *D, const FullComment *FC, 
Location Loc,
       RI->Template.emplace();
     RI->Template->Specialization.emplace();
     auto &Specialization = *RI->Template->Specialization;
+    auto *Mangler = ItaniumMangleContext::create(
+        D->getASTContext(), D->getASTContext().getDiagnostics());
+    std::string MangledName;
+    llvm::raw_string_ostream Stream(MangledName);
+    Mangler->mangleCXXVTT(dyn_cast<CXXRecordDecl>(D), Stream);
+    Specialization.MangledName.emplace(MangledName);
+    delete Mangler;
 
     // What this is a specialization of.
     auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
diff --git 
a/clang-tools-extra/test/clang-doc/json/specialization-mangled-name.cpp 
b/clang-tools-extra/test/clang-doc/json/specialization-mangled-name.cpp
new file mode 100644
index 0000000000000..5d25c53f37a36
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/json/specialization-mangled-name.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: clang-doc --output=%t --format=json --executor=standalone %s
+// RUN: FileCheck %s < %t/GlobalNamespace/_ZTT7MyClassIiE.json
+
+template<typename T> class MyClass;
+
+template<> class MyClass<int>;
+
+// CHECK:       "Name": "MyClass",
+// CHECK:       "Template": {
+// CHECK-NEXT:    "Specialization": {
+// CHECK-NEXT:      "Parameters": [
+// CHECK-NEXT:        "int"
+// CHECK-NEXT:      ],
+// CHECK-NEXT:      "SpecializationOf": "{{[0-9A-F]*}}"

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to