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

>From 4e87ab11a1c19a2f7f897521f0bfb60d68470e1a Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvel...@gmail.com>
Date: Thu, 10 Jul 2025 11:16:20 -0700
Subject: [PATCH] explicitly use ItaniumMangleContext to avoid platform errors

---
 clang-tools-extra/clang-doc/BitcodeReader.cpp |  2 +
 clang-tools-extra/clang-doc/BitcodeWriter.cpp |  5 ++-
 clang-tools-extra/clang-doc/BitcodeWriter.h   |  1 +
 clang-tools-extra/clang-doc/JSONGenerator.cpp | 16 +++++++-
 .../clang-doc/Representation.cpp              |  2 +
 clang-tools-extra/clang-doc/Representation.h  |  1 +
 clang-tools-extra/clang-doc/Serialize.cpp     | 12 ++++++
 .../test/clang-doc/json/class-requires.cpp    |  2 +-
 .../clang-doc/json/class-specialization.cpp   | 37 +++++++++++++++++++
 .../test/clang-doc/json/class-template.cpp    |  2 +-
 .../test/clang-doc/json/class.cpp             |  3 +-
 .../clang-doc/json/compound-constraints.cpp   |  2 +-
 .../test/clang-doc/json/concept.cpp           |  2 +-
 .../test/clang-doc/json/function-requires.cpp |  2 +-
 .../clang-doc/json/function-specifiers.cpp    |  2 +-
 .../test/clang-doc/json/method-template.cpp   |  2 +-
 .../test/clang-doc/json/namespace.cpp         |  2 +-
 .../test/clang-doc/json/nested-namespace.cpp  |  4 +-
 .../unittests/clang-doc/JSONGeneratorTest.cpp |  2 +
 19 files changed, 87 insertions(+), 14 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-doc/json/class-specialization.cpp

diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index f756ae6d897c8..dce34a8434ff8 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -180,6 +180,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID,
     return decodeRecord(R, I->TagType, Blob);
   case RECORD_IS_TYPE_DEF:
     return decodeRecord(R, I->IsTypeDef, Blob);
+  case RECORD_MANGLED_NAME:
+    return decodeRecord(R, I->MangledName, Blob);
   default:
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "invalid field for RecordInfo");
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp 
b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index 3cc0d4ad332f0..eed23726e17bf 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -189,6 +189,7 @@ static const llvm::IndexedMap<RecordIdDsc, 
RecordIdToIndexFunctor>
           {RECORD_LOCATION, {"Location", &genLocationAbbrev}},
           {RECORD_TAG_TYPE, {"TagType", &genIntAbbrev}},
           {RECORD_IS_TYPE_DEF, {"IsTypeDef", &genBoolAbbrev}},
+          {RECORD_MANGLED_NAME, {"MangledName", &genStringAbbrev}},
           {BASE_RECORD_USR, {"USR", &genSymbolIdAbbrev}},
           {BASE_RECORD_NAME, {"Name", &genStringAbbrev}},
           {BASE_RECORD_PATH, {"Path", &genStringAbbrev}},
