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