//===- MicrosoftDemangle.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines a demangler for MSVC-style mangled symbols.
//
// This file has no dependencies on the rest of LLVM so that it can be
// easily reused in other programs such as libcxxabi.
//
//===----------------------------------------------------------------------===//

#include "llvm/Demangle/MicrosoftDemangle.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/MicrosoftDemangleNodes.h"

#include "llvm/Demangle/DemangleConfig.h"
#include "llvm/Demangle/StringView.h"
#include "llvm/Demangle/Utility.h"

#include <array>
#include <cctype>
#include <cstdio>
#include <tuple>

using namespace llvm;
using namespace ms_demangle;

static bool startsWithDigit(StringView S) {
  return !S.empty() && std::isdigit(S.front());
}


struct NodeList {
  Node *N = nullptr;
  NodeList *Next = nullptr;
};

static bool isMemberPointer(StringView MangledName, bool &Error) {
  Error = false;
  switch (MangledName.popFront()) {
  case '$':
    // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
    // rvalue reference to a member.
    return false;
  case 'A':
    // 'A' indicates a reference, and you cannot have a reference to a member
    // function or member.
    return false;
  case 'P':
  case 'Q':
  case 'R':
  case 'S':
    // These 4 values indicate some kind of pointer, but we still don't know
    // what.
    break;
  default:
    Error = true;
    return false;
  }

  // If it starts with a number, then 6 indicates a non-member function
  // pointer, and 8 indicates a member function pointer.
  if (startsWithDigit(MangledName)) {
    if (MangledName[0] != '6' && MangledName[0] != '8') {
      Error = true;
      return false;
    }
    return (MangledName[0] == '8');
  }

  // Remove ext qualifiers since those can appear on either type and are
  // therefore not indicative.
  MangledName.consumeFront('E'); // 64-bit
  MangledName.consumeFront('I'); // restrict
  MangledName.consumeFront('F'); // unaligned

  if (MangledName.empty()) {
    Error = true;
    return false;
  }

  // The next value should be either ABCD (non-member) or QRST (member).
  switch (MangledName.front()) {
  case 'A':
  case 'B':
  case 'C':
  case 'D':
    return false;
  case 'Q':
  case 'R':
  case 'S':
  case 'T':
    return true;
  default:
    Error = true;
    return false;
  }
}

static SpecialIntrinsicKind
consumeSpecialIntrinsicKind(StringView &MangledName) {
  if (MangledName.consumeFront("?_7"))
    return SpecialIntrinsicKind::Vftable;
  if (MangledName.consumeFront("?_8"))
    return SpecialIntrinsicKind::Vbtable;
  if (MangledName.consumeFront("?_9"))
    return SpecialIntrinsicKind::VcallThunk;
  if (MangledName.consumeFront("?_A"))
    return SpecialIntrinsicKind::Typeof;
  if (MangledName.consumeFront("?_B"))
    return SpecialIntrinsicKind::LocalStaticGuard;
  if (MangledName.consumeFront("?_C"))
    return SpecialIntrinsicKind::StringLiteralSymbol;
  if (MangledName.consumeFront("?_P"))
    return SpecialIntrinsicKind::UdtReturning;
  if (MangledName.consumeFront("?_R0"))
    return SpecialIntrinsicKind::RttiTypeDescriptor;
  if (MangledName.consumeFront("?_R1"))
    return SpecialIntrinsicKind::RttiBaseClassDescriptor;
  if (MangledName.consumeFront("?_R2"))
    return SpecialIntrinsicKind::RttiBaseClassArray;
  if (MangledName.consumeFront("?_R3"))
    return SpecialIntrinsicKind::RttiClassHierarchyDescriptor;
  if (MangledName.consumeFront("?_R4"))
    return SpecialIntrinsicKind::RttiCompleteObjLocator;
  if (MangledName.consumeFront("?_S"))
    return SpecialIntrinsicKind::LocalVftable;
  if (MangledName.consumeFront("?__E"))
    return SpecialIntrinsicKind::DynamicInitializer;
  if (MangledName.consumeFront("?__F"))
    return SpecialIntrinsicKind::DynamicAtexitDestructor;
  if (MangledName.consumeFront("?__J"))
    return SpecialIntrinsicKind::LocalStaticThreadGuard;
  return SpecialIntrinsicKind::None;
}

static bool startsWithLocalScopePattern(StringView S) {
  if (!S.consumeFront('?'))
    return false;
  if (S.size() < 2)
    return false;

  size_t End = S.find('?');
  if (End == StringView::npos)
    return false;
  StringView Candidate = S.substr(0, End);
  if (Candidate.empty())
    return false;

  // \?[0-9]\?
  // ?@? is the discriminator 0.
  if (Candidate.size() == 1)
    return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');

  // If it's not 0-9, then it's an encoded number terminated with an @
  if (Candidate.back() != '@')
    return false;
  Candidate = Candidate.dropBack();

  // An encoded number starts with B-P and all subsequent digits are in A-P.
  // Note that the reason the first digit cannot be A is two fold.  First, it
  // would create an ambiguity with ?A which delimits the beginning of an
  // anonymous namespace.  Second, A represents 0, and you don't start a multi
  // digit number with a leading 0.  Presumably the anonymous namespace
  // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
  if (Candidate[0] < 'B' || Candidate[0] > 'P')
    return false;
  Candidate = Candidate.dropFront();
  while (!Candidate.empty()) {
    if (Candidate[0] < 'A' || Candidate[0] > 'P')
      return false;
    Candidate = Candidate.dropFront();
  }

  return true;
}

static bool isTagType(StringView S) {
  switch (S.front()) {
  case 'T': // union
  case 'U': // struct
  case 'V': // class
  case 'W': // enum
    return true;
  }
  return false;
}

static bool isCustomType(StringView S) { return S[0] == '?'; }

static bool isPointerType(StringView S) {
  if (S.startsWith("$$Q")) // foo &&
    return true;

  switch (S.front()) {
  case 'A': // foo &
  case 'P': // foo *
  case 'Q': // foo *const
  case 'R': // foo *volatile
  case 'S': // foo *const volatile
    return true;
  }
  return false;
}

static bool isArrayType(StringView S) { return S[0] == 'Y'; }

static bool isFunctionType(StringView S) {
  return S.startsWith("$$A8@@") || S.startsWith("$$A6");
}

static FunctionRefQualifier
demangleFunctionRefQualifier(StringView &MangledName) {
  if (MangledName.consumeFront('G'))
    return FunctionRefQualifier::Reference;
  else if (MangledName.consumeFront('H'))
    return FunctionRefQualifier::RValueReference;
  return FunctionRefQualifier::None;
}

static std::pair<Qualifiers, PointerAffinity>
demanglePointerCVQualifiers(StringView &MangledName) {
  if (MangledName.consumeFront("$$Q"))
    return std::make_pair(Q_None, PointerAffinity::RValueReference);

  switch (MangledName.popFront()) {
  case 'A':
    return std::make_pair(Q_None, PointerAffinity::Reference);
  case 'P':
    return std::make_pair(Q_None, PointerAffinity::Pointer);
  case 'Q':
    return std::make_pair(Q_Const, PointerAffinity::Pointer);
  case 'R':
    return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
  case 'S':
    return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
                          PointerAffinity::Pointer);
  default:
    assert(false && "Ty is not a pointer type!");
  }
  return std::make_pair(Q_None, PointerAffinity::Pointer);
}

StringView Demangler::copyString(StringView Borrowed) {
  char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
  std::strcpy(Stable, Borrowed.begin());

  return {Stable, Borrowed.size()};
}

SpecialTableSymbolNode *
Demangler::demangleSpecialTableSymbolNode(StringView &MangledName,
                                          SpecialIntrinsicKind K) {
  NamedIdentifierNode *NI = Arena.alloc<NamedIdentifierNode>();
  switch (K) {
  case SpecialIntrinsicKind::Vftable:
    NI->Name = "`vftable'";
    break;
  case SpecialIntrinsicKind::Vbtable:
    NI->Name = "`vbtable'";
    break;
  case SpecialIntrinsicKind::LocalVftable:
    NI->Name = "`local vftable'";
    break;
  case SpecialIntrinsicKind::RttiCompleteObjLocator:
    NI->Name = "`RTTI Complete Object Locator'";
    break;
  default:
    DEMANGLE_UNREACHABLE;
  }
  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
  SpecialTableSymbolNode *STSN = Arena.alloc<SpecialTableSymbolNode>();
  STSN->Name = QN;
  bool IsMember = false;
  char Front = MangledName.popFront();
  if (Front != '6' && Front != '7') {
    Error = true;
    return nullptr;
  }

  std::tie(STSN->Quals, IsMember) = demangleQualifiers(MangledName);
  if (!MangledName.consumeFront('@'))
    STSN->TargetName = demangleFullyQualifiedTypeName(MangledName);
  return STSN;
}

