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