blob: 8977b9fe570fc8fea3ec601086d87b097742dc7f [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,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000170 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000171};
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;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000231 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000232 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;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000243 void outputPre(OutputStream &OS) override;
244 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000245
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
Zachary Turner91ecedd2018-07-20 18:07:33 +0000497 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000498 // if (Ty.Quals & Q_Pointer64)
499 // OS << " __ptr64";
500 if (Quals & Q_Restrict)
501 OS << " __restrict";
502}
503
504void PointerType::outputPost(OutputStream &OS) {
505 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
506 OS << ")";
507
508 Type::outputPost(OS, *Pointee);
509}
510
511Type *FunctionType::clone(ArenaAllocator &Arena) const {
512 return new (Arena) FunctionType(*this);
513}
514
515void FunctionType::outputPre(OutputStream &OS) {
516 if (!(FunctionClass & Global)) {
517 if (FunctionClass & Static)
518 OS << "static ";
519 }
520
521 if (ReturnType)
522 Type::outputPre(OS, *ReturnType);
523
524 outputCallingConvention(OS, CallConvention);
525}
526
527void FunctionType::outputPost(OutputStream &OS) {
528 OS << "(";
529 outputParameterList(OS, Params);
530 OS << ")";
531 if (Quals & Q_Const)
532 OS << " const";
533 if (Quals & Q_Volatile)
534 OS << " volatile";
535 return;
536}
537
538Type *UdtType::clone(ArenaAllocator &Arena) const {
539 return new (Arena) UdtType(*this);
540}
541
542void UdtType::outputPre(OutputStream &OS) {
543 switch (Prim) {
544 case PrimTy::Class:
545 OS << "class ";
546 break;
547 case PrimTy::Struct:
548 OS << "struct ";
549 break;
550 case PrimTy::Union:
551 OS << "union ";
552 break;
553 case PrimTy::Enum:
554 OS << "enum ";
555 break;
556 default:
557 assert(false && "Not a udt type!");
558 }
559
560 outputName(OS, UdtName);
561}
562
563Type *ArrayType::clone(ArenaAllocator &Arena) const {
564 return new (Arena) ArrayType(*this);
565}
566
567void ArrayType::outputPre(OutputStream &OS) {
568 Type::outputPre(OS, *ElementType);
569}
570
571void ArrayType::outputPost(OutputStream &OS) {
572 if (ArrayDimension > 0)
573 OS << "[" << ArrayDimension << "]";
574 if (NextDimension)
575 Type::outputPost(OS, *NextDimension);
576 else if (ElementType)
577 Type::outputPost(OS, *ElementType);
578}
579
580} // namespace
581
582namespace {
583
584// Demangler class takes the main role in demangling symbols.
585// It has a set of functions to parse mangled symbols into Type instances.
586// It also has a set of functions to cnovert Type instances to strings.
587class Demangler {
588public:
589 Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
590
591 // You are supposed to call parse() first and then check if error is true. If
592 // it is false, call output() to write the formatted name to the given stream.
593 void parse();
594 void output();
595
596 // True if an error occurred.
597 bool Error = false;
598
599private:
600 Type *demangleVariableEncoding();
601 Type *demangleFunctionEncoding();
602
603 Qualifiers demanglePointerExtQualifiers();
604
605 // Parser functions. This is a recursive-descent parser.
606 Type *demangleType(QualifierMangleMode QMM);
607 Type *demangleBasicType();
608 UdtType *demangleClassType();
609 PointerType *demanglePointerType();
610
611 ArrayType *demangleArrayType();
612
613 ParamList demangleParameterList();
614
615 int demangleNumber();
616 void demangleNamePiece(Name &Node, bool IsHead);
617
618 StringView demangleString(bool memorize);
619 void memorizeString(StringView s);
620 Name *demangleName();
621 void demangleOperator(Name *);
622 StringView demangleOperatorName();
623 int demangleFunctionClass();
624 CallingConv demangleCallingConvention();
625 StorageClass demangleVariableStorageClass();
626 ReferenceKind demangleReferenceKind();
627
628 Qualifiers demangleFunctionQualifiers();
Zachary Turner91ecedd2018-07-20 18:07:33 +0000629 Qualifiers demangleVariablQualifiers();
630 Qualifiers demangleReturnTypQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000631
632 Qualifiers demangleQualifiers(
633 QualifierMangleLocation Location = QualifierMangleLocation::Detect);
634
Zachary Turner91ecedd2018-07-20 18:07:33 +0000635 // The result is written to this stream.
636 OutputStream OS;
637
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000638 // Mangled symbol. demangle* functions shorten this string
639 // as they parse it.
640 StringView MangledName;
641
642 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000643 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000644
645 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
646 Name *SymbolName = nullptr;
647
648 // Memory allocator.
649 ArenaAllocator Arena;
650
651 // The first 10 BackReferences in a mangled name can be back-referenced by
652 // special name @[0-9]. This is a storage for the first 10 BackReferences.
653 StringView BackReferences[10];
654 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000655};
656} // namespace
657
658// Parser entry point.
659void Demangler::parse() {
660 // MSVC-style mangled symbols must start with '?'.
661 if (!MangledName.consumeFront("?")) {
662 SymbolName = new (Arena) Name;
663 SymbolName->Str = MangledName;
664 SymbolType = new (Arena) Type;
665 SymbolType->Prim = PrimTy::Unknown;
666 }
667
668 // What follows is a main symbol name. This may include
669 // namespaces or class BackReferences.
670 SymbolName = demangleName();
671
672 // Read a variable.
673 if (startsWithDigit(MangledName)) {
674 SymbolType = demangleVariableEncoding();
675 return;
676 }
677
678 // Read a function.
679 SymbolType = demangleFunctionEncoding();
680}
681
682// <type-encoding> ::= <storage-class> <variable-type>
683// <storage-class> ::= 0 # private static member
684// ::= 1 # protected static member
685// ::= 2 # public static member
686// ::= 3 # global
687// ::= 4 # static local
688
689Type *Demangler::demangleVariableEncoding() {
690 StorageClass SC = demangleVariableStorageClass();
691
692 Type *Ty = demangleType(QualifierMangleMode::Drop);
693
694 Ty->Storage = SC;
695
696 // <variable-type> ::= <type> <cvr-qualifiers>
697 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
698 switch (Ty->Prim) {
699 case PrimTy::Ptr:
700 case PrimTy::Ref: {
701 Qualifiers ExtraChildQuals = Q_None;
702 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
703
704 PointerType *PTy = static_cast<PointerType *>(Ty);
705 QualifierMangleLocation Location = PTy->isMemberPointer()
706 ? QualifierMangleLocation::Member
707 : QualifierMangleLocation::NonMember;
708
709 ExtraChildQuals = demangleQualifiers(Location);
710
711 if (PTy->isMemberPointer()) {
712 Name *BackRefName = demangleName();
713 (void)BackRefName;
714 }
715
716 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
717 break;
718 }
719 default:
720 Ty->Quals = demangleQualifiers();
721 break;
722 }
723
724 return Ty;
725}
726
727// Sometimes numbers are encoded in mangled symbols. For example,
728// "int (*x)[20]" is a valid C type (x is a pointer to an array of
729// length 20), so we need some way to embed numbers as part of symbols.
730// This function parses it.
731//
732// <number> ::= [?] <non-negative integer>
733//
734// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
735// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
736//
737// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
738int Demangler::demangleNumber() {
739 bool neg = MangledName.consumeFront("?");
740
741 if (startsWithDigit(MangledName)) {
742 int32_t Ret = MangledName[0] - '0' + 1;
743 MangledName = MangledName.dropFront(1);
744 return neg ? -Ret : Ret;
745 }
746
747 int Ret = 0;
748 for (size_t i = 0; i < MangledName.size(); ++i) {
749 char C = MangledName[i];
750 if (C == '@') {
751 MangledName = MangledName.dropFront(i + 1);
752 return neg ? -Ret : Ret;
753 }
754 if ('A' <= C && C <= 'P') {
755 Ret = (Ret << 4) + (C - 'A');
756 continue;
757 }
758 break;
759 }
760
761 Error = true;
762 return 0;
763}
764
765// Read until the next '@'.
766StringView Demangler::demangleString(bool Memorize) {
767 for (size_t i = 0; i < MangledName.size(); ++i) {
768 if (MangledName[i] != '@')
769 continue;
770 StringView ret = MangledName.substr(0, i);
771 MangledName = MangledName.dropFront(i + 1);
772
773 if (Memorize)
774 memorizeString(ret);
775 return ret;
776 }
777
778 Error = true;
779 return "";
780}
781
782// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
783// Memorize it.
784void Demangler::memorizeString(StringView S) {
785 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
786 return;
787 for (size_t i = 0; i < BackRefCount; ++i)
788 if (S == BackReferences[i])
789 return;
790 BackReferences[BackRefCount++] = S;
791}
792
793void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
794 if (startsWithDigit(MangledName)) {
795 size_t I = MangledName[0] - '0';
796 if (I >= BackRefCount) {
797 Error = true;
798 return;
799 }
800 MangledName = MangledName.dropFront();
801 Node.Str = BackReferences[I];
802 } else if (MangledName.consumeFront("?$")) {
803 // Class template.
804 Node.Str = demangleString(false);
805 Node.TemplateParams = demangleParameterList();
806 if (!MangledName.consumeFront('@')) {
807 Error = true;
808 return;
809 }
810 } else if (!IsHead && MangledName.consumeFront("?A")) {
811 // Anonymous namespace starts with ?A. So does overloaded operator[],
812 // but the distinguishing factor is that namespace themselves are not
813 // mangled, only the variables and functions inside of them are. So
814 // an anonymous namespace will never occur as the first item in the
815 // name.
816 Node.Str = "`anonymous namespace'";
817 if (!MangledName.consumeFront('@')) {
818 Error = true;
819 return;
820 }
821 } else if (MangledName.consumeFront("?")) {
822 // Overloaded operator.
823 demangleOperator(&Node);
824 } else {
825 // Non-template functions or classes.
826 Node.Str = demangleString(true);
827 }
828}
829
830// Parses a name in the form of A@B@C@@ which represents C::B::A.
831Name *Demangler::demangleName() {
832 Name *Head = nullptr;
833
834 while (!MangledName.consumeFront("@")) {
835 Name *Elem = new (Arena) Name;
836
837 assert(!Error);
838 demangleNamePiece(*Elem, Head == nullptr);
839 if (Error)
840 return nullptr;
841
842 Elem->Next = Head;
843 Head = Elem;
844 }
845
846 return Head;
847}
848
849void Demangler::demangleOperator(Name *OpName) {
850 OpName->Operator = demangleOperatorName();
851 if (!Error && !MangledName.empty() && MangledName.front() != '@')
852 demangleNamePiece(*OpName, false);
853}
854
855StringView Demangler::demangleOperatorName() {
856 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
857 RestoreOnError.shouldRestore(false);
858
859 switch (MangledName.popFront()) {
860 case '0':
861 return "ctor";
862 case '1':
863 return "dtor";
864 case '2':
865 return " new";
866 case '3':
867 return " delete";
868 case '4':
869 return "=";
870 case '5':
871 return ">>";
872 case '6':
873 return "<<";
874 case '7':
875 return "!";
876 case '8':
877 return "==";
878 case '9':
879 return "!=";
880 case 'A':
881 return "[]";
882 case 'C':
883 return "->";
884 case 'D':
885 return "*";
886 case 'E':
887 return "++";
888 case 'F':
889 return "--";
890 case 'G':
891 return "-";
892 case 'H':
893 return "+";
894 case 'I':
895 return "&";
896 case 'J':
897 return "->*";
898 case 'K':
899 return "/";
900 case 'L':
901 return "%";
902 case 'M':
903 return "<";
904 case 'N':
905 return "<=";
906 case 'O':
907 return ">";
908 case 'P':
909 return ">=";
910 case 'Q':
911 return ",";
912 case 'R':
913 return "()";
914 case 'S':
915 return "~";
916 case 'T':
917 return "^";
918 case 'U':
919 return "|";
920 case 'V':
921 return "&&";
922 case 'W':
923 return "||";
924 case 'X':
925 return "*=";
926 case 'Y':
927 return "+=";
928 case 'Z':
929 return "-=";
930 case '_': {
931 if (MangledName.empty())
932 break;
933
934 switch (MangledName.popFront()) {
935 case '0':
936 return "/=";
937 case '1':
938 return "%=";
939 case '2':
940 return ">>=";
941 case '3':
942 return "<<=";
943 case '4':
944 return "&=";
945 case '5':
946 return "|=";
947 case '6':
948 return "^=";
949 case 'U':
950 return " new[]";
951 case 'V':
952 return " delete[]";
953 case '_':
954 if (MangledName.consumeFront("L"))
955 return " co_await";
956 }
957 }
958 }
959
960 Error = true;
961 RestoreOnError.shouldRestore(true);
962 return "";
963}
964
965int Demangler::demangleFunctionClass() {
966 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
967 RestoreOnError.shouldRestore(false);
968
969 switch (MangledName.popFront()) {
970 case 'A':
971 return Private;
972 case 'B':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000973 return Private | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000974 case 'C':
975 return Private | Static;
976 case 'D':
977 return Private | Static;
978 case 'E':
979 return Private | Virtual;
980 case 'F':
981 return Private | Virtual;
982 case 'I':
983 return Protected;
984 case 'J':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000985 return Protected | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000986 case 'K':
987 return Protected | Static;
988 case 'L':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000989 return Protected | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000990 case 'M':
991 return Protected | Virtual;
992 case 'N':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000993 return Protected | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000994 case 'Q':
995 return Public;
996 case 'R':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000997 return Public | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000998 case 'S':
999 return Public | Static;
1000 case 'T':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001001 return Public | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001002 case 'U':
1003 return Public | Virtual;
1004 case 'V':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001005 return Public | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001006 case 'Y':
1007 return Global;
1008 case 'Z':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001009 return Global | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001010 }
1011
1012 Error = true;
1013 RestoreOnError.shouldRestore(true);
1014 return 0;
1015}
1016
1017Qualifiers Demangler::demangleFunctionQualifiers() {
1018 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1019 RestoreOnError.shouldRestore(false);
1020
1021 switch (MangledName.popFront()) {
1022 case 'A':
1023 return Q_None;
1024 case 'B':
1025 return Q_Const;
1026 case 'C':
1027 return Q_Volatile;
1028 case 'D':
1029 return Qualifiers(Q_Const | Q_Volatile);
1030 }
1031
1032 Error = true;
1033 RestoreOnError.shouldRestore(true);
1034 return Q_None;
1035}
1036
1037CallingConv Demangler::demangleCallingConvention() {
1038 switch (MangledName.popFront()) {
1039 case 'A':
1040 case 'B':
1041 return CallingConv::Cdecl;
1042 case 'C':
1043 case 'D':
1044 return CallingConv::Pascal;
1045 case 'E':
1046 case 'F':
1047 return CallingConv::Thiscall;
1048 case 'G':
1049 case 'H':
1050 return CallingConv::Stdcall;
1051 case 'I':
1052 case 'J':
1053 return CallingConv::Fastcall;
1054 case 'M':
1055 case 'N':
1056 return CallingConv::Clrcall;
1057 case 'O':
1058 case 'P':
1059 return CallingConv::Eabi;
1060 case 'Q':
1061 return CallingConv::Vectorcall;
1062 }
1063
1064 return CallingConv::None;
1065};
1066
1067StorageClass Demangler::demangleVariableStorageClass() {
1068 assert(std::isdigit(MangledName.front()));
1069
1070 switch (MangledName.popFront()) {
1071 case '0':
1072 return StorageClass::PrivateStatic;
1073 case '1':
1074 return StorageClass::ProtectedStatic;
1075 case '2':
1076 return StorageClass::PublicStatic;
1077 case '3':
1078 return StorageClass::Global;
1079 case '4':
1080 return StorageClass::FunctionLocalStatic;
1081 }
1082 Error = true;
1083 return StorageClass::None;
1084}
1085
Zachary Turner91ecedd2018-07-20 18:07:33 +00001086Qualifiers Demangler::demangleVariablQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001087 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1088 RestoreOnError.shouldRestore(false);
1089
1090 switch (MangledName.popFront()) {
1091 case 'A':
1092 return Q_None;
1093 case 'B':
1094 return Q_Const;
1095 case 'C':
1096 return Q_Volatile;
1097 case 'D':
1098 return Qualifiers(Q_Const | Q_Volatile);
1099 case 'E':
1100 return Q_Far;
1101 case 'F':
1102 return Qualifiers(Q_Const | Q_Far);
1103 case 'G':
1104 return Qualifiers(Q_Volatile | Q_Far);
1105 case 'H':
1106 return Qualifiers(Q_Const | Q_Volatile | Q_Far);
1107 }
1108
1109 Error = true;
1110 RestoreOnError.shouldRestore(true);
1111 return Q_None;
1112}
1113
Zachary Turner91ecedd2018-07-20 18:07:33 +00001114Qualifiers Demangler::demangleReturnTypQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001115 if (!MangledName.consumeFront("?"))
1116 return Q_None;
1117
1118 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1119 RestoreOnError.shouldRestore(false);
1120
1121 switch (MangledName.popFront()) {
1122 case 'A':
1123 return Q_None;
1124 case 'B':
1125 return Q_Const;
1126 case 'C':
1127 return Q_Volatile;
1128 case 'D':
1129 return Qualifiers(Q_Const | Q_Volatile);
1130 }
1131
1132 Error = true;
1133 RestoreOnError.shouldRestore(true);
1134 return Q_None;
1135}
1136
1137Qualifiers Demangler::demangleQualifiers(QualifierMangleLocation Location) {
1138 if (Location == QualifierMangleLocation::Detect) {
1139 switch (MangledName.front()) {
1140 case 'Q':
1141 case 'R':
1142 case 'S':
1143 case 'T':
1144 Location = QualifierMangleLocation::Member;
1145 break;
1146 case 'A':
1147 case 'B':
1148 case 'C':
1149 case 'D':
1150 Location = QualifierMangleLocation::NonMember;
1151 break;
1152 default:
1153 Error = true;
1154 return Q_None;
1155 }
1156 }
1157
1158 if (Location == QualifierMangleLocation::Member) {
1159 switch (MangledName.popFront()) {
1160 // Member qualifiers
1161 case 'Q':
1162 return Q_None;
1163 case 'R':
1164 return Q_Const;
1165 case 'S':
1166 return Q_Volatile;
1167 case 'T':
1168 return Qualifiers(Q_Const | Q_Volatile);
1169 }
1170 } else {
1171 switch (MangledName.popFront()) {
1172 // Non-Member qualifiers
1173 case 'A':
1174 return Q_None;
1175 case 'B':
1176 return Q_Const;
1177 case 'C':
1178 return Q_Volatile;
1179 case 'D':
1180 return Qualifiers(Q_Const | Q_Volatile);
1181 }
1182 }
1183 Error = true;
1184 return Q_None;
1185}
1186
1187// <variable-type> ::= <type> <cvr-qualifiers>
1188// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1189Type *Demangler::demangleType(QualifierMangleMode QMM) {
1190 Qualifiers Quals = Q_None;
1191 if (QMM == QualifierMangleMode::Mangle)
1192 Quals = Qualifiers(Quals | demangleQualifiers());
1193 else if (QMM == QualifierMangleMode::Result) {
1194 if (MangledName.consumeFront('?'))
1195 Quals = Qualifiers(Quals | demangleQualifiers());
1196 }
1197
1198 Type *Ty = nullptr;
1199 switch (MangledName.front()) {
1200 case 'T': // union
1201 case 'U': // struct
1202 case 'V': // class
1203 case 'W': // enum
1204 Ty = demangleClassType();
1205 break;
1206 case 'A': // foo &
1207 case 'P': // foo *
1208 case 'Q': // foo *const
1209 case 'R': // foo *volatile
1210 case 'S': // foo *const volatile
1211 Ty = demanglePointerType();
1212 break;
1213 case 'Y':
1214 Ty = demangleArrayType();
1215 break;
1216 default:
1217 Ty = demangleBasicType();
1218 break;
1219 }
1220 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1221 return Ty;
1222}
1223
1224static bool functionHasThisPtr(const FunctionType &Ty) {
1225 assert(Ty.Prim == PrimTy::Function);
1226 if (Ty.FunctionClass & Global)
1227 return false;
1228 if (Ty.FunctionClass & Static)
1229 return false;
1230 return true;
1231}
1232
1233ReferenceKind Demangler::demangleReferenceKind() {
1234 if (MangledName.consumeFront('G'))
1235 return ReferenceKind::LValueRef;
1236 else if (MangledName.consumeFront('H'))
1237 return ReferenceKind::RValueRef;
1238 return ReferenceKind::None;
1239}
1240
1241Type *Demangler::demangleFunctionEncoding() {
1242 FunctionType *FTy = new (Arena) FunctionType;
1243
1244 FTy->Prim = PrimTy::Function;
1245 FTy->FunctionClass = (FuncClass)demangleFunctionClass();
1246 if (functionHasThisPtr(*FTy)) {
1247 FTy->Quals = demanglePointerExtQualifiers();
1248 FTy->RefKind = demangleReferenceKind();
1249 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers());
1250 }
1251
1252 // Fields that appear on both member and non-member functions.
1253 FTy->CallConvention = demangleCallingConvention();
1254
1255 // <return-type> ::= <type>
1256 // ::= @ # structors (they have no declared return type)
1257 bool IsStructor = MangledName.consumeFront('@');
1258 if (!IsStructor)
1259 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1260
1261 FTy->Params = demangleParameterList();
1262
1263 return FTy;
1264}
1265
1266// Reads a primitive type.
1267Type *Demangler::demangleBasicType() {
1268 Type *Ty = new (Arena) Type;
1269
1270 switch (MangledName.popFront()) {
1271 case 'X':
1272 Ty->Prim = PrimTy::Void;
1273 break;
1274 case 'D':
1275 Ty->Prim = PrimTy::Char;
1276 break;
1277 case 'C':
1278 Ty->Prim = PrimTy::Schar;
1279 break;
1280 case 'E':
1281 Ty->Prim = PrimTy::Uchar;
1282 break;
1283 case 'F':
1284 Ty->Prim = PrimTy::Short;
1285 break;
1286 case 'G':
1287 Ty->Prim = PrimTy::Ushort;
1288 break;
1289 case 'H':
1290 Ty->Prim = PrimTy::Int;
1291 break;
1292 case 'I':
1293 Ty->Prim = PrimTy::Uint;
1294 break;
1295 case 'J':
1296 Ty->Prim = PrimTy::Long;
1297 break;
1298 case 'K':
1299 Ty->Prim = PrimTy::Ulong;
1300 break;
1301 case 'M':
1302 Ty->Prim = PrimTy::Float;
1303 break;
1304 case 'N':
1305 Ty->Prim = PrimTy::Double;
1306 break;
1307 case 'O':
1308 Ty->Prim = PrimTy::Ldouble;
1309 break;
1310 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001311 if (MangledName.empty()) {
1312 Error = true;
1313 return nullptr;
1314 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001315 switch (MangledName.popFront()) {
1316 case 'N':
1317 Ty->Prim = PrimTy::Bool;
1318 break;
1319 case 'J':
1320 Ty->Prim = PrimTy::Int64;
1321 break;
1322 case 'K':
1323 Ty->Prim = PrimTy::Uint64;
1324 break;
1325 case 'W':
1326 Ty->Prim = PrimTy::Wchar;
1327 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001328 default:
1329 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001330 }
1331 break;
1332 }
1333 }
1334 return Ty;
1335}
1336
1337UdtType *Demangler::demangleClassType() {
1338 UdtType *UTy = new (Arena) UdtType;
1339
1340 switch (MangledName.popFront()) {
1341 case 'T':
1342 UTy->Prim = PrimTy::Union;
1343 break;
1344 case 'U':
1345 UTy->Prim = PrimTy::Struct;
1346 break;
1347 case 'V':
1348 UTy->Prim = PrimTy::Class;
1349 break;
1350 case 'W':
1351 if (MangledName.popFront() != '4') {
1352 Error = true;
1353 return nullptr;
1354 }
1355 UTy->Prim = PrimTy::Enum;
1356 break;
1357 default:
1358 assert(false);
1359 }
1360
1361 UTy->UdtName = demangleName();
1362 return UTy;
1363}
1364
1365// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1366// # the E is required for 64-bit non-static pointers
1367PointerType *Demangler::demanglePointerType() {
1368 PointerType *Pointer = new (Arena) PointerType;
1369
1370 Pointer->Quals = Q_None;
1371 switch (MangledName.popFront()) {
1372 case 'A':
1373 Pointer->Prim = PrimTy::Ref;
1374 break;
1375 case 'P':
1376 Pointer->Prim = PrimTy::Ptr;
1377 break;
1378 case 'Q':
1379 Pointer->Prim = PrimTy::Ptr;
1380 Pointer->Quals = Q_Const;
1381 break;
1382 case 'R':
1383 Pointer->Quals = Q_Volatile;
1384 Pointer->Prim = PrimTy::Ptr;
1385 break;
1386 case 'S':
1387 Pointer->Quals = Qualifiers(Q_Const | Q_Volatile);
1388 Pointer->Prim = PrimTy::Ptr;
1389 break;
1390 default:
1391 assert(false && "Ty is not a pointer type!");
1392 }
1393
1394 if (MangledName.consumeFront("6")) {
1395 FunctionType *FTy = new (Arena) FunctionType;
1396 FTy->Prim = PrimTy::Function;
1397 FTy->CallConvention = demangleCallingConvention();
1398
1399 FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
1400 FTy->Params = demangleParameterList();
1401
1402 if (!MangledName.consumeFront("@Z"))
1403 MangledName.consumeFront("Z");
1404
1405 Pointer->Pointee = FTy;
1406 return Pointer;
1407 }
1408
1409 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1410 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1411
1412 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1413 return Pointer;
1414}
1415
1416Qualifiers Demangler::demanglePointerExtQualifiers() {
1417 Qualifiers Quals = Q_None;
1418 if (MangledName.consumeFront('E'))
1419 Quals = Qualifiers(Quals | Q_Pointer64);
1420 if (MangledName.consumeFront('I'))
1421 Quals = Qualifiers(Quals | Q_Restrict);
1422 if (MangledName.consumeFront('F'))
1423 Quals = Qualifiers(Quals | Q_Unaligned);
1424
1425 return Quals;
1426}
1427
1428ArrayType *Demangler::demangleArrayType() {
1429 assert(MangledName.front() == 'Y');
1430 MangledName.popFront();
1431
1432 int Dimension = demangleNumber();
1433 if (Dimension <= 0) {
1434 Error = true;
1435 return nullptr;
1436 }
1437
1438 ArrayType *ATy = new (Arena) ArrayType;
1439 ArrayType *Dim = ATy;
1440 for (int I = 0; I < Dimension; ++I) {
1441 Dim->Prim = PrimTy::Array;
1442 Dim->ArrayDimension = demangleNumber();
1443 Dim->NextDimension = new (Arena) ArrayType;
1444 Dim = Dim->NextDimension;
1445 }
1446
1447 if (MangledName.consumeFront("$$C")) {
1448 if (MangledName.consumeFront("B"))
1449 ATy->Quals = Q_Const;
1450 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1451 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1452 else if (!MangledName.consumeFront("A"))
1453 Error = true;
1454 }
1455
1456 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1457 Dim->ElementType = ATy->ElementType;
1458 return ATy;
1459}
1460
1461// Reads a function or a template parameters.
1462ParamList Demangler::demangleParameterList() {
1463 // Within the same parameter list, you can backreference the first 10 types.
1464 Type *BackRef[10];
1465 int Idx = 0;
1466
1467 ParamList *Head;
1468 ParamList **Current = &Head;
1469 while (!Error && !MangledName.startsWith('@') &&
1470 !MangledName.startsWith('Z')) {
1471 if (startsWithDigit(MangledName)) {
1472 int N = MangledName[0] - '0';
1473 if (N >= Idx) {
1474 Error = true;
1475 return {};
1476 }
1477 MangledName = MangledName.dropFront();
1478
1479 *Current = new (Arena) ParamList;
1480 (*Current)->Current = BackRef[N]->clone(Arena);
1481 Current = &(*Current)->Next;
1482 continue;
1483 }
1484
1485 size_t ArrayDimension = MangledName.size();
1486
1487 *Current = new (Arena) ParamList;
1488 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1489
1490 // Single-letter types are ignored for backreferences because
1491 // memorizing them doesn't save anything.
1492 if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
1493 BackRef[Idx++] = (*Current)->Current;
1494 Current = &(*Current)->Next;
1495 }
1496
1497 return *Head;
1498}
1499
1500void Demangler::output() {
1501 // Converts an AST to a string.
1502 //
1503 // Converting an AST representing a C++ type to a string is tricky due
1504 // to the bad grammar of the C++ declaration inherited from C. You have
1505 // to construct a string from inside to outside. For example, if a type
1506 // X is a pointer to a function returning int, the order you create a
1507 // string becomes something like this:
1508 //
1509 // (1) X is a pointer: *X
1510 // (2) (1) is a function returning int: int (*X)()
1511 //
1512 // So you cannot construct a result just by appending strings to a result.
1513 //
1514 // To deal with this, we split the function into two. outputPre() writes
1515 // the "first half" of type declaration, and outputPost() writes the
1516 // "second half". For example, outputPre() writes a return type for a
1517 // function and outputPost() writes an parameter list.
1518 Type::outputPre(OS, *SymbolType);
1519 outputName(OS, SymbolName);
1520 Type::outputPost(OS, *SymbolType);
1521
1522 // Null terminate the buffer.
1523 OS << '\0';
1524}
1525
1526char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1527 int *Status) {
1528 OutputStream OS = OutputStream::create(Buf, N, 1024);
1529
1530 Demangler D(OS, StringView(MangledName));
1531 D.parse();
1532
1533 if (D.Error)
1534 *Status = llvm::demangle_invalid_mangled_name;
1535 else
1536 *Status = llvm::demangle_success;
1537
1538 D.output();
1539 return OS.getBuffer();
1540}