LocalStaticGuardVariableNode *
Demangler::demangleLocalStaticGuard(StringView &MangledName) {
  LocalStaticGuardIdentifierNode *LSGI =
      Arena.alloc<LocalStaticGuardIdentifierNode>();
  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, LSGI);
  LocalStaticGuardVariableNode *LSGVN =
      Arena.alloc<LocalStaticGuardVariableNode>();
  LSGVN->Name = QN;

  if (MangledName.consumeFront("4IA"))
    LSGVN->IsVisible = false;
  else if (MangledName.consumeFront("5"))
    LSGVN->IsVisible = true;
  else {
    Error = true;
    return nullptr;
  }

  if (!MangledName.empty())
    LSGI->ScopeIndex = demangleUnsigned(MangledName);
  return LSGVN;
}

static NamedIdentifierNode *synthesizeNamedIdentifier(ArenaAllocator &Arena,
                                                      StringView Name) {
  NamedIdentifierNode *Id = Arena.alloc<NamedIdentifierNode>();
  Id->Name = Name;
  return Id;
}

static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena,
                                                  IdentifierNode *Identifier) {
  QualifiedNameNode *QN = Arena.alloc<QualifiedNameNode>();
  QN->Components = Arena.alloc<NodeArrayNode>();
  QN->Components->Count = 1;
  QN->Components->Nodes = Arena.allocArray<Node *>(1);
  QN->Components->Nodes[0] = Identifier;
  return QN;
}

static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena,
                                                  StringView Name) {
  NamedIdentifierNode *Id = synthesizeNamedIdentifier(Arena, Name);
  return synthesizeQualifiedName(Arena, Id);
}

static VariableSymbolNode *synthesizeVariable(ArenaAllocator &Arena,
                                              TypeNode *Type,
                                              StringView VariableName) {
  VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
  VSN->Type = Type;
  VSN->Name = synthesizeQualifiedName(Arena, VariableName);
  return VSN;
}

VariableSymbolNode *Demangler::demangleUntypedVariable(
    ArenaAllocator &Arena, StringView &MangledName, StringView VariableName) {
  NamedIdentifierNode *NI = synthesizeNamedIdentifier(Arena, VariableName);
  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
  VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
  VSN->Name = QN;
  if (MangledName.consumeFront("8"))
    return VSN;

  Error = true;
  return nullptr;
}

VariableSymbolNode *
Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
                                               StringView &MangledName) {
  RttiBaseClassDescriptorNode *RBCDN =
      Arena.alloc<RttiBaseClassDescriptorNode>();
  RBCDN->NVOffset = demangleUnsigned(MangledName);
  RBCDN->VBPtrOffset = demangleSigned(MangledName);
  RBCDN->VBTableOffset = demangleUnsigned(MangledName);
  RBCDN->Flags = demangleUnsigned(MangledName);
  if (Error)
    return nullptr;

  VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
  VSN->Name = demangleNameScopeChain(MangledName, RBCDN);
  MangledName.consumeFront('8');
  return VSN;
}

FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
                                                    bool IsDestructor) {
  DynamicStructorIdentifierNode *DSIN =
      Arena.alloc<DynamicStructorIdentifierNode>();
  DSIN->IsDestructor = IsDestructor;

  bool IsKnownStaticDataMember = false;
  if (MangledName.consumeFront('?'))
    IsKnownStaticDataMember = true;

  SymbolNode *Symbol = demangleDeclarator(MangledName);
  if (Error)
    return nullptr;

  FunctionSymbolNode *FSN = nullptr;

  if (Symbol->kind() == NodeKind::VariableSymbol) {
    DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol);

    // Older versions of clang mangled this type of symbol incorrectly.  They
    // would omit the leading ? and they would only emit a single @ at the end.
    // The correct mangling is a leading ? and 2 trailing @ signs.  Handle
    // both cases.
    int AtCount = IsKnownStaticDataMember ? 2 : 1;
    for (int I = 0; I < AtCount; ++I) {
      if (MangledName.consumeFront('@'))
        continue;
      Error = true;
      return nullptr;
    }

    FSN = demangleFunctionEncoding(MangledName);
    if (FSN)
      FSN->Name = synthesizeQualifiedName(Arena, DSIN);
  } else {
    if (IsKnownStaticDataMember) {
      // This was supposed to be a static data member, but we got a function.
      Error = true;
      return nullptr;
    }

    FSN = static_cast<FunctionSymbolNode *>(Symbol);
    DSIN->Name = Symbol->Name;
    FSN->Name = synthesizeQualifiedName(Arena, DSIN);
  }

  return FSN;
}

SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
  SpecialIntrinsicKind SIK = consumeSpecialIntrinsicKind(MangledName);
  if (SIK == SpecialIntrinsicKind::None)
    return nullptr;

  switch (SIK) {
  case SpecialIntrinsicKind::StringLiteralSymbol:
    return demangleStringLiteral(MangledName);
  case SpecialIntrinsicKind::Vftable:
  case SpecialIntrinsicKind::Vbtable:
  case SpecialIntrinsicKind::LocalVftable:
  case SpecialIntrinsicKind::RttiCompleteObjLocator:
    return demangleSpecialTableSymbolNode(MangledName, SIK);
  case SpecialIntrinsicKind::VcallThunk:
    return demangleVcallThunkNode(MangledName);
  case SpecialIntrinsicKind::LocalStaticGuard:
    return demangleLocalStaticGuard(MangledName);
  case SpecialIntrinsicKind::RttiTypeDescriptor: {
    TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result);
    if (Error)
      break;
    if (!MangledName.consumeFront("@8"))
      break;
    if (!MangledName.empty())
      break;
    return synthesizeVariable(Arena, T, "`RTTI Type Descriptor'");
  }
  case SpecialIntrinsicKind::RttiBaseClassArray:
    return demangleUntypedVariable(Arena, MangledName,
                                   "`RTTI Base Class Array'");
  case SpecialIntrinsicKind::RttiClassHierarchyDescriptor:
    return demangleUntypedVariable(Arena, MangledName,
                                   "`RTTI Class Hierarchy Descriptor'");
  case SpecialIntrinsicKind::RttiBaseClassDescriptor:
    return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
  case SpecialIntrinsicKind::DynamicInitializer:
    return demangleInitFiniStub(MangledName, false);
  case SpecialIntrinsicKind::DynamicAtexitDestructor:
    return demangleInitFiniStub(MangledName, true);
  default:
    break;
  }
  Error = true;
  return nullptr;
}

IdentifierNode *
Demangler::demangleFunctionIdentifierCode(StringView &MangledName) {
  assert(MangledName.startsWith('?'));
  MangledName = MangledName.dropFront();
  if (MangledName.empty()) {
    Error = true;
    return nullptr;
  }

  if (MangledName.consumeFront("__"))
    return demangleFunctionIdentifierCode(
        MangledName, FunctionIdentifierCodeGroup::DoubleUnder);
  if (MangledName.consumeFront("_"))
    return demangleFunctionIdentifierCode(MangledName,
                                          FunctionIdentifierCodeGroup::Under);
  return demangleFunctionIdentifierCode(MangledName,
                                        FunctionIdentifierCodeGroup::Basic);
}

StructorIdentifierNode *
Demangler::demangleStructorIdentifier(StringView &MangledName,
                                      bool IsDestructor) {
  StructorIdentifierNode *N = Arena.alloc<StructorIdentifierNode>();
  N->IsDestructor = IsDestructor;
  return N;
}

ConversionOperatorIdentifierNode *
Demangler::demangleConversionOperatorIdentifier(StringView &MangledName) {
  ConversionOperatorIdentifierNode *N =
      Arena.alloc<ConversionOperatorIdentifierNode>();
  return N;
}

LiteralOperatorIdentifierNode *
Demangler::demangleLiteralOperatorIdentifier(StringView &MangledName) {
  LiteralOperatorIdentifierNode *N =
      Arena.alloc<LiteralOperatorIdentifierNode>();
  N->Name = demangleSimpleString(MangledName, /*Memorize=*/false);
  return N;
}

