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