blob: 1bf94ff8469f554e42dce085420c4d5a217f88d6 [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 {
Zachary Turner38b78a72018-07-26 20:20:10 +0000190 bool IsVariadic = false;
191
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000192 Type *Current = nullptr;
193
194 ParamList *Next = nullptr;
195};
196
197// The type class. Mangled symbols are first parsed and converted to
198// this type and then converted to string.
199struct Type {
200 virtual ~Type() {}
201
202 virtual Type *clone(ArenaAllocator &Arena) const;
203
204 // Write the "first half" of a given type. This is a static functions to
205 // give the code a chance to do processing that is common to a subset of
206 // subclasses
207 static void outputPre(OutputStream &OS, Type &Ty);
208
209 // Write the "second half" of a given type. This is a static functions to
210 // give the code a chance to do processing that is common to a subset of
211 // subclasses
212 static void outputPost(OutputStream &OS, Type &Ty);
213
214 virtual void outputPre(OutputStream &OS);
215 virtual void outputPost(OutputStream &OS);
216
217 // Primitive type such as Int.
218 PrimTy Prim = PrimTy::Unknown;
219
220 Qualifiers Quals = Q_None;
221 StorageClass Storage = StorageClass::None; // storage class
222};
223
224// Represents an identifier which may be a template.
225struct Name {
226 // Name read from an MangledName string.
227 StringView Str;
228
229 // Overloaded operators are represented as special BackReferences in mangled
230 // symbols. If this is an operator name, "op" has an operator name (e.g.
231 // ">>"). Otherwise, empty.
232 StringView Operator;
233
234 // Template parameters. Null if not a template.
235 ParamList TemplateParams;
236
237 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
238 Name *Next = nullptr;
239};
240
241struct PointerType : public Type {
242 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000243 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000244 void outputPost(OutputStream &OS) override;
245
Zachary Turnerd742d642018-07-26 19:56:09 +0000246 // Represents a type X in "a pointer to X", "a reference to X",
247 // "an array of X", or "a function returning X".
248 Type *Pointee = nullptr;
249};
250
251struct MemberPointerType : public Type {
252 Type *clone(ArenaAllocator &Arena) const override;
253 void outputPre(OutputStream &OS) override;
254 void outputPost(OutputStream &OS) override;
255
256 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000257
258 // Represents a type X in "a pointer to X", "a reference to X",
259 // "an array of X", or "a function returning X".
260 Type *Pointee = nullptr;
261};
262
263struct FunctionType : public Type {
264 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000265 void outputPre(OutputStream &OS) override;
266 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000267
268 Type *ReturnType = nullptr;
269 // If this is a reference, the type of reference.
270 ReferenceKind RefKind;
271
272 CallingConv CallConvention;
273 FuncClass FunctionClass;
274
275 ParamList Params;
276};
277
278struct UdtType : public Type {
279 Type *clone(ArenaAllocator &Arena) const override;
280 void outputPre(OutputStream &OS) override;
281
282 Name *UdtName = nullptr;
283};
284
285struct ArrayType : public Type {
286 Type *clone(ArenaAllocator &Arena) const override;
287 void outputPre(OutputStream &OS) override;
288 void outputPost(OutputStream &OS) override;
289
290 // Either NextDimension or ElementType will be valid.
291 ArrayType *NextDimension = nullptr;
292 uint32_t ArrayDimension = 0;
293
294 Type *ElementType = nullptr;
295};
296
297} // namespace
298
Zachary Turnerd742d642018-07-26 19:56:09 +0000299static bool isMemberPointer(StringView MangledName) {
300 switch (MangledName.popFront()) {
301 case 'A':
302 // 'A' indicates a reference, and you cannot have a reference to a member
303 // function or member variable.
304 return false;
305 case 'P':
306 case 'Q':
307 case 'R':
308 case 'S':
309 // These 4 values indicate some kind of pointer, but we still don't know
310 // what.
311 break;
312 default:
313 assert(false && "Ty is not a pointer type!");
314 }
315
316 // If it starts with a number, then 6 indicates a non-member function
317 // pointer, and 8 indicates a member function pointer.
318 if (startsWithDigit(MangledName)) {
319 assert(MangledName[0] == '6' || MangledName[0] == '8');
320 return (MangledName[0] == '8');
321 }
322
323 // Remove ext qualifiers since those can appear on either type and are
324 // therefore not indicative.
325 MangledName.consumeFront('E'); // 64-bit
326 MangledName.consumeFront('I'); // restrict
327 MangledName.consumeFront('F'); // unaligned
328
329 assert(!MangledName.empty());
330
331 // The next value should be either ABCD (non-member) or QRST (member).
332 switch (MangledName.front()) {
333 case 'A':
334 case 'B':
335 case 'C':
336 case 'D':
337 return false;
338 case 'Q':
339 case 'R':
340 case 'S':
341 case 'T':
342 return true;
343 default:
344 assert(false);
345 }
346 return false;
347}
348
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000349static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
350 outputSpaceIfNecessary(OS);
351
352 switch (CC) {
353 case CallingConv::Cdecl:
354 OS << "__cdecl";
355 break;
356 case CallingConv::Fastcall:
357 OS << "__fastcall";
358 break;
359 case CallingConv::Pascal:
360 OS << "__pascal";
361 break;
362 case CallingConv::Regcall:
363 OS << "__regcall";
364 break;
365 case CallingConv::Stdcall:
366 OS << "__stdcall";
367 break;
368 case CallingConv::Thiscall:
369 OS << "__thiscall";
370 break;
371 case CallingConv::Eabi:
372 OS << "__eabi";
373 break;
374 case CallingConv::Vectorcall:
375 OS << "__vectorcall";
376 break;
377 case CallingConv::Clrcall:
378 OS << "__clrcall";
379 break;
380 default:
381 break;
382 }
383}
384
385// Write a function or template parameter list.
386static void outputParameterList(OutputStream &OS, const ParamList &Params) {
Zachary Turner38b78a72018-07-26 20:20:10 +0000387 if (!Params.Current) {
388 OS << "void";
389 return;
390 }
391
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000392 const ParamList *Head = &Params;
393 while (Head) {
394 Type::outputPre(OS, *Head->Current);
395 Type::outputPost(OS, *Head->Current);
396
397 Head = Head->Next;
398
399 if (Head)
400 OS << ", ";
401 }
402}
403
404static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
405 if (!TheName.TemplateParams.Current)
406 return;
407
408 OS << "<";
409 outputParameterList(OS, TheName.TemplateParams);
410 OS << ">";
411}
412
413static void outputName(OutputStream &OS, const Name *TheName) {
414 if (!TheName)
415 return;
416
417 outputSpaceIfNecessary(OS);
418
419 // Print out namespaces or outer class BackReferences.
420 for (; TheName->Next; TheName = TheName->Next) {
421 OS << TheName->Str;
422 outputTemplateParams(OS, *TheName);
423 OS << "::";
424 }
425
426 // Print out a regular name.
427 if (TheName->Operator.empty()) {
428 OS << TheName->Str;
429 outputTemplateParams(OS, *TheName);
430 return;
431 }
432
433 // Print out ctor or dtor.
434 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
435 OS << TheName->Str;
436 outputTemplateParams(OS, *TheName);
437 OS << "::";
438 if (TheName->Operator == "dtor")
439 OS << "~";
440 OS << TheName->Str;
441 outputTemplateParams(OS, *TheName);
442 return;
443 }
444
445 // Print out an overloaded operator.
446 if (!TheName->Str.empty())
447 OS << TheName->Str << "::";
448 OS << "operator" << TheName->Operator;
449}
450
451namespace {
452
453Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000454 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000455}
456
457// Write the "first half" of a given type.
458void Type::outputPre(OutputStream &OS, Type &Ty) {
459 // Function types require custom handling of const and static so we
460 // handle them separately. All other types use the same decoration
461 // for these modifiers, so handle them here in common code.
462 if (Ty.Prim == PrimTy::Function) {
463 Ty.outputPre(OS);
464 return;
465 }
466
467 switch (Ty.Storage) {
468 case StorageClass::PrivateStatic:
469 case StorageClass::PublicStatic:
470 case StorageClass::ProtectedStatic:
471 OS << "static ";
472 default:
473 break;
474 }
475 Ty.outputPre(OS);
476
477 if (Ty.Quals & Q_Const) {
478 outputSpaceIfNecessary(OS);
479 OS << "const";
480 }
481
482 if (Ty.Quals & Q_Volatile) {
483 outputSpaceIfNecessary(OS);
484 OS << "volatile";
485 }
486}
487
488// Write the "second half" of a given type.
489void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
490
491void Type::outputPre(OutputStream &OS) {
492 switch (Prim) {
493 case PrimTy::Void:
494 OS << "void";
495 break;
496 case PrimTy::Bool:
497 OS << "bool";
498 break;
499 case PrimTy::Char:
500 OS << "char";
501 break;
502 case PrimTy::Schar:
503 OS << "signed char";
504 break;
505 case PrimTy::Uchar:
506 OS << "unsigned char";
507 break;
508 case PrimTy::Short:
509 OS << "short";
510 break;
511 case PrimTy::Ushort:
512 OS << "unsigned short";
513 break;
514 case PrimTy::Int:
515 OS << "int";
516 break;
517 case PrimTy::Uint:
518 OS << "unsigned int";
519 break;
520 case PrimTy::Long:
521 OS << "long";
522 break;
523 case PrimTy::Ulong:
524 OS << "unsigned long";
525 break;
526 case PrimTy::Int64:
527 OS << "__int64";
528 break;
529 case PrimTy::Uint64:
530 OS << "unsigned __int64";
531 break;
532 case PrimTy::Wchar:
533 OS << "wchar_t";
534 break;
535 case PrimTy::Float:
536 OS << "float";
537 break;
538 case PrimTy::Double:
539 OS << "double";
540 break;
541 case PrimTy::Ldouble:
542 OS << "long double";
543 break;
544 default:
545 assert(false && "Invalid primitive type!");
546 }
547}
548void Type::outputPost(OutputStream &OS) {}
549
550Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000551 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000552}
553
554void PointerType::outputPre(OutputStream &OS) {
555 Type::outputPre(OS, *Pointee);
556
557 outputSpaceIfNecessary(OS);
558
559 if (Quals & Q_Unaligned)
560 OS << "__unaligned ";
561
562 // "[]" and "()" (for function parameters) take precedence over "*",
563 // so "int *x(int)" means "x is a function returning int *". We need
564 // parentheses to supercede the default precedence. (e.g. we want to
565 // emit something like "int (*x)(int)".)
566 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
567 OS << "(";
568
569 if (Prim == PrimTy::Ptr)
570 OS << "*";
571 else
572 OS << "&";
573
Zachary Turner91ecedd2018-07-20 18:07:33 +0000574 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000575 // if (Ty.Quals & Q_Pointer64)
576 // OS << " __ptr64";
577 if (Quals & Q_Restrict)
578 OS << " __restrict";
579}
580
581void PointerType::outputPost(OutputStream &OS) {
582 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
583 OS << ")";
584
585 Type::outputPost(OS, *Pointee);
586}
587
Zachary Turnerd742d642018-07-26 19:56:09 +0000588Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
589 return Arena.alloc<MemberPointerType>(*this);
590}
591
592void MemberPointerType::outputPre(OutputStream &OS) {
593 Type::outputPre(OS, *Pointee);
594
595 outputSpaceIfNecessary(OS);
596
597 // "[]" and "()" (for function parameters) take precedence over "*",
598 // so "int *x(int)" means "x is a function returning int *". We need
599 // parentheses to supercede the default precedence. (e.g. we want to
600 // emit something like "int (*x)(int)".)
601 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
602 OS << "(";
603
604 outputName(OS, MemberName);
605 OS << "::*";
606
607 // FIXME: We should output this, but it requires updating lots of tests.
608 // if (Ty.Quals & Q_Pointer64)
609 // OS << " __ptr64";
610 if (Quals & Q_Restrict)
611 OS << " __restrict";
612}
613
614void MemberPointerType::outputPost(OutputStream &OS) {
615 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
616 OS << ")";
617
618 Type::outputPost(OS, *Pointee);
619}
620
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000621Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000622 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000623}
624
625void FunctionType::outputPre(OutputStream &OS) {
626 if (!(FunctionClass & Global)) {
627 if (FunctionClass & Static)
628 OS << "static ";
629 }
630
Zachary Turner38b78a72018-07-26 20:20:10 +0000631 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000632 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000633 OS << " ";
634 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000635
636 outputCallingConvention(OS, CallConvention);
637}
638
639void FunctionType::outputPost(OutputStream &OS) {
640 OS << "(";
641 outputParameterList(OS, Params);
642 OS << ")";
643 if (Quals & Q_Const)
644 OS << " const";
645 if (Quals & Q_Volatile)
646 OS << " volatile";
Zachary Turner38b78a72018-07-26 20:20:10 +0000647
648 if (ReturnType)
649 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000650 return;
651}
652
653Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000654 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000655}
656
657void UdtType::outputPre(OutputStream &OS) {
658 switch (Prim) {
659 case PrimTy::Class:
660 OS << "class ";
661 break;
662 case PrimTy::Struct:
663 OS << "struct ";
664 break;
665 case PrimTy::Union:
666 OS << "union ";
667 break;
668 case PrimTy::Enum:
669 OS << "enum ";
670 break;
671 default:
672 assert(false && "Not a udt type!");
673 }
674
675 outputName(OS, UdtName);
676}
677
678Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000679 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000680}
681
682void ArrayType::outputPre(OutputStream &OS) {
683 Type::outputPre(OS, *ElementType);
684}
685
686void ArrayType::outputPost(OutputStream &OS) {
687 if (ArrayDimension > 0)
688 OS << "[" << ArrayDimension << "]";
689 if (NextDimension)
690 Type::outputPost(OS, *NextDimension);
691 else if (ElementType)
692 Type::outputPost(OS, *ElementType);
693}
694
695} // namespace
696
697namespace {
698
699// Demangler class takes the main role in demangling symbols.
700// It has a set of functions to parse mangled symbols into Type instances.
701// It also has a set of functions to cnovert Type instances to strings.
702class Demangler {
703public:
704 Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
705
706 // You are supposed to call parse() first and then check if error is true. If
707 // it is false, call output() to write the formatted name to the given stream.
708 void parse();
709 void output();
710
711 // True if an error occurred.
712 bool Error = false;
713
714private:
715 Type *demangleVariableEncoding();
716 Type *demangleFunctionEncoding();
717
718 Qualifiers demanglePointerExtQualifiers();
719
720 // Parser functions. This is a recursive-descent parser.
721 Type *demangleType(QualifierMangleMode QMM);
722 Type *demangleBasicType();
723 UdtType *demangleClassType();
724 PointerType *demanglePointerType();
Zachary Turnerd742d642018-07-26 19:56:09 +0000725 MemberPointerType *demangleMemberPointerType();
Zachary Turner38b78a72018-07-26 20:20:10 +0000726 FunctionType *demangleFunctionType(bool HasThisQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000727
728 ArrayType *demangleArrayType();
729
730 ParamList demangleParameterList();
731
732 int demangleNumber();
733 void demangleNamePiece(Name &Node, bool IsHead);
734
735 StringView demangleString(bool memorize);
736 void memorizeString(StringView s);
737 Name *demangleName();
738 void demangleOperator(Name *);
739 StringView demangleOperatorName();
Zachary Turner38b78a72018-07-26 20:20:10 +0000740 FuncClass demangleFunctionClass();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000741 CallingConv demangleCallingConvention();
742 StorageClass demangleVariableStorageClass();
743 ReferenceKind demangleReferenceKind();
Zachary Turner38b78a72018-07-26 20:20:10 +0000744 void demangleThrowSpecification();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000745
Zachary Turnerd742d642018-07-26 19:56:09 +0000746 std::pair<Qualifiers, bool> demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000747
Zachary Turner91ecedd2018-07-20 18:07:33 +0000748 // The result is written to this stream.
749 OutputStream OS;
750
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000751 // Mangled symbol. demangle* functions shorten this string
752 // as they parse it.
753 StringView MangledName;
754
755 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000756 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000757
758 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
759 Name *SymbolName = nullptr;
760
761 // Memory allocator.
762 ArenaAllocator Arena;
763
764 // The first 10 BackReferences in a mangled name can be back-referenced by
765 // special name @[0-9]. This is a storage for the first 10 BackReferences.
766 StringView BackReferences[10];
767 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000768};
769} // namespace
770
771// Parser entry point.
772void Demangler::parse() {
773 // MSVC-style mangled symbols must start with '?'.
774 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000775 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000776 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000777 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000778 SymbolType->Prim = PrimTy::Unknown;
779 }
780
781 // What follows is a main symbol name. This may include
782 // namespaces or class BackReferences.
783 SymbolName = demangleName();
784
785 // Read a variable.
786 if (startsWithDigit(MangledName)) {
787 SymbolType = demangleVariableEncoding();
788 return;
789 }
790
791 // Read a function.
792 SymbolType = demangleFunctionEncoding();
793}
794
795// <type-encoding> ::= <storage-class> <variable-type>
796// <storage-class> ::= 0 # private static member
797// ::= 1 # protected static member
798// ::= 2 # public static member
799// ::= 3 # global
800// ::= 4 # static local
801
802Type *Demangler::demangleVariableEncoding() {
803 StorageClass SC = demangleVariableStorageClass();
804
805 Type *Ty = demangleType(QualifierMangleMode::Drop);
806
807 Ty->Storage = SC;
808
809 // <variable-type> ::= <type> <cvr-qualifiers>
810 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
811 switch (Ty->Prim) {
812 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000813 case PrimTy::Ref:
814 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000815 Qualifiers ExtraChildQuals = Q_None;
816 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
817
Zachary Turnerd742d642018-07-26 19:56:09 +0000818 bool IsMember = false;
819 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000820
Zachary Turnerd742d642018-07-26 19:56:09 +0000821 if (Ty->Prim == PrimTy::MemberPtr) {
822 assert(IsMember);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000823 Name *BackRefName = demangleName();
824 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000825 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
826 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
827 } else {
828 PointerType *PTy = static_cast<PointerType *>(Ty);
829 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000830 }
831
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000832 break;
833 }
834 default:
Zachary Turnerd742d642018-07-26 19:56:09 +0000835 Ty->Quals = demangleQualifiers().first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000836 break;
837 }
838
839 return Ty;
840}
841
842// Sometimes numbers are encoded in mangled symbols. For example,
843// "int (*x)[20]" is a valid C type (x is a pointer to an array of
844// length 20), so we need some way to embed numbers as part of symbols.
845// This function parses it.
846//
847// <number> ::= [?] <non-negative integer>
848//
849// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
850// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
851//
852// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
853int Demangler::demangleNumber() {
854 bool neg = MangledName.consumeFront("?");
855
856 if (startsWithDigit(MangledName)) {
857 int32_t Ret = MangledName[0] - '0' + 1;
858 MangledName = MangledName.dropFront(1);
859 return neg ? -Ret : Ret;
860 }
861
862 int Ret = 0;
863 for (size_t i = 0; i < MangledName.size(); ++i) {
864 char C = MangledName[i];
865 if (C == '@') {
866 MangledName = MangledName.dropFront(i + 1);
867 return neg ? -Ret : Ret;
868 }
869 if ('A' <= C && C <= 'P') {
870 Ret = (Ret << 4) + (C - 'A');
871 continue;
872 }
873 break;
874 }
875
876 Error = true;
877 return 0;
878}
879
880// Read until the next '@'.
881StringView Demangler::demangleString(bool Memorize) {
882 for (size_t i = 0; i < MangledName.size(); ++i) {
883 if (MangledName[i] != '@')
884 continue;
885 StringView ret = MangledName.substr(0, i);
886 MangledName = MangledName.dropFront(i + 1);
887
888 if (Memorize)
889 memorizeString(ret);
890 return ret;
891 }
892
893 Error = true;
894 return "";
895}
896
897// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
898// Memorize it.
899void Demangler::memorizeString(StringView S) {
900 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
901 return;
902 for (size_t i = 0; i < BackRefCount; ++i)
903 if (S == BackReferences[i])
904 return;
905 BackReferences[BackRefCount++] = S;
906}
907
908void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
909 if (startsWithDigit(MangledName)) {
910 size_t I = MangledName[0] - '0';
911 if (I >= BackRefCount) {
912 Error = true;
913 return;
914 }
915 MangledName = MangledName.dropFront();
916 Node.Str = BackReferences[I];
917 } else if (MangledName.consumeFront("?$")) {
918 // Class template.
919 Node.Str = demangleString(false);
920 Node.TemplateParams = demangleParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000921 } else if (!IsHead && MangledName.consumeFront("?A")) {
922 // Anonymous namespace starts with ?A. So does overloaded operator[],
923 // but the distinguishing factor is that namespace themselves are not
924 // mangled, only the variables and functions inside of them are. So
925 // an anonymous namespace will never occur as the first item in the
926 // name.
927 Node.Str = "`anonymous namespace'";
928 if (!MangledName.consumeFront('@')) {
929 Error = true;
930 return;
931 }
932 } else if (MangledName.consumeFront("?")) {
933 // Overloaded operator.
934 demangleOperator(&Node);
935 } else {
936 // Non-template functions or classes.
937 Node.Str = demangleString(true);
938 }
939}
940
941// Parses a name in the form of A@B@C@@ which represents C::B::A.
942Name *Demangler::demangleName() {
943 Name *Head = nullptr;
944
945 while (!MangledName.consumeFront("@")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000946 Name *Elem = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000947
948 assert(!Error);
949 demangleNamePiece(*Elem, Head == nullptr);
950 if (Error)
951 return nullptr;
952
953 Elem->Next = Head;
954 Head = Elem;
Zachary Turnerd742d642018-07-26 19:56:09 +0000955 if (MangledName.empty()) {
956 Error = true;
957 return nullptr;
958 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000959 }
960
961 return Head;
962}
963
964void Demangler::demangleOperator(Name *OpName) {
965 OpName->Operator = demangleOperatorName();
966 if (!Error && !MangledName.empty() && MangledName.front() != '@')
967 demangleNamePiece(*OpName, false);
968}
969
970StringView Demangler::demangleOperatorName() {
971 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
972 RestoreOnError.shouldRestore(false);
973
974 switch (MangledName.popFront()) {
975 case '0':
976 return "ctor";
977 case '1':
978 return "dtor";
979 case '2':
980 return " new";
981 case '3':
982 return " delete";
983 case '4':
984 return "=";
985 case '5':
986 return ">>";
987 case '6':
988 return "<<";
989 case '7':
990 return "!";
991 case '8':
992 return "==";
993 case '9':
994 return "!=";
995 case 'A':
996 return "[]";
997 case 'C':
998 return "->";
999 case 'D':
1000 return "*";
1001 case 'E':
1002 return "++";
1003 case 'F':
1004 return "--";
1005 case 'G':
1006 return "-";
1007 case 'H':
1008 return "+";
1009 case 'I':
1010 return "&";
1011 case 'J':
1012 return "->*";
1013 case 'K':
1014 return "/";
1015 case 'L':
1016 return "%";
1017 case 'M':
1018 return "<";
1019 case 'N':
1020 return "<=";
1021 case 'O':
1022 return ">";
1023 case 'P':
1024 return ">=";
1025 case 'Q':
1026 return ",";
1027 case 'R':
1028 return "()";
1029 case 'S':
1030 return "~";
1031 case 'T':
1032 return "^";
1033 case 'U':
1034 return "|";
1035 case 'V':
1036 return "&&";
1037 case 'W':
1038 return "||";
1039 case 'X':
1040 return "*=";
1041 case 'Y':
1042 return "+=";
1043 case 'Z':
1044 return "-=";
1045 case '_': {
1046 if (MangledName.empty())
1047 break;
1048
1049 switch (MangledName.popFront()) {
1050 case '0':
1051 return "/=";
1052 case '1':
1053 return "%=";
1054 case '2':
1055 return ">>=";
1056 case '3':
1057 return "<<=";
1058 case '4':
1059 return "&=";
1060 case '5':
1061 return "|=";
1062 case '6':
1063 return "^=";
1064 case 'U':
1065 return " new[]";
1066 case 'V':
1067 return " delete[]";
1068 case '_':
1069 if (MangledName.consumeFront("L"))
1070 return " co_await";
1071 }
1072 }
1073 }
1074
1075 Error = true;
1076 RestoreOnError.shouldRestore(true);
1077 return "";
1078}
1079
Zachary Turner38b78a72018-07-26 20:20:10 +00001080FuncClass Demangler::demangleFunctionClass() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001081 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1082 RestoreOnError.shouldRestore(false);
1083
1084 switch (MangledName.popFront()) {
1085 case 'A':
1086 return Private;
1087 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001088 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001089 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001090 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001091 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001092 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001093 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001094 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001095 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001096 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001097 case 'I':
1098 return Protected;
1099 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001100 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001101 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001102 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001103 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001104 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001106 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001107 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001108 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001109 case 'Q':
1110 return Public;
1111 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001112 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001113 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001114 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001115 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001116 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001117 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001118 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001119 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001120 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001121 case 'Y':
1122 return Global;
1123 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001124 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001125 }
1126
1127 Error = true;
1128 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001129 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001130}
1131
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001132CallingConv Demangler::demangleCallingConvention() {
1133 switch (MangledName.popFront()) {
1134 case 'A':
1135 case 'B':
1136 return CallingConv::Cdecl;
1137 case 'C':
1138 case 'D':
1139 return CallingConv::Pascal;
1140 case 'E':
1141 case 'F':
1142 return CallingConv::Thiscall;
1143 case 'G':
1144 case 'H':
1145 return CallingConv::Stdcall;
1146 case 'I':
1147 case 'J':
1148 return CallingConv::Fastcall;
1149 case 'M':
1150 case 'N':
1151 return CallingConv::Clrcall;
1152 case 'O':
1153 case 'P':
1154 return CallingConv::Eabi;
1155 case 'Q':
1156 return CallingConv::Vectorcall;
1157 }
1158
1159 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001160}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001161
1162StorageClass Demangler::demangleVariableStorageClass() {
1163 assert(std::isdigit(MangledName.front()));
1164
1165 switch (MangledName.popFront()) {
1166 case '0':
1167 return StorageClass::PrivateStatic;
1168 case '1':
1169 return StorageClass::ProtectedStatic;
1170 case '2':
1171 return StorageClass::PublicStatic;
1172 case '3':
1173 return StorageClass::Global;
1174 case '4':
1175 return StorageClass::FunctionLocalStatic;
1176 }
1177 Error = true;
1178 return StorageClass::None;
1179}
1180
Zachary Turnerd742d642018-07-26 19:56:09 +00001181std::pair<Qualifiers, bool> Demangler::demangleQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001182
1183 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001184 // Member qualifiers
1185 case 'Q':
1186 return std::make_pair(Q_None, true);
1187 case 'R':
1188 return std::make_pair(Q_Const, true);
1189 case 'S':
1190 return std::make_pair(Q_Volatile, true);
1191 case 'T':
1192 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1193 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001194 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001195 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001196 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001197 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001198 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001199 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001200 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001201 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001202 }
1203 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001204 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001205}
1206
1207// <variable-type> ::= <type> <cvr-qualifiers>
1208// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1209Type *Demangler::demangleType(QualifierMangleMode QMM) {
1210 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001211 bool IsMember = false;
1212 bool IsMemberKnown = false;
1213 if (QMM == QualifierMangleMode::Mangle) {
1214 std::tie(Quals, IsMember) = demangleQualifiers();
1215 IsMemberKnown = true;
1216 } else if (QMM == QualifierMangleMode::Result) {
1217 if (MangledName.consumeFront('?')) {
1218 std::tie(Quals, IsMember) = demangleQualifiers();
1219 IsMemberKnown = true;
1220 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001221 }
1222
1223 Type *Ty = nullptr;
1224 switch (MangledName.front()) {
1225 case 'T': // union
1226 case 'U': // struct
1227 case 'V': // class
1228 case 'W': // enum
1229 Ty = demangleClassType();
1230 break;
1231 case 'A': // foo &
1232 case 'P': // foo *
1233 case 'Q': // foo *const
1234 case 'R': // foo *volatile
1235 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001236 if (!IsMemberKnown)
1237 IsMember = isMemberPointer(MangledName);
1238 if (IsMember)
1239 Ty = demangleMemberPointerType();
1240 else
1241 Ty = demanglePointerType();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001242 break;
1243 case 'Y':
1244 Ty = demangleArrayType();
1245 break;
1246 default:
1247 Ty = demangleBasicType();
1248 break;
1249 }
1250 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1251 return Ty;
1252}
1253
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001254ReferenceKind Demangler::demangleReferenceKind() {
1255 if (MangledName.consumeFront('G'))
1256 return ReferenceKind::LValueRef;
1257 else if (MangledName.consumeFront('H'))
1258 return ReferenceKind::RValueRef;
1259 return ReferenceKind::None;
1260}
1261
Zachary Turner38b78a72018-07-26 20:20:10 +00001262void Demangler::demangleThrowSpecification() {
1263 if (MangledName.consumeFront('Z'))
1264 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001265
Zachary Turner38b78a72018-07-26 20:20:10 +00001266 Error = true;
1267}
1268
1269FunctionType *Demangler::demangleFunctionType(bool HasThisQuals) {
1270 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001271 FTy->Prim = PrimTy::Function;
Zachary Turner38b78a72018-07-26 20:20:10 +00001272
1273 if (HasThisQuals) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001274 FTy->Quals = demanglePointerExtQualifiers();
1275 FTy->RefKind = demangleReferenceKind();
Zachary Turnerd742d642018-07-26 19:56:09 +00001276 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers().first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001277 }
1278
1279 // Fields that appear on both member and non-member functions.
1280 FTy->CallConvention = demangleCallingConvention();
1281
1282 // <return-type> ::= <type>
1283 // ::= @ # structors (they have no declared return type)
1284 bool IsStructor = MangledName.consumeFront('@');
1285 if (!IsStructor)
1286 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1287
1288 FTy->Params = demangleParameterList();
1289
Zachary Turner38b78a72018-07-26 20:20:10 +00001290 demangleThrowSpecification();
1291
1292 return FTy;
1293}
1294
1295Type *Demangler::demangleFunctionEncoding() {
1296 FuncClass FC = demangleFunctionClass();
1297
1298 bool HasThisQuals = !(FC & (Global | Static));
1299 FunctionType *FTy = demangleFunctionType(HasThisQuals);
1300 FTy->FunctionClass = FC;
1301
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001302 return FTy;
1303}
1304
1305// Reads a primitive type.
1306Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001307 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001308
1309 switch (MangledName.popFront()) {
1310 case 'X':
1311 Ty->Prim = PrimTy::Void;
1312 break;
1313 case 'D':
1314 Ty->Prim = PrimTy::Char;
1315 break;
1316 case 'C':
1317 Ty->Prim = PrimTy::Schar;
1318 break;
1319 case 'E':
1320 Ty->Prim = PrimTy::Uchar;
1321 break;
1322 case 'F':
1323 Ty->Prim = PrimTy::Short;
1324 break;
1325 case 'G':
1326 Ty->Prim = PrimTy::Ushort;
1327 break;
1328 case 'H':
1329 Ty->Prim = PrimTy::Int;
1330 break;
1331 case 'I':
1332 Ty->Prim = PrimTy::Uint;
1333 break;
1334 case 'J':
1335 Ty->Prim = PrimTy::Long;
1336 break;
1337 case 'K':
1338 Ty->Prim = PrimTy::Ulong;
1339 break;
1340 case 'M':
1341 Ty->Prim = PrimTy::Float;
1342 break;
1343 case 'N':
1344 Ty->Prim = PrimTy::Double;
1345 break;
1346 case 'O':
1347 Ty->Prim = PrimTy::Ldouble;
1348 break;
1349 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001350 if (MangledName.empty()) {
1351 Error = true;
1352 return nullptr;
1353 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001354 switch (MangledName.popFront()) {
1355 case 'N':
1356 Ty->Prim = PrimTy::Bool;
1357 break;
1358 case 'J':
1359 Ty->Prim = PrimTy::Int64;
1360 break;
1361 case 'K':
1362 Ty->Prim = PrimTy::Uint64;
1363 break;
1364 case 'W':
1365 Ty->Prim = PrimTy::Wchar;
1366 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001367 default:
1368 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001369 }
1370 break;
1371 }
1372 }
1373 return Ty;
1374}
1375
1376UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001377 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001378
1379 switch (MangledName.popFront()) {
1380 case 'T':
1381 UTy->Prim = PrimTy::Union;
1382 break;
1383 case 'U':
1384 UTy->Prim = PrimTy::Struct;
1385 break;
1386 case 'V':
1387 UTy->Prim = PrimTy::Class;
1388 break;
1389 case 'W':
1390 if (MangledName.popFront() != '4') {
1391 Error = true;
1392 return nullptr;
1393 }
1394 UTy->Prim = PrimTy::Enum;
1395 break;
1396 default:
1397 assert(false);
1398 }
1399
1400 UTy->UdtName = demangleName();
1401 return UTy;
1402}
1403
Zachary Turnerd742d642018-07-26 19:56:09 +00001404static std::pair<Qualifiers, PointerAffinity>
1405demanglePointerCVQualifiers(StringView &MangledName) {
1406 switch (MangledName.popFront()) {
1407 case 'A':
1408 return std::make_pair(Q_None, PointerAffinity::Reference);
1409 case 'P':
1410 return std::make_pair(Q_None, PointerAffinity::Pointer);
1411 case 'Q':
1412 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1413 case 'R':
1414 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1415 case 'S':
1416 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1417 PointerAffinity::Pointer);
1418 default:
1419 assert(false && "Ty is not a pointer type!");
1420 }
1421 return std::make_pair(Q_None, PointerAffinity::Pointer);
1422}
1423
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001424// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1425// # the E is required for 64-bit non-static pointers
1426PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001427 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001428
Zachary Turnerd742d642018-07-26 19:56:09 +00001429 PointerAffinity Affinity;
1430 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001431
Zachary Turnerd742d642018-07-26 19:56:09 +00001432 Pointer->Prim =
1433 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001434 if (MangledName.consumeFront("6")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001435 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001436 FTy->Prim = PrimTy::Function;
1437 FTy->CallConvention = demangleCallingConvention();
1438
1439 FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
1440 FTy->Params = demangleParameterList();
1441
1442 if (!MangledName.consumeFront("@Z"))
1443 MangledName.consumeFront("Z");
1444
1445 Pointer->Pointee = FTy;
1446 return Pointer;
1447 }
1448
1449 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1450 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1451
1452 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1453 return Pointer;
1454}
1455
Zachary Turnerd742d642018-07-26 19:56:09 +00001456MemberPointerType *Demangler::demangleMemberPointerType() {
1457 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1458 Pointer->Prim = PrimTy::MemberPtr;
1459
1460 PointerAffinity Affinity;
1461 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1462 assert(Affinity == PointerAffinity::Pointer);
1463
1464 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1465 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1466
Zachary Turner38b78a72018-07-26 20:20:10 +00001467 if (MangledName.consumeFront("8")) {
1468 Pointer->MemberName = demangleName();
1469 Pointer->Pointee = demangleFunctionType(true);
1470 } else {
1471 Qualifiers PointeeQuals = Q_None;
1472 bool IsMember = false;
1473 std::tie(PointeeQuals, IsMember) = demangleQualifiers();
1474 assert(IsMember);
1475 Pointer->MemberName = demangleName();
Zachary Turnerd742d642018-07-26 19:56:09 +00001476
Zachary Turner38b78a72018-07-26 20:20:10 +00001477 Pointer->Pointee = demangleType(QualifierMangleMode::Drop);
1478 Pointer->Pointee->Quals = PointeeQuals;
1479 }
1480
Zachary Turnerd742d642018-07-26 19:56:09 +00001481 return Pointer;
1482}
1483
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001484Qualifiers Demangler::demanglePointerExtQualifiers() {
1485 Qualifiers Quals = Q_None;
1486 if (MangledName.consumeFront('E'))
1487 Quals = Qualifiers(Quals | Q_Pointer64);
1488 if (MangledName.consumeFront('I'))
1489 Quals = Qualifiers(Quals | Q_Restrict);
1490 if (MangledName.consumeFront('F'))
1491 Quals = Qualifiers(Quals | Q_Unaligned);
1492
1493 return Quals;
1494}
1495
1496ArrayType *Demangler::demangleArrayType() {
1497 assert(MangledName.front() == 'Y');
1498 MangledName.popFront();
1499
1500 int Dimension = demangleNumber();
1501 if (Dimension <= 0) {
1502 Error = true;
1503 return nullptr;
1504 }
1505
Zachary Turner9d72aa92018-07-20 18:35:06 +00001506 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001507 ArrayType *Dim = ATy;
1508 for (int I = 0; I < Dimension; ++I) {
1509 Dim->Prim = PrimTy::Array;
1510 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001511 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001512 Dim = Dim->NextDimension;
1513 }
1514
1515 if (MangledName.consumeFront("$$C")) {
1516 if (MangledName.consumeFront("B"))
1517 ATy->Quals = Q_Const;
1518 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1519 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1520 else if (!MangledName.consumeFront("A"))
1521 Error = true;
1522 }
1523
1524 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1525 Dim->ElementType = ATy->ElementType;
1526 return ATy;
1527}
1528
1529// Reads a function or a template parameters.
1530ParamList Demangler::demangleParameterList() {
1531 // Within the same parameter list, you can backreference the first 10 types.
1532 Type *BackRef[10];
1533 int Idx = 0;
1534
Zachary Turner38b78a72018-07-26 20:20:10 +00001535 // Empty parameter list.
1536 // FIXME: Will this cause problems if demangleParameterList() is called in the
1537 // context of a template parameter list?
1538 if (MangledName.consumeFront('X'))
1539 return {};
1540
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001541 ParamList *Head;
1542 ParamList **Current = &Head;
1543 while (!Error && !MangledName.startsWith('@') &&
1544 !MangledName.startsWith('Z')) {
1545 if (startsWithDigit(MangledName)) {
1546 int N = MangledName[0] - '0';
1547 if (N >= Idx) {
1548 Error = true;
1549 return {};
1550 }
1551 MangledName = MangledName.dropFront();
1552
Zachary Turner9d72aa92018-07-20 18:35:06 +00001553 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001554 (*Current)->Current = BackRef[N]->clone(Arena);
1555 Current = &(*Current)->Next;
1556 continue;
1557 }
1558
1559 size_t ArrayDimension = MangledName.size();
1560
Zachary Turner9d72aa92018-07-20 18:35:06 +00001561 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001562 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1563
1564 // Single-letter types are ignored for backreferences because
1565 // memorizing them doesn't save anything.
1566 if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
1567 BackRef[Idx++] = (*Current)->Current;
1568 Current = &(*Current)->Next;
1569 }
1570
Zachary Turner38b78a72018-07-26 20:20:10 +00001571 if (Error)
1572 return {};
1573
1574 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1575 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1576 // the following Z could be a throw specifier.
1577 if (MangledName.consumeFront('@'))
1578 return *Head;
1579
1580 if (MangledName.consumeFront('Z')) {
1581 Head->IsVariadic = true;
1582 return *Head;
1583 }
1584
1585 Error = true;
1586 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001587}
1588
1589void Demangler::output() {
1590 // Converts an AST to a string.
1591 //
1592 // Converting an AST representing a C++ type to a string is tricky due
1593 // to the bad grammar of the C++ declaration inherited from C. You have
1594 // to construct a string from inside to outside. For example, if a type
1595 // X is a pointer to a function returning int, the order you create a
1596 // string becomes something like this:
1597 //
1598 // (1) X is a pointer: *X
1599 // (2) (1) is a function returning int: int (*X)()
1600 //
1601 // So you cannot construct a result just by appending strings to a result.
1602 //
1603 // To deal with this, we split the function into two. outputPre() writes
1604 // the "first half" of type declaration, and outputPost() writes the
1605 // "second half". For example, outputPre() writes a return type for a
1606 // function and outputPost() writes an parameter list.
1607 Type::outputPre(OS, *SymbolType);
1608 outputName(OS, SymbolName);
1609 Type::outputPost(OS, *SymbolType);
1610
1611 // Null terminate the buffer.
1612 OS << '\0';
1613}
1614
1615char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1616 int *Status) {
1617 OutputStream OS = OutputStream::create(Buf, N, 1024);
1618
1619 Demangler D(OS, StringView(MangledName));
1620 D.parse();
1621
1622 if (D.Error)
1623 *Status = llvm::demangle_invalid_mangled_name;
1624 else
1625 *Status = llvm::demangle_success;
1626
1627 D.output();
1628 return OS.getBuffer();
1629}