IntrinsicFunctionKind
Demangler::translateIntrinsicFunctionCode(char CH,
                                          FunctionIdentifierCodeGroup Group) {
  using IFK = IntrinsicFunctionKind;
  if (!(CH >= '0' && CH <= '9') && !(CH >= 'A' && CH <= 'Z')) {
    Error = true;
    return IFK::None;
  }

  // Not all ? identifiers are intrinsics *functions*.  This function only maps
  // operator codes for the special functions, all others are handled elsewhere,
  // hence the IFK::None entries in the table.
  static IFK Basic[36] = {
      IFK::None,             // ?0 # Foo::Foo()
      IFK::None,             // ?1 # Foo::~Foo()
      IFK::New,              // ?2 # operator new
      IFK::Delete,           // ?3 # operator delete
      IFK::Assign,           // ?4 # operator=
      IFK::RightShift,       // ?5 # operator>>
      IFK::LeftShift,        // ?6 # operator<<
      IFK::LogicalNot,       // ?7 # operator!
      IFK::Equals,           // ?8 # operator==
      IFK::NotEquals,        // ?9 # operator!=
      IFK::ArraySubscript,   // ?A # operator[]
      IFK::None,             // ?B # Foo::operator <type>()
      IFK::Pointer,          // ?C # operator->
      IFK::Dereference,      // ?D # operator*
      IFK::Increment,        // ?E # operator++
      IFK::Decrement,        // ?F # operator--
      IFK::Minus,            // ?G # operator-
      IFK::Plus,             // ?H # operator+
      IFK::BitwiseAnd,       // ?I # operator&
      IFK::MemberPointer,    // ?J # operator->*
      IFK::Divide,           // ?K # operator/
      IFK::Modulus,          // ?L # operator%
      IFK::LessThan,         // ?M operator<
      IFK::LessThanEqual,    // ?N operator<=
      IFK::GreaterThan,      // ?O operator>
      IFK::GreaterThanEqual, // ?P operator>=
      IFK::Comma,            // ?Q operator,
      IFK::Parens,           // ?R operator()
      IFK::BitwiseNot,       // ?S operator~
      IFK::BitwiseXor,       // ?T operator^
      IFK::BitwiseOr,        // ?U operator|
      IFK::LogicalAnd,       // ?V operator&&
      IFK::LogicalOr,        // ?W operator||
      IFK::TimesEqual,       // ?X operator*=
      IFK::PlusEqual,        // ?Y operator+=
      IFK::MinusEqual,       // ?Z operator-=
  };
  static IFK Under[36] = {
      IFK::DivEqual,           // ?_0 operator/=
      IFK::ModEqual,           // ?_1 operator%=
      IFK::RshEqual,           // ?_2 operator>>=
      IFK::LshEqual,           // ?_3 operator<<=
      IFK::BitwiseAndEqual,    // ?_4 operator&=
      IFK::BitwiseOrEqual,     // ?_5 operator|=
      IFK::BitwiseXorEqual,    // ?_6 operator^=
      IFK::None,               // ?_7 # vftable
      IFK::None,               // ?_8 # vbtable
      IFK::None,               // ?_9 # vcall
      IFK::None,               // ?_A # typeof
      IFK::None,               // ?_B # local static guard
      IFK::None,               // ?_C # string literal
      IFK::VbaseDtor,          // ?_D # vbase destructor
      IFK::VecDelDtor,         // ?_E # vector deleting destructor
      IFK::DefaultCtorClosure, // ?_F # default constructor closure
      IFK::ScalarDelDtor,      // ?_G # scalar deleting destructor
      IFK::VecCtorIter,        // ?_H # vector constructor iterator
      IFK::VecDtorIter,        // ?_I # vector destructor iterator
      IFK::VecVbaseCtorIter,   // ?_J # vector vbase constructor iterator
      IFK::VdispMap,           // ?_K # virtual displacement map
      IFK::EHVecCtorIter,      // ?_L # eh vector constructor iterator
      IFK::EHVecDtorIter,      // ?_M # eh vector destructor iterator
      IFK::EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
      IFK::CopyCtorClosure,    // ?_O # copy constructor closure
      IFK::None,               // ?_P<name> # udt returning <name>
      IFK::None,               // ?_Q # <unknown>
      IFK::None,               // ?_R0 - ?_R4 # RTTI Codes
      IFK::None,               // ?_S # local vftable
      IFK::LocalVftableCtorClosure, // ?_T # local vftable constructor closure
      IFK::ArrayNew,                // ?_U operator new[]
      IFK::ArrayDelete,             // ?_V operator delete[]
      IFK::None,                    // ?_W <unused>
      IFK::None,                    // ?_X <unused>
      IFK::None,                    // ?_Y <unused>
      IFK::None,                    // ?_Z <unused>
  };
  static IFK DoubleUnder[36] = {
      IFK::None,                       // ?__0 <unused>
      IFK::None,                       // ?__1 <unused>
      IFK::None,                       // ?__2 <unused>
      IFK::None,                       // ?__3 <unused>
      IFK::None,                       // ?__4 <unused>
      IFK::None,                       // ?__5 <unused>
      IFK::None,                       // ?__6 <unused>
      IFK::None,                       // ?__7 <unused>
      IFK::None,                       // ?__8 <unused>
      IFK::None,                       // ?__9 <unused>
      IFK::ManVectorCtorIter,          // ?__A managed vector ctor iterator
      IFK::ManVectorDtorIter,          // ?__B managed vector dtor iterator
      IFK::EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
      IFK::EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iter
      IFK::None,                       // ?__E dynamic initializer for `T'
      IFK::None,                       // ?__F dynamic atexit destructor for `T'
      IFK::VectorCopyCtorIter,         // ?__G vector copy constructor iter
      IFK::VectorVbaseCopyCtorIter,    // ?__H vector vbase copy ctor iter
      IFK::ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy ctor
                                       // iter
      IFK::None,                       // ?__J local static thread guard
      IFK::None,                       // ?__K operator ""_name
      IFK::CoAwait,                    // ?__L co_await
      IFK::None,                       // ?__M <unused>
      IFK::None,                       // ?__N <unused>
      IFK::None,                       // ?__O <unused>
      IFK::None,                       // ?__P <unused>
      IFK::None,                       // ?__Q <unused>
      IFK::None,                       // ?__R <unused>
      IFK::None,                       // ?__S <unused>
      IFK::None,                       // ?__T <unused>
      IFK::None,                       // ?__U <unused>
      IFK::None,                       // ?__V <unused>
      IFK::None,                       // ?__W <unused>
      IFK::None,                       // ?__X <unused>
      IFK::None,                       // ?__Y <unused>
      IFK::None,                       // ?__Z <unused>
  };

  int Index = (CH >= '0' && CH <= '9') ? (CH - '0') : (CH - 'A' + 10);
  switch (Group) {
  case FunctionIdentifierCodeGroup::Basic:
    return Basic[Index];
  case FunctionIdentifierCodeGroup::Under:
    return Under[Index];
  case FunctionIdentifierCodeGroup::DoubleUnder:
    return DoubleUnder[Index];
  }
  DEMANGLE_UNREACHABLE;
}

IdentifierNode *
Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
                                          FunctionIdentifierCodeGroup Group) {
  assert(!MangledName.empty());
  switch (Group) {
  case FunctionIdentifierCodeGroup::Basic:
    switch (char CH = MangledName.popFront()) {
    case '0':
    case '1':
      return demangleStructorIdentifier(MangledName, CH == '1');
    case 'B':
      return demangleConversionOperatorIdentifier(MangledName);
    default:
      return Arena.alloc<IntrinsicFunctionIdentifierNode>(
          translateIntrinsicFunctionCode(CH, Group));
    }
    break;
  case FunctionIdentifierCodeGroup::Under:
    return Arena.alloc<IntrinsicFunctionIdentifierNode>(
        translateIntrinsicFunctionCode(MangledName.popFront(), Group));
  case FunctionIdentifierCodeGroup::DoubleUnder:
    switch (char CH = MangledName.popFront()) {
    case 'K':
      return demangleLiteralOperatorIdentifier(MangledName);
    default:
      return Arena.alloc<IntrinsicFunctionIdentifierNode>(
          translateIntrinsicFunctionCode(CH, Group));
    }
  }
  // No Mangling Yet:      Spaceship,                    // operator<=>

  DEMANGLE_UNREACHABLE;
}

SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
                                             QualifiedNameNode *Name) {
  if (MangledName.empty()) {
    Error = true;
    return nullptr;
  }

  // Read a variable.
  switch (MangledName.front()) {
  case '0':
  case '1':
  case '2':
  case '3':
  case '4': {
    StorageClass SC = demangleVariableStorageClass(MangledName);
    return demangleVariableEncoding(MangledName, SC);
  }
  }
  FunctionSymbolNode *FSN = demangleFunctionEncoding(MangledName);

  IdentifierNode *UQN = Name->getUnqualifiedIdentifier();
  if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
    ConversionOperatorIdentifierNode *COIN =
        static_cast<ConversionOperatorIdentifierNode *>(UQN);
    if (FSN)
      COIN->TargetType = FSN->Signature->ReturnType;
  }
  return FSN;
}

SymbolNode *Demangler::demangleDeclarator(StringView &MangledName) {
  // What follows is a main symbol name. This may include namespaces or class
  // back references.
  QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
  if (Error)
    return nullptr;

  SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
  if (Error)
    return nullptr;
  Symbol->Name = QN;

  IdentifierNode *UQN = QN->getUnqualifiedIdentifier();
  if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
    ConversionOperatorIdentifierNode *COIN =
        static_cast<ConversionOperatorIdentifierNode *>(UQN);
    if (!COIN->TargetType) {
      Error = true;
      return nullptr;
    }
  }
  return Symbol;
}

