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