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