// Parser entry point.
SymbolNode *Demangler::parse(StringView &MangledName) {
  // We can't demangle MD5 names, just output them as-is.
  // Also, MSVC-style mangled symbols must start with '?'.
  if (MangledName.startsWith("??@")) {
    // This is an MD5 mangled name.  We can't demangle it, just return the
    // mangled name.
    SymbolNode *S = Arena.alloc<SymbolNode>(NodeKind::Md5Symbol);
    S->Name = synthesizeQualifiedName(Arena, MangledName);
    return S;
  }

  if (!MangledName.startsWith('?')) {
    Error = true;
    return nullptr;
  }

  MangledName.consumeFront('?');

  // ?$ is a template instantiation, but all other names that start with ? are
  // operators / special names.
  if (SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
    return SI;

  return demangleDeclarator(MangledName);
}

TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
  if (!MangledName.consumeFront(".?A"))
    return nullptr;
  MangledName.consumeFront(".?A");
  if (MangledName.empty())
    return nullptr;

  return demangleClassType(MangledName);
}

// <type-encoding> ::= <storage-class> <variable-type>
// <storage-class> ::= 0  # private static member
//                 ::= 1  # protected static member
//                 ::= 2  # public static member
//                 ::= 3  # global
//                 ::= 4  # static local

VariableSymbolNode *Demangler::demangleVariableEncoding(StringView &MangledName,
                                                        StorageClass SC) {
  VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();

  VSN->Type = demangleType(MangledName, QualifierMangleMode::Drop);
  VSN->SC = SC;

  if (Error)
    return nullptr;

  // <variable-type> ::= <type> <cvr-qualifiers>
  //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
  switch (VSN->Type->kind()) {
  case NodeKind::PointerType: {
    PointerTypeNode *PTN = static_cast<PointerTypeNode *>(VSN->Type);

    Qualifiers ExtraChildQuals = Q_None;
    PTN->Quals = Qualifiers(VSN->Type->Quals |
                            demanglePointerExtQualifiers(MangledName));

    bool IsMember = false;
    std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);

    if (PTN->ClassParent) {
      QualifiedNameNode *BackRefName =
          demangleFullyQualifiedTypeName(MangledName);
      (void)BackRefName;
    }
    PTN->Pointee->Quals = Qualifiers(PTN->Pointee->Quals | ExtraChildQuals);

    break;
  }
  default:
    VSN->Type->Quals = demangleQualifiers(MangledName).first;
    break;
  }

  return VSN;
}

// Sometimes numbers are encoded in mangled symbols. For example,
// "int (*x)[20]" is a valid C type (x is a pointer to an array of
// length 20), so we need some way to embed numbers as part of symbols.
// This function parses it.
//
// <number>               ::= [?] <non-negative integer>
//
// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
//                        ::= <hex digit>+ @  # when Numbrer == 0 or >= 10
//
// <hex-digit>            ::= [A-P]           # A = 0, B = 1, ...
std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
  bool IsNegative = MangledName.consumeFront('?');

  if (startsWithDigit(MangledName)) {
    uint64_t Ret = MangledName[0] - '0' + 1;
    MangledName = MangledName.dropFront(1);
    return {Ret, IsNegative};
  }

  uint64_t Ret = 0;
  for (size_t i = 0; i < MangledName.size(); ++i) {
    char C = MangledName[i];
    if (C == '@') {
      MangledName = MangledName.dropFront(i + 1);
      return {Ret, IsNegative};
    }
    if ('A' <= C && C <= 'P') {
      Ret = (Ret << 4) + (C - 'A');
      continue;
    }
    break;
  }

  Error = true;
  return {0ULL, false};
}

uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
  bool IsNegative = false;
  uint64_t Number = 0;
  std::tie(Number, IsNegative) = demangleNumber(MangledName);
  if (IsNegative)
    Error = true;
  return Number;
}

int64_t Demangler::demangleSigned(StringView &MangledName) {
  bool IsNegative = false;
  uint64_t Number = 0;
  std::tie(Number, IsNegative) = demangleNumber(MangledName);
  if (Number > INT64_MAX)
    Error = true;
  int64_t I = static_cast<int64_t>(Number);
  return IsNegative ? -I : I;
}

// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
// Memorize it.
void Demangler::memorizeString(StringView S) {
  if (Backrefs.NamesCount >= BackrefContext::Max)
    return;
  for (size_t i = 0; i < Backrefs.NamesCount; ++i)
    if (S == Backrefs.Names[i]->Name)
      return;
  NamedIdentifierNode *N = Arena.alloc<NamedIdentifierNode>();
  N->Name = S;
  Backrefs.Names[Backrefs.NamesCount++] = N;
}

NamedIdentifierNode *Demangler::demangleBackRefName(StringView &MangledName) {
  assert(startsWithDigit(MangledName));

  size_t I = MangledName[0] - '0';
  if (I >= Backrefs.NamesCount) {
    Error = true;
    return nullptr;
  }

  MangledName = MangledName.dropFront();
  return Backrefs.Names[I];
}

void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
  // Render this class template name into a string buffer so that we can
  // memorize it for the purpose of back-referencing.
  OutputStream OS;
  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
    // FIXME: Propagate out-of-memory as an error?
    std::terminate();
  Identifier->output(OS, OF_Default);
  OS << '\0';
  char *Name = OS.getBuffer();

  StringView Owned = copyString(Name);
  memorizeString(Owned);
  std::free(Name);
}

IdentifierNode *
Demangler::demangleTemplateInstantiationName(StringView &MangledName,
                                             NameBackrefBehavior NBB) {
  assert(MangledName.startsWith("?$"));
  MangledName.consumeFront("?$");

  BackrefContext OuterContext;
  std::swap(OuterContext, Backrefs);

  IdentifierNode *Identifier =
      demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
  if (!Error)
    Identifier->TemplateParams = demangleTemplateParameterList(MangledName);

  std::swap(OuterContext, Backrefs);
  if (Error)
    return nullptr;

  if (NBB & NBB_Template)
    memorizeIdentifier(Identifier);

  return Identifier;
}

NamedIdentifierNode *Demangler::demangleSimpleName(StringView &MangledName,
                                                   bool Memorize) {
  StringView S = demangleSimpleString(MangledName, Memorize);
  if (Error)
    return nullptr;

  NamedIdentifierNode *Name = Arena.alloc<NamedIdentifierNode>();
  Name->Name = S;
  return Name;
}

static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); }

static uint8_t rebasedHexDigitToNumber(char C) {
  assert(isRebasedHexDigit(C));
  return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
}

uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
  if (!MangledName.startsWith('?'))
    return MangledName.popFront();

  MangledName = MangledName.dropFront();
  if (MangledName.empty())
    goto CharLiteralError;

  if (MangledName.consumeFront('$')) {
    // Two hex digits
    if (MangledName.size() < 2)
      goto CharLiteralError;
    StringView Nibbles = MangledName.substr(0, 2);
    if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
      goto CharLiteralError;
    // Don't append the null terminator.
    uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
    uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
    MangledName = MangledName.dropFront(2);
    return (C1 << 4) | C2;
  }

  if (startsWithDigit(MangledName)) {
    const char *Lookup = ",/\\:. \n\t'-";
    char C = Lookup[MangledName[0] - '0'];
    MangledName = MangledName.dropFront();
    return C;
  }

  if (MangledName[0] >= 'a' && MangledName[0] <= 'z') {
    char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
                       '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE',
                       '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
                       '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
    char C = Lookup[MangledName[0] - 'a'];
    MangledName = MangledName.dropFront();
    return C;
  }

  if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') {
    char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
                       '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE',
                       '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
                       '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
    char C = Lookup[MangledName[0] - 'A'];
    MangledName = MangledName.dropFront();
    return C;
  }

CharLiteralError:
  Error = true;
  return '\0';
}

wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
  uint8_t C1, C2;

  C1 = demangleCharLiteral(MangledName);
  if (Error)
    goto WCharLiteralError;
  C2 = demangleCharLiteral(MangledName);
  if (Error)
    goto WCharLiteralError;

  return ((wchar_t)C1 << 8) | (wchar_t)C2;

WCharLiteralError:
  Error = true;
  return L'\0';
}

static void writeHexDigit(char *Buffer, uint8_t Digit) {
  assert(Digit <= 15);
  *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
}

