Type::outputPost(OS, *ElementType);
}
+struct Symbol {
+ Name *SymbolName = nullptr;
+ Type *SymbolType = nullptr;
+};
+
} // namespace
namespace {
// 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) {}
+ Demangler() = default;
// 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();
+ Symbol *parse(StringView &MangledName);
+ void output(const Symbol *S, OutputStream &OS);
// True if an error occurred.
bool Error = false;
private:
- Type *demangleVariableEncoding();
- Type *demangleFunctionEncoding();
+ Type *demangleVariableEncoding(StringView &MangledName);
+ Type *demangleFunctionEncoding(StringView &MangledName);
- Qualifiers demanglePointerExtQualifiers();
+ Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
// Parser functions. This is a recursive-descent parser.
- Type *demangleType(QualifierMangleMode QMM);
- Type *demangleBasicType();
- UdtType *demangleClassType();
- PointerType *demanglePointerType();
- MemberPointerType *demangleMemberPointerType();
- FunctionType *demangleFunctionType(bool HasThisQuals, bool IsFunctionPointer);
+ Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
+ Type *demangleBasicType(StringView &MangledName);
+ UdtType *demangleClassType(StringView &MangledName);
+ PointerType *demanglePointerType(StringView &MangledName);
+ MemberPointerType *demangleMemberPointerType(StringView &MangledName);
+ FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
+ bool IsFunctionPointer);
- ArrayType *demangleArrayType();
+ ArrayType *demangleArrayType(StringView &MangledName);
- ParamList demangleTemplateParameterList();
- ParamList demangleFunctionParameterList();
+ ParamList demangleTemplateParameterList(StringView &MangledName);
+ ParamList demangleFunctionParameterList(StringView &MangledName);
- int demangleNumber();
+ int demangleNumber(StringView &MangledName);
void memorizeString(StringView s);
- Name *demangleFullyQualifiedTypeName();
- Name *demangleFullyQualifiedSymbolName();
-
- Name *demangleUnqualifiedTypeName();
- Name *demangleUnqualifiedSymbolName();
+ Name *demangleFullyQualifiedTypeName(StringView &MangledName);
+ Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
- Name *demangleNameScopeChain(Name *UnqualifiedName);
- Name *demangleNameScopePiece();
+ Name *demangleUnqualifiedTypeName(StringView &MangledName);
+ Name *demangleUnqualifiedSymbolName(StringView &MangledName);
- Name *demangleBackRefName();
- Name *demangleClassTemplateName();
- Name *demangleOperatorName();
- Name *demangleSimpleName(bool Memorize);
- Name *demangleAnonymousNamespaceName();
+ Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
+ Name *demangleNameScopePiece(StringView &MangledName);
- void demangleOperator(Name *);
- FuncClass demangleFunctionClass();
- CallingConv demangleCallingConvention();
- StorageClass demangleVariableStorageClass();
- ReferenceKind demangleReferenceKind();
- void demangleThrowSpecification();
+ Name *demangleBackRefName(StringView &MangledName);
+ Name *demangleClassTemplateName(StringView &MangledName);
+ Name *demangleOperatorName(StringView &MangledName);
+ Name *demangleSimpleName(StringView &MangledName, bool Memorize);
+ Name *demangleAnonymousNamespaceName(StringView &MangledName);
- std::pair<Qualifiers, bool> demangleQualifiers();
+ void demangleOperator(StringView &MangledName, Name *);
+ FuncClass demangleFunctionClass(StringView &MangledName);
+ CallingConv demangleCallingConvention(StringView &MangledName);
+ StorageClass demangleVariableStorageClass(StringView &MangledName);
+ ReferenceKind demangleReferenceKind(StringView &MangledName);
+ void demangleThrowSpecification(StringView &MangledName);
- // The result is written to this stream.
- OutputStream OS;
-
- // Mangled symbol. demangle* functions shorten this string
- // as they parse it.
- StringView MangledName;
-
- // A parsed mangled symbol.
- Type *SymbolType = nullptr;
-
- // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
- Name *SymbolName = nullptr;
+ std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
// Memory allocator.
ArenaAllocator Arena;
} // namespace
// Parser entry point.
-void Demangler::parse() {
+Symbol *Demangler::parse(StringView &MangledName) {
+ Symbol *S = Arena.alloc<Symbol>();
+
// MSVC-style mangled symbols must start with '?'.
if (!MangledName.consumeFront("?")) {
- SymbolName = Arena.alloc<Name>();
- SymbolName->Str = MangledName;
- SymbolType = Arena.alloc<Type>();
- SymbolType->Prim = PrimTy::Unknown;
+ S->SymbolName = Arena.alloc<Name>();
+ S->SymbolName->Str = MangledName;
+ S->SymbolType = Arena.alloc<Type>();
+ S->SymbolType->Prim = PrimTy::Unknown;
+ return S;
}
// What follows is a main symbol name. This may include
// namespaces or class BackReferences.
- SymbolName = demangleFullyQualifiedSymbolName();
+ S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
// Read a variable.
- if (startsWithDigit(MangledName)) {
- SymbolType = demangleVariableEncoding();
- return;
- }
+ S->SymbolType = startsWithDigit(MangledName)
+ ? demangleVariableEncoding(MangledName)
+ : demangleFunctionEncoding(MangledName);
- // Read a function.
- SymbolType = demangleFunctionEncoding();
+ return S;
}
// <type-encoding> ::= <storage-class> <variable-type>
// ::= 3 # global
// ::= 4 # static local
-Type *Demangler::demangleVariableEncoding() {
- StorageClass SC = demangleVariableStorageClass();
+Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
+ StorageClass SC = demangleVariableStorageClass(MangledName);
- Type *Ty = demangleType(QualifierMangleMode::Drop);
+ Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Ty->Storage = SC;
case PrimTy::Ref:
case PrimTy::MemberPtr: {
Qualifiers ExtraChildQuals = Q_None;
- Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
+ Ty->Quals =
+ Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
bool IsMember = false;
- std::tie(ExtraChildQuals, IsMember) = demangleQualifiers();
+ std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
if (Ty->Prim == PrimTy::MemberPtr) {
assert(IsMember);
- Name *BackRefName = demangleFullyQualifiedTypeName();
+ Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
(void)BackRefName;
MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
break;
}
default:
- Ty->Quals = demangleQualifiers().first;
+ Ty->Quals = demangleQualifiers(MangledName).first;
break;
}
// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
//
// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
-int Demangler::demangleNumber() {
+int Demangler::demangleNumber(StringView &MangledName) {
bool neg = MangledName.consumeFront("?");
if (startsWithDigit(MangledName)) {
BackReferences[BackRefCount++] = S;
}
-Name *Demangler::demangleBackRefName() {
+Name *Demangler::demangleBackRefName(StringView &MangledName) {
assert(startsWithDigit(MangledName));
size_t I = MangledName[0] - '0';
return Node;
}
-Name *Demangler::demangleClassTemplateName() {
+Name *Demangler::demangleClassTemplateName(StringView &MangledName) {
assert(MangledName.startsWith("?$"));
MangledName.consumeFront("?$");
- Name *Node = demangleSimpleName(false);
- Node->TemplateParams = demangleTemplateParameterList();
+ Name *Node = demangleSimpleName(MangledName, false);
+ Node->TemplateParams = demangleTemplateParameterList(MangledName);
return Node;
}
-Name *Demangler::demangleOperatorName() {
+Name *Demangler::demangleOperatorName(StringView &MangledName) {
assert(MangledName.startsWith('?'));
MangledName.consumeFront('?');
- auto NameString = [this]() -> StringView {
+ auto NameString = [this, &MangledName]() -> StringView {
switch (MangledName.popFront()) {
case '0':
return "ctor";
return Node;
}
-Name *Demangler::demangleSimpleName(bool Memorize) {
+Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Name *Node = Arena.alloc<Name>();
for (size_t i = 0; i < MangledName.size(); ++i) {
if (MangledName[i] != '@')
return nullptr;
}
-Name *Demangler::demangleAnonymousNamespaceName() {
+Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
assert(MangledName.startsWith("?A"));
MangledName.consumeFront("?A");
}
// Parses a type name in the form of A@B@C@@ which represents C::B::A.
-Name *Demangler::demangleFullyQualifiedTypeName() {
- Name *TypeName = demangleUnqualifiedTypeName();
+Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
+ Name *TypeName = demangleUnqualifiedTypeName(MangledName);
assert(TypeName);
- Name *QualName = demangleNameScopeChain(TypeName);
+ Name *QualName = demangleNameScopeChain(MangledName, TypeName);
assert(QualName);
return QualName;
}
// 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.
-Name *Demangler::demangleFullyQualifiedSymbolName() {
- Name *SymbolName = demangleUnqualifiedSymbolName();
+Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
+ Name *SymbolName = demangleUnqualifiedSymbolName(MangledName);
assert(SymbolName);
- Name *QualName = demangleNameScopeChain(SymbolName);
+ Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
assert(QualName);
return QualName;
}
-Name *Demangler::demangleUnqualifiedTypeName() {
+Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName) {
// 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();
+ return demangleBackRefName(MangledName);
if (MangledName.startsWith("?$"))
- return demangleClassTemplateName();
+ return demangleClassTemplateName(MangledName);
- return demangleSimpleName(true);
+ return demangleSimpleName(MangledName, true);
}
-Name *Demangler::demangleUnqualifiedSymbolName() {
+Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName) {
if (MangledName.startsWith('?'))
- return demangleOperatorName();
- return demangleSimpleName(true);
+ return demangleOperatorName(MangledName);
+ return demangleSimpleName(MangledName, true);
}
-Name *Demangler::demangleNameScopePiece() {
+Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
if (startsWithDigit(MangledName))
- return demangleBackRefName();
+ return demangleBackRefName(MangledName);
if (MangledName.startsWith("?$"))
- return demangleClassTemplateName();
+ return demangleClassTemplateName(MangledName);
if (MangledName.startsWith("?A"))
- return demangleAnonymousNamespaceName();
+ return demangleAnonymousNamespaceName(MangledName);
- return demangleSimpleName(true);
+ return demangleSimpleName(MangledName, true);
}
-Name *Demangler::demangleNameScopeChain(Name *UnqualifiedName) {
+Name *Demangler::demangleNameScopeChain(StringView &MangledName,
+ Name *UnqualifiedName) {
Name *Head = UnqualifiedName;
while (!MangledName.consumeFront("@")) {
}
assert(!Error);
- Name *Elem = demangleNameScopePiece();
+ Name *Elem = demangleNameScopePiece(MangledName);
if (Error)
return nullptr;
return Head;
}
-FuncClass Demangler::demangleFunctionClass() {
+FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
RestoreOnError.shouldRestore(false);
return Public;
}
-CallingConv Demangler::demangleCallingConvention() {
+CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
switch (MangledName.popFront()) {
case 'A':
case 'B':
return CallingConv::None;
}
-StorageClass Demangler::demangleVariableStorageClass() {
+StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
assert(std::isdigit(MangledName.front()));
switch (MangledName.popFront()) {
return StorageClass::None;
}
-std::pair<Qualifiers, bool> Demangler::demangleQualifiers() {
+std::pair<Qualifiers, bool>
+Demangler::demangleQualifiers(StringView &MangledName) {
switch (MangledName.popFront()) {
// Member qualifiers
// <variable-type> ::= <type> <cvr-qualifiers>
// ::= <type> <pointee-cvr-qualifiers> # pointers, references
-Type *Demangler::demangleType(QualifierMangleMode QMM) {
+Type *Demangler::demangleType(StringView &MangledName,
+ QualifierMangleMode QMM) {
Qualifiers Quals = Q_None;
bool IsMember = false;
bool IsMemberKnown = false;
if (QMM == QualifierMangleMode::Mangle) {
- std::tie(Quals, IsMember) = demangleQualifiers();
+ std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
IsMemberKnown = true;
} else if (QMM == QualifierMangleMode::Result) {
if (MangledName.consumeFront('?')) {
- std::tie(Quals, IsMember) = demangleQualifiers();
+ std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
IsMemberKnown = true;
}
}
case 'U': // struct
case 'V': // class
case 'W': // enum
- Ty = demangleClassType();
+ Ty = demangleClassType(MangledName);
break;
case 'A': // foo &
case 'P': // foo *
if (!IsMemberKnown)
IsMember = isMemberPointer(MangledName);
if (IsMember)
- Ty = demangleMemberPointerType();
+ Ty = demangleMemberPointerType(MangledName);
else
- Ty = demanglePointerType();
+ Ty = demanglePointerType(MangledName);
break;
case 'Y':
- Ty = demangleArrayType();
+ Ty = demangleArrayType(MangledName);
break;
default:
- Ty = demangleBasicType();
+ Ty = demangleBasicType(MangledName);
break;
}
Ty->Quals = Qualifiers(Ty->Quals | Quals);
return Ty;
}
-ReferenceKind Demangler::demangleReferenceKind() {
+ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
if (MangledName.consumeFront('G'))
return ReferenceKind::LValueRef;
else if (MangledName.consumeFront('H'))
return ReferenceKind::None;
}
-void Demangler::demangleThrowSpecification() {
+void Demangler::demangleThrowSpecification(StringView &MangledName) {
if (MangledName.consumeFront('Z'))
return;
Error = true;
}
-FunctionType *Demangler::demangleFunctionType(bool HasThisQuals,
+FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
+ bool HasThisQuals,
bool IsFunctionPointer) {
FunctionType *FTy = Arena.alloc<FunctionType>();
FTy->Prim = PrimTy::Function;
FTy->IsFunctionPointer = IsFunctionPointer;
if (HasThisQuals) {
- FTy->Quals = demanglePointerExtQualifiers();
- FTy->RefKind = demangleReferenceKind();
- FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers().first);
+ FTy->Quals = demanglePointerExtQualifiers(MangledName);
+ FTy->RefKind = demangleReferenceKind(MangledName);
+ FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
}
// Fields that appear on both member and non-member functions.
- FTy->CallConvention = demangleCallingConvention();
+ FTy->CallConvention = demangleCallingConvention(MangledName);
// <return-type> ::= <type>
// ::= @ # structors (they have no declared return type)
bool IsStructor = MangledName.consumeFront('@');
if (!IsStructor)
- FTy->ReturnType = demangleType(QualifierMangleMode::Result);
+ FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
- FTy->Params = demangleFunctionParameterList();
+ FTy->Params = demangleFunctionParameterList(MangledName);
- demangleThrowSpecification();
+ demangleThrowSpecification(MangledName);
return FTy;
}
-Type *Demangler::demangleFunctionEncoding() {
- FuncClass FC = demangleFunctionClass();
+Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
+ FuncClass FC = demangleFunctionClass(MangledName);
bool HasThisQuals = !(FC & (Global | Static));
- FunctionType *FTy = demangleFunctionType(HasThisQuals, false);
+ FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
FTy->FunctionClass = FC;
return FTy;
}
// Reads a primitive type.
-Type *Demangler::demangleBasicType() {
+Type *Demangler::demangleBasicType(StringView &MangledName) {
Type *Ty = Arena.alloc<Type>();
switch (MangledName.popFront()) {
return Ty;
}
-UdtType *Demangler::demangleClassType() {
+UdtType *Demangler::demangleClassType(StringView &MangledName) {
UdtType *UTy = Arena.alloc<UdtType>();
switch (MangledName.popFront()) {
assert(false);
}
- UTy->UdtName = demangleFullyQualifiedTypeName();
+ UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
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 *Demangler::demanglePointerType(StringView &MangledName) {
PointerType *Pointer = Arena.alloc<PointerType>();
PointerAffinity Affinity;
Pointer->Prim =
(Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
if (MangledName.consumeFront("6")) {
- Pointer->Pointee = demangleFunctionType(false, true);
+ Pointer->Pointee = demangleFunctionType(MangledName, false, true);
return Pointer;
}
- Qualifiers ExtQuals = demanglePointerExtQualifiers();
+ Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
- Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
+ Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
return Pointer;
}
-MemberPointerType *Demangler::demangleMemberPointerType() {
+MemberPointerType *
+Demangler::demangleMemberPointerType(StringView &MangledName) {
MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
Pointer->Prim = PrimTy::MemberPtr;
std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
assert(Affinity == PointerAffinity::Pointer);
- Qualifiers ExtQuals = demanglePointerExtQualifiers();
+ Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
if (MangledName.consumeFront("8")) {
- Pointer->MemberName = demangleFullyQualifiedSymbolName();
- Pointer->Pointee = demangleFunctionType(true, true);
+ Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
+ Pointer->Pointee = demangleFunctionType(MangledName, true, true);
} else {
Qualifiers PointeeQuals = Q_None;
bool IsMember = false;
- std::tie(PointeeQuals, IsMember) = demangleQualifiers();
+ std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
assert(IsMember);
- Pointer->MemberName = demangleFullyQualifiedSymbolName();
+ Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
- Pointer->Pointee = demangleType(QualifierMangleMode::Drop);
+ Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Pointer->Pointee->Quals = PointeeQuals;
}
return Pointer;
}
-Qualifiers Demangler::demanglePointerExtQualifiers() {
+Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Qualifiers Quals = Q_None;
if (MangledName.consumeFront('E'))
Quals = Qualifiers(Quals | Q_Pointer64);
return Quals;
}
-ArrayType *Demangler::demangleArrayType() {
+ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
assert(MangledName.front() == 'Y');
MangledName.popFront();
- int Dimension = demangleNumber();
+ int Dimension = demangleNumber(MangledName);
if (Dimension <= 0) {
Error = true;
return nullptr;
ArrayType *Dim = ATy;
for (int I = 0; I < Dimension; ++I) {
Dim->Prim = PrimTy::Array;
- Dim->ArrayDimension = demangleNumber();
+ Dim->ArrayDimension = demangleNumber(MangledName);
Dim->NextDimension = Arena.alloc<ArrayType>();
Dim = Dim->NextDimension;
}
Error = true;
}
- ATy->ElementType = demangleType(QualifierMangleMode::Drop);
+ ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Dim->ElementType = ATy->ElementType;
return ATy;
}
// Reads a function or a template parameters.
-ParamList Demangler::demangleFunctionParameterList() {
+ParamList Demangler::demangleFunctionParameterList(StringView &MangledName) {
// Empty parameter list.
if (MangledName.consumeFront('X'))
return {};
size_t OldSize = MangledName.size();
*Current = Arena.alloc<ParamList>();
- (*Current)->Current = demangleType(QualifierMangleMode::Drop);
+ (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
size_t CharsConsumed = OldSize - MangledName.size();
assert(CharsConsumed != 0);
return {};
}
-ParamList Demangler::demangleTemplateParameterList() {
+ParamList Demangler::demangleTemplateParameterList(StringView &MangledName) {
ParamList *Head;
ParamList **Current = &Head;
while (!Error && !MangledName.startsWith('@')) {
// Template parameter lists don't participate in back-referencing.
*Current = Arena.alloc<ParamList>();
- (*Current)->Current = demangleType(QualifierMangleMode::Drop);
+ (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Current = &(*Current)->Next;
}
return {};
}
-void Demangler::output() {
+void Demangler::output(const Symbol *S, OutputStream &OS) {
// Converts an AST to a string.
//
// Converting an AST representing a C++ type to a string is tricky due
// 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);
+ Type::outputPre(OS, *S->SymbolType);
+ outputName(OS, S->SymbolName);
+ Type::outputPost(OS, *S->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();
+ Demangler D;
+ StringView Name{MangledName};
+ Symbol *S = D.parse(Name);
if (D.Error)
*Status = llvm::demangle_invalid_mangled_name;
else
*Status = llvm::demangle_success;
- D.output();
+ OutputStream OS = OutputStream::create(Buf, N, 1024);
+ D.output(S, OS);
return OS.getBuffer();
}