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