static void outputHex(OutputStream &OS, unsigned C) {
  if (C == 0) {
    OS << "\\x00";
    return;
  }
  // It's easier to do the math if we can work from right to left, but we need
  // to print the numbers from left to right.  So render this into a temporary
  // buffer first, then output the temporary buffer.  Each byte is of the form
  // \xAB, which means that each byte needs 4 characters.  Since there are at
  // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
  char TempBuffer[17];

  ::memset(TempBuffer, 0, sizeof(TempBuffer));
  constexpr int MaxPos = 15;

  int Pos = MaxPos - 1;
  while (C != 0) {
    for (int I = 0; I < 2; ++I) {
      writeHexDigit(&TempBuffer[Pos--], C % 16);
      C /= 16;
    }
    TempBuffer[Pos--] = 'x';
    TempBuffer[Pos--] = '\\';
    assert(Pos >= 0);
  }
  OS << StringView(&TempBuffer[Pos + 1]);
}

static void outputEscapedChar(OutputStream &OS, unsigned C) {
  switch (C) {
  case '\'': // single quote
    OS << "\\\'";
    return;
  case '\"': // double quote
    OS << "\\\"";
    return;
  case '\\': // backslash
    OS << "\\\\";
    return;
  case '\a': // bell
    OS << "\\a";
    return;
  case '\b': // backspace
    OS << "\\b";
    return;
  case '\f': // form feed
    OS << "\\f";
    return;
  case '\n': // new line
    OS << "\\n";
    return;
  case '\r': // carriage return
    OS << "\\r";
    return;
  case '\t': // tab
    OS << "\\t";
    return;
  case '\v': // vertical tab
    OS << "\\v";
    return;
  default:
    break;
  }

  if (C > 0x1F && C < 0x7F) {
    // Standard ascii char.
    OS << (char)C;
    return;
  }

  outputHex(OS, C);
}

static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
  const uint8_t *End = StringBytes + Length - 1;
  unsigned Count = 0;
  while (Length > 0 && *End == 0) {
    --Length;
    --End;
    ++Count;
  }
  return Count;
}

static unsigned countEmbeddedNulls(const uint8_t *StringBytes,
                                   unsigned Length) {
  unsigned Result = 0;
  for (unsigned I = 0; I < Length; ++I) {
    if (*StringBytes++ == 0)
      ++Result;
  }
  return Result;
}

static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
                                  unsigned NumBytes) {
  assert(NumBytes > 0);

  // If the number of bytes is odd, this is guaranteed to be a char string.
  if (NumBytes % 2 == 1)
    return 1;

  // All strings can encode at most 32 bytes of data.  If it's less than that,
  // then we encoded the entire string.  In this case we check for a 1-byte,
  // 2-byte, or 4-byte null terminator.
  if (NumBytes < 32) {
    unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
    if (TrailingNulls >= 4)
      return 4;
    if (TrailingNulls >= 2)
      return 2;
    return 1;
  }

  // The whole string was not able to be encoded.  Try to look at embedded null
  // terminators to guess.  The heuristic is that we count all embedded null
  // terminators.  If more than 2/3 are null, it's a char32.  If more than 1/3
  // are null, it's a char16.  Otherwise it's a char8.  This obviously isn't
  // perfect and is biased towards languages that have ascii alphabets, but this
  // was always going to be best effort since the encoding is lossy.
  unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
  if (Nulls >= 2 * NumChars / 3)
    return 4;
  if (Nulls >= NumChars / 3)
    return 2;
  return 1;
}

static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
                                    unsigned CharIndex, unsigned CharBytes) {
  assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
  unsigned Offset = CharIndex * CharBytes;
  unsigned Result = 0;
  StringBytes = StringBytes + Offset;
  for (unsigned I = 0; I < CharBytes; ++I) {
    unsigned C = static_cast<unsigned>(StringBytes[I]);
    Result |= C << (8 * I);
  }
  return Result;
}

FunctionSymbolNode *Demangler::demangleVcallThunkNode(StringView &MangledName) {
  FunctionSymbolNode *FSN = Arena.alloc<FunctionSymbolNode>();
  VcallThunkIdentifierNode *VTIN = Arena.alloc<VcallThunkIdentifierNode>();
  FSN->Signature = Arena.alloc<ThunkSignatureNode>();
  FSN->Signature->FunctionClass = FC_NoParameterList;

  FSN->Name = demangleNameScopeChain(MangledName, VTIN);
  if (!Error)
    Error = !MangledName.consumeFront("$B");
  if (!Error)
    VTIN->OffsetInVTable = demangleUnsigned(MangledName);
  if (!Error)
    Error = !MangledName.consumeFront('A');
  if (!Error)
    FSN->Signature->CallConvention = demangleCallingConvention(MangledName);
  return (Error) ? nullptr : FSN;
}

EncodedStringLiteralNode *
Demangler::demangleStringLiteral(StringView &MangledName) {
  // This function uses goto, so declare all variables up front.
  OutputStream OS;
  StringView CRC;
  uint64_t StringByteSize;
  bool IsWcharT = false;
  bool IsNegative = false;
  size_t CrcEndPos = 0;
  char *ResultBuffer = nullptr;

  EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>();

  // Prefix indicating the beginning of a string literal
  if (!MangledName.consumeFront("@_"))
    goto StringLiteralError;
  if (MangledName.empty())
    goto StringLiteralError;

  // Char Type (regular or wchar_t)
  switch (MangledName.popFront()) {
  case '1':
    IsWcharT = true;
    DEMANGLE_FALLTHROUGH;
  case '0':
    break;
  default:
    goto StringLiteralError;
  }

  // Encoded Length
  std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
  if (Error || IsNegative)
    goto StringLiteralError;

  // CRC 32 (always 8 characters plus a terminator)
  CrcEndPos = MangledName.find('@');
  if (CrcEndPos == StringView::npos)
    goto StringLiteralError;
  CRC = MangledName.substr(0, CrcEndPos);
  MangledName = MangledName.dropFront(CrcEndPos + 1);
  if (MangledName.empty())
    goto StringLiteralError;

  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
    // FIXME: Propagate out-of-memory as an error?
    std::terminate();
  if (IsWcharT) {
    Result->Char = CharKind::Wchar;
    if (StringByteSize > 64)
      Result->IsTruncated = true;

    while (!MangledName.consumeFront('@')) {
      assert(StringByteSize >= 2);
      wchar_t W = demangleWcharLiteral(MangledName);
      if (StringByteSize != 2 || Result->IsTruncated)
        outputEscapedChar(OS, W);
      StringByteSize -= 2;
      if (Error)
        goto StringLiteralError;
    }
  } else {
    // The max byte length is actually 32, but some compilers mangled strings
    // incorrectly, so we have to assume it can go higher.
    constexpr unsigned MaxStringByteLength = 32 * 4;
    uint8_t StringBytes[MaxStringByteLength];

    unsigned BytesDecoded = 0;
    while (!MangledName.consumeFront('@')) {
      assert(StringByteSize >= 1);
      StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
    }

    if (StringByteSize > BytesDecoded)
      Result->IsTruncated = true;

    unsigned CharBytes =
        guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
    assert(StringByteSize % CharBytes == 0);
    switch (CharBytes) {
    case 1:
      Result->Char = CharKind::Char;
      break;
    case 2:
      Result->Char = CharKind::Char16;
      break;
    case 4:
      Result->Char = CharKind::Char32;
      break;
    default:
      DEMANGLE_UNREACHABLE;
    }
    const unsigned NumChars = BytesDecoded / CharBytes;
    for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
      unsigned NextChar =
          decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
      if (CharIndex + 1 < NumChars || Result->IsTruncated)
        outputEscapedChar(OS, NextChar);
    }
  }

  OS << '\0';
  ResultBuffer = OS.getBuffer();
  Result->DecodedString = copyString(ResultBuffer);
  std::free(ResultBuffer);
  return Result;

StringLiteralError:
  Error = true;
  return nullptr;
}

// Returns MangledName's prefix before the first '@', or an error if
// MangledName contains no '@' or the prefix has length 0.
StringView Demangler::demangleSimpleString(StringView &MangledName,
                                           bool Memorize) {
  StringView S;
  for (size_t i = 0; i < MangledName.size(); ++i) {
    if (MangledName[i] != '@')
      continue;
    if (i == 0)
      break;
    S = MangledName.substr(0, i);
    MangledName = MangledName.dropFront(i + 1);

    if (Memorize)
      memorizeString(S);
    return S;
  }

  Error = true;
  return {};
}

NamedIdentifierNode *
Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
  assert(MangledName.startsWith("?A"));
  MangledName.consumeFront("?A");

  NamedIdentifierNode *Node = Arena.alloc<NamedIdentifierNode>();
  Node->Name = "`anonymous namespace'";
  size_t EndPos = MangledName.find('@');
  if (EndPos == StringView::npos) {
    Error = true;
    return nullptr;
  }
  StringView NamespaceKey = MangledName.substr(0, EndPos);
  memorizeString(NamespaceKey);
  MangledName = MangledName.substr(EndPos + 1);
  return Node;
}

