Add a Microsoft Demangler.

This adds initial support for a demangling library (LLVMDemangle)
and tool (llvm-undname) for demangling Microsoft names.  This
doesn't cover 100% of cases and there are some known limitations
which I intend to address in followup patches, at least until such
time that we have (near) 100% test coverage matching up with all
of the test cases in clang/test/CodeGenCXX/mangle-ms-*.

Differential Revision: https://reviews.llvm.org/D49552

llvm-svn: 337584
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
new file mode 100644
index 0000000..eb27e61
--- /dev/null
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -0,0 +1,1533 @@
+//===- MicrosoftDemangle.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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/Demangle.h"
+
+#include "Compiler.h"
+#include "StringView.h"
+#include "Utility.h"
+
+#include <cctype>
+
+// This memory allocator is extremely fast, but it doesn't call dtors
+// for allocated objects. That means you can't use STL containers
+// (such as std::vector) with this allocator. But it pays off --
+// the demangler is 3x faster with this allocator compared to one with
+// STL containers.
+namespace {
+class ArenaAllocator {
+  struct AllocatorNode {
+    uint8_t *Buf = nullptr;
+    size_t Used = 0;
+    AllocatorNode *Next = nullptr;
+  };
+
+public:
+  ArenaAllocator() : Head(new AllocatorNode) { Head->Buf = new uint8_t[Unit]; }
+
+  ~ArenaAllocator() {
+    while (Head) {
+      assert(Head->Buf);
+      delete[] Head->Buf;
+      Head = Head->Next;
+    }
+  }
+
+  void *alloc(size_t Size) {
+    assert(Size < Unit);
+    assert(Head && Head->Buf);
+
+    uint8_t *P = Head->Buf + Head->Used;
+    Head->Used += Size;
+    if (Head->Used < Unit)
+      return P;
+
+    AllocatorNode *NewHead = new AllocatorNode;
+    NewHead->Buf = new uint8_t[ArenaAllocator::Unit];
+    NewHead->Next = Head;
+    Head = NewHead;
+    NewHead->Used = Size;
+    return NewHead->Buf;
+  }
+
+private:
+  static constexpr size_t Unit = 4096;
+
+  AllocatorNode *Head = nullptr;
+};
+} // namespace
+
+static bool startsWithDigit(StringView S) {
+  return !S.empty() && std::isdigit(S.front());
+}
+
+// Writes a space if the last token does not end with a punctuation.
+static void outputSpaceIfNecessary(OutputStream &OS) {
+  if (OS.empty())
+    return;
+
+  char C = OS.back();
+  if (isalnum(C) || C == '>')
+    OS << " ";
+}
+
+void *operator new(size_t Size, ArenaAllocator &A) { return A.alloc(Size); }
+
+// Storage classes
+enum Qualifiers : uint8_t {
+  Q_None = 0,
+  Q_Const = 1 << 0,
+  Q_Volatile = 1 << 1,
+  Q_Far = 1 << 2,
+  Q_Huge = 1 << 3,
+  Q_Unaligned = 1 << 4,
+  Q_Restrict = 1 << 5,
+  Q_Pointer64 = 1 << 6
+};
+
+enum class StorageClass : uint8_t {
+  None,
+  PrivateStatic,
+  ProtectedStatic,
+  PublicStatic,
+  Global,
+  FunctionLocalStatic
+};
+
+enum class QualifierMangleMode { Drop, Mangle, Result };
+enum class QualifierMangleLocation { Member, NonMember, Detect };
+
+// Calling conventions
+enum class CallingConv : uint8_t {
+  None,
+  Cdecl,
+  Pascal,
+  Thiscall,
+  Stdcall,
+  Fastcall,
+  Clrcall,
+  Eabi,
+  Vectorcall,
+  Regcall,
+};
+
+enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
+
+// Types
+enum class PrimTy : uint8_t {
+  Unknown,
+  None,
+  Function,
+  Ptr,
+  Ref,
+  Array,
+
+  Struct,
+  Union,
+  Class,
+  Enum,
+
+  Void,
+  Bool,
+  Char,
+  Schar,
+  Uchar,
+  Short,
+  Ushort,
+  Int,
+  Uint,
+  Long,
+  Ulong,
+  Int64,
+  Uint64,
+  Wchar,
+  Float,
+  Double,
+  Ldouble,
+};
+
+// Function classes
+enum FuncClass : uint8_t {
+  Public = 1 << 0,
+  Protected = 1 << 1,
+  Private = 1 << 2,
+  Global = 1 << 3,
+  Static = 1 << 4,
+  Virtual = 1 << 5,
+  FFar = 1 << 6,
+};
+
+namespace {
+
+struct Type;
+
+// Represents a list of parameters (template params or function arguments.
+// It's represented as a linked list.
+struct ParamList {
+  Type *Current = nullptr;
+
+  ParamList *Next = nullptr;
+};
+
+// The type class. Mangled symbols are first parsed and converted to
+// this type and then converted to string.
+struct Type {
+  virtual ~Type() {}
+
+  virtual Type *clone(ArenaAllocator &Arena) const;
+
+  // Write the "first half" of a given type.  This is a static functions to
+  // give the code a chance to do processing that is common to a subset of
+  // subclasses
+  static void outputPre(OutputStream &OS, Type &Ty);
+
+  // Write the "second half" of a given type.  This is a static functions to
+  // give the code a chance to do processing that is common to a subset of
+  // subclasses
+  static void outputPost(OutputStream &OS, Type &Ty);
+
+  virtual void outputPre(OutputStream &OS);
+  virtual void outputPost(OutputStream &OS);
+
+  // Primitive type such as Int.
+  PrimTy Prim = PrimTy::Unknown;
+
+  Qualifiers Quals = Q_None;
+  StorageClass Storage = StorageClass::None; // storage class
+};
+
+// Represents an identifier which may be a template.
+struct Name {
+  // Name read from an MangledName string.
+  StringView Str;
+
+  // Overloaded operators are represented as special BackReferences in mangled
+  // symbols. If this is an operator name, "op" has an operator name (e.g.
+  // ">>"). Otherwise, empty.
+  StringView Operator;
+
+  // Template parameters. Null if not a template.
+  ParamList TemplateParams;
+
+  // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
+  Name *Next = nullptr;
+};
+
+struct PointerType : public Type {
+  Type *clone(ArenaAllocator &Arena) const override;
+  void outputPre(OutputStream &OS);
+  void outputPost(OutputStream &OS) override;
+
+  bool isMemberPointer() const { return false; }
+
+  // Represents a type X in "a pointer to X", "a reference to X",
+  // "an array of X", or "a function returning X".
+  Type *Pointee = nullptr;
+};
+
+struct FunctionType : public Type {
+  Type *clone(ArenaAllocator &Arena) const override;
+  void outputPre(OutputStream &OS);
+  void outputPost(OutputStream &OS);
+
+  Type *ReturnType = nullptr;
+  // If this is a reference, the type of reference.
+  ReferenceKind RefKind;
+
+  CallingConv CallConvention;
+  FuncClass FunctionClass;
+
+  ParamList Params;
+};
+
+struct UdtType : public Type {
+  Type *clone(ArenaAllocator &Arena) const override;
+  void outputPre(OutputStream &OS) override;
+
+  Name *UdtName = nullptr;
+};
+
+struct ArrayType : public Type {
+  Type *clone(ArenaAllocator &Arena) const override;
+  void outputPre(OutputStream &OS) override;
+  void outputPost(OutputStream &OS) override;
+
+  // Either NextDimension or ElementType will be valid.
+  ArrayType *NextDimension = nullptr;
+  uint32_t ArrayDimension = 0;
+
+  Type *ElementType = nullptr;
+};
+
+} // namespace
+
+static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
+  outputSpaceIfNecessary(OS);
+
+  switch (CC) {
+  case CallingConv::Cdecl:
+    OS << "__cdecl";
+    break;
+  case CallingConv::Fastcall:
+    OS << "__fastcall";
+    break;
+  case CallingConv::Pascal:
+    OS << "__pascal";
+    break;
+  case CallingConv::Regcall:
+    OS << "__regcall";
+    break;
+  case CallingConv::Stdcall:
+    OS << "__stdcall";
+    break;
+  case CallingConv::Thiscall:
+    OS << "__thiscall";
+    break;
+  case CallingConv::Eabi:
+    OS << "__eabi";
+    break;
+  case CallingConv::Vectorcall:
+    OS << "__vectorcall";
+    break;
+  case CallingConv::Clrcall:
+    OS << "__clrcall";
+    break;
+  default:
+    break;
+  }
+}
+
+// Write a function or template parameter list.
+static void outputParameterList(OutputStream &OS, const ParamList &Params) {
+  const ParamList *Head = &Params;
+  while (Head) {
+    Type::outputPre(OS, *Head->Current);
+    Type::outputPost(OS, *Head->Current);
+
+    Head = Head->Next;
+
+    if (Head)
+      OS << ", ";
+  }
+}
+
+static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
+  if (!TheName.TemplateParams.Current)
+    return;
+
+  OS << "<";
+  outputParameterList(OS, TheName.TemplateParams);
+  OS << ">";
+}
+
+static void outputName(OutputStream &OS, const Name *TheName) {
+  if (!TheName)
+    return;
+
+  outputSpaceIfNecessary(OS);
+
+  // Print out namespaces or outer class BackReferences.
+  for (; TheName->Next; TheName = TheName->Next) {
+    OS << TheName->Str;
+    outputTemplateParams(OS, *TheName);
+    OS << "::";
+  }
+
+  // Print out a regular name.
+  if (TheName->Operator.empty()) {
+    OS << TheName->Str;
+    outputTemplateParams(OS, *TheName);
+    return;
+  }
+
+  // Print out ctor or dtor.
+  if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
+    OS << TheName->Str;
+    outputTemplateParams(OS, *TheName);
+    OS << "::";
+    if (TheName->Operator == "dtor")
+      OS << "~";
+    OS << TheName->Str;
+    outputTemplateParams(OS, *TheName);
+    return;
+  }
+
+  // Print out an overloaded operator.
+  if (!TheName->Str.empty())
+    OS << TheName->Str << "::";
+  OS << "operator" << TheName->Operator;
+}
+
+namespace {
+
+Type *Type::clone(ArenaAllocator &Arena) const {
+  return new (Arena) Type(*this);
+}
+
+// Write the "first half" of a given type.
+void Type::outputPre(OutputStream &OS, Type &Ty) {
+  // Function types require custom handling of const and static so we
+  // handle them separately.  All other types use the same decoration
+  // for these modifiers, so handle them here in common code.
+  if (Ty.Prim == PrimTy::Function) {
+    Ty.outputPre(OS);
+    return;
+  }
+
+  switch (Ty.Storage) {
+  case StorageClass::PrivateStatic:
+  case StorageClass::PublicStatic:
+  case StorageClass::ProtectedStatic:
+    OS << "static ";
+  default:
+    break;
+  }
+  Ty.outputPre(OS);
+
+  if (Ty.Quals & Q_Const) {
+    outputSpaceIfNecessary(OS);
+    OS << "const";
+  }
+
+  if (Ty.Quals & Q_Volatile) {
+    outputSpaceIfNecessary(OS);
+    OS << "volatile";
+  }
+}
+
+// Write the "second half" of a given type.
+void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
+
+void Type::outputPre(OutputStream &OS) {
+  switch (Prim) {
+  case PrimTy::Void:
+    OS << "void";
+    break;
+  case PrimTy::Bool:
+    OS << "bool";
+    break;
+  case PrimTy::Char:
+    OS << "char";
+    break;
+  case PrimTy::Schar:
+    OS << "signed char";
+    break;
+  case PrimTy::Uchar:
+    OS << "unsigned char";
+    break;
+  case PrimTy::Short:
+    OS << "short";
+    break;
+  case PrimTy::Ushort:
+    OS << "unsigned short";
+    break;
+  case PrimTy::Int:
+    OS << "int";
+    break;
+  case PrimTy::Uint:
+    OS << "unsigned int";
+    break;
+  case PrimTy::Long:
+    OS << "long";
+    break;
+  case PrimTy::Ulong:
+    OS << "unsigned long";
+    break;
+  case PrimTy::Int64:
+    OS << "__int64";
+    break;
+  case PrimTy::Uint64:
+    OS << "unsigned __int64";
+    break;
+  case PrimTy::Wchar:
+    OS << "wchar_t";
+    break;
+  case PrimTy::Float:
+    OS << "float";
+    break;
+  case PrimTy::Double:
+    OS << "double";
+    break;
+  case PrimTy::Ldouble:
+    OS << "long double";
+    break;
+  default:
+    assert(false && "Invalid primitive type!");
+  }
+}
+void Type::outputPost(OutputStream &OS) {}
+
+Type *PointerType::clone(ArenaAllocator &Arena) const {
+  return new (Arena) PointerType(*this);
+}
+
+void PointerType::outputPre(OutputStream &OS) {
+  Type::outputPre(OS, *Pointee);
+
+  outputSpaceIfNecessary(OS);
+
+  if (Quals & Q_Unaligned)
+    OS << "__unaligned ";
+
+  // "[]" and "()" (for function parameters) take precedence over "*",
+  // so "int *x(int)" means "x is a function returning int *". We need
+  // parentheses to supercede the default precedence. (e.g. we want to
+  // emit something like "int (*x)(int)".)
+  if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
+    OS << "(";
+
+  if (Prim == PrimTy::Ptr)
+    OS << "*";
+  else
+    OS << "&";
+
+  // if (Ty.Quals & Q_Pointer64)
+  //  OS << " __ptr64";
+  if (Quals & Q_Restrict)
+    OS << " __restrict";
+}
+
+void PointerType::outputPost(OutputStream &OS) {
+  if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
+    OS << ")";
+
+  Type::outputPost(OS, *Pointee);
+}
+
+Type *FunctionType::clone(ArenaAllocator &Arena) const {
+  return new (Arena) FunctionType(*this);
+}
+
+void FunctionType::outputPre(OutputStream &OS) {
+  if (!(FunctionClass & Global)) {
+    if (FunctionClass & Static)
+      OS << "static ";
+  }
+
+  if (ReturnType)
+    Type::outputPre(OS, *ReturnType);
+
+  outputCallingConvention(OS, CallConvention);
+}
+
+void FunctionType::outputPost(OutputStream &OS) {
+  OS << "(";
+  outputParameterList(OS, Params);
+  OS << ")";
+  if (Quals & Q_Const)
+    OS << " const";
+  if (Quals & Q_Volatile)
+    OS << " volatile";
+  return;
+}
+
+Type *UdtType::clone(ArenaAllocator &Arena) const {
+  return new (Arena) UdtType(*this);
+}
+
+void UdtType::outputPre(OutputStream &OS) {
+  switch (Prim) {
+  case PrimTy::Class:
+    OS << "class ";
+    break;
+  case PrimTy::Struct:
+    OS << "struct ";
+    break;
+  case PrimTy::Union:
+    OS << "union ";
+    break;
+  case PrimTy::Enum:
+    OS << "enum ";
+    break;
+  default:
+    assert(false && "Not a udt type!");
+  }
+
+  outputName(OS, UdtName);
+}
+
+Type *ArrayType::clone(ArenaAllocator &Arena) const {
+  return new (Arena) ArrayType(*this);
+}
+
+void ArrayType::outputPre(OutputStream &OS) {
+  Type::outputPre(OS, *ElementType);
+}
+
+void ArrayType::outputPost(OutputStream &OS) {
+  if (ArrayDimension > 0)
+    OS << "[" << ArrayDimension << "]";
+  if (NextDimension)
+    Type::outputPost(OS, *NextDimension);
+  else if (ElementType)
+    Type::outputPost(OS, *ElementType);
+}
+
+} // namespace
+
+namespace {
+
+// Demangler class takes the main role in demangling symbols.
+// It has a set of functions to parse mangled symbols into Type instances.
+// It also has a set of functions to cnovert Type instances to strings.
+class Demangler {
+public:
+  Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
+
+  // You are supposed to call parse() first and then check if error is true.  If
+  // it is false, call output() to write the formatted name to the given stream.
+  void parse();
+  void output();
+
+  // True if an error occurred.
+  bool Error = false;
+
+private:
+  Type *demangleVariableEncoding();
+  Type *demangleFunctionEncoding();
+
+  Qualifiers demanglePointerExtQualifiers();
+
+  // Parser functions. This is a recursive-descent parser.
+  Type *demangleType(QualifierMangleMode QMM);
+  Type *demangleBasicType();
+  UdtType *demangleClassType();
+  PointerType *demanglePointerType();
+
+  ArrayType *demangleArrayType();
+
+  ParamList demangleParameterList();
+
+  int demangleNumber();
+  void demangleNamePiece(Name &Node, bool IsHead);
+
+  StringView demangleString(bool memorize);
+  void memorizeString(StringView s);
+  Name *demangleName();
+  void demangleOperator(Name *);
+  StringView demangleOperatorName();
+  int demangleFunctionClass();
+  CallingConv demangleCallingConvention();
+  StorageClass demangleVariableStorageClass();
+  ReferenceKind demangleReferenceKind();
+
+  Qualifiers demangleFunctionQualifiers();
+  Qualifiers demangleVariablQ_ifiers();
+  Qualifiers demangleReturnTypQ_ifiers();
+
+  Qualifiers demangleQualifiers(
+      QualifierMangleLocation Location = QualifierMangleLocation::Detect);
+
+  // Mangled symbol. demangle* functions shorten this string
+  // as they parse it.
+  StringView MangledName;
+
+  // A parsed mangled symbol.
+  Type *SymbolType;
+
+  // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
+  Name *SymbolName = nullptr;
+
+  // Memory allocator.
+  ArenaAllocator Arena;
+
+  // The first 10 BackReferences in a mangled name can be back-referenced by
+  // special name @[0-9]. This is a storage for the first 10 BackReferences.
+  StringView BackReferences[10];
+  size_t BackRefCount = 0;
+
+  // The result is written to this stream.
+  OutputStream OS;
+};
+} // namespace
+
+// Parser entry point.
+void Demangler::parse() {
+  // MSVC-style mangled symbols must start with '?'.
+  if (!MangledName.consumeFront("?")) {
+    SymbolName = new (Arena) Name;
+    SymbolName->Str = MangledName;
+    SymbolType = new (Arena) Type;
+    SymbolType->Prim = PrimTy::Unknown;
+  }
+
+  // What follows is a main symbol name. This may include
+  // namespaces or class BackReferences.
+  SymbolName = demangleName();
+
+  // Read a variable.
+  if (startsWithDigit(MangledName)) {
+    SymbolType = demangleVariableEncoding();
+    return;
+  }
+
+  // Read a function.
+  SymbolType = demangleFunctionEncoding();
+}
+
+// <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
+
+Type *Demangler::demangleVariableEncoding() {
+  StorageClass SC = demangleVariableStorageClass();
+
+  Type *Ty = demangleType(QualifierMangleMode::Drop);
+
+  Ty->Storage = SC;
+
+  // <variable-type> ::= <type> <cvr-qualifiers>
+  //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
+  switch (Ty->Prim) {
+  case PrimTy::Ptr:
+  case PrimTy::Ref: {
+    Qualifiers ExtraChildQuals = Q_None;
+    Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
+
+    PointerType *PTy = static_cast<PointerType *>(Ty);
+    QualifierMangleLocation Location = PTy->isMemberPointer()
+                                           ? QualifierMangleLocation::Member
+                                           : QualifierMangleLocation::NonMember;
+
+    ExtraChildQuals = demangleQualifiers(Location);
+
+    if (PTy->isMemberPointer()) {
+      Name *BackRefName = demangleName();
+      (void)BackRefName;
+    }
+
+    PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
+    break;
+  }
+  default:
+    Ty->Quals = demangleQualifiers();
+    break;
+  }
+
+  return Ty;
+}
+
+// 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, ...
+int Demangler::demangleNumber() {
+  bool neg = MangledName.consumeFront("?");
+
+  if (startsWithDigit(MangledName)) {
+    int32_t Ret = MangledName[0] - '0' + 1;
+    MangledName = MangledName.dropFront(1);
+    return neg ? -Ret : Ret;
+  }
+
+  int Ret = 0;
+  for (size_t i = 0; i < MangledName.size(); ++i) {
+    char C = MangledName[i];
+    if (C == '@') {
+      MangledName = MangledName.dropFront(i + 1);
+      return neg ? -Ret : Ret;
+    }
+    if ('A' <= C && C <= 'P') {
+      Ret = (Ret << 4) + (C - 'A');
+      continue;
+    }
+    break;
+  }
+
+  Error = true;
+  return 0;
+}
+
+// Read until the next '@'.
+StringView Demangler::demangleString(bool Memorize) {
+  for (size_t i = 0; i < MangledName.size(); ++i) {
+    if (MangledName[i] != '@')
+      continue;
+    StringView ret = MangledName.substr(0, i);
+    MangledName = MangledName.dropFront(i + 1);
+
+    if (Memorize)
+      memorizeString(ret);
+    return ret;
+  }
+
+  Error = true;
+  return "";
+}
+
+// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
+// Memorize it.
+void Demangler::memorizeString(StringView S) {
+  if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
+    return;
+  for (size_t i = 0; i < BackRefCount; ++i)
+    if (S == BackReferences[i])
+      return;
+  BackReferences[BackRefCount++] = S;
+}
+
+void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
+  if (startsWithDigit(MangledName)) {
+    size_t I = MangledName[0] - '0';
+    if (I >= BackRefCount) {
+      Error = true;
+      return;
+    }
+    MangledName = MangledName.dropFront();
+    Node.Str = BackReferences[I];
+  } else if (MangledName.consumeFront("?$")) {
+    // Class template.
+    Node.Str = demangleString(false);
+    Node.TemplateParams = demangleParameterList();
+    if (!MangledName.consumeFront('@')) {
+      Error = true;
+      return;
+    }
+  } else if (!IsHead && MangledName.consumeFront("?A")) {
+    // Anonymous namespace starts with ?A.  So does overloaded operator[],
+    // but the distinguishing factor is that namespace themselves are not
+    // mangled, only the variables and functions inside of them are.  So
+    // an anonymous namespace will never occur as the first item in the
+    // name.
+    Node.Str = "`anonymous namespace'";
+    if (!MangledName.consumeFront('@')) {
+      Error = true;
+      return;
+    }
+  } else if (MangledName.consumeFront("?")) {
+    // Overloaded operator.
+    demangleOperator(&Node);
+  } else {
+    // Non-template functions or classes.
+    Node.Str = demangleString(true);
+  }
+}
+
+// Parses a name in the form of A@B@C@@ which represents C::B::A.
+Name *Demangler::demangleName() {
+  Name *Head = nullptr;
+
+  while (!MangledName.consumeFront("@")) {
+    Name *Elem = new (Arena) Name;
+
+    assert(!Error);
+    demangleNamePiece(*Elem, Head == nullptr);
+    if (Error)
+      return nullptr;
+
+    Elem->Next = Head;
+    Head = Elem;
+  }
+
+  return Head;
+}
+
+void Demangler::demangleOperator(Name *OpName) {
+  OpName->Operator = demangleOperatorName();
+  if (!Error && !MangledName.empty() && MangledName.front() != '@')
+    demangleNamePiece(*OpName, false);
+}
+
+StringView Demangler::demangleOperatorName() {
+  SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
+  RestoreOnError.shouldRestore(false);
+
+  switch (MangledName.popFront()) {
+  case '0':
+    return "ctor";
+  case '1':
+    return "dtor";
+  case '2':
+    return " new";
+  case '3':
+    return " delete";
+  case '4':
+    return "=";
+  case '5':
+    return ">>";
+  case '6':
+    return "<<";
+  case '7':
+    return "!";
+  case '8':
+    return "==";
+  case '9':
+    return "!=";
+  case 'A':
+    return "[]";
+  case 'C':
+    return "->";
+  case 'D':
+    return "*";
+  case 'E':
+    return "++";
+  case 'F':
+    return "--";
+  case 'G':
+    return "-";
+  case 'H':
+    return "+";
+  case 'I':
+    return "&";
+  case 'J':
+    return "->*";
+  case 'K':
+    return "/";
+  case 'L':
+    return "%";
+  case 'M':
+    return "<";
+  case 'N':
+    return "<=";
+  case 'O':
+    return ">";
+  case 'P':
+    return ">=";
+  case 'Q':
+    return ",";
+  case 'R':
+    return "()";
+  case 'S':
+    return "~";
+  case 'T':
+    return "^";
+  case 'U':
+    return "|";
+  case 'V':
+    return "&&";
+  case 'W':
+    return "||";
+  case 'X':
+    return "*=";
+  case 'Y':
+    return "+=";
+  case 'Z':
+    return "-=";
+  case '_': {
+    if (MangledName.empty())
+      break;
+
+    switch (MangledName.popFront()) {
+    case '0':
+      return "/=";
+    case '1':
+      return "%=";
+    case '2':
+      return ">>=";
+    case '3':
+      return "<<=";
+    case '4':
+      return "&=";
+    case '5':
+      return "|=";
+    case '6':
+      return "^=";
+    case 'U':
+      return " new[]";
+    case 'V':
+      return " delete[]";
+    case '_':
+      if (MangledName.consumeFront("L"))
+        return " co_await";
+    }
+  }
+  }
+
+  Error = true;
+  RestoreOnError.shouldRestore(true);
+  return "";
+}
+
+int Demangler::demangleFunctionClass() {
+  SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
+  RestoreOnError.shouldRestore(false);
+
+  switch (MangledName.popFront()) {
+  case 'A':
+    return Private;
+  case 'B':
+    return Private | FFar;
+  case 'C':
+    return Private | Static;
+  case 'D':
+    return Private | Static;
+  case 'E':
+    return Private | Virtual;
+  case 'F':
+    return Private | Virtual;
+  case 'I':
+    return Protected;
+  case 'J':
+    return Protected | FFar;
+  case 'K':
+    return Protected | Static;
+  case 'L':
+    return Protected | Static | FFar;
+  case 'M':
+    return Protected | Virtual;
+  case 'N':
+    return Protected | Virtual | FFar;
+  case 'Q':
+    return Public;
+  case 'R':
+    return Public | FFar;
+  case 'S':
+    return Public | Static;
+  case 'T':
+    return Public | Static | FFar;
+  case 'U':
+    return Public | Virtual;
+  case 'V':
+    return Public | Virtual | FFar;
+  case 'Y':
+    return Global;
+  case 'Z':
+    return Global | FFar;
+  }
+
+  Error = true;
+  RestoreOnError.shouldRestore(true);
+  return 0;
+}
+
+Qualifiers Demangler::demangleFunctionQualifiers() {
+  SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
+  RestoreOnError.shouldRestore(false);
+
+  switch (MangledName.popFront()) {
+  case 'A':
+    return Q_None;
+  case 'B':
+    return Q_Const;
+  case 'C':
+    return Q_Volatile;
+  case 'D':
+    return Qualifiers(Q_Const | Q_Volatile);
+  }
+
+  Error = true;
+  RestoreOnError.shouldRestore(true);
+  return Q_None;
+}
+
+CallingConv Demangler::demangleCallingConvention() {
+  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() {
+  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;
+}
+
+Qualifiers Demangler::demangleVariablQ_ifiers() {
+  SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
+  RestoreOnError.shouldRestore(false);
+
+  switch (MangledName.popFront()) {
+  case 'A':
+    return Q_None;
+  case 'B':
+    return Q_Const;
+  case 'C':
+    return Q_Volatile;
+  case 'D':
+    return Qualifiers(Q_Const | Q_Volatile);
+  case 'E':
+    return Q_Far;
+  case 'F':
+    return Qualifiers(Q_Const | Q_Far);
+  case 'G':
+    return Qualifiers(Q_Volatile | Q_Far);
+  case 'H':
+    return Qualifiers(Q_Const | Q_Volatile | Q_Far);
+  }
+
+  Error = true;
+  RestoreOnError.shouldRestore(true);
+  return Q_None;
+}
+
+Qualifiers Demangler::demangleReturnTypQ_ifiers() {
+  if (!MangledName.consumeFront("?"))
+    return Q_None;
+
+  SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
+  RestoreOnError.shouldRestore(false);
+
+  switch (MangledName.popFront()) {
+  case 'A':
+    return Q_None;
+  case 'B':
+    return Q_Const;
+  case 'C':
+    return Q_Volatile;
+  case 'D':
+    return Qualifiers(Q_Const | Q_Volatile);
+  }
+
+  Error = true;
+  RestoreOnError.shouldRestore(true);
+  return Q_None;
+}
+
+Qualifiers Demangler::demangleQualifiers(QualifierMangleLocation Location) {
+  if (Location == QualifierMangleLocation::Detect) {
+    switch (MangledName.front()) {
+    case 'Q':
+    case 'R':
+    case 'S':
+    case 'T':
+      Location = QualifierMangleLocation::Member;
+      break;
+    case 'A':
+    case 'B':
+    case 'C':
+    case 'D':
+      Location = QualifierMangleLocation::NonMember;
+      break;
+    default:
+      Error = true;
+      return Q_None;
+    }
+  }
+
+  if (Location == QualifierMangleLocation::Member) {
+    switch (MangledName.popFront()) {
+    // Member qualifiers
+    case 'Q':
+      return Q_None;
+    case 'R':
+      return Q_Const;
+    case 'S':
+      return Q_Volatile;
+    case 'T':
+      return Qualifiers(Q_Const | Q_Volatile);
+    }
+  } else {
+    switch (MangledName.popFront()) {
+    // Non-Member qualifiers
+    case 'A':
+      return Q_None;
+    case 'B':
+      return Q_Const;
+    case 'C':
+      return Q_Volatile;
+    case 'D':
+      return Qualifiers(Q_Const | Q_Volatile);
+    }
+  }
+  Error = true;
+  return Q_None;
+}
+
+// <variable-type> ::= <type> <cvr-qualifiers>
+//                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
+Type *Demangler::demangleType(QualifierMangleMode QMM) {
+  Qualifiers Quals = Q_None;
+  if (QMM == QualifierMangleMode::Mangle)
+    Quals = Qualifiers(Quals | demangleQualifiers());
+  else if (QMM == QualifierMangleMode::Result) {
+    if (MangledName.consumeFront('?'))
+      Quals = Qualifiers(Quals | demangleQualifiers());
+  }
+
+  Type *Ty = nullptr;
+  switch (MangledName.front()) {
+  case 'T': // union
+  case 'U': // struct
+  case 'V': // class
+  case 'W': // enum
+    Ty = demangleClassType();
+    break;
+  case 'A': // foo &
+  case 'P': // foo *
+  case 'Q': // foo *const
+  case 'R': // foo *volatile
+  case 'S': // foo *const volatile
+    Ty = demanglePointerType();
+    break;
+  case 'Y':
+    Ty = demangleArrayType();
+    break;
+  default:
+    Ty = demangleBasicType();
+    break;
+  }
+  Ty->Quals = Qualifiers(Ty->Quals | Quals);
+  return Ty;
+}
+
+static bool functionHasThisPtr(const FunctionType &Ty) {
+  assert(Ty.Prim == PrimTy::Function);
+  if (Ty.FunctionClass & Global)
+    return false;
+  if (Ty.FunctionClass & Static)
+    return false;
+  return true;
+}
+
+ReferenceKind Demangler::demangleReferenceKind() {
+  if (MangledName.consumeFront('G'))
+    return ReferenceKind::LValueRef;
+  else if (MangledName.consumeFront('H'))
+    return ReferenceKind::RValueRef;
+  return ReferenceKind::None;
+}
+
+Type *Demangler::demangleFunctionEncoding() {
+  FunctionType *FTy = new (Arena) FunctionType;
+
+  FTy->Prim = PrimTy::Function;
+  FTy->FunctionClass = (FuncClass)demangleFunctionClass();
+  if (functionHasThisPtr(*FTy)) {
+    FTy->Quals = demanglePointerExtQualifiers();
+    FTy->RefKind = demangleReferenceKind();
+    FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers());
+  }
+
+  // Fields that appear on both member and non-member functions.
+  FTy->CallConvention = demangleCallingConvention();
+
+  // <return-type> ::= <type>
+  //               ::= @ # structors (they have no declared return type)
+  bool IsStructor = MangledName.consumeFront('@');
+  if (!IsStructor)
+    FTy->ReturnType = demangleType(QualifierMangleMode::Result);
+
+  FTy->Params = demangleParameterList();
+
+  return FTy;
+}
+
+// Reads a primitive type.
+Type *Demangler::demangleBasicType() {
+  Type *Ty = new (Arena) Type;
+
+  switch (MangledName.popFront()) {
+  case 'X':
+    Ty->Prim = PrimTy::Void;
+    break;
+  case 'D':
+    Ty->Prim = PrimTy::Char;
+    break;
+  case 'C':
+    Ty->Prim = PrimTy::Schar;
+    break;
+  case 'E':
+    Ty->Prim = PrimTy::Uchar;
+    break;
+  case 'F':
+    Ty->Prim = PrimTy::Short;
+    break;
+  case 'G':
+    Ty->Prim = PrimTy::Ushort;
+    break;
+  case 'H':
+    Ty->Prim = PrimTy::Int;
+    break;
+  case 'I':
+    Ty->Prim = PrimTy::Uint;
+    break;
+  case 'J':
+    Ty->Prim = PrimTy::Long;
+    break;
+  case 'K':
+    Ty->Prim = PrimTy::Ulong;
+    break;
+  case 'M':
+    Ty->Prim = PrimTy::Float;
+    break;
+  case 'N':
+    Ty->Prim = PrimTy::Double;
+    break;
+  case 'O':
+    Ty->Prim = PrimTy::Ldouble;
+    break;
+  case '_': {
+    switch (MangledName.popFront()) {
+    case 'N':
+      Ty->Prim = PrimTy::Bool;
+      break;
+    case 'J':
+      Ty->Prim = PrimTy::Int64;
+      break;
+    case 'K':
+      Ty->Prim = PrimTy::Uint64;
+      break;
+    case 'W':
+      Ty->Prim = PrimTy::Wchar;
+      break;
+    }
+    break;
+  }
+  }
+  return Ty;
+}
+
+UdtType *Demangler::demangleClassType() {
+  UdtType *UTy = new (Arena) UdtType;
+
+  switch (MangledName.popFront()) {
+  case 'T':
+    UTy->Prim = PrimTy::Union;
+    break;
+  case 'U':
+    UTy->Prim = PrimTy::Struct;
+    break;
+  case 'V':
+    UTy->Prim = PrimTy::Class;
+    break;
+  case 'W':
+    if (MangledName.popFront() != '4') {
+      Error = true;
+      return nullptr;
+    }
+    UTy->Prim = PrimTy::Enum;
+    break;
+  default:
+    assert(false);
+  }
+
+  UTy->UdtName = demangleName();
+  return UTy;
+}
+
+// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
+//                       # the E is required for 64-bit non-static pointers
+PointerType *Demangler::demanglePointerType() {
+  PointerType *Pointer = new (Arena) PointerType;
+
+  Pointer->Quals = Q_None;
+  switch (MangledName.popFront()) {
+  case 'A':
+    Pointer->Prim = PrimTy::Ref;
+    break;
+  case 'P':
+    Pointer->Prim = PrimTy::Ptr;
+    break;
+  case 'Q':
+    Pointer->Prim = PrimTy::Ptr;
+    Pointer->Quals = Q_Const;
+    break;
+  case 'R':
+    Pointer->Quals = Q_Volatile;
+    Pointer->Prim = PrimTy::Ptr;
+    break;
+  case 'S':
+    Pointer->Quals = Qualifiers(Q_Const | Q_Volatile);
+    Pointer->Prim = PrimTy::Ptr;
+    break;
+  default:
+    assert(false && "Ty is not a pointer type!");
+  }
+
+  if (MangledName.consumeFront("6")) {
+    FunctionType *FTy = new (Arena) FunctionType;
+    FTy->Prim = PrimTy::Function;
+    FTy->CallConvention = demangleCallingConvention();
+
+    FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
+    FTy->Params = demangleParameterList();
+
+    if (!MangledName.consumeFront("@Z"))
+      MangledName.consumeFront("Z");
+
+    Pointer->Pointee = FTy;
+    return Pointer;
+  }
+
+  Qualifiers ExtQuals = demanglePointerExtQualifiers();
+  Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
+
+  Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
+  return Pointer;
+}
+
+Qualifiers Demangler::demanglePointerExtQualifiers() {
+  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;
+}
+
+ArrayType *Demangler::demangleArrayType() {
+  assert(MangledName.front() == 'Y');
+  MangledName.popFront();
+
+  int Dimension = demangleNumber();
+  if (Dimension <= 0) {
+    Error = true;
+    return nullptr;
+  }
+
+  ArrayType *ATy = new (Arena) ArrayType;
+  ArrayType *Dim = ATy;
+  for (int I = 0; I < Dimension; ++I) {
+    Dim->Prim = PrimTy::Array;
+    Dim->ArrayDimension = demangleNumber();
+    Dim->NextDimension = new (Arena) ArrayType;
+    Dim = Dim->NextDimension;
+  }
+
+  if (MangledName.consumeFront("$$C")) {
+    if (MangledName.consumeFront("B"))
+      ATy->Quals = Q_Const;
+    else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
+      ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
+    else if (!MangledName.consumeFront("A"))
+      Error = true;
+  }
+
+  ATy->ElementType = demangleType(QualifierMangleMode::Drop);
+  Dim->ElementType = ATy->ElementType;
+  return ATy;
+}
+
+// Reads a function or a template parameters.
+ParamList Demangler::demangleParameterList() {
+  // Within the same parameter list, you can backreference the first 10 types.
+  Type *BackRef[10];
+  int Idx = 0;
+
+  ParamList *Head;
+  ParamList **Current = &Head;
+  while (!Error && !MangledName.startsWith('@') &&
+         !MangledName.startsWith('Z')) {
+    if (startsWithDigit(MangledName)) {
+      int N = MangledName[0] - '0';
+      if (N >= Idx) {
+        Error = true;
+        return {};
+      }
+      MangledName = MangledName.dropFront();
+
+      *Current = new (Arena) ParamList;
+      (*Current)->Current = BackRef[N]->clone(Arena);
+      Current = &(*Current)->Next;
+      continue;
+    }
+
+    size_t ArrayDimension = MangledName.size();
+
+    *Current = new (Arena) ParamList;
+    (*Current)->Current = demangleType(QualifierMangleMode::Drop);
+
+    // Single-letter types are ignored for backreferences because
+    // memorizing them doesn't save anything.
+    if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
+      BackRef[Idx++] = (*Current)->Current;
+    Current = &(*Current)->Next;
+  }
+
+  return *Head;
+}
+
+void Demangler::output() {
+  // Converts an AST to a string.
+  //
+  // Converting an AST representing a C++ type to a string is tricky due
+  // to the bad grammar of the C++ declaration inherited from C. You have
+  // to construct a string from inside to outside. For example, if a type
+  // X is a pointer to a function returning int, the order you create a
+  // string becomes something like this:
+  //
+  //   (1) X is a pointer: *X
+  //   (2) (1) is a function returning int: int (*X)()
+  //
+  // So you cannot construct a result just by appending strings to a result.
+  //
+  // To deal with this, we split the function into two. outputPre() writes
+  // the "first half" of type declaration, and outputPost() writes the
+  // "second half". For example, outputPre() writes a return type for a
+  // function and outputPost() writes an parameter list.
+  Type::outputPre(OS, *SymbolType);
+  outputName(OS, SymbolName);
+  Type::outputPost(OS, *SymbolType);
+
+  // Null terminate the buffer.
+  OS << '\0';
+}
+
+char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
+                              int *Status) {
+  OutputStream OS = OutputStream::create(Buf, N, 1024);
+
+  Demangler D(OS, StringView(MangledName));
+  D.parse();
+
+  if (D.Error)
+    *Status = llvm::demangle_invalid_mangled_name;
+  else
+    *Status = llvm::demangle_success;
+
+  D.output();
+  return OS.getBuffer();
+}