913 lines · cpp
1//===-- MangledTest.cpp ---------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"10#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"11#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"12#include "TestingSupport/SubsystemRAII.h"13#include "TestingSupport/TestUtilities.h"14 15#include "lldb/Core/DemangledNameInfo.h"16#include "lldb/Core/Mangled.h"17#include "lldb/Core/Module.h"18#include "lldb/Core/ModuleSpec.h"19#include "lldb/Host/FileSystem.h"20#include "lldb/Host/HostInfo.h"21#include "lldb/Symbol/SymbolContext.h"22 23#include "llvm/Support/Error.h"24#include "llvm/Support/FileUtilities.h"25#include "llvm/Support/Path.h"26#include "llvm/Support/Program.h"27#include "llvm/Testing/Support/Error.h"28 29#include "gtest/gtest.h"30 31#include <cstdlib>32#include <memory>33 34using namespace lldb;35using namespace lldb_private;36 37/// Custom deleter to use with unique_ptr.38///39/// Usage:40/// \code{.cpp}41///42/// auto OB =43/// std::unique_ptr<TrackingOutputBuffer, TrackingOutputBufferDeleter>(44/// new TrackingOutputBuffer());45///46/// \endcode47struct TrackingOutputBufferDeleter {48 void operator()(TrackingOutputBuffer *TOB) {49 if (!TOB)50 return;51 std::free(TOB->getBuffer());52 delete TOB;53 }54};55 56TEST(MangledTest, ResultForValidName) {57 ConstString MangledName("_ZN1a1b1cIiiiEEvm");58 Mangled TheMangled(MangledName);59 ConstString TheDemangled = TheMangled.GetDemangledName();60 61 ConstString ExpectedResult("void a::b::c<int, int, int>(unsigned long)");62 EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());63}64 65TEST(MangledTest, ResultForBlockInvocation) {66 ConstString MangledName("___Z1fU13block_pointerFviE_block_invoke");67 Mangled TheMangled(MangledName);68 ConstString TheDemangled = TheMangled.GetDemangledName();69 70 ConstString ExpectedResult(71 "invocation function for block in f(void (int) block_pointer)");72 EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());73}74 75TEST(MangledTest, EmptyForInvalidName) {76 ConstString MangledName("_ZN1a1b1cmxktpEEvm");77 Mangled TheMangled(MangledName);78 ConstString TheDemangled = TheMangled.GetDemangledName();79 80 EXPECT_STREQ("", TheDemangled.GetCString());81}82 83TEST(MangledTest, ResultForValidRustV0Name) {84 ConstString mangled_name("_RNvC1a4main");85 Mangled the_mangled(mangled_name);86 ConstString the_demangled = the_mangled.GetDemangledName();87 88 ConstString expected_result("a::main");89 EXPECT_STREQ(expected_result.GetCString(), the_demangled.GetCString());90}91 92TEST(MangledTest, EmptyForInvalidRustV0Name) {93 ConstString mangled_name("_RRR");94 Mangled the_mangled(mangled_name);95 ConstString the_demangled = the_mangled.GetDemangledName();96 97 EXPECT_STREQ("", the_demangled.GetCString());98}99 100TEST(MangledTest, ResultForValidDLangName) {101 ConstString mangled_name("_Dmain");102 Mangled the_mangled(mangled_name);103 ConstString the_demangled = the_mangled.GetDemangledName();104 105 ConstString expected_result("D main");106 EXPECT_STREQ(expected_result.GetCString(), the_demangled.GetCString());107}108 109TEST(MangledTest, SameForInvalidDLangPrefixedName) {110 ConstString mangled_name("_DDD");111 Mangled the_mangled(mangled_name);112 ConstString the_demangled = the_mangled.GetDemangledName();113 114 EXPECT_STREQ("_DDD", the_demangled.GetCString());115}116 117TEST(MangledTest, RecognizeSwiftMangledNames) {118 llvm::StringRef valid_swift_mangled_names[] = {119 "_TtC4main7MyClass", // Mangled objc class name120 "_TtP4main3Foo_", // Mangld objc protocol name121 "$s4main3BarCACycfC", // Mangled name122 "_$s4main3BarCACycfC", // Mangled name with leading underscore123 "$S4main3BarCACycfC", // Older swift mangled name124 "_$S4main3BarCACycfC", // Older swift mangled name125 // with leading underscore126 // Mangled swift filename127 "@__swiftmacro_4main16FunVariableNames9OptionSetfMm_.swift",128 };129 130 for (llvm::StringRef mangled : valid_swift_mangled_names)131 EXPECT_EQ(Mangled::GetManglingScheme(mangled),132 Mangled::eManglingSchemeSwift);133}134 135TEST(MangledTest, BoolConversionOperator) {136 {137 ConstString MangledName("_ZN1a1b1cIiiiEEvm");138 Mangled TheMangled(MangledName);139 EXPECT_EQ(true, bool(TheMangled));140 EXPECT_EQ(false, !TheMangled);141 }142 {143 ConstString UnmangledName("puts");144 Mangled TheMangled(UnmangledName);145 EXPECT_EQ(true, bool(TheMangled));146 EXPECT_EQ(false, !TheMangled);147 }148 {149 Mangled TheMangled{};150 EXPECT_EQ(false, bool(TheMangled));151 EXPECT_EQ(true, !TheMangled);152 }153}154 155TEST(MangledTest, NameIndexes_FindFunctionSymbols) {156 SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>157 subsystems;158 159 auto ExpectedFile = TestFile::fromYaml(R"(160--- !ELF161FileHeader: 162 Class: ELFCLASS64163 Data: ELFDATA2LSB164 Type: ET_EXEC165 Machine: EM_X86_64166Sections: 167 - Name: .text168 Type: SHT_PROGBITS169 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]170 AddressAlign: 0x0000000000000010171 Size: 0x20172 - Name: .anothertext173 Type: SHT_PROGBITS174 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]175 Address: 0x0000000000000010176 AddressAlign: 0x0000000000000010177 Size: 0x40178 - Name: .data179 Type: SHT_PROGBITS180 Flags: [ SHF_WRITE, SHF_ALLOC ]181 Address: 0x00000000000000A8182 AddressAlign: 0x0000000000000004183 Content: '01000000'184Symbols:185 - Name: somedata186 Type: STT_OBJECT187 Section: .anothertext188 Value: 0x0000000000000045189 Binding: STB_GLOBAL190 - Name: main191 Type: STT_FUNC192 Section: .anothertext193 Value: 0x0000000000000010194 Size: 0x000000000000003F195 Binding: STB_GLOBAL196 - Name: _Z3foov197 Type: STT_FUNC198 Section: .text199 Size: 0x000000000000000D200 Binding: STB_GLOBAL201 - Name: puts@GLIBC_2.5202 Type: STT_FUNC203 Section: .text204 Size: 0x000000000000000D205 Binding: STB_GLOBAL206 - Name: puts@GLIBC_2.6207 Type: STT_FUNC208 Section: .text209 Size: 0x000000000000000D210 Binding: STB_GLOBAL211 - Name: _Z5annotv@VERSION3212 Type: STT_FUNC213 Section: .text214 Size: 0x000000000000000D215 Binding: STB_GLOBAL216 - Name: _ZN1AC2Ev217 Type: STT_FUNC218 Section: .text219 Size: 0x000000000000000D220 Binding: STB_GLOBAL221 - Name: _ZN1AD2Ev222 Type: STT_FUNC223 Section: .text224 Size: 0x000000000000000D225 Binding: STB_GLOBAL226 - Name: _ZN1A3barEv227 Type: STT_FUNC228 Section: .text229 Size: 0x000000000000000D230 Binding: STB_GLOBAL231 - Name: _ZGVZN4llvm4dbgsEvE7thestrm232 Type: STT_FUNC233 Section: .text234 Size: 0x000000000000000D235 Binding: STB_GLOBAL236 - Name: _ZZN4llvm4dbgsEvE7thestrm237 Type: STT_FUNC238 Section: .text239 Size: 0x000000000000000D240 Binding: STB_GLOBAL241 - Name: _ZTVN5clang4DeclE242 Type: STT_FUNC243 Section: .text244 Size: 0x000000000000000D245 Binding: STB_GLOBAL246 - Name: -[ObjCfoo]247 Type: STT_FUNC248 Section: .text249 Size: 0x000000000000000D250 Binding: STB_GLOBAL251 - Name: +[B ObjCbar(WithCategory)]252 Type: STT_FUNC253 Section: .text254 Size: 0x000000000000000D255 Binding: STB_GLOBAL256 - Name: _Z12undemangableEvx42257 Type: STT_FUNC258 Section: .text259 Size: 0x000000000000000D260 Binding: STB_GLOBAL261...262)");263 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());264 265 auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());266 267 auto Count = [M](const char *Name, FunctionNameType Type) -> int {268 SymbolContextList SymList;269 M->FindFunctionSymbols(ConstString(Name), Type, SymList);270 return SymList.GetSize();271 };272 273 // Unmangled274 EXPECT_EQ(1, Count("main", eFunctionNameTypeFull));275 EXPECT_EQ(1, Count("main", eFunctionNameTypeBase));276 EXPECT_EQ(0, Count("main", eFunctionNameTypeMethod));277 278 // Itanium mangled279 EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeFull));280 EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeBase));281 EXPECT_EQ(1, Count("foo", eFunctionNameTypeBase));282 EXPECT_EQ(0, Count("foo", eFunctionNameTypeMethod));283 284 // Unmangled with linker annotation285 EXPECT_EQ(1, Count("puts@GLIBC_2.5", eFunctionNameTypeFull));286 EXPECT_EQ(1, Count("puts@GLIBC_2.6", eFunctionNameTypeFull));287 EXPECT_EQ(2, Count("puts", eFunctionNameTypeFull));288 EXPECT_EQ(2, Count("puts", eFunctionNameTypeBase));289 EXPECT_EQ(0, Count("puts", eFunctionNameTypeMethod));290 291 // Itanium mangled with linker annotation292 EXPECT_EQ(1, Count("_Z5annotv@VERSION3", eFunctionNameTypeFull));293 EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeFull));294 EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeBase));295 EXPECT_EQ(0, Count("annot", eFunctionNameTypeBase));296 EXPECT_EQ(0, Count("annot", eFunctionNameTypeMethod));297 298 // Itanium mangled ctor A::A()299 EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeFull));300 EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeBase));301 EXPECT_EQ(1, Count("A", eFunctionNameTypeMethod));302 EXPECT_EQ(0, Count("A", eFunctionNameTypeBase));303 304 // Itanium mangled dtor A::~A()305 EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeFull));306 EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeBase));307 EXPECT_EQ(1, Count("~A", eFunctionNameTypeMethod));308 EXPECT_EQ(0, Count("~A", eFunctionNameTypeBase));309 310 // Itanium mangled method A::bar()311 EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeFull));312 EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeBase));313 EXPECT_EQ(1, Count("bar", eFunctionNameTypeMethod));314 EXPECT_EQ(0, Count("bar", eFunctionNameTypeBase));315 316 // Itanium mangled names that are explicitly excluded from parsing317 EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));318 EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));319 EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));320 EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));321 EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));322 EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));323 EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));324 EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));325 EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeFull));326 EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeBase));327 EXPECT_EQ(0, Count("Decl", eFunctionNameTypeMethod));328 EXPECT_EQ(0, Count("Decl", eFunctionNameTypeBase));329 330 // ObjC mangled static331 EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeFull));332 EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeBase));333 EXPECT_EQ(0, Count("ObjCfoo", eFunctionNameTypeMethod));334 335 // ObjC mangled method with category336 EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeFull));337 EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeBase));338 EXPECT_EQ(0, Count("ObjCbar", eFunctionNameTypeMethod));339 340 // Invalid things: unable to decode but still possible to find by full name341 EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeFull));342 EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeBase));343 EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod));344 EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase));345 EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod));346}347 348static bool NameInfoEquals(const DemangledNameInfo &lhs,349 const DemangledNameInfo &rhs) {350 return std::tie(lhs.BasenameRange, lhs.ArgumentsRange, lhs.ScopeRange,351 lhs.QualifiersRange) ==352 std::tie(rhs.BasenameRange, rhs.ArgumentsRange, rhs.ScopeRange,353 rhs.QualifiersRange);354}355 356TEST(MangledTest, DemangledNameInfo_SetMangledResets) {357 Mangled mangled;358 EXPECT_EQ(mangled.GetDemangledInfo(), std::nullopt);359 360 mangled.SetMangledName(ConstString("_Z3foov"));361 ASSERT_TRUE(mangled);362 363 auto info1 = mangled.GetDemangledInfo();364 EXPECT_NE(info1, std::nullopt);365 EXPECT_TRUE(info1->hasBasename());366 367 mangled.SetMangledName(ConstString("_Z4funcv"));368 369 // Should have re-calculated demangled-info since mangled name changed.370 auto info2 = mangled.GetDemangledInfo();371 ASSERT_NE(info2, std::nullopt);372 EXPECT_TRUE(info2->hasBasename());373 374 EXPECT_FALSE(NameInfoEquals(info1.value(), info2.value()));375 EXPECT_EQ(mangled.GetDemangledName(), "func()");376}377 378TEST(MangledTest, DemangledNameInfo_SetDemangledResets) {379 Mangled mangled("_Z3foov");380 ASSERT_TRUE(mangled);381 382 mangled.SetDemangledName(ConstString(""));383 384 // Mangled name hasn't changed, so GetDemangledInfo causes re-demangling385 // of previously set mangled name.386 EXPECT_NE(mangled.GetDemangledInfo(), std::nullopt);387 EXPECT_EQ(mangled.GetDemangledName(), "foo()");388}389 390TEST(MangledTest, DemangledNameInfo_Clear) {391 Mangled mangled("_Z3foov");392 ASSERT_TRUE(mangled);393 EXPECT_NE(mangled.GetDemangledInfo(), std::nullopt);394 395 mangled.Clear();396 397 EXPECT_EQ(mangled.GetDemangledInfo(), std::nullopt);398}399 400TEST(MangledTest, DemangledNameInfo_SetValue) {401 Mangled mangled("_Z4funcv");402 ASSERT_TRUE(mangled);403 404 auto demangled_func = mangled.GetDemangledInfo();405 406 // SetValue(mangled) resets demangled-info407 mangled.SetValue(ConstString("_Z3foov"));408 auto demangled_foo = mangled.GetDemangledInfo();409 EXPECT_NE(demangled_foo, std::nullopt);410 EXPECT_FALSE(NameInfoEquals(demangled_foo.value(), demangled_func.value()));411 412 // SetValue(demangled) resets demangled-info413 mangled.SetValue(ConstString("_Z4funcv"));414 EXPECT_TRUE(NameInfoEquals(mangled.GetDemangledInfo().value(),415 demangled_func.value()));416 417 // SetValue(empty) resets demangled-info418 mangled.SetValue(ConstString());419 EXPECT_EQ(mangled.GetDemangledInfo(), std::nullopt);420 421 // Demangling invalid mangled name will set demangled-info422 // (without a valid basename).423 mangled.SetValue(ConstString("_Zinvalid"));424 ASSERT_NE(mangled.GetDemangledInfo(), std::nullopt);425 EXPECT_FALSE(mangled.GetDemangledInfo()->hasBasename());426}427 428struct DemanglingPartsTestCase {429 const char *mangled;430 DemangledNameInfo expected_info;431 std::string_view basename;432 std::string_view scope;433 std::string_view qualifiers;434 bool valid_basename = true;435};436 437DemanglingPartsTestCase g_demangling_parts_test_cases[] = {438 // clang-format off439 { "_ZNVKO3BarIN2ns3QuxIiEEE1CIPFi3FooIS_IiES6_EEE6methodIS6_EENS5_IT_SC_E5InnerIiEESD_SD_",440 {441 /*.BasenameRange=*/{92, 98}, /*.TemplateArgumentsRange=*/{98, 108}, /*.ScopeRange=*/{36, 92},442 /*.ArgumentsRange=*/{108, 158}, /*.QualifiersRange=*/{158, 176}, /*.NameQualifiersRange=*/{0, 0},443 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}444 },445 /*.basename=*/"method",446 /*.scope=*/"Bar<ns::Qux<int>>::C<int (*)(Foo<Bar<int>, Bar<int>>)>::",447 /*.qualifiers=*/" const volatile &&"448 },449 { "_Z7getFuncIfEPFiiiET_",450 {451 /*.BasenameRange=*/{6, 13}, /*.TemplateArgumentsRange=*/{13, 20}, /*.ScopeRange=*/{6, 6},452 /*.ArgumentsRange=*/{20, 27}, /*.QualifiersRange=*/{38, 38}, /*.NameQualifiersRange=*/{0, 0},453 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}454 },455 /*.basename=*/"getFunc",456 /*.scope=*/"",457 /*.qualifiers=*/""458 },459 { "_ZN1f1b1c1gEv",460 {461 /*.BasenameRange=*/{9, 10}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 9},462 /*.ArgumentsRange=*/{10, 12}, /*.QualifiersRange=*/{12, 12}, /*.NameQualifiersRange=*/{0, 0},463 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}464 },465 /*.basename=*/"g",466 /*.scope=*/"f::b::c::",467 /*.qualifiers=*/""468 },469 { "_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_",470 {471 /*.BasenameRange=*/{45, 48}, /*.TemplateArgumentsRange=*/{48, 53}, /*.ScopeRange=*/{38, 45},472 /*.ArgumentsRange=*/{53, 58}, /*.QualifiersRange=*/{58, 58}, /*.NameQualifiersRange=*/{0, 0},473 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}474 },475 /*.basename=*/"fD1",476 /*.scope=*/"test7::",477 /*.qualifiers=*/""478 },479 { "_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bINDT1cE1dEEEEEcvT__EES2_",480 {481 /*.BasenameRange=*/{61, 64}, /*.TemplateArgumentsRange=*/{64, 69},/*.ScopeRange=*/{54, 61},482 /*.ArgumentsRange=*/{69, 79}, /*.QualifiersRange=*/{79, 79}, /*.NameQualifiersRange=*/{0, 0},483 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}484 },485 /*.basename=*/"fD1",486 /*.scope=*/"test7::",487 /*.qualifiers=*/""488 },489 { "_ZN5test7INDT1cE1dINDT1cE1dEEEE3fD1INDT1cE1dINDT1cE1dEEEEEDTcmtlNS_1DEL_ZNS_1bINDT1cE1dEEEEEcvT__EES2_",490 {491 /*.BasenameRange=*/{120, 123}, /*.TemplateArgumentsRange=*/{123, 155}, /*.ScopeRange=*/{81, 120},492 /*.ArgumentsRange=*/{155, 168}, /*.QualifiersRange=*/{168, 168}, /*.NameQualifiersRange=*/{0, 0},493 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}494 },495 /*.basename=*/"fD1",496 /*.scope=*/"test7<decltype(c)::d<decltype(c)::d>>::",497 /*.qualifiers=*/""498 },499 { "_ZN8nlohmann16json_abi_v3_11_310basic_jsonINSt3__13mapENS2_6vectorENS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEbxydS8_NS0_14adl_serializerENS4_IhNS8_IhEEEEvE5parseIRA29_KcEESE_OT_NS2_8functionIFbiNS0_6detail13parse_event_tERSE_EEEbb",500 {501 /*.BasenameRange=*/{687, 692}, /*.TemplateArgumentsRange=*/{692, 713}, /*.ScopeRange=*/{343, 687},502 /*.ArgumentsRange=*/{713, 1174}, /*.QualifiersRange=*/{1174, 1174}, /*.NameQualifiersRange=*/{0, 0},503 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}504 },505 /*.basename=*/"parse",506 /*.scope=*/"nlohmann::json_abi_v3_11_3::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, bool, long long, unsigned long long, double, std::__1::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>, void>::",507 /*.qualifiers=*/""508 },509 { "_ZN8nlohmann16json_abi_v3_11_310basic_jsonINSt3__13mapENS2_6vectorENS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEbxydS8_NS0_14adl_serializerENS4_IhNS8_IhEEEEvEC1EDn",510 {511 /*.BasenameRange=*/{344, 354}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 344},512 /*.ArgumentsRange=*/{354, 370}, /*.QualifiersRange=*/{370, 370}, /*.NameQualifiersRange=*/{0, 0},513 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}514 },515 /*.basename=*/"basic_json",516 /*.scope=*/"nlohmann::json_abi_v3_11_3::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, bool, long long, unsigned long long, double, std::__1::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>, void>::",517 /*.qualifiers=*/""518 },519 { "_Z3fppIiEPFPFvvEiEf",520 {521 /*.BasenameRange=*/{10, 13}, /*.TemplateArgumentsRange=*/{13, 18}, /*.ScopeRange=*/{10, 10},522 /*.ArgumentsRange=*/{18, 25}, /*.QualifiersRange=*/{34,34}, /*.NameQualifiersRange=*/{0, 0},523 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}524 },525 /*.basename=*/"fpp",526 /*.scope=*/"",527 /*.qualifiers=*/""528 },529 { "_Z3fppIiEPFPFvvEN2ns3FooIiEEEf",530 {531 /*.BasenameRange=*/{10, 13}, /*.TemplateArgumentsRange=*/{13, 18}, /*.ScopeRange=*/{10, 10},532 /*.ArgumentsRange=*/{18, 25}, /*.QualifiersRange=*/{43, 43}, /*.NameQualifiersRange=*/{0, 0},533 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}534 },535 /*.basename=*/"fpp",536 /*.scope=*/"",537 /*.qualifiers=*/""538 },539 { "_Z3fppIiEPFPFvPFN2ns3FooIiEENS2_3BarIfE3QuxEEEPFS2_S2_EEf",540 {541 /*.BasenameRange=*/{10, 13}, /*.TemplateArgumentsRange=*/{13, 18}, /*.ScopeRange=*/{10, 10},542 /*.ArgumentsRange=*/{18, 25}, /*.QualifiersRange=*/{108, 108}, /*.NameQualifiersRange=*/{0, 0},543 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}544 },545 /*.basename=*/"fpp",546 /*.scope=*/"",547 /*.qualifiers=*/""548 },549 { "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvvEiEf",550 {551 /*.BasenameRange=*/{64, 67}, /*.TemplateArgumentsRange=*/{67, 72}, /*.ScopeRange=*/{10, 64},552 /*.ArgumentsRange=*/{72, 79}, /*.QualifiersRange=*/{88, 88}, /*.NameQualifiersRange=*/{0, 0},553 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}554 },555 /*.basename=*/"fpp",556 /*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",557 /*.qualifiers=*/""558 },559 { "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvvES2_Ef",560 {561 /*.BasenameRange=*/{64, 67}, /*.TemplateArgumentsRange=*/{67, 72}, /*.ScopeRange=*/{10, 64},562 /*.ArgumentsRange=*/{72, 79}, /*.QualifiersRange=*/{97, 97}, /*.NameQualifiersRange=*/{0, 0},563 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}564 },565 /*.basename=*/"fpp",566 /*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",567 /*.qualifiers=*/"",568 },569 { "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvPFS2_S5_EEPFS2_S2_EEf",570 {571 /*.BasenameRange=*/{64, 67}, /*.TemplateArgumentsRange=*/{67, 72}, /*.ScopeRange=*/{10, 64},572 /*.ArgumentsRange=*/{72, 79}, /*.QualifiersRange=*/{162, 162}, /*.NameQualifiersRange=*/{0, 0},573 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}574 },575 /*.basename=*/"fpp",576 /*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",577 /*.qualifiers=*/"",578 },579 { "_ZNKO2ns3ns23Bar3fooIiEEPFPFNS0_3FooIiEEiENS3_IfEEEi",580 {581 /*.BasenameRange=*/{37, 40}, /*.TemplateArgumentsRange=*/{40, 45}, /*.ScopeRange=*/{23, 37},582 /*.ArgumentsRange=*/{45, 50}, /*.QualifiersRange=*/{78, 87}, /*.NameQualifiersRange=*/{0, 0},583 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}584 },585 /*.basename=*/"foo",586 /*.scope=*/"ns::ns2::Bar::",587 /*.qualifiers=*/" const &&",588 },589 { "_ZTV11ImageLoader",590 {591 /*.BasenameRange=*/{0, 0}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 0},592 /*.ArgumentsRange=*/{0, 0}, /*.QualifiersRange=*/{0, 0}, /*.NameQualifiersRange=*/{0, 0},593 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}594 },595 /*.basename=*/"",596 /*.scope=*/"",597 /*.qualifiers=*/"",598 /*.valid_basename=*/false599 },600 { "___ZNK5dyld313MachOAnalyzer18forEachInitializerER11DiagnosticsRKNS0_15VMAddrConverterEU13block_pointerFvjEPKv_block_invoke.204",601 {602 /*.BasenameRange=*/{55, 73}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{33, 55},603 /*.ArgumentsRange=*/{73, 181}, /*.QualifiersRange=*/{181, 187}, /*.NameQualifiersRange=*/{0, 0},604 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}605 },606 /*.basename=*/"forEachInitializer",607 /*.scope=*/"dyld3::MachOAnalyzer::",608 /*.qualifiers=*/" const",609 },610 { "_ZZN5dyld45startEPNS_10KernelArgsEPvS2_ENK3$_1clEv",611 {612 /*.BasenameRange=*/{53, 63}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 53},613 /*.ArgumentsRange=*/{63, 65}, /*.QualifiersRange=*/{65, 71}, /*.NameQualifiersRange=*/{0, 0},614 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}615 },616 /*.basename=*/"operator()",617 /*.scope=*/"dyld4::start(dyld4::KernelArgs*, void*, void*)::$_1::",618 /*.qualifiers=*/" const",619 },620 { "_ZZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateEENK3$_0clEv",621 {622 /*.BasenameRange=*/{88, 98}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 88},623 /*.ArgumentsRange=*/{98, 100}, /*.QualifiersRange=*/{100, 106}, /*.NameQualifiersRange=*/{0, 0},624 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}625 },626 /*.basename=*/"operator()",627 /*.scope=*/"dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::",628 /*.qualifiers=*/" const",629 },630 { "_ZZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateEENK3$_0clEv.cold",631 {632 /*.BasenameRange=*/{88, 98}, /*.TemplateArgumentsRange=*/{0, 0}, /*.ScopeRange=*/{0, 88},633 /*.ArgumentsRange=*/{98, 100}, /*.QualifiersRange=*/{100, 106}, /*.NameQualifiersRange=*/{0, 0},634 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}635 },636 /*.basename=*/"operator()",637 /*.scope=*/"dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::",638 /*.qualifiers=*/" const",639 },640 {"_Z4funcILN3foo4EnumE1EEvv",641 {642 /*.BasenameRange=*/{5, 9}, /*.TemplateArgumentsRange=*/{9, 23}, /*.ScopeRange=*/{5, 5},643 /*.ArgumentsRange=*/{23, 25}, /*.QualifiersRange=*/{25, 25}, /*.NameQualifiersRange=*/{0, 0},644 /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0}645 },646 /*.basename=*/"func",647 /*.scope=*/"",648 /*.qualifiers=*/"",649 }650 // clang-format on651};652 653struct DemanglingPartsTestFixture654 : public ::testing::TestWithParam<DemanglingPartsTestCase> {};655 656namespace {657class TestAllocator {658 llvm::BumpPtrAllocator Alloc;659 660public:661 void reset() { Alloc.Reset(); }662 663 template <typename T, typename... Args> T *makeNode(Args &&...args) {664 return new (Alloc.Allocate(sizeof(T), alignof(T)))665 T(std::forward<Args>(args)...);666 }667 668 void *allocateNodeArray(size_t sz) {669 return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,670 alignof(llvm::itanium_demangle::Node *));671 }672};673} // namespace674 675TEST_P(DemanglingPartsTestFixture, DemanglingParts) {676 const auto &[mangled, info, basename, scope, qualifiers, valid_basename] =677 GetParam();678 679 llvm::itanium_demangle::ManglingParser<TestAllocator> Parser(680 mangled, mangled + ::strlen(mangled));681 682 const auto *Root = Parser.parse();683 684 ASSERT_NE(nullptr, Root);685 686 auto OB = std::unique_ptr<TrackingOutputBuffer, TrackingOutputBufferDeleter>(687 new TrackingOutputBuffer());688 Root->print(*OB);689 auto demangled = std::string_view(*OB);690 691 ASSERT_EQ(OB->NameInfo.hasBasename(), valid_basename);692 EXPECT_EQ(OB->NameInfo.BasenameRange, info.BasenameRange);693 EXPECT_EQ(OB->NameInfo.TemplateArgumentsRange, info.TemplateArgumentsRange);694 EXPECT_EQ(OB->NameInfo.ScopeRange, info.ScopeRange);695 EXPECT_EQ(OB->NameInfo.ArgumentsRange, info.ArgumentsRange);696 EXPECT_EQ(OB->NameInfo.QualifiersRange, info.QualifiersRange);697 EXPECT_EQ(OB->NameInfo.NameQualifiersRange, info.NameQualifiersRange);698 699 auto get_part = [&](const std::pair<size_t, size_t> &loc) {700 return demangled.substr(loc.first, loc.second - loc.first);701 };702 703 EXPECT_EQ(get_part(OB->NameInfo.BasenameRange), basename);704 EXPECT_EQ(get_part(OB->NameInfo.ScopeRange), scope);705 EXPECT_EQ(get_part(OB->NameInfo.QualifiersRange), qualifiers);706}707 708INSTANTIATE_TEST_SUITE_P(DemanglingPartsTests, DemanglingPartsTestFixture,709 ::testing::ValuesIn(g_demangling_parts_test_cases));710 711struct DemangledNameInfoTestCase {712 DemangledNameInfo expected_info;713 bool valid_basename;714 bool valid_template;715 bool valid_scope;716 bool valid_arguments;717 bool valid_qualifiers;718 bool valid_name_qualifiers;719 bool valid_prefix;720 bool valid_suffix;721};722 723DemangledNameInfoTestCase g_demangled_name_info_test_cases[] = {724 // clang-format off725 {726 {727 /*.BasenameRange=*/{0, 10}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},728 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},729 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}730 },731 /*valid_basename=*/true, /*valid_template=*/false, /*valid_scope=*/false,732 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,733 /*valid_prefix=*/false, /*valid_suffix=*/false,734 },735 {736 {737 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{0, 10}, /*.ScopeRange=*/{1, 0},738 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},739 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}740 },741 /*valid_basename=*/false, /*valid_name_qualifiers=*/true, /*valid_scope=*/false,742 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,743 /*valid_prefix=*/false, /*valid_suffix=*/false,744 },745 {746 {747 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{0, 10},748 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},749 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}750 },751 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/true,752 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,753 /*valid_prefix=*/false, /*valid_suffix=*/false,754 },755 {756 {757 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},758 /*.ArgumentsRange=*/{0, 10}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},759 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}760 },761 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/false,762 /*valid_arguments=*/true, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,763 /*valid_prefix=*/false, /*valid_suffix=*/false,764 },765 {766 {767 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},768 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{0, 10}, /*.NameQualifiersRange=*/{1, 0},769 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}770 },771 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/false,772 /*valid_arguments=*/false, /*valid_qualifiers=*/true, /*valid_name_qualifiers=*/false,773 /*valid_prefix=*/false, /*valid_suffix=*/false,774 },775 {776 {777 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},778 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{0, 10},779 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{1, 0}780 },781 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/false,782 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/true,783 /*valid_prefix=*/false, /*valid_suffix=*/false,784 },785 {786 {787 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},788 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},789 /*.PrefixRange=*/{0, 10}, /*.SuffixRange=*/{1, 0}790 },791 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/false,792 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,793 /*valid_prefix=*/true, /*valid_suffix=*/false,794 },795 {796 {797 /*.BasenameRange=*/{1, 0}, /*.TemplateArgumentsRange=*/{1, 0}, /*.ScopeRange=*/{1, 0},798 /*.ArgumentsRange=*/{1, 0}, /*.QualifiersRange=*/{1, 0}, /*.NameQualifiersRange=*/{1, 0},799 /*.PrefixRange=*/{1, 0}, /*.SuffixRange=*/{0, 10}800 },801 /*valid_basename=*/false, /*valid_template=*/false, /*valid_scope=*/false,802 /*valid_arguments=*/false, /*valid_qualifiers=*/false, /*valid_name_qualifiers=*/false,803 /*valid_prefix=*/false, /*valid_suffix=*/true,804 },805 // clang-format on806};807 808struct DemangledNameInfoTestFixture809 : public ::testing::TestWithParam<DemangledNameInfoTestCase> {};810 811TEST_P(DemangledNameInfoTestFixture, DemangledNameInfoRanges) {812 const auto &[info, valid_basename, valid_template_arguments, valid_scope,813 valid_arguments, valid_qualifiers, valid_name_qualifiers,814 valid_prefix, valid_suffix] = GetParam();815 816 ASSERT_EQ(info.hasBasename(), valid_basename);817 ASSERT_EQ(info.hasTemplateArguments(), valid_template_arguments);818 ASSERT_EQ(info.hasScope(), valid_scope);819 ASSERT_EQ(info.hasArguments(), valid_arguments);820 ASSERT_EQ(info.hasQualifiers(), valid_qualifiers);821 ASSERT_EQ(info.hasNameQualifiers(), valid_name_qualifiers);822 ASSERT_EQ(info.hasPrefix(), valid_prefix);823 ASSERT_EQ(info.hasSuffix(), valid_suffix);824}825 826INSTANTIATE_TEST_SUITE_P(DemangledNameInfoRangesTests,827 DemangledNameInfoTestFixture,828 ::testing::ValuesIn(g_demangled_name_info_test_cases));829 830struct DemanglingInfoCorrectnessTestCase {831 const char *mangled;832 const char *demangled;833};834 835DemanglingInfoCorrectnessTestCase g_demangling_correctness_test_cases[] = {836#include "llvm/Testing/Demangle/DemangleTestCases.inc"837};838 839struct DemanglingInfoCorrectnessTestFixutre840 : public ::testing::TestWithParam<DemanglingInfoCorrectnessTestCase> {};841 842TEST_P(DemanglingInfoCorrectnessTestFixutre, Correctness) {843 auto [mangled, demangled] = GetParam();844 845 llvm::itanium_demangle::ManglingParser<TestAllocator> Parser(846 mangled, mangled + ::strlen(mangled));847 848 const auto *Root = Parser.parse();849 850 ASSERT_NE(nullptr, Root);851 852 auto OB = std::unique_ptr<TrackingOutputBuffer, TrackingOutputBufferDeleter>(853 new TrackingOutputBuffer());854 Root->print(*OB);855 856 // Filter out cases which would never show up in frames. We only care about857 // function names.858 if (Root->getKind() !=859 llvm::itanium_demangle::Node::Kind::KFunctionEncoding &&860 Root->getKind() != llvm::itanium_demangle::Node::Kind::KDotSuffix)861 return;862 863 ASSERT_TRUE(OB->NameInfo.hasBasename());864 865 auto tracked_name = llvm::StringRef(*OB);866 867 std::string reconstructed_name;868 869 auto return_left =870 CPlusPlusLanguage::GetDemangledReturnTypeLHS(tracked_name, OB->NameInfo);871 EXPECT_THAT_EXPECTED(return_left, llvm::Succeeded());872 reconstructed_name += *return_left;873 874 auto scope = CPlusPlusLanguage::GetDemangledScope(tracked_name, OB->NameInfo);875 EXPECT_THAT_EXPECTED(scope, llvm::Succeeded());876 reconstructed_name += *scope;877 878 auto basename =879 CPlusPlusLanguage::GetDemangledBasename(tracked_name, OB->NameInfo);880 reconstructed_name += basename;881 882 auto template_args = CPlusPlusLanguage::GetDemangledTemplateArguments(883 tracked_name, OB->NameInfo);884 EXPECT_THAT_EXPECTED(template_args, llvm::Succeeded());885 reconstructed_name += *template_args;886 887 auto args = CPlusPlusLanguage::GetDemangledFunctionArguments(tracked_name,888 OB->NameInfo);889 EXPECT_THAT_EXPECTED(args, llvm::Succeeded());890 reconstructed_name += *args;891 892 auto return_right =893 CPlusPlusLanguage::GetDemangledReturnTypeRHS(tracked_name, OB->NameInfo);894 EXPECT_THAT_EXPECTED(return_right, llvm::Succeeded());895 reconstructed_name += *return_right;896 897 auto qualifiers = CPlusPlusLanguage::GetDemangledFunctionQualifiers(898 tracked_name, OB->NameInfo);899 EXPECT_THAT_EXPECTED(qualifiers, llvm::Succeeded());900 reconstructed_name += *qualifiers;901 902 auto suffix =903 CPlusPlusLanguage::GetDemangledFunctionSuffix(tracked_name, OB->NameInfo);904 EXPECT_THAT_EXPECTED(suffix, llvm::Succeeded());905 reconstructed_name += *suffix;906 907 EXPECT_EQ(reconstructed_name, demangled);908}909 910INSTANTIATE_TEST_SUITE_P(911 DemanglingInfoCorrectnessTests, DemanglingInfoCorrectnessTestFixutre,912 ::testing::ValuesIn(g_demangling_correctness_test_cases));913