blob: 09892cf8993cf306989e1375f48caa6a0b949c80 [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
24
25// This memory allocator is extremely fast, but it doesn't call dtors
26// for allocated objects. That means you can't use STL containers
27// (such as std::vector) with this allocator. But it pays off --
28// the demangler is 3x faster with this allocator compared to one with
29// STL containers.
30namespace {
31class ArenaAllocator {
32 struct AllocatorNode {
33 uint8_t *Buf = nullptr;
34 size_t Used = 0;
35 AllocatorNode *Next = nullptr;
36 };
37
38public:
39 ArenaAllocator() : Head(new AllocatorNode) { Head->Buf = new uint8_t[Unit]; }
40
41 ~ArenaAllocator() {
42 while (Head) {
43 assert(Head->Buf);
44 delete[] Head->Buf;
45 Head = Head->Next;
46 }
47 }
48
Zachary Turner9d72aa92018-07-20 18:35:06 +000049 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
50
51 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000052 assert(Size < Unit);
53 assert(Head && Head->Buf);
54
Zachary Turner9d72aa92018-07-20 18:35:06 +000055 size_t P = (size_t)Head->Buf + Head->Used;
56 uintptr_t AlignedP =
57 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
58 uint8_t *PP = (uint8_t *)AlignedP;
59 size_t Adjustment = AlignedP - P;
60
61 Head->Used += Size + Adjustment;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000062 if (Head->Used < Unit)
Zachary Turner9d72aa92018-07-20 18:35:06 +000063 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000064
65 AllocatorNode *NewHead = new AllocatorNode;
66 NewHead->Buf = new uint8_t[ArenaAllocator::Unit];
67 NewHead->Next = Head;
68 Head = NewHead;
69 NewHead->Used = Size;
Zachary Turner9d72aa92018-07-20 18:35:06 +000070 return new (NewHead->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000071 }
72
73private:
74 static constexpr size_t Unit = 4096;
75
76 AllocatorNode *Head = nullptr;
77};
78} // namespace
79
80static bool startsWithDigit(StringView S) {
81 return !S.empty() && std::isdigit(S.front());
82}
83
84// Writes a space if the last token does not end with a punctuation.
85static void outputSpaceIfNecessary(OutputStream &OS) {
86 if (OS.empty())
87 return;
88
89 char C = OS.back();
90 if (isalnum(C) || C == '>')
91 OS << " ";
92}
93
Zachary Turnerf435a7e2018-07-20 17:27:48 +000094// Storage classes
95enum Qualifiers : uint8_t {
96 Q_None = 0,
97 Q_Const = 1 << 0,
98 Q_Volatile = 1 << 1,
99 Q_Far = 1 << 2,
100 Q_Huge = 1 << 3,
101 Q_Unaligned = 1 << 4,
102 Q_Restrict = 1 << 5,
103 Q_Pointer64 = 1 << 6
104};
105
106enum class StorageClass : uint8_t {
107 None,
108 PrivateStatic,
109 ProtectedStatic,
110 PublicStatic,
111 Global,
112 FunctionLocalStatic
113};
114
115enum class QualifierMangleMode { Drop, Mangle, Result };
116enum class QualifierMangleLocation { Member, NonMember, Detect };
117
118// Calling conventions
119enum class CallingConv : uint8_t {
120 None,
121 Cdecl,
122 Pascal,
123 Thiscall,
124 Stdcall,
125 Fastcall,
126 Clrcall,
127 Eabi,
128 Vectorcall,
129 Regcall,
130};
131
132enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
133
134// Types
135enum class PrimTy : uint8_t {
136 Unknown,
137 None,
138 Function,
139 Ptr,
140 Ref,
141 Array,
142
143 Struct,
144 Union,
145 Class,
146 Enum,
147
148 Void,
149 Bool,
150 Char,
151 Schar,
152 Uchar,
153 Short,
154 Ushort,
155 Int,
156 Uint,
157 Long,
158 Ulong,
159 Int64,
160 Uint64,
161 Wchar,
162 Float,
163 Double,
164 Ldouble,
165};
166
167// Function classes
168enum FuncClass : uint8_t {
169 Public = 1 << 0,
170 Protected = 1 << 1,
171 Private = 1 << 2,
172 Global = 1 << 3,
173 Static = 1 << 4,
174 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000175 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000176};
177
178namespace {
179
180struct Type;
181
182// Represents a list of parameters (template params or function arguments.
183// It's represented as a linked list.
184struct ParamList {
185 Type *Current = nullptr;
186
187 ParamList *Next = nullptr;
188};
189
190// The type class. Mangled symbols are first parsed and converted to
191// this type and then converted to string.
192struct Type {
193 virtual ~Type() {}
194
195 virtual Type *clone(ArenaAllocator &Arena) const;
196
197 // Write the "first half" of a given type. This is a static functions to
198 // give the code a chance to do processing that is common to a subset of
199 // subclasses
200 static void outputPre(OutputStream &OS, Type &Ty);
201
202 // Write the "second half" of a given type. This is a static functions to
203 // give the code a chance to do processing that is common to a subset of
204 // subclasses
205 static void outputPost(OutputStream &OS, Type &Ty);
206
207 virtual void outputPre(OutputStream &OS);
208 virtual void outputPost(OutputStream &OS);
209
210 // Primitive type such as Int.
211 PrimTy Prim = PrimTy::Unknown;
212
213 Qualifiers Quals = Q_None;
214 StorageClass Storage = StorageClass::None; // storage class
215};
216
217// Represents an identifier which may be a template.
218struct Name {
219 // Name read from an MangledName string.
220 StringView Str;
221
222 // Overloaded operators are represented as special BackReferences in mangled
223 // symbols. If this is an operator name, "op" has an operator name (e.g.
224 // ">>"). Otherwise, empty.
225 StringView Operator;
226
227 // Template parameters. Null if not a template.
228 ParamList TemplateParams;
229
230 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
231 Name *Next = nullptr;
232};
233
234struct PointerType : public Type {
235 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000236 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000237 void outputPost(OutputStream &OS) override;
238
239 bool isMemberPointer() const { return false; }
240
241 // Represents a type X in "a pointer to X", "a reference to X",
242 // "an array of X", or "a function returning X".
243 Type *Pointee = nullptr;
244};
245
246struct FunctionType : public Type {
247 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000248 void outputPre(OutputStream &OS) override;
249 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000250
251 Type *ReturnType = nullptr;
252 // If this is a reference, the type of reference.
253 ReferenceKind RefKind;
254
255 CallingConv CallConvention;
256 FuncClass FunctionClass;
257
258 ParamList Params;
259};
260
261struct UdtType : public Type {
262 Type *clone(ArenaAllocator &Arena) const override;
263 void outputPre(OutputStream &OS) override;
264
265 Name *UdtName = nullptr;
266};
267
268struct ArrayType : public Type {
269 Type *clone(ArenaAllocator &Arena) const override;
270 void outputPre(OutputStream &OS) override;
271 void outputPost(OutputStream &OS) override;
272
273 // Either NextDimension or ElementType will be valid.
274 ArrayType *NextDimension = nullptr;
275 uint32_t ArrayDimension = 0;
276
277 Type *ElementType = nullptr;
278};
279
280} // namespace
281
282static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
283 outputSpaceIfNecessary(OS);
284
285 switch (CC) {
286 case CallingConv::Cdecl:
287 OS << "__cdecl";
288 break;
289 case CallingConv::Fastcall:
290 OS << "__fastcall";
291 break;
292 case CallingConv::Pascal:
293 OS << "__pascal";
294 break;
295 case CallingConv::Regcall:
296 OS << "__regcall";
297 break;
298 case CallingConv::Stdcall:
299 OS << "__stdcall";
300 break;
301 case CallingConv::Thiscall:
302 OS << "__thiscall";
303 break;
304 case CallingConv::Eabi:
305 OS << "__eabi";
306 break;
307 case CallingConv::Vectorcall:
308 OS << "__vectorcall";
309 break;
310 case CallingConv::Clrcall:
311 OS << "__clrcall";
312 break;
313 default:
314 break;
315 }
316}
317
318// Write a function or template parameter list.
319static void outputParameterList(OutputStream &OS, const ParamList &Params) {
320 const ParamList *Head = &Params;
321 while (Head) {
322 Type::outputPre(OS, *Head->Current);
323 Type::outputPost(OS, *Head->Current);
324
325 Head = Head->Next;
326
327 if (Head)
328 OS << ", ";
329 }
330}
331
332static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
333 if (!TheName.TemplateParams.Current)
334 return;
335
336 OS << "<";
337 outputParameterList(OS, TheName.TemplateParams);
338 OS << ">";
339}
340
341static void outputName(OutputStream &OS, const Name *TheName) {
342 if (!TheName)
343 return;
344
345 outputSpaceIfNecessary(OS);
346
347 // Print out namespaces or outer class BackReferences.
348 for (; TheName->Next; TheName = TheName->Next) {
349 OS << TheName->Str;
350 outputTemplateParams(OS, *TheName);
351 OS << "::";
352 }
353
354 // Print out a regular name.
355 if (TheName->Operator.empty()) {
356 OS << TheName->Str;
357 outputTemplateParams(OS, *TheName);
358 return;
359 }
360
361 // Print out ctor or dtor.
362 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
363 OS << TheName->Str;
364 outputTemplateParams(OS, *TheName);
365 OS << "::";
366 if (TheName->Operator == "dtor")
367 OS << "~";
368 OS << TheName->Str;
369 outputTemplateParams(OS, *TheName);
370 return;
371 }
372
373 // Print out an overloaded operator.
374 if (!TheName->Str.empty())
375 OS << TheName->Str << "::";
376 OS << "operator" << TheName->Operator;
377}
378
379namespace {
380
381Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000382 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000383}
384
385// Write the "first half" of a given type.
386void Type::outputPre(OutputStream &OS, Type &Ty) {
387 // Function types require custom handling of const and static so we
388 // handle them separately. All other types use the same decoration
389 // for these modifiers, so handle them here in common code.
390 if (Ty.Prim == PrimTy::Function) {
391 Ty.outputPre(OS);
392 return;
393 }
394
395 switch (Ty.Storage) {
396 case StorageClass::PrivateStatic:
397 case StorageClass::PublicStatic:
398 case StorageClass::ProtectedStatic:
399 OS << "static ";
400 default:
401 break;
402 }
403 Ty.outputPre(OS);
404
405 if (Ty.Quals & Q_Const) {
406 outputSpaceIfNecessary(OS);
407 OS << "const";
408 }
409
410 if (Ty.Quals & Q_Volatile) {
411 outputSpaceIfNecessary(OS);
412 OS << "volatile";
413 }
414}
415
416// Write the "second half" of a given type.
417void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
418
419void Type::outputPre(OutputStream &OS) {
420 switch (Prim) {
421 case PrimTy::Void:
422 OS << "void";
423 break;
424 case PrimTy::Bool:
425 OS << "bool";
426 break;
427 case PrimTy::Char:
428 OS << "char";
429 break;
430 case PrimTy::Schar:
431 OS << "signed char";
432 break;
433 case PrimTy::Uchar:
434 OS << "unsigned char";
435 break;
436 case PrimTy::Short:
437 OS << "short";
438 break;
439 case PrimTy::Ushort:
440 OS << "unsigned short";
441 break;
442 case PrimTy::Int:
443 OS << "int";
444 break;
445 case PrimTy::Uint:
446 OS << "unsigned int";
447 break;
448 case PrimTy::Long:
449 OS << "long";
450 break;
451 case PrimTy::Ulong:
452 OS << "unsigned long";
453 break;
454 case PrimTy::Int64:
455 OS << "__int64";
456 break;
457 case PrimTy::Uint64:
458 OS << "unsigned __int64";
459 break;
460 case PrimTy::Wchar:
461 OS << "wchar_t";
462 break;
463 case PrimTy::Float:
464 OS << "float";
465 break;
466 case PrimTy::Double:
467 OS << "double";
468 break;
469 case PrimTy::Ldouble:
470 OS << "long double";
471 break;
472 default:
473 assert(false && "Invalid primitive type!");
474 }
475}
476void Type::outputPost(OutputStream &OS) {}
477
478Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000479 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000480}
481
482void PointerType::outputPre(OutputStream &OS) {
483 Type::outputPre(OS, *Pointee);
484
485 outputSpaceIfNecessary(OS);
486
487 if (Quals & Q_Unaligned)
488 OS << "__unaligned ";
489
490 // "[]" and "()" (for function parameters) take precedence over "*",
491 // so "int *x(int)" means "x is a function returning int *". We need
492 // parentheses to supercede the default precedence. (e.g. we want to
493 // emit something like "int (*x)(int)".)
494 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
495 OS << "(";
496
497 if (Prim == PrimTy::Ptr)
498 OS << "*";
499 else
500 OS << "&";
501
Zachary Turner91ecedd2018-07-20 18:07:33 +0000502 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000503 // if (Ty.Quals & Q_Pointer64)
504 // OS << " __ptr64";
505 if (Quals & Q_Restrict)
506 OS << " __restrict";
507}
508
509void PointerType::outputPost(OutputStream &OS) {
510 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
511 OS << ")";
512
513 Type::outputPost(OS, *Pointee);
514}
515
516Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000517 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000518}
519
520void FunctionType::outputPre(OutputStream &OS) {
521 if (!(FunctionClass & Global)) {
522 if (FunctionClass & Static)
523 OS << "static ";
524 }
525
526 if (ReturnType)
527 Type::outputPre(OS, *ReturnType);
528
529 outputCallingConvention(OS, CallConvention);
530}
531
532void FunctionType::outputPost(OutputStream &OS) {
533 OS << "(";
534 outputParameterList(OS, Params);
535 OS << ")";
536 if (Quals & Q_Const)
537 OS << " const";
538 if (Quals & Q_Volatile)
539 OS << " volatile";
540 return;
541}
542
543Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000544 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000545}
546
547void UdtType::outputPre(OutputStream &OS) {
548 switch (Prim) {
549 case PrimTy::Class:
550 OS << "class ";
551 break;
552 case PrimTy::Struct:
553 OS << "struct ";
554 break;
555 case PrimTy::Union:
556 OS << "union ";
557 break;
558 case PrimTy::Enum:
559 OS << "enum ";
560 break;
561 default:
562 assert(false && "Not a udt type!");
563 }
564
565 outputName(OS, UdtName);
566}
567
568Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000569 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000570}
571
572void ArrayType::outputPre(OutputStream &OS) {
573 Type::outputPre(OS, *ElementType);
574}
575
576void ArrayType::outputPost(OutputStream &OS) {
577 if (ArrayDimension > 0)
578 OS << "[" << ArrayDimension << "]";
579 if (NextDimension)
580 Type::outputPost(OS, *NextDimension);
581 else if (ElementType)
582 Type::outputPost(OS, *ElementType);
583}
584
585} // namespace
586
587namespace {
588
589// Demangler class takes the main role in demangling symbols.
590// It has a set of functions to parse mangled symbols into Type instances.
591// It also has a set of functions to cnovert Type instances to strings.
592class Demangler {
593public:
594 Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
595
596 // You are supposed to call parse() first and then check if error is true. If
597 // it is false, call output() to write the formatted name to the given stream.
598 void parse();
599 void output();
600
601 // True if an error occurred.
602 bool Error = false;
603
604private:
605 Type *demangleVariableEncoding();
606 Type *demangleFunctionEncoding();
607
608 Qualifiers demanglePointerExtQualifiers();
609
610 // Parser functions. This is a recursive-descent parser.
611 Type *demangleType(QualifierMangleMode QMM);
612 Type *demangleBasicType();
613 UdtType *demangleClassType();
614 PointerType *demanglePointerType();
615
616 ArrayType *demangleArrayType();
617
618 ParamList demangleParameterList();
619
620 int demangleNumber();
621 void demangleNamePiece(Name &Node, bool IsHead);
622
623 StringView demangleString(bool memorize);
624 void memorizeString(StringView s);
625 Name *demangleName();
626 void demangleOperator(Name *);
627 StringView demangleOperatorName();
628 int demangleFunctionClass();
629 CallingConv demangleCallingConvention();
630 StorageClass demangleVariableStorageClass();
631 ReferenceKind demangleReferenceKind();
632
633 Qualifiers demangleFunctionQualifiers();
Zachary Turner91ecedd2018-07-20 18:07:33 +0000634 Qualifiers demangleVariablQualifiers();
635 Qualifiers demangleReturnTypQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000636
637 Qualifiers demangleQualifiers(
638 QualifierMangleLocation Location = QualifierMangleLocation::Detect);
639
Zachary Turner91ecedd2018-07-20 18:07:33 +0000640 // The result is written to this stream.
641 OutputStream OS;
642
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000643 // Mangled symbol. demangle* functions shorten this string
644 // as they parse it.
645 StringView MangledName;
646
647 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000648 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000649
650 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
651 Name *SymbolName = nullptr;
652
653 // Memory allocator.
654 ArenaAllocator Arena;
655
656 // The first 10 BackReferences in a mangled name can be back-referenced by
657 // special name @[0-9]. This is a storage for the first 10 BackReferences.
658 StringView BackReferences[10];
659 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000660};
661} // namespace
662
663// Parser entry point.
664void Demangler::parse() {
665 // MSVC-style mangled symbols must start with '?'.
666 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000667 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000668 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000669 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000670 SymbolType->Prim = PrimTy::Unknown;
671 }
672
673 // What follows is a main symbol name. This may include
674 // namespaces or class BackReferences.
675 SymbolName = demangleName();
676
677 // Read a variable.
678 if (startsWithDigit(MangledName)) {
679 SymbolType = demangleVariableEncoding();
680 return;
681 }
682
683 // Read a function.
684 SymbolType = demangleFunctionEncoding();
685}
686
687// <type-encoding> ::= <storage-class> <variable-type>
688// <storage-class> ::= 0 # private static member
689// ::= 1 # protected static member
690// ::= 2 # public static member
691// ::= 3 # global
692// ::= 4 # static local
693
694Type *Demangler::demangleVariableEncoding() {
695 StorageClass SC = demangleVariableStorageClass();
696
697 Type *Ty = demangleType(QualifierMangleMode::Drop);
698
699 Ty->Storage = SC;
700
701 // <variable-type> ::= <type> <cvr-qualifiers>
702 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
703 switch (Ty->Prim) {
704 case PrimTy::Ptr:
705 case PrimTy::Ref: {
706 Qualifiers ExtraChildQuals = Q_None;
707 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
708
709 PointerType *PTy = static_cast<PointerType *>(Ty);
710 QualifierMangleLocation Location = PTy->isMemberPointer()
711 ? QualifierMangleLocation::Member
712 : QualifierMangleLocation::NonMember;
713
714 ExtraChildQuals = demangleQualifiers(Location);
715
716 if (PTy->isMemberPointer()) {
717 Name *BackRefName = demangleName();
718 (void)BackRefName;
719 }
720
721 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
722 break;
723 }
724 default:
725 Ty->Quals = demangleQualifiers();
726 break;
727 }
728
729 return Ty;
730}
731
732// Sometimes numbers are encoded in mangled symbols. For example,
733// "int (*x)[20]" is a valid C type (x is a pointer to an array of
734// length 20), so we need some way to embed numbers as part of symbols.
735// This function parses it.
736//
737// <number> ::= [?] <non-negative integer>
738//
739// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
740// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
741//
742// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
743int Demangler::demangleNumber() {
744 bool neg = MangledName.consumeFront("?");
745
746 if (startsWithDigit(MangledName)) {
747 int32_t Ret = MangledName[0] - '0' + 1;
748 MangledName = MangledName.dropFront(1);
749 return neg ? -Ret : Ret;
750 }
751
752 int Ret = 0;
753 for (size_t i = 0; i < MangledName.size(); ++i) {
754 char C = MangledName[i];
755 if (C == '@') {
756 MangledName = MangledName.dropFront(i + 1);
757 return neg ? -Ret : Ret;
758 }
759 if ('A' <= C && C <= 'P') {
760 Ret = (Ret << 4) + (C - 'A');
761 continue;
762 }
763 break;
764 }
765
766 Error = true;
767 return 0;
768}
769
770// Read until the next '@'.
771StringView Demangler::demangleString(bool Memorize) {
772 for (size_t i = 0; i < MangledName.size(); ++i) {
773 if (MangledName[i] != '@')
774 continue;
775 StringView ret = MangledName.substr(0, i);
776 MangledName = MangledName.dropFront(i + 1);
777
778 if (Memorize)
779 memorizeString(ret);
780 return ret;
781 }
782
783 Error = true;
784 return "";
785}
786
787// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
788// Memorize it.
789void Demangler::memorizeString(StringView S) {
790 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
791 return;
792 for (size_t i = 0; i < BackRefCount; ++i)
793 if (S == BackReferences[i])
794 return;
795 BackReferences[BackRefCount++] = S;
796}
797
798void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
799 if (startsWithDigit(MangledName)) {
800 size_t I = MangledName[0] - '0';
801 if (I >= BackRefCount) {
802 Error = true;
803 return;
804 }
805 MangledName = MangledName.dropFront();
806 Node.Str = BackReferences[I];
807 } else if (MangledName.consumeFront("?$")) {
808 // Class template.
809 Node.Str = demangleString(false);
810 Node.TemplateParams = demangleParameterList();
811 if (!MangledName.consumeFront('@')) {
812 Error = true;
813 return;
814 }
815 } else if (!IsHead && MangledName.consumeFront("?A")) {
816 // Anonymous namespace starts with ?A. So does overloaded operator[],
817 // but the distinguishing factor is that namespace themselves are not
818 // mangled, only the variables and functions inside of them are. So
819 // an anonymous namespace will never occur as the first item in the
820 // name.
821 Node.Str = "`anonymous namespace'";
822 if (!MangledName.consumeFront('@')) {
823 Error = true;
824 return;
825 }
826 } else if (MangledName.consumeFront("?")) {
827 // Overloaded operator.
828 demangleOperator(&Node);
829 } else {
830 // Non-template functions or classes.
831 Node.Str = demangleString(true);
832 }
833}
834
835// Parses a name in the form of A@B@C@@ which represents C::B::A.
836Name *Demangler::demangleName() {
837 Name *Head = nullptr;
838
839 while (!MangledName.consumeFront("@")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000840 Name *Elem = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000841
842 assert(!Error);
843 demangleNamePiece(*Elem, Head == nullptr);
844 if (Error)
845 return nullptr;
846
847 Elem->Next = Head;
848 Head = Elem;
849 }
850
851 return Head;
852}
853
854void Demangler::demangleOperator(Name *OpName) {
855 OpName->Operator = demangleOperatorName();
856 if (!Error && !MangledName.empty() && MangledName.front() != '@')
857 demangleNamePiece(*OpName, false);
858}
859
860StringView Demangler::demangleOperatorName() {
861 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
862 RestoreOnError.shouldRestore(false);
863
864 switch (MangledName.popFront()) {
865 case '0':
866 return "ctor";
867 case '1':
868 return "dtor";
869 case '2':
870 return " new";
871 case '3':
872 return " delete";
873 case '4':
874 return "=";
875 case '5':
876 return ">>";
877 case '6':
878 return "<<";
879 case '7':
880 return "!";
881 case '8':
882 return "==";
883 case '9':
884 return "!=";
885 case 'A':
886 return "[]";
887 case 'C':
888 return "->";
889 case 'D':
890 return "*";
891 case 'E':
892 return "++";
893 case 'F':
894 return "--";
895 case 'G':
896 return "-";
897 case 'H':
898 return "+";
899 case 'I':
900 return "&";
901 case 'J':
902 return "->*";
903 case 'K':
904 return "/";
905 case 'L':
906 return "%";
907 case 'M':
908 return "<";
909 case 'N':
910 return "<=";
911 case 'O':
912 return ">";
913 case 'P':
914 return ">=";
915 case 'Q':
916 return ",";
917 case 'R':
918 return "()";
919 case 'S':
920 return "~";
921 case 'T':
922 return "^";
923 case 'U':
924 return "|";
925 case 'V':
926 return "&&";
927 case 'W':
928 return "||";
929 case 'X':
930 return "*=";
931 case 'Y':
932 return "+=";
933 case 'Z':
934 return "-=";
935 case '_': {
936 if (MangledName.empty())
937 break;
938
939 switch (MangledName.popFront()) {
940 case '0':
941 return "/=";
942 case '1':
943 return "%=";
944 case '2':
945 return ">>=";
946 case '3':
947 return "<<=";
948 case '4':
949 return "&=";
950 case '5':
951 return "|=";
952 case '6':
953 return "^=";
954 case 'U':
955 return " new[]";
956 case 'V':
957 return " delete[]";
958 case '_':
959 if (MangledName.consumeFront("L"))
960 return " co_await";
961 }
962 }
963 }
964
965 Error = true;
966 RestoreOnError.shouldRestore(true);
967 return "";
968}
969
970int Demangler::demangleFunctionClass() {
971 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
972 RestoreOnError.shouldRestore(false);
973
974 switch (MangledName.popFront()) {
975 case 'A':
976 return Private;
977 case 'B':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000978 return Private | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000979 case 'C':
980 return Private | Static;
981 case 'D':
982 return Private | Static;
983 case 'E':
984 return Private | Virtual;
985 case 'F':
986 return Private | Virtual;
987 case 'I':
988 return Protected;
989 case 'J':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000990 return Protected | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000991 case 'K':
992 return Protected | Static;
993 case 'L':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000994 return Protected | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000995 case 'M':
996 return Protected | Virtual;
997 case 'N':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000998 return Protected | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000999 case 'Q':
1000 return Public;
1001 case 'R':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001002 return Public | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001003 case 'S':
1004 return Public | Static;
1005 case 'T':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001006 return Public | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001007 case 'U':
1008 return Public | Virtual;
1009 case 'V':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001010 return Public | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001011 case 'Y':
1012 return Global;
1013 case 'Z':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001014 return Global | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001015 }
1016
1017 Error = true;
1018 RestoreOnError.shouldRestore(true);
1019 return 0;
1020}
1021
1022Qualifiers Demangler::demangleFunctionQualifiers() {
1023 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1024 RestoreOnError.shouldRestore(false);
1025
1026 switch (MangledName.popFront()) {
1027 case 'A':
1028 return Q_None;
1029 case 'B':
1030 return Q_Const;
1031 case 'C':
1032 return Q_Volatile;
1033 case 'D':
1034 return Qualifiers(Q_Const | Q_Volatile);
1035 }
1036
1037 Error = true;
1038 RestoreOnError.shouldRestore(true);
1039 return Q_None;
1040}
1041
1042CallingConv Demangler::demangleCallingConvention() {
1043 switch (MangledName.popFront()) {
1044 case 'A':
1045 case 'B':
1046 return CallingConv::Cdecl;
1047 case 'C':
1048 case 'D':
1049 return CallingConv::Pascal;
1050 case 'E':
1051 case 'F':
1052 return CallingConv::Thiscall;
1053 case 'G':
1054 case 'H':
1055 return CallingConv::Stdcall;
1056 case 'I':
1057 case 'J':
1058 return CallingConv::Fastcall;
1059 case 'M':
1060 case 'N':
1061 return CallingConv::Clrcall;
1062 case 'O':
1063 case 'P':
1064 return CallingConv::Eabi;
1065 case 'Q':
1066 return CallingConv::Vectorcall;
1067 }
1068
1069 return CallingConv::None;
1070};
1071
1072StorageClass Demangler::demangleVariableStorageClass() {
1073 assert(std::isdigit(MangledName.front()));
1074
1075 switch (MangledName.popFront()) {
1076 case '0':
1077 return StorageClass::PrivateStatic;
1078 case '1':
1079 return StorageClass::ProtectedStatic;
1080 case '2':
1081 return StorageClass::PublicStatic;
1082 case '3':
1083 return StorageClass::Global;
1084 case '4':
1085 return StorageClass::FunctionLocalStatic;
1086 }
1087 Error = true;
1088 return StorageClass::None;
1089}
1090
Zachary Turner91ecedd2018-07-20 18:07:33 +00001091Qualifiers Demangler::demangleVariablQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001092 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1093 RestoreOnError.shouldRestore(false);
1094
1095 switch (MangledName.popFront()) {
1096 case 'A':
1097 return Q_None;
1098 case 'B':
1099 return Q_Const;
1100 case 'C':
1101 return Q_Volatile;
1102 case 'D':
1103 return Qualifiers(Q_Const | Q_Volatile);
1104 case 'E':
1105 return Q_Far;
1106 case 'F':
1107 return Qualifiers(Q_Const | Q_Far);
1108 case 'G':
1109 return Qualifiers(Q_Volatile | Q_Far);
1110 case 'H':
1111 return Qualifiers(Q_Const | Q_Volatile | Q_Far);
1112 }
1113
1114 Error = true;
1115 RestoreOnError.shouldRestore(true);
1116 return Q_None;
1117}
1118
Zachary Turner91ecedd2018-07-20 18:07:33 +00001119Qualifiers Demangler::demangleReturnTypQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001120 if (!MangledName.consumeFront("?"))
1121 return Q_None;
1122
1123 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1124 RestoreOnError.shouldRestore(false);
1125
1126 switch (MangledName.popFront()) {
1127 case 'A':
1128 return Q_None;
1129 case 'B':
1130 return Q_Const;
1131 case 'C':
1132 return Q_Volatile;
1133 case 'D':
1134 return Qualifiers(Q_Const | Q_Volatile);
1135 }
1136
1137 Error = true;
1138 RestoreOnError.shouldRestore(true);
1139 return Q_None;
1140}
1141
1142Qualifiers Demangler::demangleQualifiers(QualifierMangleLocation Location) {
1143 if (Location == QualifierMangleLocation::Detect) {
1144 switch (MangledName.front()) {
1145 case 'Q':
1146 case 'R':
1147 case 'S':
1148 case 'T':
1149 Location = QualifierMangleLocation::Member;
1150 break;
1151 case 'A':
1152 case 'B':
1153 case 'C':
1154 case 'D':
1155 Location = QualifierMangleLocation::NonMember;
1156 break;
1157 default:
1158 Error = true;
1159 return Q_None;
1160 }
1161 }
1162
1163 if (Location == QualifierMangleLocation::Member) {
1164 switch (MangledName.popFront()) {
1165 // Member qualifiers
1166 case 'Q':
1167 return Q_None;
1168 case 'R':
1169 return Q_Const;
1170 case 'S':
1171 return Q_Volatile;
1172 case 'T':
1173 return Qualifiers(Q_Const | Q_Volatile);
1174 }
1175 } else {
1176 switch (MangledName.popFront()) {
1177 // Non-Member qualifiers
1178 case 'A':
1179 return Q_None;
1180 case 'B':
1181 return Q_Const;
1182 case 'C':
1183 return Q_Volatile;
1184 case 'D':
1185 return Qualifiers(Q_Const | Q_Volatile);
1186 }
1187 }
1188 Error = true;
1189 return Q_None;
1190}
1191
1192// <variable-type> ::= <type> <cvr-qualifiers>
1193// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1194Type *Demangler::demangleType(QualifierMangleMode QMM) {
1195 Qualifiers Quals = Q_None;
1196 if (QMM == QualifierMangleMode::Mangle)
1197 Quals = Qualifiers(Quals | demangleQualifiers());
1198 else if (QMM == QualifierMangleMode::Result) {
1199 if (MangledName.consumeFront('?'))
1200 Quals = Qualifiers(Quals | demangleQualifiers());
1201 }
1202
1203 Type *Ty = nullptr;
1204 switch (MangledName.front()) {
1205 case 'T': // union
1206 case 'U': // struct
1207 case 'V': // class
1208 case 'W': // enum
1209 Ty = demangleClassType();
1210 break;
1211 case 'A': // foo &
1212 case 'P': // foo *
1213 case 'Q': // foo *const
1214 case 'R': // foo *volatile
1215 case 'S': // foo *const volatile
1216 Ty = demanglePointerType();
1217 break;
1218 case 'Y':
1219 Ty = demangleArrayType();
1220 break;
1221 default:
1222 Ty = demangleBasicType();
1223 break;
1224 }
1225 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1226 return Ty;
1227}
1228
1229static bool functionHasThisPtr(const FunctionType &Ty) {
1230 assert(Ty.Prim == PrimTy::Function);
1231 if (Ty.FunctionClass & Global)
1232 return false;
1233 if (Ty.FunctionClass & Static)
1234 return false;
1235 return true;
1236}
1237
1238ReferenceKind Demangler::demangleReferenceKind() {
1239 if (MangledName.consumeFront('G'))
1240 return ReferenceKind::LValueRef;
1241 else if (MangledName.consumeFront('H'))
1242 return ReferenceKind::RValueRef;
1243 return ReferenceKind::None;
1244}
1245
1246Type *Demangler::demangleFunctionEncoding() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001247 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001248
1249 FTy->Prim = PrimTy::Function;
1250 FTy->FunctionClass = (FuncClass)demangleFunctionClass();
1251 if (functionHasThisPtr(*FTy)) {
1252 FTy->Quals = demanglePointerExtQualifiers();
1253 FTy->RefKind = demangleReferenceKind();
1254 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers());
1255 }
1256
1257 // Fields that appear on both member and non-member functions.
1258 FTy->CallConvention = demangleCallingConvention();
1259
1260 // <return-type> ::= <type>
1261 // ::= @ # structors (they have no declared return type)
1262 bool IsStructor = MangledName.consumeFront('@');
1263 if (!IsStructor)
1264 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1265
1266 FTy->Params = demangleParameterList();
1267
1268 return FTy;
1269}
1270
1271// Reads a primitive type.
1272Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001273 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001274
1275 switch (MangledName.popFront()) {
1276 case 'X':
1277 Ty->Prim = PrimTy::Void;
1278 break;
1279 case 'D':
1280 Ty->Prim = PrimTy::Char;
1281 break;
1282 case 'C':
1283 Ty->Prim = PrimTy::Schar;
1284 break;
1285 case 'E':
1286 Ty->Prim = PrimTy::Uchar;
1287 break;
1288 case 'F':
1289 Ty->Prim = PrimTy::Short;
1290 break;
1291 case 'G':
1292 Ty->Prim = PrimTy::Ushort;
1293 break;
1294 case 'H':
1295 Ty->Prim = PrimTy::Int;
1296 break;
1297 case 'I':
1298 Ty->Prim = PrimTy::Uint;
1299 break;
1300 case 'J':
1301 Ty->Prim = PrimTy::Long;
1302 break;
1303 case 'K':
1304 Ty->Prim = PrimTy::Ulong;
1305 break;
1306 case 'M':
1307 Ty->Prim = PrimTy::Float;
1308 break;
1309 case 'N':
1310 Ty->Prim = PrimTy::Double;
1311 break;
1312 case 'O':
1313 Ty->Prim = PrimTy::Ldouble;
1314 break;
1315 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001316 if (MangledName.empty()) {
1317 Error = true;
1318 return nullptr;
1319 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001320 switch (MangledName.popFront()) {
1321 case 'N':
1322 Ty->Prim = PrimTy::Bool;
1323 break;
1324 case 'J':
1325 Ty->Prim = PrimTy::Int64;
1326 break;
1327 case 'K':
1328 Ty->Prim = PrimTy::Uint64;
1329 break;
1330 case 'W':
1331 Ty->Prim = PrimTy::Wchar;
1332 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001333 default:
1334 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001335 }
1336 break;
1337 }
1338 }
1339 return Ty;
1340}
1341
1342UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001343 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001344
1345 switch (MangledName.popFront()) {
1346 case 'T':
1347 UTy->Prim = PrimTy::Union;
1348 break;
1349 case 'U':
1350 UTy->Prim = PrimTy::Struct;
1351 break;
1352 case 'V':
1353 UTy->Prim = PrimTy::Class;
1354 break;
1355 case 'W':
1356 if (MangledName.popFront() != '4') {
1357 Error = true;
1358 return nullptr;
1359 }
1360 UTy->Prim = PrimTy::Enum;
1361 break;
1362 default:
1363 assert(false);
1364 }
1365
1366 UTy->UdtName = demangleName();
1367 return UTy;
1368}
1369
1370// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1371// # the E is required for 64-bit non-static pointers
1372PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001373 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001374
1375 Pointer->Quals = Q_None;
1376 switch (MangledName.popFront()) {
1377 case 'A':
1378 Pointer->Prim = PrimTy::Ref;
1379 break;
1380 case 'P':
1381 Pointer->Prim = PrimTy::Ptr;
1382 break;
1383 case 'Q':
1384 Pointer->Prim = PrimTy::Ptr;
1385 Pointer->Quals = Q_Const;
1386 break;
1387 case 'R':
1388 Pointer->Quals = Q_Volatile;
1389 Pointer->Prim = PrimTy::Ptr;
1390 break;
1391 case 'S':
1392 Pointer->Quals = Qualifiers(Q_Const | Q_Volatile);
1393 Pointer->Prim = PrimTy::Ptr;
1394 break;
1395 default:
1396 assert(false && "Ty is not a pointer type!");
1397 }
1398
1399 if (MangledName.consumeFront("6")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001400 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001401 FTy->Prim = PrimTy::Function;
1402 FTy->CallConvention = demangleCallingConvention();
1403
1404 FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
1405 FTy->Params = demangleParameterList();
1406
1407 if (!MangledName.consumeFront("@Z"))
1408 MangledName.consumeFront("Z");
1409
1410 Pointer->Pointee = FTy;
1411 return Pointer;
1412 }
1413
1414 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1415 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1416
1417 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1418 return Pointer;
1419}
1420
1421Qualifiers Demangler::demanglePointerExtQualifiers() {
1422 Qualifiers Quals = Q_None;
1423 if (MangledName.consumeFront('E'))
1424 Quals = Qualifiers(Quals | Q_Pointer64);
1425 if (MangledName.consumeFront('I'))
1426 Quals = Qualifiers(Quals | Q_Restrict);
1427 if (MangledName.consumeFront('F'))
1428 Quals = Qualifiers(Quals | Q_Unaligned);
1429
1430 return Quals;
1431}
1432
1433ArrayType *Demangler::demangleArrayType() {
1434 assert(MangledName.front() == 'Y');
1435 MangledName.popFront();
1436
1437 int Dimension = demangleNumber();
1438 if (Dimension <= 0) {
1439 Error = true;
1440 return nullptr;
1441 }
1442
Zachary Turner9d72aa92018-07-20 18:35:06 +00001443 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001444 ArrayType *Dim = ATy;
1445 for (int I = 0; I < Dimension; ++I) {
1446 Dim->Prim = PrimTy::Array;
1447 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001448 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001449 Dim = Dim->NextDimension;
1450 }
1451
1452 if (MangledName.consumeFront("$$C")) {
1453 if (MangledName.consumeFront("B"))
1454 ATy->Quals = Q_Const;
1455 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1456 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1457 else if (!MangledName.consumeFront("A"))
1458 Error = true;
1459 }
1460
1461 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1462 Dim->ElementType = ATy->ElementType;
1463 return ATy;
1464}
1465
1466// Reads a function or a template parameters.
1467ParamList Demangler::demangleParameterList() {
1468 // Within the same parameter list, you can backreference the first 10 types.
1469 Type *BackRef[10];
1470 int Idx = 0;
1471
1472 ParamList *Head;
1473 ParamList **Current = &Head;
1474 while (!Error && !MangledName.startsWith('@') &&
1475 !MangledName.startsWith('Z')) {
1476 if (startsWithDigit(MangledName)) {
1477 int N = MangledName[0] - '0';
1478 if (N >= Idx) {
1479 Error = true;
1480 return {};
1481 }
1482 MangledName = MangledName.dropFront();
1483
Zachary Turner9d72aa92018-07-20 18:35:06 +00001484 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001485 (*Current)->Current = BackRef[N]->clone(Arena);
1486 Current = &(*Current)->Next;
1487 continue;
1488 }
1489
1490 size_t ArrayDimension = MangledName.size();
1491
Zachary Turner9d72aa92018-07-20 18:35:06 +00001492 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001493 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1494
1495 // Single-letter types are ignored for backreferences because
1496 // memorizing them doesn't save anything.
1497 if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
1498 BackRef[Idx++] = (*Current)->Current;
1499 Current = &(*Current)->Next;
1500 }
1501
1502 return *Head;
1503}
1504
1505void Demangler::output() {
1506 // Converts an AST to a string.
1507 //
1508 // Converting an AST representing a C++ type to a string is tricky due
1509 // to the bad grammar of the C++ declaration inherited from C. You have
1510 // to construct a string from inside to outside. For example, if a type
1511 // X is a pointer to a function returning int, the order you create a
1512 // string becomes something like this:
1513 //
1514 // (1) X is a pointer: *X
1515 // (2) (1) is a function returning int: int (*X)()
1516 //
1517 // So you cannot construct a result just by appending strings to a result.
1518 //
1519 // To deal with this, we split the function into two. outputPre() writes
1520 // the "first half" of type declaration, and outputPost() writes the
1521 // "second half". For example, outputPre() writes a return type for a
1522 // function and outputPost() writes an parameter list.
1523 Type::outputPre(OS, *SymbolType);
1524 outputName(OS, SymbolName);
1525 Type::outputPost(OS, *SymbolType);
1526
1527 // Null terminate the buffer.
1528 OS << '\0';
1529}
1530
1531char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1532 int *Status) {
1533 OutputStream OS = OutputStream::create(Buf, N, 1024);
1534
1535 Demangler D(OS, StringView(MangledName));
1536 D.parse();
1537
1538 if (D.Error)
1539 *Status = llvm::demangle_invalid_mangled_name;
1540 else
1541 *Status = llvm::demangle_success;
1542
1543 D.output();
1544 return OS.getBuffer();
1545}