NamedIdentifierNode *
Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
  assert(startsWithLocalScopePattern(MangledName));

  NamedIdentifierNode *Identifier = Arena.alloc<NamedIdentifierNode>();
  MangledName.consumeFront('?');
  uint64_t Number = 0;
  bool IsNegative = false;
  std::tie(Number, IsNegative) = demangleNumber(MangledName);
  assert(!IsNegative);

  // One ? to terminate the number
  MangledName.consumeFront('?');

  assert(!Error);
  Node *Scope = parse(MangledName);
  if (Error)
    return nullptr;

  // Render the parent symbol's name into a buffer.
  OutputStream OS;
  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
    // FIXME: Propagate out-of-memory as an error?
    std::terminate();
  OS << '`';
  Scope->output(OS, OF_Default);
  OS << '\'';
  OS << "::`" << Number << "'";
  OS << '\0';
  char *Result = OS.getBuffer();
  Identifier->Name = copyString(Result);
  std::free(Result);
  return Identifier;
}

// Parses a type name in the form of A@B@C@@ which represents C::B::A.
QualifiedNameNode *
Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
  IdentifierNode *Identifier =
      demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
  if (Error)
    return nullptr;
  assert(Identifier);

  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
  if (Error)
    return nullptr;
  assert(QN);
  return QN;
}

// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
// Symbol names have slightly different rules regarding what can appear
// so we separate out the implementations for flexibility.
QualifiedNameNode *
Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
  // This is the final component of a symbol name (i.e. the leftmost component
  // of a mangled name.  Since the only possible template instantiation that
  // can appear in this context is a function template, and since those are
  // not saved for the purposes of name backreferences, only backref simple
  // names.
  IdentifierNode *Identifier =
      demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
  if (Error)
    return nullptr;

  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
  if (Error)
    return nullptr;

  if (Identifier->kind() == NodeKind::StructorIdentifier) {
    if (QN->Components->Count < 2) {
      Error = true;
      return nullptr;
    }
    StructorIdentifierNode *SIN =
        static_cast<StructorIdentifierNode *>(Identifier);
    Node *ClassNode = QN->Components->Nodes[QN->Components->Count - 2];
    SIN->Class = static_cast<IdentifierNode *>(ClassNode);
  }
  assert(QN);
  return QN;
}

IdentifierNode *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
                                                       bool Memorize) {
  // An inner-most name can be a back-reference, because a fully-qualified name
  // (e.g. Scope + Inner) can contain other fully qualified names inside of
  // them (for example template parameters), and these nested parameters can
  // refer to previously mangled types.
  if (startsWithDigit(MangledName))
    return demangleBackRefName(MangledName);

  if (MangledName.startsWith("?$"))
    return demangleTemplateInstantiationName(MangledName, NBB_Template);

  return demangleSimpleName(MangledName, Memorize);
}

IdentifierNode *
Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
                                         NameBackrefBehavior NBB) {
  if (startsWithDigit(MangledName))
    return demangleBackRefName(MangledName);
  if (MangledName.startsWith("?$"))
    return demangleTemplateInstantiationName(MangledName, NBB);
  if (MangledName.startsWith('?'))
    return demangleFunctionIdentifierCode(MangledName);
  return demangleSimpleName(MangledName, /*Memorize=*/(NBB & NBB_Simple) != 0);
}

IdentifierNode *Demangler::demangleNameScopePiece(StringView &MangledName) {
  if (startsWithDigit(MangledName))
    return demangleBackRefName(MangledName);

  if (MangledName.startsWith("?$"))
    return demangleTemplateInstantiationName(MangledName, NBB_Template);

  if (MangledName.startsWith("?A"))
    return demangleAnonymousNamespaceName(MangledName);

  if (startsWithLocalScopePattern(MangledName))
    return demangleLocallyScopedNamePiece(MangledName);

  return demangleSimpleName(MangledName, /*Memorize=*/true);
}

static NodeArrayNode *nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head,
                                          size_t Count) {
  NodeArrayNode *N = Arena.alloc<NodeArrayNode>();
  N->Count = Count;
  N->Nodes = Arena.allocArray<Node *>(Count);
  for (size_t I = 0; I < Count; ++I) {
    N->Nodes[I] = Head->N;
    Head = Head->Next;
  }
  return N;
}

QualifiedNameNode *
Demangler::demangleNameScopeChain(StringView &MangledName,
                                  IdentifierNode *UnqualifiedName) {
  NodeList *Head = Arena.alloc<NodeList>();

  Head->N = UnqualifiedName;

  size_t Count = 1;
  while (!MangledName.consumeFront("@")) {
    ++Count;
    NodeList *NewHead = Arena.alloc<NodeList>();
    NewHead->Next = Head;
    Head = NewHead;

    if (MangledName.empty()) {
      Error = true;
      return nullptr;
    }

    assert(!Error);
    IdentifierNode *Elem = demangleNameScopePiece(MangledName);
    if (Error)
      return nullptr;

    Head->N = Elem;
  }

  QualifiedNameNode *QN = Arena.alloc<QualifiedNameNode>();
  QN->Components = nodeListToNodeArray(Arena, Head, Count);
  return QN;
}

FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
  switch (MangledName.popFront()) {
  case '9':
    return FuncClass(FC_ExternC | FC_NoParameterList);
  case 'A':
    return FC_Private;
  case 'B':
    return FuncClass(FC_Private | FC_Far);
  case 'C':
    return FuncClass(FC_Private | FC_Static);
  case 'D':
    return FuncClass(FC_Private | FC_Static);
  case 'E':
    return FuncClass(FC_Private | FC_Virtual);
  case 'F':
    return FuncClass(FC_Private | FC_Virtual);
  case 'G':
    return FuncClass(FC_Private | FC_StaticThisAdjust);
  case 'H':
    return FuncClass(FC_Private | FC_StaticThisAdjust | FC_Far);
  case 'I':
    return FuncClass(FC_Protected);
  case 'J':
    return FuncClass(FC_Protected | FC_Far);
  case 'K':
    return FuncClass(FC_Protected | FC_Static);
  case 'L':
    return FuncClass(FC_Protected | FC_Static | FC_Far);
  case 'M':
    return FuncClass(FC_Protected | FC_Virtual);
  case 'N':
    return FuncClass(FC_Protected | FC_Virtual | FC_Far);
  case 'O':
    return FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust);
  case 'P':
    return FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust | FC_Far);
  case 'Q':
    return FuncClass(FC_Public);
  case 'R':
    return FuncClass(FC_Public | FC_Far);
  case 'S':
    return FuncClass(FC_Public | FC_Static);
  case 'T':
    return FuncClass(FC_Public | FC_Static | FC_Far);
  case 'U':
    return FuncClass(FC_Public | FC_Virtual);
  case 'V':
    return FuncClass(FC_Public | FC_Virtual | FC_Far);
  case 'W':
    return FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust);
  case 'X':
    return FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust | FC_Far);
  case 'Y':
    return FuncClass(FC_Global);
  case 'Z':
    return FuncClass(FC_Global | FC_Far);
  case '$': {
    FuncClass VFlag = FC_VirtualThisAdjust;
    if (MangledName.consumeFront('R'))
      VFlag = FuncClass(VFlag | FC_VirtualThisAdjustEx);
    if (MangledName.empty())
      break;
    switch (MangledName.popFront()) {
    case '0':
      return FuncClass(FC_Private | FC_Virtual | VFlag);
    case '1':
      return FuncClass(FC_Private | FC_Virtual | VFlag | FC_Far);
    case '2':
      return FuncClass(FC_Protected | FC_Virtual | VFlag);
    case '3':
      return FuncClass(FC_Protected | FC_Virtual | VFlag | FC_Far);
    case '4':
      return FuncClass(FC_Public | FC_Virtual | VFlag);
    case '5':
      return FuncClass(FC_Public | FC_Virtual | VFlag | FC_Far);
    }
  }
  }

  Error = true;
  return FC_Public;
}

CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
  if (MangledName.empty()) {
    Error = true;
    return CallingConv::None;
  }

  switch (MangledName.popFront()) {
  case 'A':
  case 'B':
    return CallingConv::Cdecl;
  case 'C':
  case 'D':
    return CallingConv::Pascal;
  case 'E':
  case 'F':
    return CallingConv::Thiscall;
  case 'G':
  case 'H':
    return CallingConv::Stdcall;
  case 'I':
  case 'J':
    return CallingConv::Fastcall;
  case 'M':
  case 'N':
    return CallingConv::Clrcall;
  case 'O':
  case 'P':
    return CallingConv::Eabi;
  case 'Q':
    return CallingConv::Vectorcall;
  }

  return CallingConv::None;
}

StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
  assert(std::isdigit(MangledName.front()));

  switch (MangledName.popFront()) {
  case '0':
    return StorageClass::PrivateStatic;
  case '1':
    return StorageClass::ProtectedStatic;
  case '2':
    return StorageClass::PublicStatic;
  case '3':
    return StorageClass::Global;
  case '4':
    return StorageClass::FunctionLocalStatic;
  }
  Error = true;
  return StorageClass::None;
}

