LCOV - code coverage report
Current view: top level - lib/Demangle - MicrosoftDemangle.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 738 1006 73.4 %
Date: 2018-10-20 13:21:21 Functions: 53 68 77.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13