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