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