[clang-tools-extra] [clang-doc] mangle specialization file names (PR #144617)
Erick Velez via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 17 16:30:29 PDT 2025
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 <erickvelez7 at 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]*}}"
More information about the cfe-commits
mailing list