std::pair<Qualifiers, bool>
Demangler::demangleQualifiers(StringView &MangledName) {
  if (MangledName.empty()) {
    Error = true;
    return std::make_pair(Q_None, false);
  }

  switch (MangledName.popFront()) {
  // Member qualifiers
  case 'Q':
    return std::make_pair(Q_None, true);
  case 'R':
    return std::make_pair(Q_Const, true);
  case 'S':
    return std::make_pair(Q_Volatile, true);
  case 'T':
    return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
  // Non-Member qualifiers
  case 'A':
    return std::make_pair(Q_None, false);
  case 'B':
    return std::make_pair(Q_Const, false);
  case 'C':
    return std::make_pair(Q_Volatile, false);
  case 'D':
    return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
  }
  Error = true;
  return std::make_pair(Q_None, false);
}

// <variable-type> ::= <type> <cvr-qualifiers>
//                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
TypeNode *Demangler::demangleType(StringView &MangledName,
                                  QualifierMangleMode QMM) {
  Qualifiers Quals = Q_None;
  bool IsMember = false;
  if (QMM == QualifierMangleMode::Mangle) {
    std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
  } else if (QMM == QualifierMangleMode::Result) {
    if (MangledName.consumeFront('?'))
      std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
  }

  if (MangledName.empty()) {
    Error = true;
    return nullptr;
  }

  TypeNode *Ty = nullptr;
  if (isTagType(MangledName))
    Ty = demangleClassType(MangledName);
  else if (isPointerType(MangledName)) {
    if (isMemberPointer(MangledName, Error))
      Ty = demangleMemberPointerType(MangledName);
    else if (!Error)
      Ty = demanglePointerType(MangledName);
    else
      return nullptr;
  } else if (isArrayType(MangledName))
    Ty = demangleArrayType(MangledName);
  else if (isFunctionType(MangledName)) {
    if (MangledName.consumeFront("$$A8@@"))
      Ty = demangleFunctionType(MangledName, true);
    else {
      assert(MangledName.startsWith("$$A6"));
      MangledName.consumeFront("$$A6");
      Ty = demangleFunctionType(MangledName, false);
    }
  } else if (isCustomType(MangledName)) {
    Ty = demangleCustomType(MangledName);
  } else {
    Ty = demanglePrimitiveType(MangledName);
  }

  if (!Ty || Error)
    return Ty;
  Ty->Quals = Qualifiers(Ty->Quals | Quals);
  return Ty;
}

bool Demangler::demangleThrowSpecification(StringView &MangledName) {
  if (MangledName.consumeFront("_E"))
    return true;
  if (MangledName.consumeFront('Z'))
    return false;

  Error = true;
  return false;
}

FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName,
                                                       bool HasThisQuals) {
  FunctionSignatureNode *FTy = Arena.alloc<FunctionSignatureNode>();

  if (HasThisQuals) {
    FTy->Quals = demanglePointerExtQualifiers(MangledName);
    FTy->RefQualifier = demangleFunctionRefQualifier(MangledName);
    FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
  }

  // Fields that appear on both member and non-member functions.
  FTy->CallConvention = demangleCallingConvention(MangledName);

  // <return-type> ::= <type>
  //               ::= @ # structors (they have no declared return type)
  bool IsStructor = MangledName.consumeFront('@');
  if (!IsStructor)
    FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);

  FTy->Params = demangleFunctionParameterList(MangledName);

  FTy->IsNoexcept = demangleThrowSpecification(MangledName);

  return FTy;
}

FunctionSymbolNode *
Demangler::demangleFunctionEncoding(StringView &MangledName) {
  FuncClass ExtraFlags = FC_None;
  if (MangledName.consumeFront("$$J0"))
    ExtraFlags = FC_ExternC;

  if (MangledName.empty()) {
    Error = true;
    return nullptr;
  }

  FuncClass FC = demangleFunctionClass(MangledName);
  FC = FuncClass(ExtraFlags | FC);

  FunctionSignatureNode *FSN = nullptr;
  ThunkSignatureNode *TTN = nullptr;
  if (FC & FC_StaticThisAdjust) {
    TTN = Arena.alloc<ThunkSignatureNode>();
    TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName);
  } else if (FC & FC_VirtualThisAdjust) {
    TTN = Arena.alloc<ThunkSignatureNode>();
    if (FC & FC_VirtualThisAdjustEx) {
      TTN->ThisAdjust.VBPtrOffset = demangleSigned(MangledName);
      TTN->ThisAdjust.VBOffsetOffset = demangleSigned(MangledName);
    }
    TTN->ThisAdjust.VtordispOffset = demangleSigned(MangledName);
    TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName);
  }

  if (FC & FC_NoParameterList) {
    // This is an extern "C" function whose full signature hasn't been mangled.
    // This happens when we need to mangle a local symbol inside of an extern
    // "C" function.
    FSN = Arena.alloc<FunctionSignatureNode>();
  } else {
    bool HasThisQuals = !(FC & (FC_Global | FC_Static));
    FSN = demangleFunctionType(MangledName, HasThisQuals);
  }

  if (Error)
    return nullptr;

  if (TTN) {
    *static_cast<FunctionSignatureNode *>(TTN) = *FSN;
    FSN = TTN;
  }
  FSN->FunctionClass = FC;

  FunctionSymbolNode *Symbol = Arena.alloc<FunctionSymbolNode>();
  Symbol->Signature = FSN;
  return Symbol;
}

CustomTypeNode *Demangler::demangleCustomType(StringView &MangledName) {
  assert(MangledName.startsWith('?'));
  MangledName.popFront();

  CustomTypeNode *CTN = Arena.alloc<CustomTypeNode>();
  CTN->Identifier = demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
  if (!MangledName.consumeFront('@'))
    Error = true;
  if (Error)
    return nullptr;
  return CTN;
}

// Reads a primitive type.
PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
  if (MangledName.consumeFront("$$T"))
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Nullptr);

  switch (MangledName.popFront()) {
  case 'X':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Void);
  case 'D':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char);
  case 'C':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Schar);
  case 'E':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uchar);
  case 'F':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Short);
  case 'G':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ushort);
  case 'H':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Int);
  case 'I':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint);
  case 'J':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Long);
  case 'K':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ulong);
  case 'M':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Float);
  case 'N':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Double);
  case 'O':
    return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ldouble);
  case '_': {
    if (MangledName.empty()) {
      Error = true;
      return nullptr;
    }
    switch (MangledName.popFront()) {
    case 'N':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Bool);
    case 'J':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Int64);
    case 'K':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint64);
    case 'W':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Wchar);
    case 'S':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char16);
    case 'U':
      return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char32);
    }
    break;
  }
  }
  Error = true;
  return nullptr;
}

TagTypeNode *Demangler::demangleClassType(StringView &MangledName) {
  TagTypeNode *TT = nullptr;

  switch (MangledName.popFront()) {
  case 'T':
    TT = Arena.alloc<TagTypeNode>(TagKind::Union);
    break;
  case 'U':
    TT = Arena.alloc<TagTypeNode>(TagKind::Struct);
    break;
  case 'V':
    TT = Arena.alloc<TagTypeNode>(TagKind::Class);
    break;
  case 'W':
    if (!MangledName.consumeFront('4')) {
      Error = true;
      return nullptr;
    }
    TT = Arena.alloc<TagTypeNode>(TagKind::Enum);
    break;
  default:
    assert(false);
  }

  TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
  return TT;
}

// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
//                       # the E is required for 64-bit non-static pointers
PointerTypeNode *Demangler::demanglePointerType(StringView &MangledName) {
  PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>();

  std::tie(Pointer->Quals, Pointer->Affinity) =
      demanglePointerCVQualifiers(MangledName);

  if (MangledName.consumeFront("6")) {
    Pointer->Pointee = demangleFunctionType(MangledName, false);
    return Pointer;
  }

  Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
  Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);

  Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
  return Pointer;
}

PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
  PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>();

  std::tie(Pointer->Quals, Pointer->Affinity) =
      demanglePointerCVQualifiers(MangledName);
  assert(Pointer->Affinity == PointerAffinity::Pointer);

  Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
  Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);

  // isMemberPointer() only returns true if there is at least one character
  // after the qualifiers.
  if (MangledName.consumeFront("8")) {
    Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
    Pointer->Pointee = demangleFunctionType(MangledName, true);
  } else {
    Qualifiers PointeeQuals = Q_None;
    bool IsMember = false;
    std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
    assert(IsMember || Error);
    Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);

    Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
    if (Pointer->Pointee)
      Pointer->Pointee->Quals = PointeeQuals;
  }

  return Pointer;
}

Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
  Qualifiers Quals = Q_None;
  if (MangledName.consumeFront('E'))
    Quals = Qualifiers(Quals | Q_Pointer64);
  if (MangledName.consumeFront('I'))
    Quals = Qualifiers(Quals | Q_Restrict);
  if (MangledName.consumeFront('F'))
    Quals = Qualifiers(Quals | Q_Unaligned);

  return Quals;
}

