1 //===- MicrosoftDemangle.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a demangler for MSVC-style mangled symbols. 10 // 11 // This file has no dependencies on the rest of LLVM so that it can be 12 // easily reused in other programs such as libcxxabi. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Demangle/MicrosoftDemangle.h" 17 18 #include "llvm/Demangle/Demangle.h" 19 #include "llvm/Demangle/DemangleConfig.h" 20 #include "llvm/Demangle/MicrosoftDemangleNodes.h" 21 #include "llvm/Demangle/StringViewExtras.h" 22 #include "llvm/Demangle/Utility.h" 23 24 #include <array> 25 #include <cctype> 26 #include <cstdio> 27 #include <optional> 28 #include <string_view> 29 #include <tuple> 30 31 using namespace llvm; 32 using namespace ms_demangle; 33 34 static bool startsWithDigit(std::string_view S) { 35 return !S.empty() && std::isdigit(S.front()); 36 } 37 38 struct NodeList { 39 Node *N = nullptr; 40 NodeList *Next = nullptr; 41 }; 42 43 static bool consumeFront(std::string_view &S, char C) { 44 if (!llvm::itanium_demangle::starts_with(S, C)) 45 return false; 46 S.remove_prefix(1); 47 return true; 48 } 49 50 static bool consumeFront(std::string_view &S, std::string_view C) { 51 if (!llvm::itanium_demangle::starts_with(S, C)) 52 return false; 53 S.remove_prefix(C.size()); 54 return true; 55 } 56 57 static bool consumeFront(std::string_view &S, std::string_view PrefixA, 58 std::string_view PrefixB, bool A) { 59 const std::string_view &Prefix = A ? PrefixA : PrefixB; 60 return consumeFront(S, Prefix); 61 } 62 63 static bool startsWith(std::string_view S, std::string_view PrefixA, 64 std::string_view PrefixB, bool A) { 65 const std::string_view &Prefix = A ? PrefixA : PrefixB; 66 return llvm::itanium_demangle::starts_with(S, Prefix); 67 } 68 69 bool Demangler::isMemberPointer(std::string_view MangledName, bool &Error) { 70 Error = false; 71 const char F = MangledName.front(); 72 MangledName.remove_prefix(1); 73 switch (F) { 74 case '$': 75 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an 76 // rvalue reference to a member. 77 return false; 78 case 'A': 79 // 'A' indicates a reference, and you cannot have a reference to a member 80 // function or member. 81 return false; 82 case 'P': 83 case 'Q': 84 case 'R': 85 case 'S': 86 // These 4 values indicate some kind of pointer, but we still don't know 87 // what. 88 break; 89 default: 90 // isMemberPointer() is called only if isPointerType() returns true, 91 // and it rejects other prefixes. 92 DEMANGLE_UNREACHABLE; 93 } 94 95 // If it starts with a number, then 6 indicates a non-member function 96 // pointer, and 8 indicates a member function pointer. 97 if (startsWithDigit(MangledName)) { 98 if (MangledName[0] != '6' && MangledName[0] != '8') { 99 Error = true; 100 return false; 101 } 102 return (MangledName[0] == '8'); 103 } 104 105 // Remove ext qualifiers since those can appear on either type and are 106 // therefore not indicative. 107 consumeFront(MangledName, 'E'); // 64-bit 108 consumeFront(MangledName, 'I'); // restrict 109 consumeFront(MangledName, 'F'); // unaligned 110 demanglePointerAuthQualifier(MangledName); 111 112 if (MangledName.empty()) { 113 Error = true; 114 return false; 115 } 116 117 // The next value should be either ABCD (non-member) or QRST (member). 118 switch (MangledName.front()) { 119 case 'A': 120 case 'B': 121 case 'C': 122 case 'D': 123 return false; 124 case 'Q': 125 case 'R': 126 case 'S': 127 case 'T': 128 return true; 129 default: 130 Error = true; 131 return false; 132 } 133 } 134 135 static SpecialIntrinsicKind 136 consumeSpecialIntrinsicKind(std::string_view &MangledName) { 137 if (consumeFront(MangledName, "?_7")) 138 return SpecialIntrinsicKind::Vftable; 139 if (consumeFront(MangledName, "?_8")) 140 return SpecialIntrinsicKind::Vbtable; 141 if (consumeFront(MangledName, "?_9")) 142 return SpecialIntrinsicKind::VcallThunk; 143 if (consumeFront(MangledName, "?_A")) 144 return SpecialIntrinsicKind::Typeof; 145 if (consumeFront(MangledName, "?_B")) 146 return SpecialIntrinsicKind::LocalStaticGuard; 147 if (consumeFront(MangledName, "?_C")) 148 return SpecialIntrinsicKind::StringLiteralSymbol; 149 if (consumeFront(MangledName, "?_P")) 150 return SpecialIntrinsicKind::UdtReturning; 151 if (consumeFront(MangledName, "?_R0")) 152 return SpecialIntrinsicKind::RttiTypeDescriptor; 153 if (consumeFront(MangledName, "?_R1")) 154 return SpecialIntrinsicKind::RttiBaseClassDescriptor; 155 if (consumeFront(MangledName, "?_R2")) 156 return SpecialIntrinsicKind::RttiBaseClassArray; 157 if (consumeFront(MangledName, "?_R3")) 158 return SpecialIntrinsicKind::RttiClassHierarchyDescriptor; 159 if (consumeFront(MangledName, "?_R4")) 160 return SpecialIntrinsicKind::RttiCompleteObjLocator; 161 if (consumeFront(MangledName, "?_S")) 162 return SpecialIntrinsicKind::LocalVftable; 163 if (consumeFront(MangledName, "?__E")) 164 return SpecialIntrinsicKind::DynamicInitializer; 165 if (consumeFront(MangledName, "?__F")) 166 return SpecialIntrinsicKind::DynamicAtexitDestructor; 167 if (consumeFront(MangledName, "?__J")) 168 return SpecialIntrinsicKind::LocalStaticThreadGuard; 169 return SpecialIntrinsicKind::None; 170 } 171 172 static bool startsWithLocalScopePattern(std::string_view S) { 173 if (!consumeFront(S, '?')) 174 return false; 175 176 size_t End = S.find('?'); 177 if (End == std::string_view::npos) 178 return false; 179 std::string_view Candidate = S.substr(0, End); 180 if (Candidate.empty()) 181 return false; 182 183 // \?[0-9]\? 184 // ?@? is the discriminator 0. 185 if (Candidate.size() == 1) 186 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9'); 187 188 // If it's not 0-9, then it's an encoded number terminated with an @ 189 if (Candidate.back() != '@') 190 return false; 191 Candidate.remove_suffix(1); 192 193 // An encoded number starts with B-P and all subsequent digits are in A-P. 194 // Note that the reason the first digit cannot be A is two fold. First, it 195 // would create an ambiguity with ?A which delimits the beginning of an 196 // anonymous namespace. Second, A represents 0, and you don't start a multi 197 // digit number with a leading 0. Presumably the anonymous namespace 198 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J. 199 if (Candidate[0] < 'B' || Candidate[0] > 'P') 200 return false; 201 Candidate.remove_prefix(1); 202 while (!Candidate.empty()) { 203 if (Candidate[0] < 'A' || Candidate[0] > 'P') 204 return false; 205 Candidate.remove_prefix(1); 206 } 207 208 return true; 209 } 210 211 static bool isTagType(std::string_view S) { 212 switch (S.front()) { 213 case 'T': // union 214 case 'U': // struct 215 case 'V': // class 216 case 'W': // enum 217 return true; 218 } 219 return false; 220 } 221 222 static bool isCustomType(std::string_view S) { return S[0] == '?'; } 223 224 static bool isPointerType(std::string_view S) { 225 if (llvm::itanium_demangle::starts_with(S, "$$Q")) // foo && 226 return true; 227 228 switch (S.front()) { 229 case 'A': // foo & 230 case 'P': // foo * 231 case 'Q': // foo *const 232 case 'R': // foo *volatile 233 case 'S': // foo *const volatile 234 return true; 235 } 236 return false; 237 } 238 239 static bool isArrayType(std::string_view S) { return S[0] == 'Y'; } 240 241 static bool isFunctionType(std::string_view S) { 242 return llvm::itanium_demangle::starts_with(S, "$$A8@@") || 243 llvm::itanium_demangle::starts_with(S, "$$A6"); 244 } 245 246 static FunctionRefQualifier 247 demangleFunctionRefQualifier(std::string_view &MangledName) { 248 if (consumeFront(MangledName, 'G')) 249 return FunctionRefQualifier::Reference; 250 else if (consumeFront(MangledName, 'H')) 251 return FunctionRefQualifier::RValueReference; 252 return FunctionRefQualifier::None; 253 } 254 255 static std::pair<Qualifiers, PointerAffinity> 256 demanglePointerCVQualifiers(std::string_view &MangledName) { 257 if (consumeFront(MangledName, "$$Q")) 258 return std::make_pair(Q_None, PointerAffinity::RValueReference); 259 260 const char F = MangledName.front(); 261 MangledName.remove_prefix(1); 262 switch (F) { 263 case 'A': 264 return std::make_pair(Q_None, PointerAffinity::Reference); 265 case 'P': 266 return std::make_pair(Q_None, PointerAffinity::Pointer); 267 case 'Q': 268 return std::make_pair(Q_Const, PointerAffinity::Pointer); 269 case 'R': 270 return std::make_pair(Q_Volatile, PointerAffinity::Pointer); 271 case 'S': 272 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), 273 PointerAffinity::Pointer); 274 } 275 // This function is only called if isPointerType() returns true, 276 // and it only returns true for the six cases listed above. 277 DEMANGLE_UNREACHABLE; 278 } 279 280 std::string_view Demangler::copyString(std::string_view Borrowed) { 281 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size()); 282 // This is not a micro-optimization, it avoids UB, should Borrowed be an null 283 // buffer. 284 if (Borrowed.size()) 285 std::memcpy(Stable, Borrowed.data(), Borrowed.size()); 286 287 return {Stable, Borrowed.size()}; 288 } 289 290 SpecialTableSymbolNode * 291 Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName, 292 SpecialIntrinsicKind K) { 293 NamedIdentifierNode *NI = Arena.alloc<NamedIdentifierNode>(); 294 switch (K) { 295 case SpecialIntrinsicKind::Vftable: 296 NI->Name = "`vftable'"; 297 break; 298 case SpecialIntrinsicKind::Vbtable: 299 NI->Name = "`vbtable'"; 300 break; 301 case SpecialIntrinsicKind::LocalVftable: 302 NI->Name = "`local vftable'"; 303 break; 304 case SpecialIntrinsicKind::RttiCompleteObjLocator: 305 NI->Name = "`RTTI Complete Object Locator'"; 306 break; 307 default: 308 DEMANGLE_UNREACHABLE; 309 } 310 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI); 311 SpecialTableSymbolNode *STSN = Arena.alloc<SpecialTableSymbolNode>(); 312 STSN->Name = QN; 313 bool IsMember = false; 314 if (MangledName.empty()) { 315 Error = true; 316 return nullptr; 317 } 318 char Front = MangledName.front(); 319 MangledName.remove_prefix(1); 320 if (Front != '6' && Front != '7') { 321 Error = true; 322 return nullptr; 323 } 324 325 std::tie(STSN->Quals, IsMember) = demangleQualifiers(MangledName); 326 if (!consumeFront(MangledName, '@')) 327 STSN->TargetName = demangleFullyQualifiedTypeName(MangledName); 328 return STSN; 329 } 330 331 LocalStaticGuardVariableNode * 332 Demangler::demangleLocalStaticGuard(std::string_view &MangledName, 333 bool IsThread) { 334 LocalStaticGuardIdentifierNode *LSGI = 335 Arena.alloc<LocalStaticGuardIdentifierNode>(); 336 LSGI->IsThread = IsThread; 337 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, LSGI); 338 LocalStaticGuardVariableNode *LSGVN = 339 Arena.alloc<LocalStaticGuardVariableNode>(); 340 LSGVN->Name = QN; 341 342 if (consumeFront(MangledName, "4IA")) 343 LSGVN->IsVisible = false; 344 else if (consumeFront(MangledName, "5")) 345 LSGVN->IsVisible = true; 346 else { 347 Error = true; 348 return nullptr; 349 } 350 351 if (!MangledName.empty()) 352 LSGI->ScopeIndex = demangleUnsigned(MangledName); 353 return LSGVN; 354 } 355 356 static NamedIdentifierNode *synthesizeNamedIdentifier(ArenaAllocator &Arena, 357 std::string_view Name) { 358 NamedIdentifierNode *Id = Arena.alloc<NamedIdentifierNode>(); 359 Id->Name = Name; 360 return Id; 361 } 362 363 static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena, 364 IdentifierNode *Identifier) { 365 QualifiedNameNode *QN = Arena.alloc<QualifiedNameNode>(); 366 QN->Components = Arena.alloc<NodeArrayNode>(); 367 QN->Components->Count = 1; 368 QN->Components->Nodes = Arena.allocArray<Node *>(1); 369 QN->Components->Nodes[0] = Identifier; 370 return QN; 371 } 372 373 static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena, 374 std::string_view Name) { 375 NamedIdentifierNode *Id = synthesizeNamedIdentifier(Arena, Name); 376 return synthesizeQualifiedName(Arena, Id); 377 } 378 379 static VariableSymbolNode *synthesizeVariable(ArenaAllocator &Arena, 380 TypeNode *Type, 381 std::string_view VariableName) { 382 VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>(); 383 VSN->Type = Type; 384 VSN->Name = synthesizeQualifiedName(Arena, VariableName); 385 return VSN; 386 } 387 388 VariableSymbolNode * 389 Demangler::demangleUntypedVariable(ArenaAllocator &Arena, 390 std::string_view &MangledName, 391 std::string_view VariableName) { 392 NamedIdentifierNode *NI = synthesizeNamedIdentifier(Arena, VariableName); 393 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI); 394 VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>(); 395 VSN->Name = QN; 396 if (consumeFront(MangledName, "8")) 397 return VSN; 398 399 Error = true; 400 return nullptr; 401 } 402 403 VariableSymbolNode * 404 Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena, 405 std::string_view &MangledName) { 406 RttiBaseClassDescriptorNode *RBCDN = 407 Arena.alloc<RttiBaseClassDescriptorNode>(); 408 RBCDN->NVOffset = demangleUnsigned(MangledName); 409 RBCDN->VBPtrOffset = demangleSigned(MangledName); 410 RBCDN->VBTableOffset = demangleUnsigned(MangledName); 411 RBCDN->Flags = demangleUnsigned(MangledName); 412 if (Error) 413 return nullptr; 414 415 VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>(); 416 VSN->Name = demangleNameScopeChain(MangledName, RBCDN); 417 consumeFront(MangledName, '8'); 418 return VSN; 419 } 420 421 FunctionSymbolNode * 422 Demangler::demangleInitFiniStub(std::string_view &MangledName, 423 bool IsDestructor) { 424 DynamicStructorIdentifierNode *DSIN = 425 Arena.alloc<DynamicStructorIdentifierNode>(); 426 DSIN->IsDestructor = IsDestructor; 427 428 bool IsKnownStaticDataMember = false; 429 if (consumeFront(MangledName, '?')) 430 IsKnownStaticDataMember = true; 431 432 SymbolNode *Symbol = demangleDeclarator(MangledName); 433 if (Error) 434 return nullptr; 435 436 FunctionSymbolNode *FSN = nullptr; 437 438 if (Symbol->kind() == NodeKind::VariableSymbol) { 439 DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol); 440 441 // Older versions of clang mangled this type of symbol incorrectly. They 442 // would omit the leading ? and they would only emit a single @ at the end. 443 // The correct mangling is a leading ? and 2 trailing @ signs. Handle 444 // both cases. 445 int AtCount = IsKnownStaticDataMember ? 2 : 1; 446 for (int I = 0; I < AtCount; ++I) { 447 if (consumeFront(MangledName, '@')) 448 continue; 449 Error = true; 450 return nullptr; 451 } 452 453 FSN = demangleFunctionEncoding(MangledName); 454 if (FSN) 455 FSN->Name = synthesizeQualifiedName(Arena, DSIN); 456 } else { 457 if (IsKnownStaticDataMember) { 458 // This was supposed to be a static data member, but we got a function. 459 Error = true; 460 return nullptr; 461 } 462 463 FSN = static_cast<FunctionSymbolNode *>(Symbol); 464 DSIN->Name = Symbol->Name; 465 FSN->Name = synthesizeQualifiedName(Arena, DSIN); 466 } 467 468 return FSN; 469 } 470 471 SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) { 472 SpecialIntrinsicKind SIK = consumeSpecialIntrinsicKind(MangledName); 473 474 switch (SIK) { 475 case SpecialIntrinsicKind::None: 476 return nullptr; 477 case SpecialIntrinsicKind::StringLiteralSymbol: 478 return demangleStringLiteral(MangledName); 479 case SpecialIntrinsicKind::Vftable: 480 case SpecialIntrinsicKind::Vbtable: 481 case SpecialIntrinsicKind::LocalVftable: 482 case SpecialIntrinsicKind::RttiCompleteObjLocator: 483 return demangleSpecialTableSymbolNode(MangledName, SIK); 484 case SpecialIntrinsicKind::VcallThunk: 485 return demangleVcallThunkNode(MangledName); 486 case SpecialIntrinsicKind::LocalStaticGuard: 487 return demangleLocalStaticGuard(MangledName, /*IsThread=*/false); 488 case SpecialIntrinsicKind::LocalStaticThreadGuard: 489 return demangleLocalStaticGuard(MangledName, /*IsThread=*/true); 490 case SpecialIntrinsicKind::RttiTypeDescriptor: { 491 TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result); 492 if (Error) 493 break; 494 if (!consumeFront(MangledName, "@8")) 495 break; 496 if (!MangledName.empty()) 497 break; 498 return synthesizeVariable(Arena, T, "`RTTI Type Descriptor'"); 499 } 500 case SpecialIntrinsicKind::RttiBaseClassArray: 501 return demangleUntypedVariable(Arena, MangledName, 502 "`RTTI Base Class Array'"); 503 case SpecialIntrinsicKind::RttiClassHierarchyDescriptor: 504 return demangleUntypedVariable(Arena, MangledName, 505 "`RTTI Class Hierarchy Descriptor'"); 506 case SpecialIntrinsicKind::RttiBaseClassDescriptor: 507 return demangleRttiBaseClassDescriptorNode(Arena, MangledName); 508 case SpecialIntrinsicKind::DynamicInitializer: 509 return demangleInitFiniStub(MangledName, /*IsDestructor=*/false); 510 case SpecialIntrinsicKind::DynamicAtexitDestructor: 511 return demangleInitFiniStub(MangledName, /*IsDestructor=*/true); 512 case SpecialIntrinsicKind::Typeof: 513 case SpecialIntrinsicKind::UdtReturning: 514 // It's unclear which tools produces these manglings, so demangling 515 // support is not (yet?) implemented. 516 break; 517 case SpecialIntrinsicKind::Unknown: 518 DEMANGLE_UNREACHABLE; // Never returned by consumeSpecialIntrinsicKind. 519 } 520 Error = true; 521 return nullptr; 522 } 523 524 IdentifierNode * 525 Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) { 526 assert(llvm::itanium_demangle::starts_with(MangledName, '?')); 527 MangledName.remove_prefix(1); 528 if (MangledName.empty()) { 529 Error = true; 530 return nullptr; 531 } 532 533 if (consumeFront(MangledName, "__")) 534 return demangleFunctionIdentifierCode( 535 MangledName, FunctionIdentifierCodeGroup::DoubleUnder); 536 if (consumeFront(MangledName, "_")) 537 return demangleFunctionIdentifierCode(MangledName, 538 FunctionIdentifierCodeGroup::Under); 539 return demangleFunctionIdentifierCode(MangledName, 540 FunctionIdentifierCodeGroup::Basic); 541 } 542 543 StructorIdentifierNode * 544 Demangler::demangleStructorIdentifier(std::string_view &MangledName, 545 bool IsDestructor) { 546 StructorIdentifierNode *N = Arena.alloc<StructorIdentifierNode>(); 547 N->IsDestructor = IsDestructor; 548 return N; 549 } 550 551 ConversionOperatorIdentifierNode * 552 Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) { 553 ConversionOperatorIdentifierNode *N = 554 Arena.alloc<ConversionOperatorIdentifierNode>(); 555 return N; 556 } 557 558 LiteralOperatorIdentifierNode * 559 Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) { 560 LiteralOperatorIdentifierNode *N = 561 Arena.alloc<LiteralOperatorIdentifierNode>(); 562 N->Name = demangleSimpleString(MangledName, /*Memorize=*/false); 563 return N; 564 } 565 566 IntrinsicFunctionKind 567 Demangler::translateIntrinsicFunctionCode(char CH, 568 FunctionIdentifierCodeGroup Group) { 569 using IFK = IntrinsicFunctionKind; 570 if (!(CH >= '0' && CH <= '9') && !(CH >= 'A' && CH <= 'Z')) { 571 Error = true; 572 return IFK::None; 573 } 574 575 // Not all ? identifiers are intrinsics *functions*. This function only maps 576 // operator codes for the special functions, all others are handled elsewhere, 577 // hence the IFK::None entries in the table. 578 static IFK Basic[36] = { 579 IFK::None, // ?0 # Foo::Foo() 580 IFK::None, // ?1 # Foo::~Foo() 581 IFK::New, // ?2 # operator new 582 IFK::Delete, // ?3 # operator delete 583 IFK::Assign, // ?4 # operator= 584 IFK::RightShift, // ?5 # operator>> 585 IFK::LeftShift, // ?6 # operator<< 586 IFK::LogicalNot, // ?7 # operator! 587 IFK::Equals, // ?8 # operator== 588 IFK::NotEquals, // ?9 # operator!= 589 IFK::ArraySubscript, // ?A # operator[] 590 IFK::None, // ?B # Foo::operator <type>() 591 IFK::Pointer, // ?C # operator-> 592 IFK::Dereference, // ?D # operator* 593 IFK::Increment, // ?E # operator++ 594 IFK::Decrement, // ?F # operator-- 595 IFK::Minus, // ?G # operator- 596 IFK::Plus, // ?H # operator+ 597 IFK::BitwiseAnd, // ?I # operator& 598 IFK::MemberPointer, // ?J # operator->* 599 IFK::Divide, // ?K # operator/ 600 IFK::Modulus, // ?L # operator% 601 IFK::LessThan, // ?M operator< 602 IFK::LessThanEqual, // ?N operator<= 603 IFK::GreaterThan, // ?O operator> 604 IFK::GreaterThanEqual, // ?P operator>= 605 IFK::Comma, // ?Q operator, 606 IFK::Parens, // ?R operator() 607 IFK::BitwiseNot, // ?S operator~ 608 IFK::BitwiseXor, // ?T operator^ 609 IFK::BitwiseOr, // ?U operator| 610 IFK::LogicalAnd, // ?V operator&& 611 IFK::LogicalOr, // ?W operator|| 612 IFK::TimesEqual, // ?X operator*= 613 IFK::PlusEqual, // ?Y operator+= 614 IFK::MinusEqual, // ?Z operator-= 615 }; 616 static IFK Under[36] = { 617 IFK::DivEqual, // ?_0 operator/= 618 IFK::ModEqual, // ?_1 operator%= 619 IFK::RshEqual, // ?_2 operator>>= 620 IFK::LshEqual, // ?_3 operator<<= 621 IFK::BitwiseAndEqual, // ?_4 operator&= 622 IFK::BitwiseOrEqual, // ?_5 operator|= 623 IFK::BitwiseXorEqual, // ?_6 operator^= 624 IFK::None, // ?_7 # vftable 625 IFK::None, // ?_8 # vbtable 626 IFK::None, // ?_9 # vcall 627 IFK::None, // ?_A # typeof 628 IFK::None, // ?_B # local static guard 629 IFK::None, // ?_C # string literal 630 IFK::VbaseDtor, // ?_D # vbase destructor 631 IFK::VecDelDtor, // ?_E # vector deleting destructor 632 IFK::DefaultCtorClosure, // ?_F # default constructor closure 633 IFK::ScalarDelDtor, // ?_G # scalar deleting destructor 634 IFK::VecCtorIter, // ?_H # vector constructor iterator 635 IFK::VecDtorIter, // ?_I # vector destructor iterator 636 IFK::VecVbaseCtorIter, // ?_J # vector vbase constructor iterator 637 IFK::VdispMap, // ?_K # virtual displacement map 638 IFK::EHVecCtorIter, // ?_L # eh vector constructor iterator 639 IFK::EHVecDtorIter, // ?_M # eh vector destructor iterator 640 IFK::EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator 641 IFK::CopyCtorClosure, // ?_O # copy constructor closure 642 IFK::None, // ?_P<name> # udt returning <name> 643 IFK::None, // ?_Q # <unknown> 644 IFK::None, // ?_R0 - ?_R4 # RTTI Codes 645 IFK::None, // ?_S # local vftable 646 IFK::LocalVftableCtorClosure, // ?_T # local vftable constructor closure 647 IFK::ArrayNew, // ?_U operator new[] 648 IFK::ArrayDelete, // ?_V operator delete[] 649 IFK::None, // ?_W <unused> 650 IFK::None, // ?_X <unused> 651 IFK::None, // ?_Y <unused> 652 IFK::None, // ?_Z <unused> 653 }; 654 static IFK DoubleUnder[36] = { 655 IFK::None, // ?__0 <unused> 656 IFK::None, // ?__1 <unused> 657 IFK::None, // ?__2 <unused> 658 IFK::None, // ?__3 <unused> 659 IFK::None, // ?__4 <unused> 660 IFK::None, // ?__5 <unused> 661 IFK::None, // ?__6 <unused> 662 IFK::None, // ?__7 <unused> 663 IFK::None, // ?__8 <unused> 664 IFK::None, // ?__9 <unused> 665 IFK::ManVectorCtorIter, // ?__A managed vector ctor iterator 666 IFK::ManVectorDtorIter, // ?__B managed vector dtor iterator 667 IFK::EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator 668 IFK::EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iter 669 IFK::None, // ?__E dynamic initializer for `T' 670 IFK::None, // ?__F dynamic atexit destructor for `T' 671 IFK::VectorCopyCtorIter, // ?__G vector copy constructor iter 672 IFK::VectorVbaseCopyCtorIter, // ?__H vector vbase copy ctor iter 673 IFK::ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy ctor 674 // iter 675 IFK::None, // ?__J local static thread guard 676 IFK::None, // ?__K operator ""_name 677 IFK::CoAwait, // ?__L operator co_await 678 IFK::Spaceship, // ?__M operator<=> 679 IFK::None, // ?__N <unused> 680 IFK::None, // ?__O <unused> 681 IFK::None, // ?__P <unused> 682 IFK::None, // ?__Q <unused> 683 IFK::None, // ?__R <unused> 684 IFK::None, // ?__S <unused> 685 IFK::None, // ?__T <unused> 686 IFK::None, // ?__U <unused> 687 IFK::None, // ?__V <unused> 688 IFK::None, // ?__W <unused> 689 IFK::None, // ?__X <unused> 690 IFK::None, // ?__Y <unused> 691 IFK::None, // ?__Z <unused> 692 }; 693 694 int Index = (CH >= '0' && CH <= '9') ? (CH - '0') : (CH - 'A' + 10); 695 switch (Group) { 696 case FunctionIdentifierCodeGroup::Basic: 697 return Basic[Index]; 698 case FunctionIdentifierCodeGroup::Under: 699 return Under[Index]; 700 case FunctionIdentifierCodeGroup::DoubleUnder: 701 return DoubleUnder[Index]; 702 } 703 DEMANGLE_UNREACHABLE; 704 } 705 706 IdentifierNode * 707 Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName, 708 FunctionIdentifierCodeGroup Group) { 709 if (MangledName.empty()) { 710 Error = true; 711 return nullptr; 712 } 713 const char CH = MangledName.front(); 714 switch (Group) { 715 case FunctionIdentifierCodeGroup::Basic: 716 MangledName.remove_prefix(1); 717 switch (CH) { 718 case '0': 719 case '1': 720 return demangleStructorIdentifier(MangledName, CH == '1'); 721 case 'B': 722 return demangleConversionOperatorIdentifier(MangledName); 723 default: 724 return Arena.alloc<IntrinsicFunctionIdentifierNode>( 725 translateIntrinsicFunctionCode(CH, Group)); 726 } 727 case FunctionIdentifierCodeGroup::Under: 728 MangledName.remove_prefix(1); 729 return Arena.alloc<IntrinsicFunctionIdentifierNode>( 730 translateIntrinsicFunctionCode(CH, Group)); 731 case FunctionIdentifierCodeGroup::DoubleUnder: 732 MangledName.remove_prefix(1); 733 switch (CH) { 734 case 'K': 735 return demangleLiteralOperatorIdentifier(MangledName); 736 default: 737 return Arena.alloc<IntrinsicFunctionIdentifierNode>( 738 translateIntrinsicFunctionCode(CH, Group)); 739 } 740 } 741 742 DEMANGLE_UNREACHABLE; 743 } 744 745 SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName, 746 QualifiedNameNode *Name) { 747 if (MangledName.empty()) { 748 Error = true; 749 return nullptr; 750 } 751 752 // Read a variable. 753 switch (MangledName.front()) { 754 case '0': 755 case '1': 756 case '2': 757 case '3': 758 case '4': { 759 StorageClass SC = demangleVariableStorageClass(MangledName); 760 return demangleVariableEncoding(MangledName, SC); 761 } 762 } 763 FunctionSymbolNode *FSN = demangleFunctionEncoding(MangledName); 764 765 IdentifierNode *UQN = Name->getUnqualifiedIdentifier(); 766 if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) { 767 ConversionOperatorIdentifierNode *COIN = 768 static_cast<ConversionOperatorIdentifierNode *>(UQN); 769 if (FSN) 770 COIN->TargetType = FSN->Signature->ReturnType; 771 } 772 return FSN; 773 } 774 775 SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) { 776 // What follows is a main symbol name. This may include namespaces or class 777 // back references. 778 QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName); 779 if (Error) 780 return nullptr; 781 782 SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN); 783 if (Error) 784 return nullptr; 785 Symbol->Name = QN; 786 787 IdentifierNode *UQN = QN->getUnqualifiedIdentifier(); 788 if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) { 789 ConversionOperatorIdentifierNode *COIN = 790 static_cast<ConversionOperatorIdentifierNode *>(UQN); 791 if (!COIN->TargetType) { 792 Error = true; 793 return nullptr; 794 } 795 } 796 return Symbol; 797 } 798 799 SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) { 800 assert(llvm::itanium_demangle::starts_with(MangledName, "??@")); 801 // This is an MD5 mangled name. We can't demangle it, just return the 802 // mangled name. 803 // An MD5 mangled name is ??@ followed by 32 characters and a terminating @. 804 size_t MD5Last = MangledName.find('@', strlen("??@")); 805 if (MD5Last == std::string_view::npos) { 806 Error = true; 807 return nullptr; 808 } 809 const char *Start = MangledName.data(); 810 const size_t StartSize = MangledName.size(); 811 MangledName.remove_prefix(MD5Last + 1); 812 813 // There are two additional special cases for MD5 names: 814 // 1. For complete object locators where the object name is long enough 815 // for the object to have an MD5 name, the complete object locator is 816 // called ??@...@??_R4@ (with a trailing "??_R4@" instead of the usual 817 // leading "??_R4". This is handled here. 818 // 2. For catchable types, in versions of MSVC before 2015 (<1900) or after 819 // 2017.2 (>= 1914), the catchable type mangling is _CT??@...@??@...@8 820 // instead of_CT??@...@8 with just one MD5 name. Since we don't yet 821 // demangle catchable types anywhere, this isn't handled for MD5 names 822 // either. 823 consumeFront(MangledName, "??_R4@"); 824 825 assert(MangledName.size() < StartSize); 826 const size_t Count = StartSize - MangledName.size(); 827 std::string_view MD5(Start, Count); 828 SymbolNode *S = Arena.alloc<SymbolNode>(NodeKind::Md5Symbol); 829 S->Name = synthesizeQualifiedName(Arena, MD5); 830 831 return S; 832 } 833 834 SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) { 835 assert(llvm::itanium_demangle::starts_with(MangledName, '.')); 836 consumeFront(MangledName, '.'); 837 838 TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result); 839 if (Error || !MangledName.empty()) { 840 Error = true; 841 return nullptr; 842 } 843 return synthesizeVariable(Arena, T, "`RTTI Type Descriptor Name'"); 844 } 845 846 // Parser entry point. 847 SymbolNode *Demangler::parse(std::string_view &MangledName) { 848 // Typeinfo names are strings stored in RTTI data. They're not symbol names. 849 // It's still useful to demangle them. They're the only demangled entity 850 // that doesn't start with a "?" but a ".". 851 if (llvm::itanium_demangle::starts_with(MangledName, '.')) 852 return demangleTypeinfoName(MangledName); 853 854 if (llvm::itanium_demangle::starts_with(MangledName, "??@")) 855 return demangleMD5Name(MangledName); 856 857 // MSVC-style mangled symbols must start with '?'. 858 if (!llvm::itanium_demangle::starts_with(MangledName, '?')) { 859 Error = true; 860 return nullptr; 861 } 862 863 consumeFront(MangledName, '?'); 864 865 // ?$ is a template instantiation, but all other names that start with ? are 866 // operators / special names. 867 if (SymbolNode *SI = demangleSpecialIntrinsic(MangledName)) 868 return SI; 869 870 return demangleDeclarator(MangledName); 871 } 872 873 TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) { 874 if (!consumeFront(MangledName, ".?A")) { 875 Error = true; 876 return nullptr; 877 } 878 consumeFront(MangledName, ".?A"); 879 if (MangledName.empty()) { 880 Error = true; 881 return nullptr; 882 } 883 884 return demangleClassType(MangledName); 885 } 886 887 // <type-encoding> ::= <storage-class> <variable-type> 888 // <storage-class> ::= 0 # private static member 889 // ::= 1 # protected static member 890 // ::= 2 # public static member 891 // ::= 3 # global 892 // ::= 4 # static local 893 894 VariableSymbolNode * 895 Demangler::demangleVariableEncoding(std::string_view &MangledName, 896 StorageClass SC) { 897 VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>(); 898 899 VSN->Type = demangleType(MangledName, QualifierMangleMode::Drop); 900 VSN->SC = SC; 901 902 if (Error) 903 return nullptr; 904 905 // <variable-type> ::= <type> <cvr-qualifiers> 906 // ::= <type> <pointee-cvr-qualifiers> # pointers, references 907 switch (VSN->Type->kind()) { 908 case NodeKind::PointerType: { 909 PointerTypeNode *PTN = static_cast<PointerTypeNode *>(VSN->Type); 910 911 Qualifiers ExtraChildQuals = Q_None; 912 PTN->Quals = Qualifiers(VSN->Type->Quals | 913 demanglePointerExtQualifiers(MangledName)); 914 915 bool IsMember = false; 916 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName); 917 918 if (PTN->ClassParent) { 919 QualifiedNameNode *BackRefName = 920 demangleFullyQualifiedTypeName(MangledName); 921 (void)BackRefName; 922 } 923 PTN->Pointee->Quals = Qualifiers(PTN->Pointee->Quals | ExtraChildQuals); 924 925 break; 926 } 927 default: 928 VSN->Type->Quals = demangleQualifiers(MangledName).first; 929 break; 930 } 931 932 return VSN; 933 } 934 935 // Sometimes numbers are encoded in mangled symbols. For example, 936 // "int (*x)[20]" is a valid C type (x is a pointer to an array of 937 // length 20), so we need some way to embed numbers as part of symbols. 938 // This function parses it. 939 // 940 // <number> ::= [?] <non-negative integer> 941 // 942 // <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10 943 // ::= <hex digit>+ @ # when Number == 0 or >= 10 944 // 945 // <hex-digit> ::= [A-P] # A = 0, B = 1, ... 946 std::pair<uint64_t, bool> 947 Demangler::demangleNumber(std::string_view &MangledName) { 948 bool IsNegative = consumeFront(MangledName, '?'); 949 950 if (startsWithDigit(MangledName)) { 951 uint64_t Ret = MangledName[0] - '0' + 1; 952 MangledName.remove_prefix(1); 953 return {Ret, IsNegative}; 954 } 955 956 uint64_t Ret = 0; 957 for (size_t i = 0; i < MangledName.size(); ++i) { 958 char C = MangledName[i]; 959 if (C == '@') { 960 MangledName.remove_prefix(i + 1); 961 return {Ret, IsNegative}; 962 } 963 if ('A' <= C && C <= 'P') { 964 Ret = (Ret << 4) + (C - 'A'); 965 continue; 966 } 967 break; 968 } 969 970 Error = true; 971 return {0ULL, false}; 972 } 973 974 uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) { 975 bool IsNegative = false; 976 uint64_t Number = 0; 977 std::tie(Number, IsNegative) = demangleNumber(MangledName); 978 if (IsNegative) 979 Error = true; 980 return Number; 981 } 982 983 int64_t Demangler::demangleSigned(std::string_view &MangledName) { 984 bool IsNegative = false; 985 uint64_t Number = 0; 986 std::tie(Number, IsNegative) = demangleNumber(MangledName); 987 if (Number > INT64_MAX) 988 Error = true; 989 int64_t I = static_cast<int64_t>(Number); 990 return IsNegative ? -I : I; 991 } 992 993 // First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9. 994 // Memorize it. 995 void Demangler::memorizeString(std::string_view S) { 996 if (Backrefs.NamesCount >= BackrefContext::Max) 997 return; 998 for (size_t i = 0; i < Backrefs.NamesCount; ++i) 999 if (S == Backrefs.Names[i]->Name) 1000 return; 1001 NamedIdentifierNode *N = Arena.alloc<NamedIdentifierNode>(); 1002 N->Name = S; 1003 Backrefs.Names[Backrefs.NamesCount++] = N; 1004 } 1005 1006 NamedIdentifierNode * 1007 Demangler::demangleBackRefName(std::string_view &MangledName) { 1008 assert(startsWithDigit(MangledName)); 1009 1010 size_t I = MangledName[0] - '0'; 1011 if (I >= Backrefs.NamesCount) { 1012 Error = true; 1013 return nullptr; 1014 } 1015 1016 MangledName.remove_prefix(1); 1017 return Backrefs.Names[I]; 1018 } 1019 1020 void Demangler::memorizeIdentifier(IdentifierNode *Identifier) { 1021 // Render this class template name into a string buffer so that we can 1022 // memorize it for the purpose of back-referencing. 1023 OutputBuffer OB; 1024 Identifier->output(OB, OF_Default); 1025 std::string_view Owned = copyString(OB); 1026 memorizeString(Owned); 1027 std::free(OB.getBuffer()); 1028 } 1029 1030 IdentifierNode * 1031 Demangler::demangleTemplateInstantiationName(std::string_view &MangledName, 1032 NameBackrefBehavior NBB) { 1033 assert(llvm::itanium_demangle::starts_with(MangledName, "?$")); 1034 consumeFront(MangledName, "?$"); 1035 1036 BackrefContext OuterContext; 1037 std::swap(OuterContext, Backrefs); 1038 1039 IdentifierNode *Identifier = 1040 demangleUnqualifiedSymbolName(MangledName, NBB_Simple); 1041 if (!Error) 1042 Identifier->TemplateParams = demangleTemplateParameterList(MangledName); 1043 1044 std::swap(OuterContext, Backrefs); 1045 if (Error) 1046 return nullptr; 1047 1048 if (NBB & NBB_Template) { 1049 // NBB_Template is only set for types and non-leaf names ("a::" in "a::b"). 1050 // Structors and conversion operators only makes sense in a leaf name, so 1051 // reject them in NBB_Template contexts. 1052 if (Identifier->kind() == NodeKind::ConversionOperatorIdentifier || 1053 Identifier->kind() == NodeKind::StructorIdentifier) { 1054 Error = true; 1055 return nullptr; 1056 } 1057 1058 memorizeIdentifier(Identifier); 1059 } 1060 1061 return Identifier; 1062 } 1063 1064 NamedIdentifierNode * 1065 Demangler::demangleSimpleName(std::string_view &MangledName, bool Memorize) { 1066 std::string_view S = demangleSimpleString(MangledName, Memorize); 1067 if (Error) 1068 return nullptr; 1069 1070 NamedIdentifierNode *Name = Arena.alloc<NamedIdentifierNode>(); 1071 Name->Name = S; 1072 return Name; 1073 } 1074 1075 static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); } 1076 1077 static uint8_t rebasedHexDigitToNumber(char C) { 1078 assert(isRebasedHexDigit(C)); 1079 return (C <= 'J') ? (C - 'A') : (10 + C - 'K'); 1080 } 1081 1082 uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) { 1083 assert(!MangledName.empty()); 1084 if (!llvm::itanium_demangle::starts_with(MangledName, '?')) { 1085 const uint8_t F = MangledName.front(); 1086 MangledName.remove_prefix(1); 1087 return F; 1088 } 1089 1090 MangledName.remove_prefix(1); 1091 if (MangledName.empty()) 1092 goto CharLiteralError; 1093 1094 if (consumeFront(MangledName, '$')) { 1095 // Two hex digits 1096 if (MangledName.size() < 2) 1097 goto CharLiteralError; 1098 std::string_view Nibbles = MangledName.substr(0, 2); 1099 if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1])) 1100 goto CharLiteralError; 1101 // Don't append the null terminator. 1102 uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]); 1103 uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]); 1104 MangledName.remove_prefix(2); 1105 return (C1 << 4) | C2; 1106 } 1107 1108 if (startsWithDigit(MangledName)) { 1109 const char *Lookup = ",/\\:. \n\t'-"; 1110 char C = Lookup[MangledName[0] - '0']; 1111 MangledName.remove_prefix(1); 1112 return C; 1113 } 1114 1115 if (MangledName[0] >= 'a' && MangledName[0] <= 'z') { 1116 char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7', 1117 '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', 1118 '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', 1119 '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'}; 1120 char C = Lookup[MangledName[0] - 'a']; 1121 MangledName.remove_prefix(1); 1122 return C; 1123 } 1124 1125 if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') { 1126 char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7', 1127 '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', 1128 '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', 1129 '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'}; 1130 char C = Lookup[MangledName[0] - 'A']; 1131 MangledName.remove_prefix(1); 1132 return C; 1133 } 1134 1135 CharLiteralError: 1136 Error = true; 1137 return '\0'; 1138 } 1139 1140 wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) { 1141 uint8_t C1, C2; 1142 1143 C1 = demangleCharLiteral(MangledName); 1144 if (Error || MangledName.empty()) 1145 goto WCharLiteralError; 1146 C2 = demangleCharLiteral(MangledName); 1147 if (Error) 1148 goto WCharLiteralError; 1149 1150 return ((wchar_t)C1 << 8) | (wchar_t)C2; 1151 1152 WCharLiteralError: 1153 Error = true; 1154 return L'\0'; 1155 } 1156 1157 static void writeHexDigit(char *Buffer, uint8_t Digit) { 1158 assert(Digit <= 15); 1159 *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10); 1160 } 1161 1162 static void outputHex(OutputBuffer &OB, unsigned C) { 1163 assert (C != 0); 1164 1165 // It's easier to do the math if we can work from right to left, but we need 1166 // to print the numbers from left to right. So render this into a temporary 1167 // buffer first, then output the temporary buffer. Each byte is of the form 1168 // \xAB, which means that each byte needs 4 characters. Since there are at 1169 // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer. 1170 char TempBuffer[17]; 1171 1172 ::memset(TempBuffer, 0, sizeof(TempBuffer)); 1173 constexpr int MaxPos = sizeof(TempBuffer) - 1; 1174 1175 int Pos = MaxPos - 1; // TempBuffer[MaxPos] is the terminating \0. 1176 while (C != 0) { 1177 for (int I = 0; I < 2; ++I) { 1178 writeHexDigit(&TempBuffer[Pos--], C % 16); 1179 C /= 16; 1180 } 1181 } 1182 TempBuffer[Pos--] = 'x'; 1183 assert(Pos >= 0); 1184 TempBuffer[Pos--] = '\\'; 1185 OB << std::string_view(&TempBuffer[Pos + 1]); 1186 } 1187 1188 static void outputEscapedChar(OutputBuffer &OB, unsigned C) { 1189 switch (C) { 1190 case '\0': // nul 1191 OB << "\\0"; 1192 return; 1193 case '\'': // single quote 1194 OB << "\\\'"; 1195 return; 1196 case '\"': // double quote 1197 OB << "\\\""; 1198 return; 1199 case '\\': // backslash 1200 OB << "\\\\"; 1201 return; 1202 case '\a': // bell 1203 OB << "\\a"; 1204 return; 1205 case '\b': // backspace 1206 OB << "\\b"; 1207 return; 1208 case '\f': // form feed 1209 OB << "\\f"; 1210 return; 1211 case '\n': // new line 1212 OB << "\\n"; 1213 return; 1214 case '\r': // carriage return 1215 OB << "\\r"; 1216 return; 1217 case '\t': // tab 1218 OB << "\\t"; 1219 return; 1220 case '\v': // vertical tab 1221 OB << "\\v"; 1222 return; 1223 default: 1224 break; 1225 } 1226 1227 if (C > 0x1F && C < 0x7F) { 1228 // Standard ascii char. 1229 OB << (char)C; 1230 return; 1231 } 1232 1233 outputHex(OB, C); 1234 } 1235 1236 static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) { 1237 const uint8_t *End = StringBytes + Length - 1; 1238 unsigned Count = 0; 1239 while (Length > 0 && *End == 0) { 1240 --Length; 1241 --End; 1242 ++Count; 1243 } 1244 return Count; 1245 } 1246 1247 static unsigned countEmbeddedNulls(const uint8_t *StringBytes, 1248 unsigned Length) { 1249 unsigned Result = 0; 1250 for (unsigned I = 0; I < Length; ++I) { 1251 if (*StringBytes++ == 0) 1252 ++Result; 1253 } 1254 return Result; 1255 } 1256 1257 // A mangled (non-wide) string literal stores the total length of the string it 1258 // refers to (passed in NumBytes), and it contains up to 32 bytes of actual text 1259 // (passed in StringBytes, NumChars). 1260 static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars, 1261 uint64_t NumBytes) { 1262 assert(NumBytes > 0); 1263 1264 // If the number of bytes is odd, this is guaranteed to be a char string. 1265 if (NumBytes % 2 == 1) 1266 return 1; 1267 1268 // All strings can encode at most 32 bytes of data. If it's less than that, 1269 // then we encoded the entire string. In this case we check for a 1-byte, 1270 // 2-byte, or 4-byte null terminator. 1271 if (NumBytes < 32) { 1272 unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars); 1273 if (TrailingNulls >= 4 && NumBytes % 4 == 0) 1274 return 4; 1275 if (TrailingNulls >= 2) 1276 return 2; 1277 return 1; 1278 } 1279 1280 // The whole string was not able to be encoded. Try to look at embedded null 1281 // terminators to guess. The heuristic is that we count all embedded null 1282 // terminators. If more than 2/3 are null, it's a char32. If more than 1/3 1283 // are null, it's a char16. Otherwise it's a char8. This obviously isn't 1284 // perfect and is biased towards languages that have ascii alphabets, but this 1285 // was always going to be best effort since the encoding is lossy. 1286 unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars); 1287 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0) 1288 return 4; 1289 if (Nulls >= NumChars / 3) 1290 return 2; 1291 return 1; 1292 } 1293 1294 static unsigned decodeMultiByteChar(const uint8_t *StringBytes, 1295 unsigned CharIndex, unsigned CharBytes) { 1296 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4); 1297 unsigned Offset = CharIndex * CharBytes; 1298 unsigned Result = 0; 1299 StringBytes = StringBytes + Offset; 1300 for (unsigned I = 0; I < CharBytes; ++I) { 1301 unsigned C = static_cast<unsigned>(StringBytes[I]); 1302 Result |= C << (8 * I); 1303 } 1304 return Result; 1305 } 1306 1307 FunctionSymbolNode * 1308 Demangler::demangleVcallThunkNode(std::string_view &MangledName) { 1309 FunctionSymbolNode *FSN = Arena.alloc<FunctionSymbolNode>(); 1310 VcallThunkIdentifierNode *VTIN = Arena.alloc<VcallThunkIdentifierNode>(); 1311 FSN->Signature = Arena.alloc<ThunkSignatureNode>(); 1312 FSN->Signature->FunctionClass = FC_NoParameterList; 1313 1314 FSN->Name = demangleNameScopeChain(MangledName, VTIN); 1315 if (!Error) 1316 Error = !consumeFront(MangledName, "$B"); 1317 if (!Error) 1318 VTIN->OffsetInVTable = demangleUnsigned(MangledName); 1319 if (!Error) 1320 Error = !consumeFront(MangledName, 'A'); 1321 if (!Error) 1322 FSN->Signature->CallConvention = demangleCallingConvention(MangledName); 1323 return (Error) ? nullptr : FSN; 1324 } 1325 1326 EncodedStringLiteralNode * 1327 Demangler::demangleStringLiteral(std::string_view &MangledName) { 1328 // This function uses goto, so declare all variables up front. 1329 OutputBuffer OB; 1330 std::string_view CRC; 1331 uint64_t StringByteSize; 1332 bool IsWcharT = false; 1333 bool IsNegative = false; 1334 size_t CrcEndPos = 0; 1335 char F; 1336 1337 EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>(); 1338 1339 // Prefix indicating the beginning of a string literal 1340 if (!consumeFront(MangledName, "@_")) 1341 goto StringLiteralError; 1342 if (MangledName.empty()) 1343 goto StringLiteralError; 1344 1345 // Char Type (regular or wchar_t) 1346 F = MangledName.front(); 1347 MangledName.remove_prefix(1); 1348 switch (F) { 1349 case '1': 1350 IsWcharT = true; 1351 DEMANGLE_FALLTHROUGH; 1352 case '0': 1353 break; 1354 default: 1355 goto StringLiteralError; 1356 } 1357 1358 // Encoded Length 1359 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName); 1360 if (Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1)) 1361 goto StringLiteralError; 1362 1363 // CRC 32 (always 8 characters plus a terminator) 1364 CrcEndPos = MangledName.find('@'); 1365 if (CrcEndPos == std::string_view::npos) 1366 goto StringLiteralError; 1367 CRC = MangledName.substr(0, CrcEndPos); 1368 MangledName.remove_prefix(CrcEndPos + 1); 1369 if (MangledName.empty()) 1370 goto StringLiteralError; 1371 1372 if (IsWcharT) { 1373 Result->Char = CharKind::Wchar; 1374 if (StringByteSize > 64) 1375 Result->IsTruncated = true; 1376 1377 while (!consumeFront(MangledName, '@')) { 1378 // For a wide string StringByteSize has to have an even length. 1379 if (StringByteSize % 2 != 0) 1380 goto StringLiteralError; 1381 if (StringByteSize == 0) 1382 goto StringLiteralError; 1383 if (MangledName.size() < 2) 1384 goto StringLiteralError; 1385 wchar_t W = demangleWcharLiteral(MangledName); 1386 if (StringByteSize != 2 || Result->IsTruncated) 1387 outputEscapedChar(OB, W); 1388 StringByteSize -= 2; 1389 if (Error) 1390 goto StringLiteralError; 1391 } 1392 } else { 1393 // The max byte length is actually 32, but some compilers mangled strings 1394 // incorrectly, so we have to assume it can go higher. 1395 constexpr unsigned MaxStringByteLength = 32 * 4; 1396 uint8_t StringBytes[MaxStringByteLength]; 1397 1398 unsigned BytesDecoded = 0; 1399 while (!consumeFront(MangledName, '@')) { 1400 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength) 1401 goto StringLiteralError; 1402 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName); 1403 } 1404 1405 if (StringByteSize > BytesDecoded) 1406 Result->IsTruncated = true; 1407 1408 unsigned CharBytes = 1409 guessCharByteSize(StringBytes, BytesDecoded, StringByteSize); 1410 assert(StringByteSize % CharBytes == 0); 1411 switch (CharBytes) { 1412 case 1: 1413 Result->Char = CharKind::Char; 1414 break; 1415 case 2: 1416 Result->Char = CharKind::Char16; 1417 break; 1418 case 4: 1419 Result->Char = CharKind::Char32; 1420 break; 1421 default: 1422 DEMANGLE_UNREACHABLE; 1423 } 1424 const unsigned NumChars = BytesDecoded / CharBytes; 1425 for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) { 1426 unsigned NextChar = 1427 decodeMultiByteChar(StringBytes, CharIndex, CharBytes); 1428 if (CharIndex + 1 < NumChars || Result->IsTruncated) 1429 outputEscapedChar(OB, NextChar); 1430 } 1431 } 1432 1433 Result->DecodedString = copyString(OB); 1434 std::free(OB.getBuffer()); 1435 return Result; 1436 1437 StringLiteralError: 1438 Error = true; 1439 std::free(OB.getBuffer()); 1440 return nullptr; 1441 } 1442 1443 // Returns MangledName's prefix before the first '@', or an error if 1444 // MangledName contains no '@' or the prefix has length 0. 1445 std::string_view Demangler::demangleSimpleString(std::string_view &MangledName, 1446 bool Memorize) { 1447 std::string_view S; 1448 for (size_t i = 0; i < MangledName.size(); ++i) { 1449 if (MangledName[i] != '@') 1450 continue; 1451 if (i == 0) 1452 break; 1453 S = MangledName.substr(0, i); 1454 MangledName.remove_prefix(i + 1); 1455 1456 if (Memorize) 1457 memorizeString(S); 1458 return S; 1459 } 1460 1461 Error = true; 1462 return {}; 1463 } 1464 1465 NamedIdentifierNode * 1466 Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) { 1467 assert(llvm::itanium_demangle::starts_with(MangledName, "?A")); 1468 consumeFront(MangledName, "?A"); 1469 1470 NamedIdentifierNode *Node = Arena.alloc<NamedIdentifierNode>(); 1471 Node->Name = "`anonymous namespace'"; 1472 size_t EndPos = MangledName.find('@'); 1473 if (EndPos == std::string_view::npos) { 1474 Error = true; 1475 return nullptr; 1476 } 1477 std::string_view NamespaceKey = MangledName.substr(0, EndPos); 1478 memorizeString(NamespaceKey); 1479 MangledName = MangledName.substr(EndPos + 1); 1480 return Node; 1481 } 1482 1483 NamedIdentifierNode * 1484 Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) { 1485 assert(startsWithLocalScopePattern(MangledName)); 1486 1487 NamedIdentifierNode *Identifier = Arena.alloc<NamedIdentifierNode>(); 1488 consumeFront(MangledName, '?'); 1489 uint64_t Number = 0; 1490 bool IsNegative = false; 1491 std::tie(Number, IsNegative) = demangleNumber(MangledName); 1492 assert(!IsNegative); 1493 1494 // One ? to terminate the number 1495 consumeFront(MangledName, '?'); 1496 1497 assert(!Error); 1498 Node *Scope = parse(MangledName); 1499 if (Error) 1500 return nullptr; 1501 1502 // Render the parent symbol's name into a buffer. 1503 OutputBuffer OB; 1504 OB << '`'; 1505 Scope->output(OB, OF_Default); 1506 OB << '\''; 1507 OB << "::`" << Number << "'"; 1508 1509 Identifier->Name = copyString(OB); 1510 std::free(OB.getBuffer()); 1511 return Identifier; 1512 } 1513 1514 // Parses a type name in the form of A@B@C@@ which represents C::B::A. 1515 QualifiedNameNode * 1516 Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) { 1517 IdentifierNode *Identifier = 1518 demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true); 1519 if (Error) 1520 return nullptr; 1521 assert(Identifier); 1522 1523 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier); 1524 if (Error) 1525 return nullptr; 1526 assert(QN); 1527 return QN; 1528 } 1529 1530 // Parses a symbol name in the form of A@B@C@@ which represents C::B::A. 1531 // Symbol names have slightly different rules regarding what can appear 1532 // so we separate out the implementations for flexibility. 1533 QualifiedNameNode * 1534 Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) { 1535 // This is the final component of a symbol name (i.e. the leftmost component 1536 // of a mangled name. Since the only possible template instantiation that 1537 // can appear in this context is a function template, and since those are 1538 // not saved for the purposes of name backreferences, only backref simple 1539 // names. 1540 IdentifierNode *Identifier = 1541 demangleUnqualifiedSymbolName(MangledName, NBB_Simple); 1542 if (Error) 1543 return nullptr; 1544 1545 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier); 1546 if (Error) 1547 return nullptr; 1548 1549 if (Identifier->kind() == NodeKind::StructorIdentifier) { 1550 if (QN->Components->Count < 2) { 1551 Error = true; 1552 return nullptr; 1553 } 1554 StructorIdentifierNode *SIN = 1555 static_cast<StructorIdentifierNode *>(Identifier); 1556 Node *ClassNode = QN->Components->Nodes[QN->Components->Count - 2]; 1557 SIN->Class = static_cast<IdentifierNode *>(ClassNode); 1558 } 1559 assert(QN); 1560 return QN; 1561 } 1562 1563 IdentifierNode * 1564 Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName, 1565 bool Memorize) { 1566 // An inner-most name can be a back-reference, because a fully-qualified name 1567 // (e.g. Scope + Inner) can contain other fully qualified names inside of 1568 // them (for example template parameters), and these nested parameters can 1569 // refer to previously mangled types. 1570 if (startsWithDigit(MangledName)) 1571 return demangleBackRefName(MangledName); 1572 1573 if (llvm::itanium_demangle::starts_with(MangledName, "?$")) 1574 return demangleTemplateInstantiationName(MangledName, NBB_Template); 1575 1576 return demangleSimpleName(MangledName, Memorize); 1577 } 1578 1579 IdentifierNode * 1580 Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName, 1581 NameBackrefBehavior NBB) { 1582 if (startsWithDigit(MangledName)) 1583 return demangleBackRefName(MangledName); 1584 if (llvm::itanium_demangle::starts_with(MangledName, "?$")) 1585 return demangleTemplateInstantiationName(MangledName, NBB); 1586 if (llvm::itanium_demangle::starts_with(MangledName, '?')) 1587 return demangleFunctionIdentifierCode(MangledName); 1588 return demangleSimpleName(MangledName, /*Memorize=*/(NBB & NBB_Simple) != 0); 1589 } 1590 1591 IdentifierNode * 1592 Demangler::demangleNameScopePiece(std::string_view &MangledName) { 1593 if (startsWithDigit(MangledName)) 1594 return demangleBackRefName(MangledName); 1595 1596 if (llvm::itanium_demangle::starts_with(MangledName, "?$")) 1597 return demangleTemplateInstantiationName(MangledName, NBB_Template); 1598 1599 if (llvm::itanium_demangle::starts_with(MangledName, "?A")) 1600 return demangleAnonymousNamespaceName(MangledName); 1601 1602 if (startsWithLocalScopePattern(MangledName)) 1603 return demangleLocallyScopedNamePiece(MangledName); 1604 1605 return demangleSimpleName(MangledName, /*Memorize=*/true); 1606 } 1607 1608 static NodeArrayNode *nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head, 1609 size_t Count) { 1610 NodeArrayNode *N = Arena.alloc<NodeArrayNode>(); 1611 N->Count = Count; 1612 N->Nodes = Arena.allocArray<Node *>(Count); 1613 for (size_t I = 0; I < Count; ++I) { 1614 N->Nodes[I] = Head->N; 1615 Head = Head->Next; 1616 } 1617 return N; 1618 } 1619 1620 QualifiedNameNode * 1621 Demangler::demangleNameScopeChain(std::string_view &MangledName, 1622 IdentifierNode *UnqualifiedName) { 1623 NodeList *Head = Arena.alloc<NodeList>(); 1624 1625 Head->N = UnqualifiedName; 1626 1627 size_t Count = 1; 1628 while (!consumeFront(MangledName, "@")) { 1629 ++Count; 1630 NodeList *NewHead = Arena.alloc<NodeList>(); 1631 NewHead->Next = Head; 1632 Head = NewHead; 1633 1634 if (MangledName.empty()) { 1635 Error = true; 1636 return nullptr; 1637 } 1638 1639 assert(!Error); 1640 IdentifierNode *Elem = demangleNameScopePiece(MangledName); 1641 if (Error) 1642 return nullptr; 1643 1644 Head->N = Elem; 1645 } 1646 1647 QualifiedNameNode *QN = Arena.alloc<QualifiedNameNode>(); 1648 QN->Components = nodeListToNodeArray(Arena, Head, Count); 1649 return QN; 1650 } 1651 1652 FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) { 1653 const char F = MangledName.front(); 1654 MangledName.remove_prefix(1); 1655 switch (F) { 1656 case '9': 1657 return FuncClass(FC_ExternC | FC_NoParameterList); 1658 case 'A': 1659 return FC_Private; 1660 case 'B': 1661 return FuncClass(FC_Private | FC_Far); 1662 case 'C': 1663 return FuncClass(FC_Private | FC_Static); 1664 case 'D': 1665 return FuncClass(FC_Private | FC_Static | FC_Far); 1666 case 'E': 1667 return FuncClass(FC_Private | FC_Virtual); 1668 case 'F': 1669 return FuncClass(FC_Private | FC_Virtual | FC_Far); 1670 case 'G': 1671 return FuncClass(FC_Private | FC_StaticThisAdjust); 1672 case 'H': 1673 return FuncClass(FC_Private | FC_StaticThisAdjust | FC_Far); 1674 case 'I': 1675 return FuncClass(FC_Protected); 1676 case 'J': 1677 return FuncClass(FC_Protected | FC_Far); 1678 case 'K': 1679 return FuncClass(FC_Protected | FC_Static); 1680 case 'L': 1681 return FuncClass(FC_Protected | FC_Static | FC_Far); 1682 case 'M': 1683 return FuncClass(FC_Protected | FC_Virtual); 1684 case 'N': 1685 return FuncClass(FC_Protected | FC_Virtual | FC_Far); 1686 case 'O': 1687 return FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust); 1688 case 'P': 1689 return FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust | FC_Far); 1690 case 'Q': 1691 return FuncClass(FC_Public); 1692 case 'R': 1693 return FuncClass(FC_Public | FC_Far); 1694 case 'S': 1695 return FuncClass(FC_Public | FC_Static); 1696 case 'T': 1697 return FuncClass(FC_Public | FC_Static | FC_Far); 1698 case 'U': 1699 return FuncClass(FC_Public | FC_Virtual); 1700 case 'V': 1701 return FuncClass(FC_Public | FC_Virtual | FC_Far); 1702 case 'W': 1703 return FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust); 1704 case 'X': 1705 return FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust | FC_Far); 1706 case 'Y': 1707 return FuncClass(FC_Global); 1708 case 'Z': 1709 return FuncClass(FC_Global | FC_Far); 1710 case '$': { 1711 FuncClass VFlag = FC_VirtualThisAdjust; 1712 if (consumeFront(MangledName, 'R')) 1713 VFlag = FuncClass(VFlag | FC_VirtualThisAdjustEx); 1714 if (MangledName.empty()) 1715 break; 1716 const char F = MangledName.front(); 1717 MangledName.remove_prefix(1); 1718 switch (F) { 1719 case '0': 1720 return FuncClass(FC_Private | FC_Virtual | VFlag); 1721 case '1': 1722 return FuncClass(FC_Private | FC_Virtual | VFlag | FC_Far); 1723 case '2': 1724 return FuncClass(FC_Protected | FC_Virtual | VFlag); 1725 case '3': 1726 return FuncClass(FC_Protected | FC_Virtual | VFlag | FC_Far); 1727 case '4': 1728 return FuncClass(FC_Public | FC_Virtual | VFlag); 1729 case '5': 1730 return FuncClass(FC_Public | FC_Virtual | VFlag | FC_Far); 1731 } 1732 } 1733 } 1734 1735 Error = true; 1736 return FC_Public; 1737 } 1738 1739 CallingConv 1740 Demangler::demangleCallingConvention(std::string_view &MangledName) { 1741 if (MangledName.empty()) { 1742 Error = true; 1743 return CallingConv::None; 1744 } 1745 1746 const char F = MangledName.front(); 1747 MangledName.remove_prefix(1); 1748 switch (F) { 1749 case 'A': 1750 case 'B': 1751 return CallingConv::Cdecl; 1752 case 'C': 1753 case 'D': 1754 return CallingConv::Pascal; 1755 case 'E': 1756 case 'F': 1757 return CallingConv::Thiscall; 1758 case 'G': 1759 case 'H': 1760 return CallingConv::Stdcall; 1761 case 'I': 1762 case 'J': 1763 return CallingConv::Fastcall; 1764 case 'M': 1765 case 'N': 1766 return CallingConv::Clrcall; 1767 case 'O': 1768 case 'P': 1769 return CallingConv::Eabi; 1770 case 'Q': 1771 return CallingConv::Vectorcall; 1772 case 'S': 1773 return CallingConv::Swift; 1774 case 'W': 1775 return CallingConv::SwiftAsync; 1776 } 1777 1778 return CallingConv::None; 1779 } 1780 1781 StorageClass 1782 Demangler::demangleVariableStorageClass(std::string_view &MangledName) { 1783 assert(MangledName.front() >= '0' && MangledName.front() <= '4'); 1784 1785 const char F = MangledName.front(); 1786 MangledName.remove_prefix(1); 1787 switch (F) { 1788 case '0': 1789 return StorageClass::PrivateStatic; 1790 case '1': 1791 return StorageClass::ProtectedStatic; 1792 case '2': 1793 return StorageClass::PublicStatic; 1794 case '3': 1795 return StorageClass::Global; 1796 case '4': 1797 return StorageClass::FunctionLocalStatic; 1798 } 1799 DEMANGLE_UNREACHABLE; 1800 } 1801 1802 std::pair<Qualifiers, bool> 1803 Demangler::demangleQualifiers(std::string_view &MangledName) { 1804 if (MangledName.empty()) { 1805 Error = true; 1806 return std::make_pair(Q_None, false); 1807 } 1808 1809 const char F = MangledName.front(); 1810 MangledName.remove_prefix(1); 1811 switch (F) { 1812 // Member qualifiers 1813 case 'Q': 1814 return std::make_pair(Q_None, true); 1815 case 'R': 1816 return std::make_pair(Q_Const, true); 1817 case 'S': 1818 return std::make_pair(Q_Volatile, true); 1819 case 'T': 1820 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true); 1821 // Non-Member qualifiers 1822 case 'A': 1823 return std::make_pair(Q_None, false); 1824 case 'B': 1825 return std::make_pair(Q_Const, false); 1826 case 'C': 1827 return std::make_pair(Q_Volatile, false); 1828 case 'D': 1829 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false); 1830 } 1831 Error = true; 1832 return std::make_pair(Q_None, false); 1833 } 1834 1835 // <variable-type> ::= <type> <cvr-qualifiers> 1836 // ::= <type> <pointee-cvr-qualifiers> # pointers, references 1837 TypeNode *Demangler::demangleType(std::string_view &MangledName, 1838 QualifierMangleMode QMM) { 1839 Qualifiers Quals = Q_None; 1840 bool IsMember = false; 1841 if (QMM == QualifierMangleMode::Mangle) { 1842 std::tie(Quals, IsMember) = demangleQualifiers(MangledName); 1843 } else if (QMM == QualifierMangleMode::Result) { 1844 if (consumeFront(MangledName, '?')) 1845 std::tie(Quals, IsMember) = demangleQualifiers(MangledName); 1846 } 1847 1848 if (MangledName.empty()) { 1849 Error = true; 1850 return nullptr; 1851 } 1852 1853 TypeNode *Ty = nullptr; 1854 if (isTagType(MangledName)) 1855 Ty = demangleClassType(MangledName); 1856 else if (isPointerType(MangledName)) { 1857 if (isMemberPointer(MangledName, Error)) 1858 Ty = demangleMemberPointerType(MangledName); 1859 else if (!Error) 1860 Ty = demanglePointerType(MangledName); 1861 else 1862 return nullptr; 1863 } else if (isArrayType(MangledName)) 1864 Ty = demangleArrayType(MangledName); 1865 else if (isFunctionType(MangledName)) { 1866 if (consumeFront(MangledName, "$$A8@@")) 1867 Ty = demangleFunctionType(MangledName, true); 1868 else { 1869 assert(llvm::itanium_demangle::starts_with(MangledName, "$$A6")); 1870 consumeFront(MangledName, "$$A6"); 1871 Ty = demangleFunctionType(MangledName, false); 1872 } 1873 } else if (isCustomType(MangledName)) { 1874 Ty = demangleCustomType(MangledName); 1875 } else { 1876 Ty = demanglePrimitiveType(MangledName); 1877 } 1878 1879 if (!Ty || Error) 1880 return Ty; 1881 Ty->Quals = Qualifiers(Ty->Quals | Quals); 1882 return Ty; 1883 } 1884 1885 bool Demangler::demangleThrowSpecification(std::string_view &MangledName) { 1886 if (consumeFront(MangledName, "_E")) 1887 return true; 1888 if (consumeFront(MangledName, 'Z')) 1889 return false; 1890 1891 Error = true; 1892 return false; 1893 } 1894 1895 FunctionSignatureNode * 1896 Demangler::demangleFunctionType(std::string_view &MangledName, 1897 bool HasThisQuals) { 1898 FunctionSignatureNode *FTy = Arena.alloc<FunctionSignatureNode>(); 1899 1900 if (HasThisQuals) { 1901 FTy->Quals = demanglePointerExtQualifiers(MangledName); 1902 FTy->RefQualifier = demangleFunctionRefQualifier(MangledName); 1903 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first); 1904 } 1905 1906 // Fields that appear on both member and non-member functions. 1907 FTy->CallConvention = demangleCallingConvention(MangledName); 1908 1909 // <return-type> ::= <type> 1910 // ::= @ # structors (they have no declared return type) 1911 bool IsStructor = consumeFront(MangledName, '@'); 1912 if (!IsStructor) 1913 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result); 1914 1915 FTy->Params = demangleFunctionParameterList(MangledName, FTy->IsVariadic); 1916 1917 FTy->IsNoexcept = demangleThrowSpecification(MangledName); 1918 1919 return FTy; 1920 } 1921 1922 FunctionSymbolNode * 1923 Demangler::demangleFunctionEncoding(std::string_view &MangledName) { 1924 FuncClass ExtraFlags = FC_None; 1925 if (consumeFront(MangledName, "$$J0")) 1926 ExtraFlags = FC_ExternC; 1927 1928 if (MangledName.empty()) { 1929 Error = true; 1930 return nullptr; 1931 } 1932 1933 FuncClass FC = demangleFunctionClass(MangledName); 1934 FC = FuncClass(ExtraFlags | FC); 1935 1936 FunctionSignatureNode *FSN = nullptr; 1937 ThunkSignatureNode *TTN = nullptr; 1938 if (FC & FC_StaticThisAdjust) { 1939 TTN = Arena.alloc<ThunkSignatureNode>(); 1940 TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName); 1941 } else if (FC & FC_VirtualThisAdjust) { 1942 TTN = Arena.alloc<ThunkSignatureNode>(); 1943 if (FC & FC_VirtualThisAdjustEx) { 1944 TTN->ThisAdjust.VBPtrOffset = demangleSigned(MangledName); 1945 TTN->ThisAdjust.VBOffsetOffset = demangleSigned(MangledName); 1946 } 1947 TTN->ThisAdjust.VtordispOffset = demangleSigned(MangledName); 1948 TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName); 1949 } 1950 1951 if (FC & FC_NoParameterList) { 1952 // This is an extern "C" function whose full signature hasn't been mangled. 1953 // This happens when we need to mangle a local symbol inside of an extern 1954 // "C" function. 1955 FSN = Arena.alloc<FunctionSignatureNode>(); 1956 } else { 1957 bool HasThisQuals = !(FC & (FC_Global | FC_Static)); 1958 FSN = demangleFunctionType(MangledName, HasThisQuals); 1959 } 1960 1961 if (Error) 1962 return nullptr; 1963 1964 if (TTN) { 1965 *static_cast<FunctionSignatureNode *>(TTN) = *FSN; 1966 FSN = TTN; 1967 } 1968 FSN->FunctionClass = FC; 1969 1970 FunctionSymbolNode *Symbol = Arena.alloc<FunctionSymbolNode>(); 1971 Symbol->Signature = FSN; 1972 return Symbol; 1973 } 1974 1975 CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) { 1976 assert(llvm::itanium_demangle::starts_with(MangledName, '?')); 1977 MangledName.remove_prefix(1); 1978 1979 CustomTypeNode *CTN = Arena.alloc<CustomTypeNode>(); 1980 CTN->Identifier = demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true); 1981 if (!consumeFront(MangledName, '@')) 1982 Error = true; 1983 if (Error) 1984 return nullptr; 1985 return CTN; 1986 } 1987 1988 // Reads a primitive type. 1989 PrimitiveTypeNode * 1990 Demangler::demanglePrimitiveType(std::string_view &MangledName) { 1991 if (consumeFront(MangledName, "$$T")) 1992 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Nullptr); 1993 1994 const char F = MangledName.front(); 1995 MangledName.remove_prefix(1); 1996 switch (F) { 1997 case 'X': 1998 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Void); 1999 case 'D': 2000 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char); 2001 case 'C': 2002 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Schar); 2003 case 'E': 2004 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uchar); 2005 case 'F': 2006 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Short); 2007 case 'G': 2008 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ushort); 2009 case 'H': 2010 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Int); 2011 case 'I': 2012 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint); 2013 case 'J': 2014 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Long); 2015 case 'K': 2016 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ulong); 2017 case 'M': 2018 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Float); 2019 case 'N': 2020 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Double); 2021 case 'O': 2022 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ldouble); 2023 case '_': { 2024 if (MangledName.empty()) { 2025 Error = true; 2026 return nullptr; 2027 } 2028 const char F = MangledName.front(); 2029 MangledName.remove_prefix(1); 2030 switch (F) { 2031 case 'N': 2032 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Bool); 2033 case 'J': 2034 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Int64); 2035 case 'K': 2036 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint64); 2037 case 'W': 2038 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Wchar); 2039 case 'Q': 2040 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char8); 2041 case 'S': 2042 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char16); 2043 case 'U': 2044 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char32); 2045 case 'P': 2046 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Auto); 2047 case 'T': 2048 return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::DecltypeAuto); 2049 } 2050 break; 2051 } 2052 } 2053 Error = true; 2054 return nullptr; 2055 } 2056 2057 TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) { 2058 TagTypeNode *TT = nullptr; 2059 2060 const char F = MangledName.front(); 2061 MangledName.remove_prefix(1); 2062 switch (F) { 2063 case 'T': 2064 TT = Arena.alloc<TagTypeNode>(TagKind::Union); 2065 break; 2066 case 'U': 2067 TT = Arena.alloc<TagTypeNode>(TagKind::Struct); 2068 break; 2069 case 'V': 2070 TT = Arena.alloc<TagTypeNode>(TagKind::Class); 2071 break; 2072 case 'W': 2073 if (!consumeFront(MangledName, '4')) { 2074 Error = true; 2075 return nullptr; 2076 } 2077 TT = Arena.alloc<TagTypeNode>(TagKind::Enum); 2078 break; 2079 default: 2080 assert(false); 2081 } 2082 2083 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName); 2084 return TT; 2085 } 2086 2087 // <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type> 2088 // # the E is required for 64-bit non-static pointers 2089 PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) { 2090 PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>(); 2091 2092 std::tie(Pointer->Quals, Pointer->Affinity) = 2093 demanglePointerCVQualifiers(MangledName); 2094 2095 if (consumeFront(MangledName, "6")) { 2096 Pointer->Pointee = demangleFunctionType(MangledName, false); 2097 return Pointer; 2098 } 2099 2100 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName); 2101 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals); 2102 2103 Pointer->PointerAuthQualifier = createPointerAuthQualifier(MangledName); 2104 2105 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle); 2106 return Pointer; 2107 } 2108 2109 PointerTypeNode * 2110 Demangler::demangleMemberPointerType(std::string_view &MangledName) { 2111 PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>(); 2112 2113 std::tie(Pointer->Quals, Pointer->Affinity) = 2114 demanglePointerCVQualifiers(MangledName); 2115 assert(Pointer->Affinity == PointerAffinity::Pointer); 2116 2117 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName); 2118 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals); 2119 2120 // isMemberPointer() only returns true if there is at least one character 2121 // after the qualifiers. 2122 if (consumeFront(MangledName, "8")) { 2123 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName); 2124 Pointer->Pointee = demangleFunctionType(MangledName, true); 2125 } else { 2126 Qualifiers PointeeQuals = Q_None; 2127 bool IsMember = false; 2128 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName); 2129 assert(IsMember || Error); 2130 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName); 2131 2132 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop); 2133 if (Pointer->Pointee) 2134 Pointer->Pointee->Quals = PointeeQuals; 2135 } 2136 2137 return Pointer; 2138 } 2139 2140 Qualifiers 2141 Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) { 2142 Qualifiers Quals = Q_None; 2143 if (consumeFront(MangledName, 'E')) 2144 Quals = Qualifiers(Quals | Q_Pointer64); 2145 if (consumeFront(MangledName, 'I')) 2146 Quals = Qualifiers(Quals | Q_Restrict); 2147 if (consumeFront(MangledName, 'F')) 2148 Quals = Qualifiers(Quals | Q_Unaligned); 2149 2150 return Quals; 2151 } 2152 2153 std::optional<PointerAuthQualifierNode::ArgArray> 2154 Demangler::demanglePointerAuthQualifier(std::string_view &MangledName) { 2155 if (!consumeFront(MangledName, "__ptrauth")) 2156 return std::nullopt; 2157 2158 constexpr unsigned NumArgs = PointerAuthQualifierNode::NumArgs; 2159 PointerAuthQualifierNode::ArgArray Array; 2160 2161 for (unsigned I = 0; I < NumArgs; ++I) { 2162 bool IsNegative = false; 2163 uint64_t Value = 0; 2164 std::tie(Value, IsNegative) = demangleNumber(MangledName); 2165 if (IsNegative) 2166 return std::nullopt; 2167 2168 Array[I] = Value; 2169 } 2170 2171 return Array; 2172 } 2173 2174 PointerAuthQualifierNode * 2175 Demangler::createPointerAuthQualifier(std::string_view &MangledName) { 2176 constexpr unsigned NumArgs = PointerAuthQualifierNode::NumArgs; 2177 std::optional<PointerAuthQualifierNode::ArgArray> Vals = 2178 demanglePointerAuthQualifier(MangledName); 2179 2180 if (!Vals) 2181 return nullptr; 2182 2183 PointerAuthQualifierNode *PtrAuthQual = 2184 Arena.alloc<PointerAuthQualifierNode>(); 2185 NodeArrayNode *Array = Arena.alloc<NodeArrayNode>(); 2186 PtrAuthQual->Components = Array; 2187 Array->Count = NumArgs; 2188 Array->Nodes = Arena.allocArray<Node *>(NumArgs); 2189 2190 for (unsigned I = 0; I < NumArgs; ++I) 2191 Array->Nodes[I] = Arena.alloc<IntegerLiteralNode>((*Vals)[I], false); 2192 2193 return PtrAuthQual; 2194 } 2195 2196 ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) { 2197 assert(MangledName.front() == 'Y'); 2198 MangledName.remove_prefix(1); 2199 2200 uint64_t Rank = 0; 2201 bool IsNegative = false; 2202 std::tie(Rank, IsNegative) = demangleNumber(MangledName); 2203 if (IsNegative || Rank == 0) { 2204 Error = true; 2205 return nullptr; 2206 } 2207 2208 ArrayTypeNode *ATy = Arena.alloc<ArrayTypeNode>(); 2209 NodeList *Head = Arena.alloc<NodeList>(); 2210 NodeList *Tail = Head; 2211 2212 for (uint64_t I = 0; I < Rank; ++I) { 2213 uint64_t D = 0; 2214 std::tie(D, IsNegative) = demangleNumber(MangledName); 2215 if (Error || IsNegative) { 2216 Error = true; 2217 return nullptr; 2218 } 2219 Tail->N = Arena.alloc<IntegerLiteralNode>(D, IsNegative); 2220 if (I + 1 < Rank) { 2221 Tail->Next = Arena.alloc<NodeList>(); 2222 Tail = Tail->Next; 2223 } 2224 } 2225 ATy->Dimensions = nodeListToNodeArray(Arena, Head, Rank); 2226 2227 if (consumeFront(MangledName, "$$C")) { 2228 bool IsMember = false; 2229 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName); 2230 if (IsMember) { 2231 Error = true; 2232 return nullptr; 2233 } 2234 } 2235 2236 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop); 2237 return ATy; 2238 } 2239 2240 // Reads a function's parameters. 2241 NodeArrayNode * 2242 Demangler::demangleFunctionParameterList(std::string_view &MangledName, 2243 bool &IsVariadic) { 2244 // Empty parameter list. 2245 if (consumeFront(MangledName, 'X')) 2246 return nullptr; 2247 2248 NodeList *Head = Arena.alloc<NodeList>(); 2249 NodeList **Current = &Head; 2250 size_t Count = 0; 2251 while (!Error && !llvm::itanium_demangle::starts_with(MangledName, '@') && 2252 !llvm::itanium_demangle::starts_with(MangledName, 'Z')) { 2253 ++Count; 2254 2255 if (startsWithDigit(MangledName)) { 2256 size_t N = MangledName[0] - '0'; 2257 if (N >= Backrefs.FunctionParamCount) { 2258 Error = true; 2259 return nullptr; 2260 } 2261 MangledName.remove_prefix(1); 2262 2263 *Current = Arena.alloc<NodeList>(); 2264 (*Current)->N = Backrefs.FunctionParams[N]; 2265 Current = &(*Current)->Next; 2266 continue; 2267 } 2268 2269 size_t OldSize = MangledName.size(); 2270 2271 *Current = Arena.alloc<NodeList>(); 2272 TypeNode *TN = demangleType(MangledName, QualifierMangleMode::Drop); 2273 if (!TN || Error) 2274 return nullptr; 2275 2276 (*Current)->N = TN; 2277 2278 size_t CharsConsumed = OldSize - MangledName.size(); 2279 assert(CharsConsumed != 0); 2280 2281 // Single-letter types are ignored for backreferences because memorizing 2282 // them doesn't save anything. 2283 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1) 2284 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] = TN; 2285 2286 Current = &(*Current)->Next; 2287 } 2288 2289 if (Error) 2290 return nullptr; 2291 2292 NodeArrayNode *NA = nodeListToNodeArray(Arena, Head, Count); 2293 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter 2294 // list or '@' (non variadic). Careful not to consume "@Z", as in that case 2295 // the following Z could be a throw specifier. 2296 if (consumeFront(MangledName, '@')) 2297 return NA; 2298 2299 if (consumeFront(MangledName, 'Z')) { 2300 IsVariadic = true; 2301 return NA; 2302 } 2303 2304 DEMANGLE_UNREACHABLE; 2305 } 2306 2307 NodeArrayNode * 2308 Demangler::demangleTemplateParameterList(std::string_view &MangledName) { 2309 NodeList *Head = nullptr; 2310 NodeList **Current = &Head; 2311 size_t Count = 0; 2312 2313 while (!llvm::itanium_demangle::starts_with(MangledName, '@')) { 2314 if (consumeFront(MangledName, "$S") || consumeFront(MangledName, "$$V") || 2315 consumeFront(MangledName, "$$$V") || consumeFront(MangledName, "$$Z")) { 2316 // parameter pack separator 2317 continue; 2318 } 2319 2320 ++Count; 2321 2322 // Template parameter lists don't participate in back-referencing. 2323 *Current = Arena.alloc<NodeList>(); 2324 2325 NodeList &TP = **Current; 2326 2327 // <auto-nttp> ::= $ M <type> <nttp> 2328 const bool IsAutoNTTP = consumeFront(MangledName, "$M"); 2329 if (IsAutoNTTP) { 2330 // The deduced type of the auto NTTP parameter isn't printed so 2331 // we want to ignore the AST created from demangling the type. 2332 // 2333 // TODO: Avoid the extra allocations to the bump allocator in this case. 2334 (void)demangleType(MangledName, QualifierMangleMode::Drop); 2335 if (Error) 2336 return nullptr; 2337 } 2338 2339 TemplateParameterReferenceNode *TPRN = nullptr; 2340 if (consumeFront(MangledName, "$$Y")) { 2341 // Template alias 2342 TP.N = demangleFullyQualifiedTypeName(MangledName); 2343 } else if (consumeFront(MangledName, "$$B")) { 2344 // Array 2345 TP.N = demangleType(MangledName, QualifierMangleMode::Drop); 2346 } else if (consumeFront(MangledName, "$$C")) { 2347 // Type has qualifiers. 2348 TP.N = demangleType(MangledName, QualifierMangleMode::Mangle); 2349 } else if (startsWith(MangledName, "$1", "1", !IsAutoNTTP) || 2350 startsWith(MangledName, "$H", "H", !IsAutoNTTP) || 2351 startsWith(MangledName, "$I", "I", !IsAutoNTTP) || 2352 startsWith(MangledName, "$J", "J", !IsAutoNTTP)) { 2353 // Pointer to member 2354 TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>(); 2355 TPRN->IsMemberPointer = true; 2356 2357 if (!IsAutoNTTP) 2358 MangledName.remove_prefix(1); // Remove leading '$' 2359 2360 // 1 - single inheritance <name> 2361 // H - multiple inheritance <name> <number> 2362 // I - virtual inheritance <name> <number> <number> 2363 // J - unspecified inheritance <name> <number> <number> <number> 2364 char InheritanceSpecifier = MangledName.front(); 2365 MangledName.remove_prefix(1); 2366 SymbolNode *S = nullptr; 2367 if (llvm::itanium_demangle::starts_with(MangledName, '?')) { 2368 S = parse(MangledName); 2369 if (Error || !S->Name) { 2370 Error = true; 2371 return nullptr; 2372 } 2373 memorizeIdentifier(S->Name->getUnqualifiedIdentifier()); 2374 } 2375 2376 switch (InheritanceSpecifier) { 2377 case 'J': 2378 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2379 demangleSigned(MangledName); 2380 DEMANGLE_FALLTHROUGH; 2381 case 'I': 2382 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2383 demangleSigned(MangledName); 2384 DEMANGLE_FALLTHROUGH; 2385 case 'H': 2386 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2387 demangleSigned(MangledName); 2388 DEMANGLE_FALLTHROUGH; 2389 case '1': 2390 break; 2391 default: 2392 DEMANGLE_UNREACHABLE; 2393 } 2394 TPRN->Affinity = PointerAffinity::Pointer; 2395 TPRN->Symbol = S; 2396 } else if (llvm::itanium_demangle::starts_with(MangledName, "$E?")) { 2397 consumeFront(MangledName, "$E"); 2398 // Reference to symbol 2399 TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>(); 2400 TPRN->Symbol = parse(MangledName); 2401 TPRN->Affinity = PointerAffinity::Reference; 2402 } else if (startsWith(MangledName, "$F", "F", !IsAutoNTTP) || 2403 startsWith(MangledName, "$G", "G", !IsAutoNTTP)) { 2404 TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>(); 2405 2406 // Data member pointer. 2407 if (!IsAutoNTTP) 2408 MangledName.remove_prefix(1); // Remove leading '$' 2409 char InheritanceSpecifier = MangledName.front(); 2410 MangledName.remove_prefix(1); 2411 2412 switch (InheritanceSpecifier) { 2413 case 'G': 2414 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2415 demangleSigned(MangledName); 2416 DEMANGLE_FALLTHROUGH; 2417 case 'F': 2418 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2419 demangleSigned(MangledName); 2420 TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] = 2421 demangleSigned(MangledName); 2422 break; 2423 default: 2424 DEMANGLE_UNREACHABLE; 2425 } 2426 TPRN->IsMemberPointer = true; 2427 2428 } else if (consumeFront(MangledName, "$0", "0", !IsAutoNTTP)) { 2429 // Integral non-type template parameter 2430 bool IsNegative = false; 2431 uint64_t Value = 0; 2432 std::tie(Value, IsNegative) = demangleNumber(MangledName); 2433 2434 TP.N = Arena.alloc<IntegerLiteralNode>(Value, IsNegative); 2435 } else { 2436 TP.N = demangleType(MangledName, QualifierMangleMode::Drop); 2437 } 2438 if (Error) 2439 return nullptr; 2440 2441 Current = &TP.Next; 2442 } 2443 2444 // The loop above returns nullptr on Error. 2445 assert(!Error); 2446 2447 // Template parameter lists cannot be variadic, so it can only be terminated 2448 // by @ (as opposed to 'Z' in the function parameter case). 2449 assert(llvm::itanium_demangle::starts_with( 2450 MangledName, '@')); // The above loop exits only on '@'. 2451 consumeFront(MangledName, '@'); 2452 return nodeListToNodeArray(Arena, Head, Count); 2453 } 2454 2455 void Demangler::dumpBackReferences() { 2456 std::printf("%d function parameter backreferences\n", 2457 (int)Backrefs.FunctionParamCount); 2458 2459 // Create an output stream so we can render each type. 2460 OutputBuffer OB; 2461 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) { 2462 OB.setCurrentPosition(0); 2463 2464 TypeNode *T = Backrefs.FunctionParams[I]; 2465 T->output(OB, OF_Default); 2466 2467 std::string_view B = OB; 2468 std::printf(" [%d] - %.*s\n", (int)I, (int)B.size(), B.data()); 2469 } 2470 std::free(OB.getBuffer()); 2471 2472 if (Backrefs.FunctionParamCount > 0) 2473 std::printf("\n"); 2474 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount); 2475 for (size_t I = 0; I < Backrefs.NamesCount; ++I) { 2476 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I]->Name.size(), 2477 Backrefs.Names[I]->Name.data()); 2478 } 2479 if (Backrefs.NamesCount > 0) 2480 std::printf("\n"); 2481 } 2482 2483 std::optional<size_t> 2484 llvm::getArm64ECInsertionPointInMangledName(std::string_view MangledName) { 2485 std::string_view ProcessedName{MangledName}; 2486 2487 // We only support this for MSVC-style C++ symbols. 2488 if (!consumeFront(ProcessedName, '?')) 2489 return std::nullopt; 2490 2491 // The insertion point is just after the name of the symbol, so parse that to 2492 // remove it from the processed name. 2493 Demangler D; 2494 D.demangleFullyQualifiedSymbolName(ProcessedName); 2495 if (D.Error) 2496 return std::nullopt; 2497 2498 return MangledName.length() - ProcessedName.length(); 2499 } 2500 2501 char *llvm::microsoftDemangle(std::string_view MangledName, size_t *NMangled, 2502 int *Status, MSDemangleFlags Flags) { 2503 Demangler D; 2504 2505 std::string_view Name{MangledName}; 2506 SymbolNode *AST = D.parse(Name); 2507 if (!D.Error && NMangled) 2508 *NMangled = MangledName.size() - Name.size(); 2509 2510 if (Flags & MSDF_DumpBackrefs) 2511 D.dumpBackReferences(); 2512 2513 OutputFlags OF = OF_Default; 2514 if (Flags & MSDF_NoCallingConvention) 2515 OF = OutputFlags(OF | OF_NoCallingConvention); 2516 if (Flags & MSDF_NoAccessSpecifier) 2517 OF = OutputFlags(OF | OF_NoAccessSpecifier); 2518 if (Flags & MSDF_NoReturnType) 2519 OF = OutputFlags(OF | OF_NoReturnType); 2520 if (Flags & MSDF_NoMemberType) 2521 OF = OutputFlags(OF | OF_NoMemberType); 2522 if (Flags & MSDF_NoVariableType) 2523 OF = OutputFlags(OF | OF_NoVariableType); 2524 2525 int InternalStatus = demangle_success; 2526 char *Buf; 2527 if (D.Error) 2528 InternalStatus = demangle_invalid_mangled_name; 2529 else { 2530 OutputBuffer OB; 2531 AST->output(OB, OF); 2532 OB += '\0'; 2533 Buf = OB.getBuffer(); 2534 } 2535 2536 if (Status) 2537 *Status = InternalStatus; 2538 return InternalStatus == demangle_success ? Buf : nullptr; 2539 } 2540