blob: f7c7864826748ba1484a3b47adf7e613db85ed2d [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 {
Zachary Turnera6869512018-07-30 03:25:27 +000032 constexpr size_t AllocUnit = 4096;
33
Zachary Turnerf435a7e2018-07-20 17:27:48 +000034class ArenaAllocator {
35 struct AllocatorNode {
36 uint8_t *Buf = nullptr;
37 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000038 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000039 AllocatorNode *Next = nullptr;
40 };
41
Zachary Turner71c91f92018-07-30 03:12:34 +000042 void addNode(size_t Capacity) {
43 AllocatorNode *NewHead = new AllocatorNode;
44 NewHead->Buf = new uint8_t[Capacity];
45 NewHead->Next = Head;
46 NewHead->Capacity = Capacity;
47 Head = NewHead;
48 NewHead->Used = 0;
49 }
50
Zachary Turnerf435a7e2018-07-20 17:27:48 +000051public:
Zachary Turnera6869512018-07-30 03:25:27 +000052 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000053
54 ~ArenaAllocator() {
55 while (Head) {
56 assert(Head->Buf);
57 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000058 AllocatorNode *Next = Head->Next;
59 delete Head;
60 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000061 }
62 }
63
Zachary Turner71c91f92018-07-30 03:12:34 +000064 char *allocUnalignedBuffer(size_t Length) {
65 uint8_t *Buf = Head->Buf + Head->Used;
66
67 Head->Used += Length;
68 if (Head->Used > Head->Capacity) {
69 // It's possible we need a buffer which is larger than our default unit
70 // size, so we need to be careful to add a node with capacity that is at
71 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000072 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000073 Head->Used = Length;
74 Buf = Head->Buf;
75 }
76
77 return reinterpret_cast<char *>(Buf);
78 }
79
Zachary Turner9d72aa92018-07-20 18:35:06 +000080 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
81
82 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000083 assert(Head && Head->Buf);
84
Zachary Turner9d72aa92018-07-20 18:35:06 +000085 size_t P = (size_t)Head->Buf + Head->Used;
86 uintptr_t AlignedP =
87 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
88 uint8_t *PP = (uint8_t *)AlignedP;
89 size_t Adjustment = AlignedP - P;
90
91 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000092 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000093 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000094
Zachary Turnera6869512018-07-30 03:25:27 +000095 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000096 Head->Used = Size;
97 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000098 }
99
100private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000101 AllocatorNode *Head = nullptr;
102};
103} // namespace
104
105static bool startsWithDigit(StringView S) {
106 return !S.empty() && std::isdigit(S.front());
107}
108
109// Writes a space if the last token does not end with a punctuation.
110static void outputSpaceIfNecessary(OutputStream &OS) {
111 if (OS.empty())
112 return;
113
114 char C = OS.back();
115 if (isalnum(C) || C == '>')
116 OS << " ";
117}
118
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000119// Storage classes
120enum Qualifiers : uint8_t {
121 Q_None = 0,
122 Q_Const = 1 << 0,
123 Q_Volatile = 1 << 1,
124 Q_Far = 1 << 2,
125 Q_Huge = 1 << 3,
126 Q_Unaligned = 1 << 4,
127 Q_Restrict = 1 << 5,
128 Q_Pointer64 = 1 << 6
129};
130
131enum class StorageClass : uint8_t {
132 None,
133 PrivateStatic,
134 ProtectedStatic,
135 PublicStatic,
136 Global,
137 FunctionLocalStatic
138};
139
140enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000141
142enum class PointerAffinity { Pointer, Reference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000143
144// Calling conventions
145enum class CallingConv : uint8_t {
146 None,
147 Cdecl,
148 Pascal,
149 Thiscall,
150 Stdcall,
151 Fastcall,
152 Clrcall,
153 Eabi,
154 Vectorcall,
155 Regcall,
156};
157
158enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
159
160// Types
161enum class PrimTy : uint8_t {
162 Unknown,
163 None,
164 Function,
165 Ptr,
166 Ref,
Zachary Turnerd742d642018-07-26 19:56:09 +0000167 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000168 Array,
169
170 Struct,
171 Union,
172 Class,
173 Enum,
174
175 Void,
176 Bool,
177 Char,
178 Schar,
179 Uchar,
180 Short,
181 Ushort,
182 Int,
183 Uint,
184 Long,
185 Ulong,
186 Int64,
187 Uint64,
188 Wchar,
189 Float,
190 Double,
191 Ldouble,
192};
193
194// Function classes
195enum FuncClass : uint8_t {
196 Public = 1 << 0,
197 Protected = 1 << 1,
198 Private = 1 << 2,
199 Global = 1 << 3,
200 Static = 1 << 4,
201 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000202 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000203};
204
205namespace {
206
207struct Type;
208
209// Represents a list of parameters (template params or function arguments.
210// It's represented as a linked list.
211struct ParamList {
Zachary Turner38b78a72018-07-26 20:20:10 +0000212 bool IsVariadic = false;
213
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000214 Type *Current = nullptr;
215
216 ParamList *Next = nullptr;
217};
218
219// The type class. Mangled symbols are first parsed and converted to
220// this type and then converted to string.
221struct Type {
222 virtual ~Type() {}
223
224 virtual Type *clone(ArenaAllocator &Arena) const;
225
226 // Write the "first half" of a given type. This is a static functions to
227 // give the code a chance to do processing that is common to a subset of
228 // subclasses
229 static void outputPre(OutputStream &OS, Type &Ty);
230
231 // Write the "second half" of a given type. This is a static functions to
232 // give the code a chance to do processing that is common to a subset of
233 // subclasses
234 static void outputPost(OutputStream &OS, Type &Ty);
235
236 virtual void outputPre(OutputStream &OS);
237 virtual void outputPost(OutputStream &OS);
238
239 // Primitive type such as Int.
240 PrimTy Prim = PrimTy::Unknown;
241
242 Qualifiers Quals = Q_None;
243 StorageClass Storage = StorageClass::None; // storage class
244};
245
246// Represents an identifier which may be a template.
247struct Name {
248 // Name read from an MangledName string.
249 StringView Str;
250
251 // Overloaded operators are represented as special BackReferences in mangled
252 // symbols. If this is an operator name, "op" has an operator name (e.g.
253 // ">>"). Otherwise, empty.
254 StringView Operator;
255
256 // Template parameters. Null if not a template.
257 ParamList TemplateParams;
258
259 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
260 Name *Next = nullptr;
261};
262
263struct PointerType : public Type {
264 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000265 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000266 void outputPost(OutputStream &OS) override;
267
Zachary Turnerd742d642018-07-26 19:56:09 +0000268 // Represents a type X in "a pointer to X", "a reference to X",
269 // "an array of X", or "a function returning X".
270 Type *Pointee = nullptr;
271};
272
273struct MemberPointerType : public Type {
274 Type *clone(ArenaAllocator &Arena) const override;
275 void outputPre(OutputStream &OS) override;
276 void outputPost(OutputStream &OS) override;
277
278 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000279
280 // Represents a type X in "a pointer to X", "a reference to X",
281 // "an array of X", or "a function returning X".
282 Type *Pointee = nullptr;
283};
284
285struct FunctionType : public Type {
286 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000287 void outputPre(OutputStream &OS) override;
288 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000289
Zachary Turner024e1762018-07-26 20:33:48 +0000290 // True if this FunctionType instance is the Pointee of a PointerType or
291 // MemberPointerType.
292 bool IsFunctionPointer = false;
293
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000294 Type *ReturnType = nullptr;
295 // If this is a reference, the type of reference.
296 ReferenceKind RefKind;
297
298 CallingConv CallConvention;
299 FuncClass FunctionClass;
300
301 ParamList Params;
302};
303
304struct UdtType : public Type {
305 Type *clone(ArenaAllocator &Arena) const override;
306 void outputPre(OutputStream &OS) override;
307
308 Name *UdtName = nullptr;
309};
310
311struct ArrayType : public Type {
312 Type *clone(ArenaAllocator &Arena) const override;
313 void outputPre(OutputStream &OS) override;
314 void outputPost(OutputStream &OS) override;
315
316 // Either NextDimension or ElementType will be valid.
317 ArrayType *NextDimension = nullptr;
318 uint32_t ArrayDimension = 0;
319
320 Type *ElementType = nullptr;
321};
322
323} // namespace
324
Zachary Turnerd742d642018-07-26 19:56:09 +0000325static bool isMemberPointer(StringView MangledName) {
326 switch (MangledName.popFront()) {
327 case 'A':
328 // 'A' indicates a reference, and you cannot have a reference to a member
329 // function or member variable.
330 return false;
331 case 'P':
332 case 'Q':
333 case 'R':
334 case 'S':
335 // These 4 values indicate some kind of pointer, but we still don't know
336 // what.
337 break;
338 default:
339 assert(false && "Ty is not a pointer type!");
340 }
341
342 // If it starts with a number, then 6 indicates a non-member function
343 // pointer, and 8 indicates a member function pointer.
344 if (startsWithDigit(MangledName)) {
345 assert(MangledName[0] == '6' || MangledName[0] == '8');
346 return (MangledName[0] == '8');
347 }
348
349 // Remove ext qualifiers since those can appear on either type and are
350 // therefore not indicative.
351 MangledName.consumeFront('E'); // 64-bit
352 MangledName.consumeFront('I'); // restrict
353 MangledName.consumeFront('F'); // unaligned
354
355 assert(!MangledName.empty());
356
357 // The next value should be either ABCD (non-member) or QRST (member).
358 switch (MangledName.front()) {
359 case 'A':
360 case 'B':
361 case 'C':
362 case 'D':
363 return false;
364 case 'Q':
365 case 'R':
366 case 'S':
367 case 'T':
368 return true;
369 default:
370 assert(false);
371 }
372 return false;
373}
374
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000375static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
376 outputSpaceIfNecessary(OS);
377
378 switch (CC) {
379 case CallingConv::Cdecl:
380 OS << "__cdecl";
381 break;
382 case CallingConv::Fastcall:
383 OS << "__fastcall";
384 break;
385 case CallingConv::Pascal:
386 OS << "__pascal";
387 break;
388 case CallingConv::Regcall:
389 OS << "__regcall";
390 break;
391 case CallingConv::Stdcall:
392 OS << "__stdcall";
393 break;
394 case CallingConv::Thiscall:
395 OS << "__thiscall";
396 break;
397 case CallingConv::Eabi:
398 OS << "__eabi";
399 break;
400 case CallingConv::Vectorcall:
401 OS << "__vectorcall";
402 break;
403 case CallingConv::Clrcall:
404 OS << "__clrcall";
405 break;
406 default:
407 break;
408 }
409}
410
Zachary Turner71c91f92018-07-30 03:12:34 +0000411static bool startsWithLocalScopePattern(StringView S) {
412 if (!S.consumeFront('?'))
413 return false;
414 if (S.size() < 2)
415 return false;
416
417 size_t End = S.find('?');
418 if (End == StringView::npos)
419 return false;
420 StringView Candidate = S.substr(0, End);
421 if (Candidate.empty())
422 return false;
423
424 // \?[0-9]\?
425 // ?@? is the discriminator 0.
426 if (Candidate.size() == 1)
427 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
428
429 // If it's not 0-9, then it's an encoded number terminated with an @
430 if (Candidate.back() != '@')
431 return false;
432 Candidate = Candidate.dropBack();
433
434 // An encoded number starts with B-P and all subsequent digits are in A-P.
435 // Note that the reason the first digit cannot be A is two fold. First, it
436 // would create an ambiguity with ?A which delimits the beginning of an
437 // anonymous namespace. Second, A represents 0, and you don't start a multi
438 // digit number with a leading 0. Presumably the anonymous namespace
439 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
440 if (Candidate[0] < 'B' || Candidate[0] > 'P')
441 return false;
442 Candidate = Candidate.dropFront();
443 while (!Candidate.empty()) {
444 if (Candidate[0] < 'A' || Candidate[0] > 'P')
445 return false;
446 Candidate = Candidate.dropFront();
447 }
448
449 return true;
450}
451
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000452// Write a function or template parameter list.
453static void outputParameterList(OutputStream &OS, const ParamList &Params) {
Zachary Turner38b78a72018-07-26 20:20:10 +0000454 if (!Params.Current) {
455 OS << "void";
456 return;
457 }
458
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000459 const ParamList *Head = &Params;
460 while (Head) {
461 Type::outputPre(OS, *Head->Current);
462 Type::outputPost(OS, *Head->Current);
463
464 Head = Head->Next;
465
466 if (Head)
467 OS << ", ";
468 }
469}
470
471static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
472 if (!TheName.TemplateParams.Current)
473 return;
474
475 OS << "<";
476 outputParameterList(OS, TheName.TemplateParams);
477 OS << ">";
478}
479
480static void outputName(OutputStream &OS, const Name *TheName) {
481 if (!TheName)
482 return;
483
484 outputSpaceIfNecessary(OS);
485
Zachary Turnera7dffb12018-07-28 22:10:42 +0000486 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000487 // Print out namespaces or outer class BackReferences.
488 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000489 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000490 OS << TheName->Str;
491 outputTemplateParams(OS, *TheName);
492 OS << "::";
493 }
494
495 // Print out a regular name.
496 if (TheName->Operator.empty()) {
497 OS << TheName->Str;
498 outputTemplateParams(OS, *TheName);
499 return;
500 }
501
502 // Print out ctor or dtor.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000503 if (TheName->Operator == "dtor")
504 OS << "~";
505
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000506 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000507 OS << Previous->Str;
508 outputTemplateParams(OS, *Previous);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000509 return;
510 }
511
512 // Print out an overloaded operator.
513 if (!TheName->Str.empty())
514 OS << TheName->Str << "::";
515 OS << "operator" << TheName->Operator;
516}
517
518namespace {
519
520Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000521 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000522}
523
524// Write the "first half" of a given type.
525void Type::outputPre(OutputStream &OS, Type &Ty) {
526 // Function types require custom handling of const and static so we
527 // handle them separately. All other types use the same decoration
528 // for these modifiers, so handle them here in common code.
529 if (Ty.Prim == PrimTy::Function) {
530 Ty.outputPre(OS);
531 return;
532 }
533
534 switch (Ty.Storage) {
535 case StorageClass::PrivateStatic:
536 case StorageClass::PublicStatic:
537 case StorageClass::ProtectedStatic:
538 OS << "static ";
539 default:
540 break;
541 }
542 Ty.outputPre(OS);
543
544 if (Ty.Quals & Q_Const) {
545 outputSpaceIfNecessary(OS);
546 OS << "const";
547 }
548
549 if (Ty.Quals & Q_Volatile) {
550 outputSpaceIfNecessary(OS);
551 OS << "volatile";
552 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000553
554 if (Ty.Quals & Q_Restrict) {
555 outputSpaceIfNecessary(OS);
556 OS << "__restrict";
557 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000558}
559
560// Write the "second half" of a given type.
561void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
562
563void Type::outputPre(OutputStream &OS) {
564 switch (Prim) {
565 case PrimTy::Void:
566 OS << "void";
567 break;
568 case PrimTy::Bool:
569 OS << "bool";
570 break;
571 case PrimTy::Char:
572 OS << "char";
573 break;
574 case PrimTy::Schar:
575 OS << "signed char";
576 break;
577 case PrimTy::Uchar:
578 OS << "unsigned char";
579 break;
580 case PrimTy::Short:
581 OS << "short";
582 break;
583 case PrimTy::Ushort:
584 OS << "unsigned short";
585 break;
586 case PrimTy::Int:
587 OS << "int";
588 break;
589 case PrimTy::Uint:
590 OS << "unsigned int";
591 break;
592 case PrimTy::Long:
593 OS << "long";
594 break;
595 case PrimTy::Ulong:
596 OS << "unsigned long";
597 break;
598 case PrimTy::Int64:
599 OS << "__int64";
600 break;
601 case PrimTy::Uint64:
602 OS << "unsigned __int64";
603 break;
604 case PrimTy::Wchar:
605 OS << "wchar_t";
606 break;
607 case PrimTy::Float:
608 OS << "float";
609 break;
610 case PrimTy::Double:
611 OS << "double";
612 break;
613 case PrimTy::Ldouble:
614 OS << "long double";
615 break;
616 default:
617 assert(false && "Invalid primitive type!");
618 }
619}
620void Type::outputPost(OutputStream &OS) {}
621
622Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000623 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000624}
625
Zachary Turner024e1762018-07-26 20:33:48 +0000626static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
627 const Name *MemberName,
628 const Type *Pointee) {
629 // "[]" and "()" (for function parameters) take precedence over "*",
630 // so "int *x(int)" means "x is a function returning int *". We need
631 // parentheses to supercede the default precedence. (e.g. we want to
632 // emit something like "int (*x)(int)".)
633 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
634 OS << "(";
635 if (Pointee->Prim == PrimTy::Function) {
636 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
637 assert(FTy->IsFunctionPointer);
638 outputCallingConvention(OS, FTy->CallConvention);
639 OS << " ";
640 }
641 }
642
643 if (MemberName) {
644 outputName(OS, MemberName);
645 OS << "::";
646 }
647
648 if (Affinity == PointerAffinity::Pointer)
649 OS << "*";
650 else
651 OS << "&";
652}
653
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000654void PointerType::outputPre(OutputStream &OS) {
655 Type::outputPre(OS, *Pointee);
656
657 outputSpaceIfNecessary(OS);
658
659 if (Quals & Q_Unaligned)
660 OS << "__unaligned ";
661
Zachary Turner024e1762018-07-26 20:33:48 +0000662 PointerAffinity Affinity = (Prim == PrimTy::Ptr) ? PointerAffinity::Pointer
663 : PointerAffinity::Reference;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000664
Zachary Turner024e1762018-07-26 20:33:48 +0000665 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000666
Zachary Turner91ecedd2018-07-20 18:07:33 +0000667 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000668 // if (Ty.Quals & Q_Pointer64)
669 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000670}
671
672void PointerType::outputPost(OutputStream &OS) {
673 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
674 OS << ")";
675
676 Type::outputPost(OS, *Pointee);
677}
678
Zachary Turnerd742d642018-07-26 19:56:09 +0000679Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
680 return Arena.alloc<MemberPointerType>(*this);
681}
682
683void MemberPointerType::outputPre(OutputStream &OS) {
684 Type::outputPre(OS, *Pointee);
685
686 outputSpaceIfNecessary(OS);
687
Zachary Turner024e1762018-07-26 20:33:48 +0000688 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000689
690 // FIXME: We should output this, but it requires updating lots of tests.
691 // if (Ty.Quals & Q_Pointer64)
692 // OS << " __ptr64";
693 if (Quals & Q_Restrict)
694 OS << " __restrict";
695}
696
697void MemberPointerType::outputPost(OutputStream &OS) {
698 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
699 OS << ")";
700
701 Type::outputPost(OS, *Pointee);
702}
703
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000704Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000705 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000706}
707
708void FunctionType::outputPre(OutputStream &OS) {
709 if (!(FunctionClass & Global)) {
710 if (FunctionClass & Static)
711 OS << "static ";
712 }
713
Zachary Turner38b78a72018-07-26 20:20:10 +0000714 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000715 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000716 OS << " ";
717 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000718
Zachary Turner024e1762018-07-26 20:33:48 +0000719 // Function pointers print the calling convention as void (__cdecl *)(params)
720 // rather than void __cdecl (*)(params). So we need to let the PointerType
721 // class handle this.
722 if (!IsFunctionPointer)
723 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000724}
725
726void FunctionType::outputPost(OutputStream &OS) {
727 OS << "(";
728 outputParameterList(OS, Params);
729 OS << ")";
730 if (Quals & Q_Const)
731 OS << " const";
732 if (Quals & Q_Volatile)
733 OS << " volatile";
Zachary Turner38b78a72018-07-26 20:20:10 +0000734
735 if (ReturnType)
736 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000737 return;
738}
739
740Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000741 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000742}
743
744void UdtType::outputPre(OutputStream &OS) {
745 switch (Prim) {
746 case PrimTy::Class:
747 OS << "class ";
748 break;
749 case PrimTy::Struct:
750 OS << "struct ";
751 break;
752 case PrimTy::Union:
753 OS << "union ";
754 break;
755 case PrimTy::Enum:
756 OS << "enum ";
757 break;
758 default:
759 assert(false && "Not a udt type!");
760 }
761
762 outputName(OS, UdtName);
763}
764
765Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000766 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000767}
768
769void ArrayType::outputPre(OutputStream &OS) {
770 Type::outputPre(OS, *ElementType);
771}
772
773void ArrayType::outputPost(OutputStream &OS) {
774 if (ArrayDimension > 0)
775 OS << "[" << ArrayDimension << "]";
776 if (NextDimension)
777 Type::outputPost(OS, *NextDimension);
778 else if (ElementType)
779 Type::outputPost(OS, *ElementType);
780}
781
Zachary Turner316109b2018-07-29 16:38:02 +0000782struct Symbol {
783 Name *SymbolName = nullptr;
784 Type *SymbolType = nullptr;
785};
786
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000787} // namespace
788
789namespace {
790
791// Demangler class takes the main role in demangling symbols.
792// It has a set of functions to parse mangled symbols into Type instances.
793// It also has a set of functions to cnovert Type instances to strings.
794class Demangler {
795public:
Zachary Turner316109b2018-07-29 16:38:02 +0000796 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000797
798 // You are supposed to call parse() first and then check if error is true. If
799 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000800 Symbol *parse(StringView &MangledName);
801 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000802
803 // True if an error occurred.
804 bool Error = false;
805
806private:
Zachary Turner316109b2018-07-29 16:38:02 +0000807 Type *demangleVariableEncoding(StringView &MangledName);
808 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000809
Zachary Turner316109b2018-07-29 16:38:02 +0000810 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000811
812 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000813 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
814 Type *demangleBasicType(StringView &MangledName);
815 UdtType *demangleClassType(StringView &MangledName);
816 PointerType *demanglePointerType(StringView &MangledName);
817 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
818 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
819 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000820
Zachary Turner316109b2018-07-29 16:38:02 +0000821 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000822
Zachary Turner316109b2018-07-29 16:38:02 +0000823 ParamList demangleTemplateParameterList(StringView &MangledName);
824 ParamList demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000825
Zachary Turner316109b2018-07-29 16:38:02 +0000826 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000827
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000828 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000829
830 /// Allocate a copy of \p Borrowed into memory that we own.
831 StringView copyString(StringView Borrowed);
832
Zachary Turner316109b2018-07-29 16:38:02 +0000833 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
834 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000835
Zachary Turner316109b2018-07-29 16:38:02 +0000836 Name *demangleUnqualifiedTypeName(StringView &MangledName);
837 Name *demangleUnqualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000838
Zachary Turner316109b2018-07-29 16:38:02 +0000839 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
840 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000841
Zachary Turner316109b2018-07-29 16:38:02 +0000842 Name *demangleBackRefName(StringView &MangledName);
843 Name *demangleClassTemplateName(StringView &MangledName);
844 Name *demangleOperatorName(StringView &MangledName);
845 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
846 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000847 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000848
Zachary Turner316109b2018-07-29 16:38:02 +0000849 void demangleOperator(StringView &MangledName, Name *);
850 FuncClass demangleFunctionClass(StringView &MangledName);
851 CallingConv demangleCallingConvention(StringView &MangledName);
852 StorageClass demangleVariableStorageClass(StringView &MangledName);
853 ReferenceKind demangleReferenceKind(StringView &MangledName);
854 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000855
Zachary Turner316109b2018-07-29 16:38:02 +0000856 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000857
858 // Memory allocator.
859 ArenaAllocator Arena;
860
Zachary Turner23df1312018-07-26 22:13:39 +0000861 // A single type uses one global back-ref table for all function params.
862 // This means back-refs can even go "into" other types. Examples:
863 //
864 // // Second int* is a back-ref to first.
865 // void foo(int *, int*);
866 //
867 // // Second int* is not a back-ref to first (first is not a function param).
868 // int* foo(int*);
869 //
870 // // Second int* is a back-ref to first (ALL function types share the same
871 // // back-ref map.
872 // using F = void(*)(int*);
873 // F G(int *);
874 Type *FunctionParamBackRefs[10];
875 size_t FunctionParamBackRefCount = 0;
876
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000877 // The first 10 BackReferences in a mangled name can be back-referenced by
878 // special name @[0-9]. This is a storage for the first 10 BackReferences.
879 StringView BackReferences[10];
880 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000881};
882} // namespace
883
Zachary Turner71c91f92018-07-30 03:12:34 +0000884StringView Demangler::copyString(StringView Borrowed) {
885 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
886 std::strcpy(Stable, Borrowed.begin());
887
888 return {Stable, Borrowed.size()};
889}
890
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000891// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000892Symbol *Demangler::parse(StringView &MangledName) {
893 Symbol *S = Arena.alloc<Symbol>();
894
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000895 // MSVC-style mangled symbols must start with '?'.
896 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000897 S->SymbolName = Arena.alloc<Name>();
898 S->SymbolName->Str = MangledName;
899 S->SymbolType = Arena.alloc<Type>();
900 S->SymbolType->Prim = PrimTy::Unknown;
901 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000902 }
903
904 // What follows is a main symbol name. This may include
905 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000906 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000907
908 // Read a variable.
Zachary Turner316109b2018-07-29 16:38:02 +0000909 S->SymbolType = startsWithDigit(MangledName)
910 ? demangleVariableEncoding(MangledName)
911 : demangleFunctionEncoding(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000912
Zachary Turner316109b2018-07-29 16:38:02 +0000913 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000914}
915
916// <type-encoding> ::= <storage-class> <variable-type>
917// <storage-class> ::= 0 # private static member
918// ::= 1 # protected static member
919// ::= 2 # public static member
920// ::= 3 # global
921// ::= 4 # static local
922
Zachary Turner316109b2018-07-29 16:38:02 +0000923Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
924 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000925
Zachary Turner316109b2018-07-29 16:38:02 +0000926 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000927
928 Ty->Storage = SC;
929
930 // <variable-type> ::= <type> <cvr-qualifiers>
931 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
932 switch (Ty->Prim) {
933 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000934 case PrimTy::Ref:
935 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000936 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +0000937 Ty->Quals =
938 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000939
Zachary Turnerd742d642018-07-26 19:56:09 +0000940 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +0000941 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000942
Zachary Turnerd742d642018-07-26 19:56:09 +0000943 if (Ty->Prim == PrimTy::MemberPtr) {
944 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +0000945 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000946 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000947 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
948 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
949 } else {
950 PointerType *PTy = static_cast<PointerType *>(Ty);
951 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000952 }
953
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000954 break;
955 }
956 default:
Zachary Turner316109b2018-07-29 16:38:02 +0000957 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000958 break;
959 }
960
961 return Ty;
962}
963
964// Sometimes numbers are encoded in mangled symbols. For example,
965// "int (*x)[20]" is a valid C type (x is a pointer to an array of
966// length 20), so we need some way to embed numbers as part of symbols.
967// This function parses it.
968//
969// <number> ::= [?] <non-negative integer>
970//
971// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
972// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
973//
974// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +0000975int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000976 bool neg = MangledName.consumeFront("?");
977
978 if (startsWithDigit(MangledName)) {
979 int32_t Ret = MangledName[0] - '0' + 1;
980 MangledName = MangledName.dropFront(1);
981 return neg ? -Ret : Ret;
982 }
983
984 int Ret = 0;
985 for (size_t i = 0; i < MangledName.size(); ++i) {
986 char C = MangledName[i];
987 if (C == '@') {
988 MangledName = MangledName.dropFront(i + 1);
989 return neg ? -Ret : Ret;
990 }
991 if ('A' <= C && C <= 'P') {
992 Ret = (Ret << 4) + (C - 'A');
993 continue;
994 }
995 break;
996 }
997
998 Error = true;
999 return 0;
1000}
1001
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001002// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1003// Memorize it.
1004void Demangler::memorizeString(StringView S) {
1005 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1006 return;
1007 for (size_t i = 0; i < BackRefCount; ++i)
1008 if (S == BackReferences[i])
1009 return;
1010 BackReferences[BackRefCount++] = S;
1011}
1012
Zachary Turner316109b2018-07-29 16:38:02 +00001013Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001014 assert(startsWithDigit(MangledName));
1015
1016 size_t I = MangledName[0] - '0';
1017 if (I >= BackRefCount) {
1018 Error = true;
1019 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001020 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001021
1022 MangledName = MangledName.dropFront();
1023 Name *Node = Arena.alloc<Name>();
1024 Node->Str = BackReferences[I];
1025 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001026}
1027
Zachary Turner316109b2018-07-29 16:38:02 +00001028Name *Demangler::demangleClassTemplateName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001029 assert(MangledName.startsWith("?$"));
1030 MangledName.consumeFront("?$");
1031
Zachary Turner316109b2018-07-29 16:38:02 +00001032 Name *Node = demangleSimpleName(MangledName, false);
1033 Node->TemplateParams = demangleTemplateParameterList(MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001034
1035 // Render this class template name into a string buffer so that we can
1036 // memorize it for the purpose of back-referencing.
1037 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1038 outputName(OS, Node);
1039 OS << '\0';
1040 char *Name = OS.getBuffer();
1041
1042 StringView Owned = copyString(Name);
1043 memorizeString(Owned);
1044 std::free(Name);
1045
Zachary Turnera7dffb12018-07-28 22:10:42 +00001046 return Node;
1047}
1048
Zachary Turner316109b2018-07-29 16:38:02 +00001049Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001050 assert(MangledName.startsWith('?'));
1051 MangledName.consumeFront('?');
1052
Zachary Turner316109b2018-07-29 16:38:02 +00001053 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001054 switch (MangledName.popFront()) {
1055 case '0':
1056 return "ctor";
1057 case '1':
1058 return "dtor";
1059 case '2':
1060 return " new";
1061 case '3':
1062 return " delete";
1063 case '4':
1064 return "=";
1065 case '5':
1066 return ">>";
1067 case '6':
1068 return "<<";
1069 case '7':
1070 return "!";
1071 case '8':
1072 return "==";
1073 case '9':
1074 return "!=";
1075 case 'A':
1076 return "[]";
1077 case 'C':
1078 return "->";
1079 case 'D':
1080 return "*";
1081 case 'E':
1082 return "++";
1083 case 'F':
1084 return "--";
1085 case 'G':
1086 return "-";
1087 case 'H':
1088 return "+";
1089 case 'I':
1090 return "&";
1091 case 'J':
1092 return "->*";
1093 case 'K':
1094 return "/";
1095 case 'L':
1096 return "%";
1097 case 'M':
1098 return "<";
1099 case 'N':
1100 return "<=";
1101 case 'O':
1102 return ">";
1103 case 'P':
1104 return ">=";
1105 case 'Q':
1106 return ",";
1107 case 'R':
1108 return "()";
1109 case 'S':
1110 return "~";
1111 case 'T':
1112 return "^";
1113 case 'U':
1114 return "|";
1115 case 'V':
1116 return "&&";
1117 case 'W':
1118 return "||";
1119 case 'X':
1120 return "*=";
1121 case 'Y':
1122 return "+=";
1123 case 'Z':
1124 return "-=";
1125 case '_': {
1126 if (MangledName.empty())
1127 break;
1128
1129 switch (MangledName.popFront()) {
1130 case '0':
1131 return "/=";
1132 case '1':
1133 return "%=";
1134 case '2':
1135 return ">>=";
1136 case '3':
1137 return "<<=";
1138 case '4':
1139 return "&=";
1140 case '5':
1141 return "|=";
1142 case '6':
1143 return "^=";
1144 case 'U':
1145 return " new[]";
1146 case 'V':
1147 return " delete[]";
1148 case '_':
1149 if (MangledName.consumeFront("L"))
1150 return " co_await";
1151 }
1152 }
1153 }
1154 Error = true;
1155 return "";
1156 };
1157
1158 Name *Node = Arena.alloc<Name>();
1159 Node->Operator = NameString();
1160 return Node;
1161}
1162
Zachary Turner316109b2018-07-29 16:38:02 +00001163Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001164 Name *Node = Arena.alloc<Name>();
1165 for (size_t i = 0; i < MangledName.size(); ++i) {
1166 if (MangledName[i] != '@')
1167 continue;
1168 Node->Str = MangledName.substr(0, i);
1169 MangledName = MangledName.dropFront(i + 1);
1170
1171 if (Memorize)
1172 memorizeString(Node->Str);
1173 return Node;
1174 }
1175
1176 Error = true;
1177 return nullptr;
1178}
1179
Zachary Turner316109b2018-07-29 16:38:02 +00001180Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001181 assert(MangledName.startsWith("?A"));
1182 MangledName.consumeFront("?A");
1183
1184 Name *Node = Arena.alloc<Name>();
1185 Node->Str = "`anonymous namespace'";
1186 if (MangledName.consumeFront('@'))
1187 return Node;
1188
1189 Error = true;
1190 return nullptr;
1191}
1192
Zachary Turner71c91f92018-07-30 03:12:34 +00001193Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1194 assert(startsWithLocalScopePattern(MangledName));
1195
1196 Name *Node = Arena.alloc<Name>();
1197 MangledName.consumeFront('?');
1198 int ScopeIdentifier = demangleNumber(MangledName);
1199
1200 // One ? to terminate the number
1201 MangledName.consumeFront('?');
1202
1203 assert(!Error);
1204 Symbol *Scope = parse(MangledName);
1205 if (Error)
1206 return nullptr;
1207
1208 // Render the parent symbol's name into a buffer.
1209 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1210 OS << '`';
1211 output(Scope, OS);
1212 OS << '\'';
1213 OS << "::`" << ScopeIdentifier << "'";
1214 OS << '\0';
1215 char *Result = OS.getBuffer();
1216 Node->Str = copyString(Result);
1217 std::free(Result);
1218 return Node;
1219}
1220
Zachary Turnera7dffb12018-07-28 22:10:42 +00001221// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001222Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
1223 Name *TypeName = demangleUnqualifiedTypeName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001224 assert(TypeName);
1225
Zachary Turner316109b2018-07-29 16:38:02 +00001226 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001227 assert(QualName);
1228 return QualName;
1229}
1230
1231// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1232// Symbol names have slightly different rules regarding what can appear
1233// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001234Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
1235 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001236 assert(SymbolName);
1237
Zachary Turner316109b2018-07-29 16:38:02 +00001238 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001239 assert(QualName);
1240 return QualName;
1241}
1242
Zachary Turner316109b2018-07-29 16:38:02 +00001243Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001244 // An inner-most name can be a back-reference, because a fully-qualified name
1245 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1246 // them (for example template parameters), and these nested parameters can
1247 // refer to previously mangled types.
1248 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001249 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001250
1251 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001252 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001253
Zachary Turner316109b2018-07-29 16:38:02 +00001254 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001255}
1256
Zachary Turner316109b2018-07-29 16:38:02 +00001257Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001258 if (startsWithDigit(MangledName))
1259 return demangleBackRefName(MangledName);
1260 if (MangledName.startsWith("?$"))
1261 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001262 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001263 return demangleOperatorName(MangledName);
1264 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001265}
1266
Zachary Turner316109b2018-07-29 16:38:02 +00001267Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001268 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001269 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001270
1271 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001272 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001273
1274 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001275 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001276
Zachary Turner71c91f92018-07-30 03:12:34 +00001277 if (startsWithLocalScopePattern(MangledName))
1278 return demangleLocallyScopedNamePiece(MangledName);
1279
Zachary Turner316109b2018-07-29 16:38:02 +00001280 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001281}
1282
Zachary Turner316109b2018-07-29 16:38:02 +00001283Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1284 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001285 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001286
1287 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001288 if (MangledName.empty()) {
1289 Error = true;
1290 return nullptr;
1291 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001292
1293 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001294 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001295 if (Error)
1296 return nullptr;
1297
1298 Elem->Next = Head;
1299 Head = Elem;
1300 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001301 return Head;
1302}
1303
Zachary Turner316109b2018-07-29 16:38:02 +00001304FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001305 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1306 RestoreOnError.shouldRestore(false);
1307
1308 switch (MangledName.popFront()) {
1309 case 'A':
1310 return Private;
1311 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001312 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001313 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001314 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001315 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001316 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001317 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001318 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001319 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001320 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001321 case 'I':
1322 return Protected;
1323 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001324 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001325 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001326 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001327 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001328 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001329 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001330 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001331 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001332 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001333 case 'Q':
1334 return Public;
1335 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001336 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001337 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001338 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001339 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001340 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001341 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001342 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001343 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001344 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001345 case 'Y':
1346 return Global;
1347 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001348 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001349 }
1350
1351 Error = true;
1352 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001353 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001354}
1355
Zachary Turner316109b2018-07-29 16:38:02 +00001356CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001357 switch (MangledName.popFront()) {
1358 case 'A':
1359 case 'B':
1360 return CallingConv::Cdecl;
1361 case 'C':
1362 case 'D':
1363 return CallingConv::Pascal;
1364 case 'E':
1365 case 'F':
1366 return CallingConv::Thiscall;
1367 case 'G':
1368 case 'H':
1369 return CallingConv::Stdcall;
1370 case 'I':
1371 case 'J':
1372 return CallingConv::Fastcall;
1373 case 'M':
1374 case 'N':
1375 return CallingConv::Clrcall;
1376 case 'O':
1377 case 'P':
1378 return CallingConv::Eabi;
1379 case 'Q':
1380 return CallingConv::Vectorcall;
1381 }
1382
1383 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001384}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001385
Zachary Turner316109b2018-07-29 16:38:02 +00001386StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001387 assert(std::isdigit(MangledName.front()));
1388
1389 switch (MangledName.popFront()) {
1390 case '0':
1391 return StorageClass::PrivateStatic;
1392 case '1':
1393 return StorageClass::ProtectedStatic;
1394 case '2':
1395 return StorageClass::PublicStatic;
1396 case '3':
1397 return StorageClass::Global;
1398 case '4':
1399 return StorageClass::FunctionLocalStatic;
1400 }
1401 Error = true;
1402 return StorageClass::None;
1403}
1404
Zachary Turner316109b2018-07-29 16:38:02 +00001405std::pair<Qualifiers, bool>
1406Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001407
1408 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001409 // Member qualifiers
1410 case 'Q':
1411 return std::make_pair(Q_None, true);
1412 case 'R':
1413 return std::make_pair(Q_Const, true);
1414 case 'S':
1415 return std::make_pair(Q_Volatile, true);
1416 case 'T':
1417 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1418 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001419 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001420 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001421 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001422 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001423 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001424 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001425 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001426 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001427 }
1428 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001429 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001430}
1431
1432// <variable-type> ::= <type> <cvr-qualifiers>
1433// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001434Type *Demangler::demangleType(StringView &MangledName,
1435 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001436 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001437 bool IsMember = false;
1438 bool IsMemberKnown = false;
1439 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001440 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001441 IsMemberKnown = true;
1442 } else if (QMM == QualifierMangleMode::Result) {
1443 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001444 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001445 IsMemberKnown = true;
1446 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001447 }
1448
1449 Type *Ty = nullptr;
1450 switch (MangledName.front()) {
1451 case 'T': // union
1452 case 'U': // struct
1453 case 'V': // class
1454 case 'W': // enum
Zachary Turner316109b2018-07-29 16:38:02 +00001455 Ty = demangleClassType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001456 break;
1457 case 'A': // foo &
1458 case 'P': // foo *
1459 case 'Q': // foo *const
1460 case 'R': // foo *volatile
1461 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001462 if (!IsMemberKnown)
1463 IsMember = isMemberPointer(MangledName);
1464 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001465 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001466 else
Zachary Turner316109b2018-07-29 16:38:02 +00001467 Ty = demanglePointerType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001468 break;
1469 case 'Y':
Zachary Turner316109b2018-07-29 16:38:02 +00001470 Ty = demangleArrayType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001471 break;
1472 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001473 Ty = demangleBasicType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001474 break;
1475 }
1476 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1477 return Ty;
1478}
1479
Zachary Turner316109b2018-07-29 16:38:02 +00001480ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001481 if (MangledName.consumeFront('G'))
1482 return ReferenceKind::LValueRef;
1483 else if (MangledName.consumeFront('H'))
1484 return ReferenceKind::RValueRef;
1485 return ReferenceKind::None;
1486}
1487
Zachary Turner316109b2018-07-29 16:38:02 +00001488void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001489 if (MangledName.consumeFront('Z'))
1490 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001491
Zachary Turner38b78a72018-07-26 20:20:10 +00001492 Error = true;
1493}
1494
Zachary Turner316109b2018-07-29 16:38:02 +00001495FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1496 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001497 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001498 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001499 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001500 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001501
1502 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001503 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1504 FTy->RefKind = demangleReferenceKind(MangledName);
1505 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001506 }
1507
1508 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001509 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001510
1511 // <return-type> ::= <type>
1512 // ::= @ # structors (they have no declared return type)
1513 bool IsStructor = MangledName.consumeFront('@');
1514 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001515 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001516
Zachary Turner316109b2018-07-29 16:38:02 +00001517 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001518
Zachary Turner316109b2018-07-29 16:38:02 +00001519 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001520
1521 return FTy;
1522}
1523
Zachary Turner316109b2018-07-29 16:38:02 +00001524Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1525 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001526
1527 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001528 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001529 FTy->FunctionClass = FC;
1530
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001531 return FTy;
1532}
1533
1534// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001535Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001536 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001537
1538 switch (MangledName.popFront()) {
1539 case 'X':
1540 Ty->Prim = PrimTy::Void;
1541 break;
1542 case 'D':
1543 Ty->Prim = PrimTy::Char;
1544 break;
1545 case 'C':
1546 Ty->Prim = PrimTy::Schar;
1547 break;
1548 case 'E':
1549 Ty->Prim = PrimTy::Uchar;
1550 break;
1551 case 'F':
1552 Ty->Prim = PrimTy::Short;
1553 break;
1554 case 'G':
1555 Ty->Prim = PrimTy::Ushort;
1556 break;
1557 case 'H':
1558 Ty->Prim = PrimTy::Int;
1559 break;
1560 case 'I':
1561 Ty->Prim = PrimTy::Uint;
1562 break;
1563 case 'J':
1564 Ty->Prim = PrimTy::Long;
1565 break;
1566 case 'K':
1567 Ty->Prim = PrimTy::Ulong;
1568 break;
1569 case 'M':
1570 Ty->Prim = PrimTy::Float;
1571 break;
1572 case 'N':
1573 Ty->Prim = PrimTy::Double;
1574 break;
1575 case 'O':
1576 Ty->Prim = PrimTy::Ldouble;
1577 break;
1578 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001579 if (MangledName.empty()) {
1580 Error = true;
1581 return nullptr;
1582 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001583 switch (MangledName.popFront()) {
1584 case 'N':
1585 Ty->Prim = PrimTy::Bool;
1586 break;
1587 case 'J':
1588 Ty->Prim = PrimTy::Int64;
1589 break;
1590 case 'K':
1591 Ty->Prim = PrimTy::Uint64;
1592 break;
1593 case 'W':
1594 Ty->Prim = PrimTy::Wchar;
1595 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001596 default:
1597 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001598 }
1599 break;
1600 }
1601 }
1602 return Ty;
1603}
1604
Zachary Turner316109b2018-07-29 16:38:02 +00001605UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001606 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001607
1608 switch (MangledName.popFront()) {
1609 case 'T':
1610 UTy->Prim = PrimTy::Union;
1611 break;
1612 case 'U':
1613 UTy->Prim = PrimTy::Struct;
1614 break;
1615 case 'V':
1616 UTy->Prim = PrimTy::Class;
1617 break;
1618 case 'W':
1619 if (MangledName.popFront() != '4') {
1620 Error = true;
1621 return nullptr;
1622 }
1623 UTy->Prim = PrimTy::Enum;
1624 break;
1625 default:
1626 assert(false);
1627 }
1628
Zachary Turner316109b2018-07-29 16:38:02 +00001629 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001630 return UTy;
1631}
1632
Zachary Turnerd742d642018-07-26 19:56:09 +00001633static std::pair<Qualifiers, PointerAffinity>
1634demanglePointerCVQualifiers(StringView &MangledName) {
1635 switch (MangledName.popFront()) {
1636 case 'A':
1637 return std::make_pair(Q_None, PointerAffinity::Reference);
1638 case 'P':
1639 return std::make_pair(Q_None, PointerAffinity::Pointer);
1640 case 'Q':
1641 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1642 case 'R':
1643 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1644 case 'S':
1645 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1646 PointerAffinity::Pointer);
1647 default:
1648 assert(false && "Ty is not a pointer type!");
1649 }
1650 return std::make_pair(Q_None, PointerAffinity::Pointer);
1651}
1652
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001653// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1654// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001655PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001656 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001657
Zachary Turnerd742d642018-07-26 19:56:09 +00001658 PointerAffinity Affinity;
1659 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001660
Zachary Turnerd742d642018-07-26 19:56:09 +00001661 Pointer->Prim =
1662 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001663 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001664 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001665 return Pointer;
1666 }
1667
Zachary Turner316109b2018-07-29 16:38:02 +00001668 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001669 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1670
Zachary Turner316109b2018-07-29 16:38:02 +00001671 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001672 return Pointer;
1673}
1674
Zachary Turner316109b2018-07-29 16:38:02 +00001675MemberPointerType *
1676Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001677 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1678 Pointer->Prim = PrimTy::MemberPtr;
1679
1680 PointerAffinity Affinity;
1681 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1682 assert(Affinity == PointerAffinity::Pointer);
1683
Zachary Turner316109b2018-07-29 16:38:02 +00001684 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001685 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1686
Zachary Turner38b78a72018-07-26 20:20:10 +00001687 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001688 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1689 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001690 } else {
1691 Qualifiers PointeeQuals = Q_None;
1692 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001693 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001694 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001695 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001696
Zachary Turner316109b2018-07-29 16:38:02 +00001697 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001698 Pointer->Pointee->Quals = PointeeQuals;
1699 }
1700
Zachary Turnerd742d642018-07-26 19:56:09 +00001701 return Pointer;
1702}
1703
Zachary Turner316109b2018-07-29 16:38:02 +00001704Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001705 Qualifiers Quals = Q_None;
1706 if (MangledName.consumeFront('E'))
1707 Quals = Qualifiers(Quals | Q_Pointer64);
1708 if (MangledName.consumeFront('I'))
1709 Quals = Qualifiers(Quals | Q_Restrict);
1710 if (MangledName.consumeFront('F'))
1711 Quals = Qualifiers(Quals | Q_Unaligned);
1712
1713 return Quals;
1714}
1715
Zachary Turner316109b2018-07-29 16:38:02 +00001716ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001717 assert(MangledName.front() == 'Y');
1718 MangledName.popFront();
1719
Zachary Turner316109b2018-07-29 16:38:02 +00001720 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001721 if (Dimension <= 0) {
1722 Error = true;
1723 return nullptr;
1724 }
1725
Zachary Turner9d72aa92018-07-20 18:35:06 +00001726 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001727 ArrayType *Dim = ATy;
1728 for (int I = 0; I < Dimension; ++I) {
1729 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001730 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001731 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001732 Dim = Dim->NextDimension;
1733 }
1734
1735 if (MangledName.consumeFront("$$C")) {
1736 if (MangledName.consumeFront("B"))
1737 ATy->Quals = Q_Const;
1738 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1739 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1740 else if (!MangledName.consumeFront("A"))
1741 Error = true;
1742 }
1743
Zachary Turner316109b2018-07-29 16:38:02 +00001744 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001745 Dim->ElementType = ATy->ElementType;
1746 return ATy;
1747}
1748
1749// Reads a function or a template parameters.
Zachary Turner316109b2018-07-29 16:38:02 +00001750ParamList Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001751 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001752 if (MangledName.consumeFront('X'))
1753 return {};
1754
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001755 ParamList *Head;
1756 ParamList **Current = &Head;
1757 while (!Error && !MangledName.startsWith('@') &&
1758 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001759
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001760 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001761 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001762 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001763 Error = true;
1764 return {};
1765 }
1766 MangledName = MangledName.dropFront();
1767
Zachary Turner9d72aa92018-07-20 18:35:06 +00001768 *Current = Arena.alloc<ParamList>();
Zachary Turner23df1312018-07-26 22:13:39 +00001769 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001770 Current = &(*Current)->Next;
1771 continue;
1772 }
1773
Zachary Turner23df1312018-07-26 22:13:39 +00001774 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001775
Zachary Turner9d72aa92018-07-20 18:35:06 +00001776 *Current = Arena.alloc<ParamList>();
Zachary Turner316109b2018-07-29 16:38:02 +00001777 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001778
Zachary Turner23df1312018-07-26 22:13:39 +00001779 size_t CharsConsumed = OldSize - MangledName.size();
1780 assert(CharsConsumed != 0);
1781
1782 // Single-letter types are ignored for backreferences because memorizing
1783 // them doesn't save anything.
1784 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1785 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1786
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001787 Current = &(*Current)->Next;
1788 }
1789
Zachary Turner38b78a72018-07-26 20:20:10 +00001790 if (Error)
1791 return {};
1792
1793 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1794 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1795 // the following Z could be a throw specifier.
1796 if (MangledName.consumeFront('@'))
1797 return *Head;
1798
1799 if (MangledName.consumeFront('Z')) {
1800 Head->IsVariadic = true;
1801 return *Head;
1802 }
1803
1804 Error = true;
1805 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001806}
1807
Zachary Turner316109b2018-07-29 16:38:02 +00001808ParamList Demangler::demangleTemplateParameterList(StringView &MangledName) {
Zachary Turner23df1312018-07-26 22:13:39 +00001809 ParamList *Head;
1810 ParamList **Current = &Head;
1811 while (!Error && !MangledName.startsWith('@')) {
1812
1813 // Template parameter lists don't participate in back-referencing.
1814 *Current = Arena.alloc<ParamList>();
Zachary Turner316109b2018-07-29 16:38:02 +00001815 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner23df1312018-07-26 22:13:39 +00001816
1817 Current = &(*Current)->Next;
1818 }
1819
1820 if (Error)
1821 return {};
1822
1823 // Template parameter lists cannot be variadic, so it can only be terminated
1824 // by @.
1825 if (MangledName.consumeFront('@'))
1826 return *Head;
1827 Error = true;
1828 return {};
1829}
1830
Zachary Turner316109b2018-07-29 16:38:02 +00001831void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001832 // Converts an AST to a string.
1833 //
1834 // Converting an AST representing a C++ type to a string is tricky due
1835 // to the bad grammar of the C++ declaration inherited from C. You have
1836 // to construct a string from inside to outside. For example, if a type
1837 // X is a pointer to a function returning int, the order you create a
1838 // string becomes something like this:
1839 //
1840 // (1) X is a pointer: *X
1841 // (2) (1) is a function returning int: int (*X)()
1842 //
1843 // So you cannot construct a result just by appending strings to a result.
1844 //
1845 // To deal with this, we split the function into two. outputPre() writes
1846 // the "first half" of type declaration, and outputPost() writes the
1847 // "second half". For example, outputPre() writes a return type for a
1848 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00001849 Type::outputPre(OS, *S->SymbolType);
1850 outputName(OS, S->SymbolName);
1851 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001852}
1853
1854char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1855 int *Status) {
Zachary Turner316109b2018-07-29 16:38:02 +00001856 Demangler D;
1857 StringView Name{MangledName};
1858 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001859
1860 if (D.Error)
1861 *Status = llvm::demangle_invalid_mangled_name;
1862 else
1863 *Status = llvm::demangle_success;
1864
Zachary Turner316109b2018-07-29 16:38:02 +00001865 OutputStream OS = OutputStream::create(Buf, N, 1024);
1866 D.output(S, OS);
Zachary Turner71c91f92018-07-30 03:12:34 +00001867 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001868 return OS.getBuffer();
1869}