ArrayTypeNode *Demangler::demangleArrayType(StringView &MangledName) {
  assert(MangledName.front() == 'Y');
  MangledName.popFront();

  uint64_t Rank = 0;
  bool IsNegative = false;
  std::tie(Rank, IsNegative) = demangleNumber(MangledName);
  if (IsNegative || Rank == 0) {
    Error = true;
    return nullptr;
  }

  ArrayTypeNode *ATy = Arena.alloc<ArrayTypeNode>();
  NodeList *Head = Arena.alloc<NodeList>();
  NodeList *Tail = Head;

  for (uint64_t I = 0; I < Rank; ++I) {
    uint64_t D = 0;
    std::tie(D, IsNegative) = demangleNumber(MangledName);
    if (Error || IsNegative) {
      Error = true;
      return nullptr;
    }
    Tail->N = Arena.alloc<IntegerLiteralNode>(D, IsNegative);
    if (I + 1 < Rank) {
      Tail->Next = Arena.alloc<NodeList>();
      Tail = Tail->Next;
    }
  }
  ATy->Dimensions = nodeListToNodeArray(Arena, Head, Rank);

  if (MangledName.consumeFront("$$C")) {
    bool IsMember = false;
    std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
    if (IsMember) {
      Error = true;
      return nullptr;
    }
  }

  ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
  return ATy;
}

// Reads a function or a template parameters.
NodeArrayNode *
Demangler::demangleFunctionParameterList(StringView &MangledName) {
  // Empty parameter list.
  if (MangledName.consumeFront('X'))
    return {};

  NodeList *Head = Arena.alloc<NodeList>();
  NodeList **Current = &Head;
  size_t Count = 0;
  while (!Error && !MangledName.startsWith('@') &&
         !MangledName.startsWith('Z')) {
    ++Count;

    if (startsWithDigit(MangledName)) {
      size_t N = MangledName[0] - '0';
      if (N >= Backrefs.FunctionParamCount) {
        Error = true;
        return {};
      }
      MangledName = MangledName.dropFront();

      *Current = Arena.alloc<NodeList>();
      (*Current)->N = Backrefs.FunctionParams[N];
      Current = &(*Current)->Next;
      continue;
    }

    size_t OldSize = MangledName.size();

    *Current = Arena.alloc<NodeList>();
    TypeNode *TN = demangleType(MangledName, QualifierMangleMode::Drop);
    if (!TN || Error)
      return nullptr;

    (*Current)->N = TN;

    size_t CharsConsumed = OldSize - MangledName.size();
    assert(CharsConsumed != 0);

    // Single-letter types are ignored for backreferences because memorizing
    // them doesn't save anything.
    if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
      Backrefs.FunctionParams[Backrefs.FunctionParamCount++] = TN;

    Current = &(*Current)->Next;
  }

  if (Error)
    return {};

  NodeArrayNode *NA = nodeListToNodeArray(Arena, Head, Count);
  // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
  // list or '@' (non variadic).  Careful not to consume "@Z", as in that case
  // the following Z could be a throw specifier.
  if (MangledName.consumeFront('@'))
    return NA;

  if (MangledName.consumeFront('Z')) {
    // This is a variadic parameter list.  We probably need a variadic node to
    // append to the end.
    return NA;
  }

  Error = true;
  return {};
}

NodeArrayNode *
Demangler::demangleTemplateParameterList(StringView &MangledName) {
  NodeList *Head;
  NodeList **Current = &Head;
  size_t Count = 0;

  while (!Error && !MangledName.startsWith('@')) {
    if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
        MangledName.consumeFront("$$$V") || MangledName.consumeFront("$$Z")) {
      // parameter pack separator
      continue;
    }

    ++Count;

    // Template parameter lists don't participate in back-referencing.
    *Current = Arena.alloc<NodeList>();

    NodeList &TP = **Current;

    TemplateParameterReferenceNode *TPRN = nullptr;
    if (MangledName.consumeFront("$$Y")) {
      // Template alias
      TP.N = demangleFullyQualifiedTypeName(MangledName);
    } else if (MangledName.consumeFront("$$B")) {
      // Array
      TP.N = demangleType(MangledName, QualifierMangleMode::Drop);
    } else if (MangledName.consumeFront("$$C")) {
      // Type has qualifiers.
      TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
    } else if (MangledName.startsWith("$1") || MangledName.startsWith("$H") ||
               MangledName.startsWith("$I") || MangledName.startsWith("$J")) {
      // Pointer to member
      TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
      TPRN->IsMemberPointer = true;

      MangledName = MangledName.dropFront();
      // 1 - single inheritance       <name>
      // H - multiple inheritance     <name> <number>
      // I - virtual inheritance      <name> <number> <number> <number>
      // J - unspecified inheritance  <name> <number> <number> <number>
      char InheritanceSpecifier = MangledName.popFront();
      SymbolNode *S = nullptr;
      if (MangledName.startsWith('?')) {
        S = parse(MangledName);
        if (Error)
          return nullptr;
        memorizeIdentifier(S->Name->getUnqualifiedIdentifier());
      }

      switch (InheritanceSpecifier) {
      case 'J':
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        DEMANGLE_FALLTHROUGH;
      case 'I':
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        DEMANGLE_FALLTHROUGH;
      case 'H':
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        DEMANGLE_FALLTHROUGH;
      case '1':
        break;
      default:
        Error = true;
        break;
      }
      TPRN->Affinity = PointerAffinity::Pointer;
      TPRN->Symbol = S;
    } else if (MangledName.startsWith("$E?")) {
      MangledName.consumeFront("$E");
      // Reference to symbol
      TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
      TPRN->Symbol = parse(MangledName);
      TPRN->Affinity = PointerAffinity::Reference;
    } else if (MangledName.startsWith("$F") || MangledName.startsWith("$G")) {
      TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();

      // Data member pointer.
      MangledName = MangledName.dropFront();
      char InheritanceSpecifier = MangledName.popFront();

      switch (InheritanceSpecifier) {
      case 'G':
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        DEMANGLE_FALLTHROUGH;
      case 'F':
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
            demangleSigned(MangledName);
        DEMANGLE_FALLTHROUGH;
      case '0':
        break;
      default:
        Error = true;
        break;
      }
      TPRN->IsMemberPointer = true;

    } else if (MangledName.consumeFront("$0")) {
      // Integral non-type template parameter
      bool IsNegative = false;
      uint64_t Value = 0;
      std::tie(Value, IsNegative) = demangleNumber(MangledName);

      TP.N = Arena.alloc<IntegerLiteralNode>(Value, IsNegative);
    } else {
      TP.N = demangleType(MangledName, QualifierMangleMode::Drop);
    }
    if (Error)
      return nullptr;

    Current = &TP.Next;
  }

  if (Error)
    return nullptr;

  // Template parameter lists cannot be variadic, so it can only be terminated
  // by @.
  if (MangledName.consumeFront('@'))
    return nodeListToNodeArray(Arena, Head, Count);
  Error = true;
  return nullptr;
}

void Demangler::dumpBackReferences() {
  std::printf("%d function parameter backreferences\n",
              (int)Backrefs.FunctionParamCount);

  // Create an output stream so we can render each type.
  OutputStream OS;
  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
    std::terminate();
  for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
    OS.setCurrentPosition(0);

    TypeNode *T = Backrefs.FunctionParams[I];
    T->output(OS, OF_Default);

    std::printf("  [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
                OS.getBuffer());
  }
  std::free(OS.getBuffer());

  if (Backrefs.FunctionParamCount > 0)
    std::printf("\n");
  std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
  for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
    std::printf("  [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I]->Name.size(),
                Backrefs.Names[I]->Name.begin());
  }
  if (Backrefs.NamesCount > 0)
    std::printf("\n");
}

char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
                              int *Status, MSDemangleFlags Flags) {
  int InternalStatus = demangle_success;
  Demangler D;
  OutputStream S;

  StringView Name{MangledName};
  SymbolNode *AST = D.parse(Name);

  if (Flags & MSDF_DumpBackrefs)
    D.dumpBackReferences();

  if (D.Error)
    InternalStatus = demangle_invalid_mangled_name;
  else if (!initializeOutputStream(Buf, N, S, 1024))
    InternalStatus = demangle_memory_alloc_failure;
  else {
    AST->output(S, OF_Default);
    S += '\0';
    if (N != nullptr)
      *N = S.getCurrentPosition();
    Buf = S.getBuffer();
  }

  if (Status)
    *Status = InternalStatus;
  return InternalStatus == demangle_success ? Buf : nullptr;
}