@@ -271,7 +272,8 @@ static const std::vector<std::pair<BlockId, 
std::vector<RecordId>>>
         // Record Block
         {BI_RECORD_BLOCK_ID,
          {RECORD_USR, RECORD_NAME, RECORD_PATH, RECORD_DEFLOCATION,
-          RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF}},
+          RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF,
+          RECORD_MANGLED_NAME}},
         // BaseRecord Block
         {BI_BASE_RECORD_BLOCK_ID,
          {BASE_RECORD_USR, BASE_RECORD_NAME, BASE_RECORD_PATH,
@@ -616,6 +618,7 @@ void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) {
   emitRecord(I.USR, RECORD_USR);
   emitRecord(I.Name, RECORD_NAME);
   emitRecord(I.Path, RECORD_PATH);
+  emitRecord(I.MangledName, RECORD_MANGLED_NAME);
   for (const auto &N : I.Namespace)
     emitBlock(N, FieldId::F_namespace);
   for (const auto &CI : I.Description)
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h 
b/clang-tools-extra/clang-doc/BitcodeWriter.h
index d09ec4ca34006..501af12582a8e 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.h
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -126,6 +126,7 @@ enum RecordId {
   RECORD_LOCATION,
   RECORD_TAG_TYPE,
   RECORD_IS_TYPE_DEF,
+  RECORD_MANGLED_NAME,
   BASE_RECORD_USR,
   BASE_RECORD_NAME,
   BASE_RECORD_PATH,
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp 
b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 0e1a0cc347e45..7dd0b62ab6955 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -386,6 +386,7 @@ static void serializeInfo(const RecordInfo &I, json::Object 
&Obj,
   Obj["FullName"] = I.FullName;
   Obj["TagType"] = getTagType(I.TagType);
   Obj["IsTypedef"] = I.IsTypeDef;
+  Obj["MangledName"] = I.MangledName;
 
   if (!I.Children.Functions.empty()) {
     json::Value PubFunctionsArray = Array();
@@ -501,7 +502,6 @@ Error JSONGenerator::generateDocs(
 
     SmallString<128> Path;
     sys::path::native(RootDir, Path);
-    sys::path::append(Path, Info->getRelativeFilePath(""));
     if (!CreatedDirs.contains(Path)) {
       if (std::error_code Err = sys::fs::create_directories(Path);
           Err != std::error_code())
@@ -509,7 +509,19 @@ Error JSONGenerator::generateDocs(
       CreatedDirs.insert(Path);
     }
 
-    sys::path::append(Path, Info->getFileBaseName() + ".json");
+    SmallString<16> FileName;
+    if (Info->IT == InfoType::IT_record) {
+      auto *RecordSymbolInfo = static_cast<SymbolInfo *>(Info);
+      if (RecordSymbolInfo->MangledName.size() < 255)
+        FileName = RecordSymbolInfo->MangledName;
+      else
+        FileName = toStringRef(toHex(RecordSymbolInfo->USR));
+    } else if (Info->IT == InfoType::IT_namespace && Info->Name != "")
+      // Serialize the global namespace as index.json
+      FileName = Info->Name;
+    else
+      FileName = Info->getFileBaseName();
+    sys::path::append(Path, FileName + ".json");
     FileToInfos[Path].push_back(Info);
   }
 
diff --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index 422a76d99e5b3..beaf314a04ae1 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -290,6 +290,8 @@ void SymbolInfo::merge(SymbolInfo &&Other) {
   auto *Last = llvm::unique(Loc);
   Loc.erase(Last, Loc.end());
   mergeBase(std::move(Other));
+  if (MangledName.empty())
+    MangledName = std::move(Other.MangledName);
 }
 
 NamespaceInfo::NamespaceInfo(SymbolID USR, StringRef Name, StringRef Path)
diff --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index fe5cc48069d58..542e499f7c6fd 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -378,6 +378,7 @@ struct SymbolInfo : public Info {
   std::optional<Location> DefLoc;     // Location where this decl is defined.
   llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
   bool IsStatic = false;
+  SmallString<16> MangledName;
 };
 
 struct FriendInfo : SymbolInfo {
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..7a0e00c6d9c2d 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/AST/DeclFriend.h"
+#include "clang/AST/Mangle.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringExtras.h"
@@ -767,6 +768,17 @@ static void populateSymbolInfo(SymbolInfo &I, const T *D, 
const FullComment *C,
     I.DefLoc = Loc;
   else
     I.Loc.emplace_back(Loc);
+
+  auto *Mangler = ItaniumMangleContext::create(
+      D->getASTContext(), D->getASTContext().getDiagnostics());
+  std::string MangledName;
+  llvm::raw_string_ostream MangledStream(MangledName);
+  if (auto *CXXD = dyn_cast<CXXRecordDecl>(D))
+    Mangler->mangleCXXVTable(CXXD, MangledStream);
+  else
+    MangledStream << D->getNameAsString();
+  I.MangledName = MangledName;
+  delete Mangler;
 }
 
 static void
diff --git a/clang-tools-extra/test/clang-doc/json/class-requires.cpp 
b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
index 2dd25771d6d8b..213da93a1adfa 100644
--- a/clang-tools-extra/test/clang-doc/json/class-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-requires.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json 
--executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json
+// RUN: FileCheck %s < %t/_ZTV7MyClass.json
 
 template<typename T>
 concept Addable = requires(T a, T b) {
diff --git a/clang-tools-extra/test/clang-doc/json/class-specialization.cpp 
b/clang-tools-extra/test/clang-doc/json/class-specialization.cpp
new file mode 100644
index 0000000000000..e9259edad5cb8
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/json/class-specialization.cpp
@@ -0,0 +1,37 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: clang-doc --output=%t --format=json --executor=standalone %s
+// RUN: FileCheck %s < %t/_ZTV7MyClass.json --check-prefix=BASE
+// RUN: FileCheck %s < %t/_ZTV7MyClassIiE.json --check-prefix=SPECIALIZATION
+
+template<typename T> struct MyClass {};
+
+template<> struct MyClass<int> {};
+
+// BASE:       "MangledName": "_ZTV7MyClass",
+// BASE-NEXT:  "Name": "MyClass",
+// BASE-NEXT:  "Namespace": [
+// BASE-NEXT:    "GlobalNamespace"
+// BASE-NEXT:  ],
+// BASE-NEXT:  "Path": "GlobalNamespace",
+// BASE-NEXT:  "TagType": "struct",
+// BASE-NEXT:  "Template": {
+// BASE-NEXT:    "Parameters": [
+// BASE-NEXT:      "typename T"
+// BASE-NEXT:    ]
+// BASE-NEXT:  },
+
+// SPECIALIZATION:       "MangledName": "_ZTV7MyClassIiE",
+// SPECIALIZATION-NEXT:  "Name": "MyClass",
+// SPECIALIZATION-NEXT:  "Namespace": [
+// SPECIALIZATION-NEXT:    "GlobalNamespace"
+// SPECIALIZATION-NEXT:  ],
+// SPECIALIZATION-NEXT:  "Path": "GlobalNamespace",
+// SPECIALIZATION-NEXT:  "TagType": "struct",
+// SPECIALIZATION-NEXT:  "Template": {
+// SPECIALIZATION-NEXT:    "Specialization": {
+// SPECIALIZATION-NEXT:      "Parameters": [
+// SPECIALIZATION-NEXT:        "int"
+// SPECIALIZATION-NEXT:      ],
+// SPECIALIZATION-NEXT:      "SpecializationOf": "{{[0-9A-F]*}}"
+// SPECIALIZATION-NEXT:    }
+// SPECIALIZATION-NEXT:  },
diff --git a/clang-tools-extra/test/clang-doc/json/class-template.cpp 
b/clang-tools-extra/test/clang-doc/json/class-template.cpp
index fb9c4c2f21c2e..6cdc3e9175278 100644
--- a/clang-tools-extra/test/clang-doc/json/class-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class-template.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json
+// RUN: FileCheck %s < %t/_ZTV7MyClass.json
 
 template<typename T> struct MyClass {
   T MemberTemplate;
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp 
b/clang-tools-extra/test/clang-doc/json/class.cpp
index ae47da75edccb..d8317eafea91a 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json
+// RUN: FileCheck %s < %t/_ZTV7MyClass.json
 
 struct Foo;
 
@@ -134,6 +134,7 @@ struct MyClass {
 // CHECK-NEXT:      "Filename": "{{.*}}class.cpp",
 // CHECK-NEXT:      "LineNumber": 10
 // CHECK-NEXT:    },
+// CHECK-NEXT:    "MangledName": "_ZTV7MyClass",
 // CHECK-NEXT:    "Name": "MyClass",
 // CHECK-NEXT:    "Namespace": [
 // CHECK-NEXT:      "GlobalNamespace"
diff --git a/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp 
b/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
index b49dec5cc78c5..34acb6808409d 100644
--- a/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
+++ b/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json 
--executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/index.json
+// RUN: FileCheck %s < %t/index.json
 
 template<typename T> concept Incrementable = requires (T a) {
   a++;
diff --git a/clang-tools-extra/test/clang-doc/json/concept.cpp 
b/clang-tools-extra/test/clang-doc/json/concept.cpp
index 887c9d79146a0..b946393274c85 100644
--- a/clang-tools-extra/test/clang-doc/json/concept.cpp
+++ b/clang-tools-extra/test/clang-doc/json/concept.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json 
--executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/index.json
+// RUN: FileCheck %s < %t/index.json
 
 // Requires that T suports post and pre-incrementing.
 template<typename T>
diff --git a/clang-tools-extra/test/clang-doc/json/function-requires.cpp 
b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
index 4e8432e088c4f..08ac4c7ed2ca3 100644
--- a/clang-tools-extra/test/clang-doc/json/function-requires.cpp
+++ b/clang-tools-extra/test/clang-doc/json/function-requires.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json 
--executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/index.json
+// RUN: FileCheck %s < %t/index.json
 
 template<typename T>
 concept Incrementable = requires(T x) {
diff --git a/clang-tools-extra/test/clang-doc/json/function-specifiers.cpp 
b/clang-tools-extra/test/clang-doc/json/function-specifiers.cpp
index 7005fb7b3e66e..b194e3371bf76 100644
--- a/clang-tools-extra/test/clang-doc/json/function-specifiers.cpp
+++ b/clang-tools-extra/test/clang-doc/json/function-specifiers.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/index.json
+// RUN: FileCheck %s < %t/index.json
 
 static void myFunction() {}
 
diff --git a/clang-tools-extra/test/clang-doc/json/method-template.cpp 
b/clang-tools-extra/test/clang-doc/json/method-template.cpp
index ea9110d6c2d1c..ac8450a72d3a7 100644
--- a/clang-tools-extra/test/clang-doc/json/method-template.cpp
+++ b/clang-tools-extra/test/clang-doc/json/method-template.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json
+// RUN: FileCheck %s < %t/_ZTV7MyClass.json
 
 struct MyClass {
   template<class T> T methodTemplate(T param) {
diff --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp 
b/clang-tools-extra/test/clang-doc/json/namespace.cpp
index 6e4fc6938d856..779d7b49f5581 100644
--- a/clang-tools-extra/test/clang-doc/json/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/GlobalNamespace/index.json
+// RUN: FileCheck %s < %t/index.json
 
 class MyClass {};
 
diff --git a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp 
b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
index 9b176feb67a00..54f95c4d041ca 100644
--- a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: clang-doc --output=%t --format=json --executor=standalone %s
-// RUN: FileCheck %s < %t/nested/index.json --check-prefix=NESTED
-// RUN: FileCheck %s < %t/nested/inner/index.json --check-prefix=INNER
+// RUN: FileCheck %s < %t/nested.json --check-prefix=NESTED
+// RUN: FileCheck %s < %t/inner.json --check-prefix=INNER
 
 namespace nested {
   int Global;
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index 09e522133d832..5927235b3bd93 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -67,6 +67,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
       "IsParent": true,
       "IsTypedef": false,
       "IsVirtual": true,
+      "MangledName": "",
       "Name": "F",
       "Path": "path/to/F",
       "PublicFunctions": [
@@ -112,6 +113,7 @@ TEST(JSONGeneratorTest, emitRecordJSON) {
     "Filename": "main.cpp",
     "LineNumber": 1
   },
+  "MangledName": "",
   "Name": "Foo",
   "Namespace": [
     "GlobalNamespace"

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

Reply via email to