blob: 551bcdcb6206f60b4cfb63b0f05c61cf245dd7fd [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
Zachary Turner024e1762018-07-26 20:33:48 +0000268 // True if this FunctionType instance is the Pointee of a PointerType or
269 // MemberPointerType.
270 bool IsFunctionPointer = false;
271
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000272 Type *ReturnType = nullptr;
273 // If this is a reference, the type of reference.
274 ReferenceKind RefKind;
275
276 CallingConv CallConvention;
277 FuncClass FunctionClass;
278
279 ParamList Params;
280};
281
282struct UdtType : public Type {
283 Type *clone(ArenaAllocator &Arena) const override;
284 void outputPre(OutputStream &OS) override;
285
286 Name *UdtName = nullptr;
287};
288
289struct ArrayType : public Type {
290 Type *clone(ArenaAllocator &Arena) const override;
291 void outputPre(OutputStream &OS) override;
292 void outputPost(OutputStream &OS) override;
293
294 // Either NextDimension or ElementType will be valid.
295 ArrayType *NextDimension = nullptr;
296 uint32_t ArrayDimension = 0;
297
298 Type *ElementType = nullptr;
299};
300
301} // namespace
302
Zachary Turnerd742d642018-07-26 19:56:09 +0000303static bool isMemberPointer(StringView MangledName) {
304 switch (MangledName.popFront()) {
305 case 'A':
306 // 'A' indicates a reference, and you cannot have a reference to a member
307 // function or member variable.
308 return false;
309 case 'P':
310 case 'Q':
311 case 'R':
312 case 'S':
313 // These 4 values indicate some kind of pointer, but we still don't know
314 // what.
315 break;
316 default:
317 assert(false && "Ty is not a pointer type!");
318 }
319
320 // If it starts with a number, then 6 indicates a non-member function
321 // pointer, and 8 indicates a member function pointer.
322 if (startsWithDigit(MangledName)) {
323 assert(MangledName[0] == '6' || MangledName[0] == '8');
324 return (MangledName[0] == '8');
325 }
326
327 // Remove ext qualifiers since those can appear on either type and are
328 // therefore not indicative.
329 MangledName.consumeFront('E'); // 64-bit
330 MangledName.consumeFront('I'); // restrict
331 MangledName.consumeFront('F'); // unaligned
332
333 assert(!MangledName.empty());
334
335 // The next value should be either ABCD (non-member) or QRST (member).
336 switch (MangledName.front()) {
337 case 'A':
338 case 'B':
339 case 'C':
340 case 'D':
341 return false;
342 case 'Q':
343 case 'R':
344 case 'S':
345 case 'T':
346 return true;
347 default:
348 assert(false);
349 }
350 return false;
351}
352
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000353static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
354 outputSpaceIfNecessary(OS);
355
356 switch (CC) {
357 case CallingConv::Cdecl:
358 OS << "__cdecl";
359 break;
360 case CallingConv::Fastcall:
361 OS << "__fastcall";
362 break;
363 case CallingConv::Pascal:
364 OS << "__pascal";
365 break;
366 case CallingConv::Regcall:
367 OS << "__regcall";
368 break;
369 case CallingConv::Stdcall:
370 OS << "__stdcall";
371 break;
372 case CallingConv::Thiscall:
373 OS << "__thiscall";
374 break;
375 case CallingConv::Eabi:
376 OS << "__eabi";
377 break;
378 case CallingConv::Vectorcall:
379 OS << "__vectorcall";
380 break;
381 case CallingConv::Clrcall:
382 OS << "__clrcall";
383 break;
384 default:
385 break;
386 }
387}
388
389// Write a function or template parameter list.
390static void outputParameterList(OutputStream &OS, const ParamList &Params) {
Zachary Turner38b78a72018-07-26 20:20:10 +0000391 if (!Params.Current) {
392 OS << "void";
393 return;
394 }
395
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000396 const ParamList *Head = &Params;
397 while (Head) {
398 Type::outputPre(OS, *Head->Current);
399 Type::outputPost(OS, *Head->Current);
400
401 Head = Head->Next;
402
403 if (Head)
404 OS << ", ";
405 }
406}
407
408static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
409 if (!TheName.TemplateParams.Current)
410 return;
411
412 OS << "<";
413 outputParameterList(OS, TheName.TemplateParams);
414 OS << ">";
415}
416
417static void outputName(OutputStream &OS, const Name *TheName) {
418 if (!TheName)
419 return;
420
421 outputSpaceIfNecessary(OS);
422
Zachary Turnera7dffb12018-07-28 22:10:42 +0000423 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000424 // Print out namespaces or outer class BackReferences.
425 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000426 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000427 OS << TheName->Str;
428 outputTemplateParams(OS, *TheName);
429 OS << "::";
430 }
431
432 // Print out a regular name.
433 if (TheName->Operator.empty()) {
434 OS << TheName->Str;
435 outputTemplateParams(OS, *TheName);
436 return;
437 }
438
439 // Print out ctor or dtor.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000440 if (TheName->Operator == "dtor")
441 OS << "~";
442
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000443 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000444 OS << Previous->Str;
445 outputTemplateParams(OS, *Previous);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000446 return;
447 }
448
449 // Print out an overloaded operator.
450 if (!TheName->Str.empty())
451 OS << TheName->Str << "::";
452 OS << "operator" << TheName->Operator;
453}
454
455namespace {
456
457Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000458 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000459}
460
461// Write the "first half" of a given type.
462void Type::outputPre(OutputStream &OS, Type &Ty) {
463 // Function types require custom handling of const and static so we
464 // handle them separately. All other types use the same decoration
465 // for these modifiers, so handle them here in common code.
466 if (Ty.Prim == PrimTy::Function) {
467 Ty.outputPre(OS);
468 return;
469 }
470
471 switch (Ty.Storage) {
472 case StorageClass::PrivateStatic:
473 case StorageClass::PublicStatic:
474 case StorageClass::ProtectedStatic:
475 OS << "static ";
476 default:
477 break;
478 }
479 Ty.outputPre(OS);
480
481 if (Ty.Quals & Q_Const) {
482 outputSpaceIfNecessary(OS);
483 OS << "const";
484 }
485
486 if (Ty.Quals & Q_Volatile) {
487 outputSpaceIfNecessary(OS);
488 OS << "volatile";
489 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000490
491 if (Ty.Quals & Q_Restrict) {
492 outputSpaceIfNecessary(OS);
493 OS << "__restrict";
494 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000495}
496
497// Write the "second half" of a given type.
498void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
499
500void Type::outputPre(OutputStream &OS) {
501 switch (Prim) {
502 case PrimTy::Void:
503 OS << "void";
504 break;
505 case PrimTy::Bool:
506 OS << "bool";
507 break;
508 case PrimTy::Char:
509 OS << "char";
510 break;
511 case PrimTy::Schar:
512 OS << "signed char";
513 break;
514 case PrimTy::Uchar:
515 OS << "unsigned char";
516 break;
517 case PrimTy::Short:
518 OS << "short";
519 break;
520 case PrimTy::Ushort:
521 OS << "unsigned short";
522 break;
523 case PrimTy::Int:
524 OS << "int";
525 break;
526 case PrimTy::Uint:
527 OS << "unsigned int";
528 break;
529 case PrimTy::Long:
530 OS << "long";
531 break;
532 case PrimTy::Ulong:
533 OS << "unsigned long";
534 break;
535 case PrimTy::Int64:
536 OS << "__int64";
537 break;
538 case PrimTy::Uint64:
539 OS << "unsigned __int64";
540 break;
541 case PrimTy::Wchar:
542 OS << "wchar_t";
543 break;
544 case PrimTy::Float:
545 OS << "float";
546 break;
547 case PrimTy::Double:
548 OS << "double";
549 break;
550 case PrimTy::Ldouble:
551 OS << "long double";
552 break;
553 default:
554 assert(false && "Invalid primitive type!");
555 }
556}
557void Type::outputPost(OutputStream &OS) {}
558
559Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000560 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561}
562
Zachary Turner024e1762018-07-26 20:33:48 +0000563static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
564 const Name *MemberName,
565 const Type *Pointee) {
566 // "[]" and "()" (for function parameters) take precedence over "*",
567 // so "int *x(int)" means "x is a function returning int *". We need
568 // parentheses to supercede the default precedence. (e.g. we want to
569 // emit something like "int (*x)(int)".)
570 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
571 OS << "(";
572 if (Pointee->Prim == PrimTy::Function) {
573 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
574 assert(FTy->IsFunctionPointer);
575 outputCallingConvention(OS, FTy->CallConvention);
576 OS << " ";
577 }
578 }
579
580 if (MemberName) {
581 outputName(OS, MemberName);
582 OS << "::";
583 }
584
585 if (Affinity == PointerAffinity::Pointer)
586 OS << "*";
587 else
588 OS << "&";
589}
590
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000591void PointerType::outputPre(OutputStream &OS) {
592 Type::outputPre(OS, *Pointee);
593
594 outputSpaceIfNecessary(OS);
595
596 if (Quals & Q_Unaligned)
597 OS << "__unaligned ";
598
Zachary Turner024e1762018-07-26 20:33:48 +0000599 PointerAffinity Affinity = (Prim == PrimTy::Ptr) ? PointerAffinity::Pointer
600 : PointerAffinity::Reference;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000601
Zachary Turner024e1762018-07-26 20:33:48 +0000602 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000603
Zachary Turner91ecedd2018-07-20 18:07:33 +0000604 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000605 // if (Ty.Quals & Q_Pointer64)
606 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000607}
608
609void PointerType::outputPost(OutputStream &OS) {
610 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
611 OS << ")";
612
613 Type::outputPost(OS, *Pointee);
614}
615
Zachary Turnerd742d642018-07-26 19:56:09 +0000616Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
617 return Arena.alloc<MemberPointerType>(*this);
618}
619
620void MemberPointerType::outputPre(OutputStream &OS) {
621 Type::outputPre(OS, *Pointee);
622
623 outputSpaceIfNecessary(OS);
624
Zachary Turner024e1762018-07-26 20:33:48 +0000625 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000626
627 // FIXME: We should output this, but it requires updating lots of tests.
628 // if (Ty.Quals & Q_Pointer64)
629 // OS << " __ptr64";
630 if (Quals & Q_Restrict)
631 OS << " __restrict";
632}
633
634void MemberPointerType::outputPost(OutputStream &OS) {
635 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
636 OS << ")";
637
638 Type::outputPost(OS, *Pointee);
639}
640
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000641Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000642 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000643}
644
645void FunctionType::outputPre(OutputStream &OS) {
646 if (!(FunctionClass & Global)) {
647 if (FunctionClass & Static)
648 OS << "static ";
649 }
650
Zachary Turner38b78a72018-07-26 20:20:10 +0000651 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000652 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000653 OS << " ";
654 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000655
Zachary Turner024e1762018-07-26 20:33:48 +0000656 // Function pointers print the calling convention as void (__cdecl *)(params)
657 // rather than void __cdecl (*)(params). So we need to let the PointerType
658 // class handle this.
659 if (!IsFunctionPointer)
660 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000661}
662
663void FunctionType::outputPost(OutputStream &OS) {
664 OS << "(";
665 outputParameterList(OS, Params);
666 OS << ")";
667 if (Quals & Q_Const)
668 OS << " const";
669 if (Quals & Q_Volatile)
670 OS << " volatile";
Zachary Turner38b78a72018-07-26 20:20:10 +0000671
672 if (ReturnType)
673 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000674 return;
675}
676
677Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000678 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000679}
680
681void UdtType::outputPre(OutputStream &OS) {
682 switch (Prim) {
683 case PrimTy::Class:
684 OS << "class ";
685 break;
686 case PrimTy::Struct:
687 OS << "struct ";
688 break;
689 case PrimTy::Union:
690 OS << "union ";
691 break;
692 case PrimTy::Enum:
693 OS << "enum ";
694 break;
695 default:
696 assert(false && "Not a udt type!");
697 }
698
699 outputName(OS, UdtName);
700}
701
702Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000703 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000704}
705
706void ArrayType::outputPre(OutputStream &OS) {
707 Type::outputPre(OS, *ElementType);
708}
709
710void ArrayType::outputPost(OutputStream &OS) {
711 if (ArrayDimension > 0)
712 OS << "[" << ArrayDimension << "]";
713 if (NextDimension)
714 Type::outputPost(OS, *NextDimension);
715 else if (ElementType)
716 Type::outputPost(OS, *ElementType);
717}
718
Zachary Turner316109b2018-07-29 16:38:02 +0000719struct Symbol {
720 Name *SymbolName = nullptr;
721 Type *SymbolType = nullptr;
722};
723
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000724} // namespace
725
726namespace {
727
728// Demangler class takes the main role in demangling symbols.
729// It has a set of functions to parse mangled symbols into Type instances.
730// It also has a set of functions to cnovert Type instances to strings.
731class Demangler {
732public:
Zachary Turner316109b2018-07-29 16:38:02 +0000733 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000734
735 // You are supposed to call parse() first and then check if error is true. If
736 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000737 Symbol *parse(StringView &MangledName);
738 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000739
740 // True if an error occurred.
741 bool Error = false;
742
743private:
Zachary Turner316109b2018-07-29 16:38:02 +0000744 Type *demangleVariableEncoding(StringView &MangledName);
745 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000746
Zachary Turner316109b2018-07-29 16:38:02 +0000747 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000748
749 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000750 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
751 Type *demangleBasicType(StringView &MangledName);
752 UdtType *demangleClassType(StringView &MangledName);
753 PointerType *demanglePointerType(StringView &MangledName);
754 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
755 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
756 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000757
Zachary Turner316109b2018-07-29 16:38:02 +0000758 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000759
Zachary Turner316109b2018-07-29 16:38:02 +0000760 ParamList demangleTemplateParameterList(StringView &MangledName);
761 ParamList demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000762
Zachary Turner316109b2018-07-29 16:38:02 +0000763 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000764
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000765 void memorizeString(StringView s);
Zachary Turner316109b2018-07-29 16:38:02 +0000766 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
767 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000768
Zachary Turner316109b2018-07-29 16:38:02 +0000769 Name *demangleUnqualifiedTypeName(StringView &MangledName);
770 Name *demangleUnqualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000771
Zachary Turner316109b2018-07-29 16:38:02 +0000772 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
773 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000774
Zachary Turner316109b2018-07-29 16:38:02 +0000775 Name *demangleBackRefName(StringView &MangledName);
776 Name *demangleClassTemplateName(StringView &MangledName);
777 Name *demangleOperatorName(StringView &MangledName);
778 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
779 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000780
Zachary Turner316109b2018-07-29 16:38:02 +0000781 void demangleOperator(StringView &MangledName, Name *);
782 FuncClass demangleFunctionClass(StringView &MangledName);
783 CallingConv demangleCallingConvention(StringView &MangledName);
784 StorageClass demangleVariableStorageClass(StringView &MangledName);
785 ReferenceKind demangleReferenceKind(StringView &MangledName);
786 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000787
Zachary Turner316109b2018-07-29 16:38:02 +0000788 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000789
790 // Memory allocator.
791 ArenaAllocator Arena;
792
Zachary Turner23df1312018-07-26 22:13:39 +0000793 // A single type uses one global back-ref table for all function params.
794 // This means back-refs can even go "into" other types. Examples:
795 //
796 // // Second int* is a back-ref to first.
797 // void foo(int *, int*);
798 //
799 // // Second int* is not a back-ref to first (first is not a function param).
800 // int* foo(int*);
801 //
802 // // Second int* is a back-ref to first (ALL function types share the same
803 // // back-ref map.
804 // using F = void(*)(int*);
805 // F G(int *);
806 Type *FunctionParamBackRefs[10];
807 size_t FunctionParamBackRefCount = 0;
808
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000809 // The first 10 BackReferences in a mangled name can be back-referenced by
810 // special name @[0-9]. This is a storage for the first 10 BackReferences.
811 StringView BackReferences[10];
812 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000813};
814} // namespace
815
816// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000817Symbol *Demangler::parse(StringView &MangledName) {
818 Symbol *S = Arena.alloc<Symbol>();
819
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000820 // MSVC-style mangled symbols must start with '?'.
821 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000822 S->SymbolName = Arena.alloc<Name>();
823 S->SymbolName->Str = MangledName;
824 S->SymbolType = Arena.alloc<Type>();
825 S->SymbolType->Prim = PrimTy::Unknown;
826 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000827 }
828
829 // What follows is a main symbol name. This may include
830 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000831 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000832
833 // Read a variable.
Zachary Turner316109b2018-07-29 16:38:02 +0000834 S->SymbolType = startsWithDigit(MangledName)
835 ? demangleVariableEncoding(MangledName)
836 : demangleFunctionEncoding(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000837
Zachary Turner316109b2018-07-29 16:38:02 +0000838 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000839}
840
841// <type-encoding> ::= <storage-class> <variable-type>
842// <storage-class> ::= 0 # private static member
843// ::= 1 # protected static member
844// ::= 2 # public static member
845// ::= 3 # global
846// ::= 4 # static local
847
Zachary Turner316109b2018-07-29 16:38:02 +0000848Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
849 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000850
Zachary Turner316109b2018-07-29 16:38:02 +0000851 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000852
853 Ty->Storage = SC;
854
855 // <variable-type> ::= <type> <cvr-qualifiers>
856 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
857 switch (Ty->Prim) {
858 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000859 case PrimTy::Ref:
860 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000861 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +0000862 Ty->Quals =
863 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000864
Zachary Turnerd742d642018-07-26 19:56:09 +0000865 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +0000866 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000867
Zachary Turnerd742d642018-07-26 19:56:09 +0000868 if (Ty->Prim == PrimTy::MemberPtr) {
869 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +0000870 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000871 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000872 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
873 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
874 } else {
875 PointerType *PTy = static_cast<PointerType *>(Ty);
876 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000877 }
878
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000879 break;
880 }
881 default:
Zachary Turner316109b2018-07-29 16:38:02 +0000882 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000883 break;
884 }
885
886 return Ty;
887}
888
889// Sometimes numbers are encoded in mangled symbols. For example,
890// "int (*x)[20]" is a valid C type (x is a pointer to an array of
891// length 20), so we need some way to embed numbers as part of symbols.
892// This function parses it.
893//
894// <number> ::= [?] <non-negative integer>
895//
896// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
897// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
898//
899// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +0000900int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000901 bool neg = MangledName.consumeFront("?");
902
903 if (startsWithDigit(MangledName)) {
904 int32_t Ret = MangledName[0] - '0' + 1;
905 MangledName = MangledName.dropFront(1);
906 return neg ? -Ret : Ret;
907 }
908
909 int Ret = 0;
910 for (size_t i = 0; i < MangledName.size(); ++i) {
911 char C = MangledName[i];
912 if (C == '@') {
913 MangledName = MangledName.dropFront(i + 1);
914 return neg ? -Ret : Ret;
915 }
916 if ('A' <= C && C <= 'P') {
917 Ret = (Ret << 4) + (C - 'A');
918 continue;
919 }
920 break;
921 }
922
923 Error = true;
924 return 0;
925}
926
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000927// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
928// Memorize it.
929void Demangler::memorizeString(StringView S) {
930 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
931 return;
932 for (size_t i = 0; i < BackRefCount; ++i)
933 if (S == BackReferences[i])
934 return;
935 BackReferences[BackRefCount++] = S;
936}
937
Zachary Turner316109b2018-07-29 16:38:02 +0000938Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000939 assert(startsWithDigit(MangledName));
940
941 size_t I = MangledName[0] - '0';
942 if (I >= BackRefCount) {
943 Error = true;
944 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000945 }
Zachary Turnera7dffb12018-07-28 22:10:42 +0000946
947 MangledName = MangledName.dropFront();
948 Name *Node = Arena.alloc<Name>();
949 Node->Str = BackReferences[I];
950 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000951}
952
Zachary Turner316109b2018-07-29 16:38:02 +0000953Name *Demangler::demangleClassTemplateName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000954 assert(MangledName.startsWith("?$"));
955 MangledName.consumeFront("?$");
956
Zachary Turner316109b2018-07-29 16:38:02 +0000957 Name *Node = demangleSimpleName(MangledName, false);
958 Node->TemplateParams = demangleTemplateParameterList(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000959 return Node;
960}
961
Zachary Turner316109b2018-07-29 16:38:02 +0000962Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000963 assert(MangledName.startsWith('?'));
964 MangledName.consumeFront('?');
965
Zachary Turner316109b2018-07-29 16:38:02 +0000966 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000967 switch (MangledName.popFront()) {
968 case '0':
969 return "ctor";
970 case '1':
971 return "dtor";
972 case '2':
973 return " new";
974 case '3':
975 return " delete";
976 case '4':
977 return "=";
978 case '5':
979 return ">>";
980 case '6':
981 return "<<";
982 case '7':
983 return "!";
984 case '8':
985 return "==";
986 case '9':
987 return "!=";
988 case 'A':
989 return "[]";
990 case 'C':
991 return "->";
992 case 'D':
993 return "*";
994 case 'E':
995 return "++";
996 case 'F':
997 return "--";
998 case 'G':
999 return "-";
1000 case 'H':
1001 return "+";
1002 case 'I':
1003 return "&";
1004 case 'J':
1005 return "->*";
1006 case 'K':
1007 return "/";
1008 case 'L':
1009 return "%";
1010 case 'M':
1011 return "<";
1012 case 'N':
1013 return "<=";
1014 case 'O':
1015 return ">";
1016 case 'P':
1017 return ">=";
1018 case 'Q':
1019 return ",";
1020 case 'R':
1021 return "()";
1022 case 'S':
1023 return "~";
1024 case 'T':
1025 return "^";
1026 case 'U':
1027 return "|";
1028 case 'V':
1029 return "&&";
1030 case 'W':
1031 return "||";
1032 case 'X':
1033 return "*=";
1034 case 'Y':
1035 return "+=";
1036 case 'Z':
1037 return "-=";
1038 case '_': {
1039 if (MangledName.empty())
1040 break;
1041
1042 switch (MangledName.popFront()) {
1043 case '0':
1044 return "/=";
1045 case '1':
1046 return "%=";
1047 case '2':
1048 return ">>=";
1049 case '3':
1050 return "<<=";
1051 case '4':
1052 return "&=";
1053 case '5':
1054 return "|=";
1055 case '6':
1056 return "^=";
1057 case 'U':
1058 return " new[]";
1059 case 'V':
1060 return " delete[]";
1061 case '_':
1062 if (MangledName.consumeFront("L"))
1063 return " co_await";
1064 }
1065 }
1066 }
1067 Error = true;
1068 return "";
1069 };
1070
1071 Name *Node = Arena.alloc<Name>();
1072 Node->Operator = NameString();
1073 return Node;
1074}
1075
Zachary Turner316109b2018-07-29 16:38:02 +00001076Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001077 Name *Node = Arena.alloc<Name>();
1078 for (size_t i = 0; i < MangledName.size(); ++i) {
1079 if (MangledName[i] != '@')
1080 continue;
1081 Node->Str = MangledName.substr(0, i);
1082 MangledName = MangledName.dropFront(i + 1);
1083
1084 if (Memorize)
1085 memorizeString(Node->Str);
1086 return Node;
1087 }
1088
1089 Error = true;
1090 return nullptr;
1091}
1092
Zachary Turner316109b2018-07-29 16:38:02 +00001093Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001094 assert(MangledName.startsWith("?A"));
1095 MangledName.consumeFront("?A");
1096
1097 Name *Node = Arena.alloc<Name>();
1098 Node->Str = "`anonymous namespace'";
1099 if (MangledName.consumeFront('@'))
1100 return Node;
1101
1102 Error = true;
1103 return nullptr;
1104}
1105
1106// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001107Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
1108 Name *TypeName = demangleUnqualifiedTypeName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001109 assert(TypeName);
1110
Zachary Turner316109b2018-07-29 16:38:02 +00001111 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001112 assert(QualName);
1113 return QualName;
1114}
1115
1116// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1117// Symbol names have slightly different rules regarding what can appear
1118// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001119Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
1120 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001121 assert(SymbolName);
1122
Zachary Turner316109b2018-07-29 16:38:02 +00001123 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001124 assert(QualName);
1125 return QualName;
1126}
1127
Zachary Turner316109b2018-07-29 16:38:02 +00001128Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001129 // An inner-most name can be a back-reference, because a fully-qualified name
1130 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1131 // them (for example template parameters), and these nested parameters can
1132 // refer to previously mangled types.
1133 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001134 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001135
1136 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001137 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001138
Zachary Turner316109b2018-07-29 16:38:02 +00001139 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001140}
1141
Zachary Turner316109b2018-07-29 16:38:02 +00001142Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001143 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001144 return demangleOperatorName(MangledName);
1145 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001146}
1147
Zachary Turner316109b2018-07-29 16:38:02 +00001148Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001149 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001150 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001151
1152 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001153 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001154
1155 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001156 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001157
Zachary Turner316109b2018-07-29 16:38:02 +00001158 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001159}
1160
Zachary Turner316109b2018-07-29 16:38:02 +00001161Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1162 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001163 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001164
1165 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001166 if (MangledName.empty()) {
1167 Error = true;
1168 return nullptr;
1169 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001170
1171 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001172 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001173 if (Error)
1174 return nullptr;
1175
1176 Elem->Next = Head;
1177 Head = Elem;
1178 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001179 return Head;
1180}
1181
Zachary Turner316109b2018-07-29 16:38:02 +00001182FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001183 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1184 RestoreOnError.shouldRestore(false);
1185
1186 switch (MangledName.popFront()) {
1187 case 'A':
1188 return Private;
1189 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001190 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001191 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001192 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001193 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001194 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001195 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001196 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001197 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001198 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001199 case 'I':
1200 return Protected;
1201 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001202 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001203 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001204 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001205 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001206 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001207 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001208 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001209 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001210 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001211 case 'Q':
1212 return Public;
1213 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001214 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001215 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001216 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001217 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001218 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001219 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001220 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001221 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001222 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001223 case 'Y':
1224 return Global;
1225 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001226 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001227 }
1228
1229 Error = true;
1230 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001231 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001232}
1233
Zachary Turner316109b2018-07-29 16:38:02 +00001234CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001235 switch (MangledName.popFront()) {
1236 case 'A':
1237 case 'B':
1238 return CallingConv::Cdecl;
1239 case 'C':
1240 case 'D':
1241 return CallingConv::Pascal;
1242 case 'E':
1243 case 'F':
1244 return CallingConv::Thiscall;
1245 case 'G':
1246 case 'H':
1247 return CallingConv::Stdcall;
1248 case 'I':
1249 case 'J':
1250 return CallingConv::Fastcall;
1251 case 'M':
1252 case 'N':
1253 return CallingConv::Clrcall;
1254 case 'O':
1255 case 'P':
1256 return CallingConv::Eabi;
1257 case 'Q':
1258 return CallingConv::Vectorcall;
1259 }
1260
1261 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001262}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001263
Zachary Turner316109b2018-07-29 16:38:02 +00001264StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001265 assert(std::isdigit(MangledName.front()));
1266
1267 switch (MangledName.popFront()) {
1268 case '0':
1269 return StorageClass::PrivateStatic;
1270 case '1':
1271 return StorageClass::ProtectedStatic;
1272 case '2':
1273 return StorageClass::PublicStatic;
1274 case '3':
1275 return StorageClass::Global;
1276 case '4':
1277 return StorageClass::FunctionLocalStatic;
1278 }
1279 Error = true;
1280 return StorageClass::None;
1281}
1282
Zachary Turner316109b2018-07-29 16:38:02 +00001283std::pair<Qualifiers, bool>
1284Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001285
1286 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001287 // Member qualifiers
1288 case 'Q':
1289 return std::make_pair(Q_None, true);
1290 case 'R':
1291 return std::make_pair(Q_Const, true);
1292 case 'S':
1293 return std::make_pair(Q_Volatile, true);
1294 case 'T':
1295 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1296 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001297 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001298 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001299 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001300 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001301 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001302 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001303 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001304 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001305 }
1306 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001307 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001308}
1309
1310// <variable-type> ::= <type> <cvr-qualifiers>
1311// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001312Type *Demangler::demangleType(StringView &MangledName,
1313 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001314 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001315 bool IsMember = false;
1316 bool IsMemberKnown = false;
1317 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001318 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001319 IsMemberKnown = true;
1320 } else if (QMM == QualifierMangleMode::Result) {
1321 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001322 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001323 IsMemberKnown = true;
1324 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001325 }
1326
1327 Type *Ty = nullptr;
1328 switch (MangledName.front()) {
1329 case 'T': // union
1330 case 'U': // struct
1331 case 'V': // class
1332 case 'W': // enum
Zachary Turner316109b2018-07-29 16:38:02 +00001333 Ty = demangleClassType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001334 break;
1335 case 'A': // foo &
1336 case 'P': // foo *
1337 case 'Q': // foo *const
1338 case 'R': // foo *volatile
1339 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001340 if (!IsMemberKnown)
1341 IsMember = isMemberPointer(MangledName);
1342 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001343 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001344 else
Zachary Turner316109b2018-07-29 16:38:02 +00001345 Ty = demanglePointerType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001346 break;
1347 case 'Y':
Zachary Turner316109b2018-07-29 16:38:02 +00001348 Ty = demangleArrayType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001349 break;
1350 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001351 Ty = demangleBasicType(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001352 break;
1353 }
1354 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1355 return Ty;
1356}
1357
Zachary Turner316109b2018-07-29 16:38:02 +00001358ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001359 if (MangledName.consumeFront('G'))
1360 return ReferenceKind::LValueRef;
1361 else if (MangledName.consumeFront('H'))
1362 return ReferenceKind::RValueRef;
1363 return ReferenceKind::None;
1364}
1365
Zachary Turner316109b2018-07-29 16:38:02 +00001366void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001367 if (MangledName.consumeFront('Z'))
1368 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001369
Zachary Turner38b78a72018-07-26 20:20:10 +00001370 Error = true;
1371}
1372
Zachary Turner316109b2018-07-29 16:38:02 +00001373FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1374 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001375 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001376 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001377 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001378 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001379
1380 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001381 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1382 FTy->RefKind = demangleReferenceKind(MangledName);
1383 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001384 }
1385
1386 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001387 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001388
1389 // <return-type> ::= <type>
1390 // ::= @ # structors (they have no declared return type)
1391 bool IsStructor = MangledName.consumeFront('@');
1392 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001393 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001394
Zachary Turner316109b2018-07-29 16:38:02 +00001395 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001396
Zachary Turner316109b2018-07-29 16:38:02 +00001397 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001398
1399 return FTy;
1400}
1401
Zachary Turner316109b2018-07-29 16:38:02 +00001402Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1403 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001404
1405 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001406 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001407 FTy->FunctionClass = FC;
1408
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001409 return FTy;
1410}
1411
1412// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001413Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001414 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001415
1416 switch (MangledName.popFront()) {
1417 case 'X':
1418 Ty->Prim = PrimTy::Void;
1419 break;
1420 case 'D':
1421 Ty->Prim = PrimTy::Char;
1422 break;
1423 case 'C':
1424 Ty->Prim = PrimTy::Schar;
1425 break;
1426 case 'E':
1427 Ty->Prim = PrimTy::Uchar;
1428 break;
1429 case 'F':
1430 Ty->Prim = PrimTy::Short;
1431 break;
1432 case 'G':
1433 Ty->Prim = PrimTy::Ushort;
1434 break;
1435 case 'H':
1436 Ty->Prim = PrimTy::Int;
1437 break;
1438 case 'I':
1439 Ty->Prim = PrimTy::Uint;
1440 break;
1441 case 'J':
1442 Ty->Prim = PrimTy::Long;
1443 break;
1444 case 'K':
1445 Ty->Prim = PrimTy::Ulong;
1446 break;
1447 case 'M':
1448 Ty->Prim = PrimTy::Float;
1449 break;
1450 case 'N':
1451 Ty->Prim = PrimTy::Double;
1452 break;
1453 case 'O':
1454 Ty->Prim = PrimTy::Ldouble;
1455 break;
1456 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001457 if (MangledName.empty()) {
1458 Error = true;
1459 return nullptr;
1460 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001461 switch (MangledName.popFront()) {
1462 case 'N':
1463 Ty->Prim = PrimTy::Bool;
1464 break;
1465 case 'J':
1466 Ty->Prim = PrimTy::Int64;
1467 break;
1468 case 'K':
1469 Ty->Prim = PrimTy::Uint64;
1470 break;
1471 case 'W':
1472 Ty->Prim = PrimTy::Wchar;
1473 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001474 default:
1475 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001476 }
1477 break;
1478 }
1479 }
1480 return Ty;
1481}
1482
Zachary Turner316109b2018-07-29 16:38:02 +00001483UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001484 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001485
1486 switch (MangledName.popFront()) {
1487 case 'T':
1488 UTy->Prim = PrimTy::Union;
1489 break;
1490 case 'U':
1491 UTy->Prim = PrimTy::Struct;
1492 break;
1493 case 'V':
1494 UTy->Prim = PrimTy::Class;
1495 break;
1496 case 'W':
1497 if (MangledName.popFront() != '4') {
1498 Error = true;
1499 return nullptr;
1500 }
1501 UTy->Prim = PrimTy::Enum;
1502 break;
1503 default:
1504 assert(false);
1505 }
1506
Zachary Turner316109b2018-07-29 16:38:02 +00001507 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001508 return UTy;
1509}
1510
Zachary Turnerd742d642018-07-26 19:56:09 +00001511static std::pair<Qualifiers, PointerAffinity>
1512demanglePointerCVQualifiers(StringView &MangledName) {
1513 switch (MangledName.popFront()) {
1514 case 'A':
1515 return std::make_pair(Q_None, PointerAffinity::Reference);
1516 case 'P':
1517 return std::make_pair(Q_None, PointerAffinity::Pointer);
1518 case 'Q':
1519 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1520 case 'R':
1521 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1522 case 'S':
1523 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1524 PointerAffinity::Pointer);
1525 default:
1526 assert(false && "Ty is not a pointer type!");
1527 }
1528 return std::make_pair(Q_None, PointerAffinity::Pointer);
1529}
1530
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001531// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1532// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001533PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001534 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001535
Zachary Turnerd742d642018-07-26 19:56:09 +00001536 PointerAffinity Affinity;
1537 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001538
Zachary Turnerd742d642018-07-26 19:56:09 +00001539 Pointer->Prim =
1540 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001541 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001542 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001543 return Pointer;
1544 }
1545
Zachary Turner316109b2018-07-29 16:38:02 +00001546 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001547 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1548
Zachary Turner316109b2018-07-29 16:38:02 +00001549 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001550 return Pointer;
1551}
1552
Zachary Turner316109b2018-07-29 16:38:02 +00001553MemberPointerType *
1554Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001555 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1556 Pointer->Prim = PrimTy::MemberPtr;
1557
1558 PointerAffinity Affinity;
1559 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1560 assert(Affinity == PointerAffinity::Pointer);
1561
Zachary Turner316109b2018-07-29 16:38:02 +00001562 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001563 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1564
Zachary Turner38b78a72018-07-26 20:20:10 +00001565 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001566 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1567 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001568 } else {
1569 Qualifiers PointeeQuals = Q_None;
1570 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001571 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001572 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001573 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001574
Zachary Turner316109b2018-07-29 16:38:02 +00001575 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001576 Pointer->Pointee->Quals = PointeeQuals;
1577 }
1578
Zachary Turnerd742d642018-07-26 19:56:09 +00001579 return Pointer;
1580}
1581
Zachary Turner316109b2018-07-29 16:38:02 +00001582Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001583 Qualifiers Quals = Q_None;
1584 if (MangledName.consumeFront('E'))
1585 Quals = Qualifiers(Quals | Q_Pointer64);
1586 if (MangledName.consumeFront('I'))
1587 Quals = Qualifiers(Quals | Q_Restrict);
1588 if (MangledName.consumeFront('F'))
1589 Quals = Qualifiers(Quals | Q_Unaligned);
1590
1591 return Quals;
1592}
1593
Zachary Turner316109b2018-07-29 16:38:02 +00001594ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001595 assert(MangledName.front() == 'Y');
1596 MangledName.popFront();
1597
Zachary Turner316109b2018-07-29 16:38:02 +00001598 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001599 if (Dimension <= 0) {
1600 Error = true;
1601 return nullptr;
1602 }
1603
Zachary Turner9d72aa92018-07-20 18:35:06 +00001604 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001605 ArrayType *Dim = ATy;
1606 for (int I = 0; I < Dimension; ++I) {
1607 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001608 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001609 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001610 Dim = Dim->NextDimension;
1611 }
1612
1613 if (MangledName.consumeFront("$$C")) {
1614 if (MangledName.consumeFront("B"))
1615 ATy->Quals = Q_Const;
1616 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1617 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1618 else if (!MangledName.consumeFront("A"))
1619 Error = true;
1620 }
1621
Zachary Turner316109b2018-07-29 16:38:02 +00001622 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001623 Dim->ElementType = ATy->ElementType;
1624 return ATy;
1625}
1626
1627// Reads a function or a template parameters.
Zachary Turner316109b2018-07-29 16:38:02 +00001628ParamList Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001629 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001630 if (MangledName.consumeFront('X'))
1631 return {};
1632
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001633 ParamList *Head;
1634 ParamList **Current = &Head;
1635 while (!Error && !MangledName.startsWith('@') &&
1636 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001637
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001638 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001639 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001640 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001641 Error = true;
1642 return {};
1643 }
1644 MangledName = MangledName.dropFront();
1645
Zachary Turner9d72aa92018-07-20 18:35:06 +00001646 *Current = Arena.alloc<ParamList>();
Zachary Turner23df1312018-07-26 22:13:39 +00001647 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001648 Current = &(*Current)->Next;
1649 continue;
1650 }
1651
Zachary Turner23df1312018-07-26 22:13:39 +00001652 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001653
Zachary Turner9d72aa92018-07-20 18:35:06 +00001654 *Current = Arena.alloc<ParamList>();
Zachary Turner316109b2018-07-29 16:38:02 +00001655 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001656
Zachary Turner23df1312018-07-26 22:13:39 +00001657 size_t CharsConsumed = OldSize - MangledName.size();
1658 assert(CharsConsumed != 0);
1659
1660 // Single-letter types are ignored for backreferences because memorizing
1661 // them doesn't save anything.
1662 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1663 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1664
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001665 Current = &(*Current)->Next;
1666 }
1667
Zachary Turner38b78a72018-07-26 20:20:10 +00001668 if (Error)
1669 return {};
1670
1671 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1672 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1673 // the following Z could be a throw specifier.
1674 if (MangledName.consumeFront('@'))
1675 return *Head;
1676
1677 if (MangledName.consumeFront('Z')) {
1678 Head->IsVariadic = true;
1679 return *Head;
1680 }
1681
1682 Error = true;
1683 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001684}
1685
Zachary Turner316109b2018-07-29 16:38:02 +00001686ParamList Demangler::demangleTemplateParameterList(StringView &MangledName) {
Zachary Turner23df1312018-07-26 22:13:39 +00001687 ParamList *Head;
1688 ParamList **Current = &Head;
1689 while (!Error && !MangledName.startsWith('@')) {
1690
1691 // Template parameter lists don't participate in back-referencing.
1692 *Current = Arena.alloc<ParamList>();
Zachary Turner316109b2018-07-29 16:38:02 +00001693 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner23df1312018-07-26 22:13:39 +00001694
1695 Current = &(*Current)->Next;
1696 }
1697
1698 if (Error)
1699 return {};
1700
1701 // Template parameter lists cannot be variadic, so it can only be terminated
1702 // by @.
1703 if (MangledName.consumeFront('@'))
1704 return *Head;
1705 Error = true;
1706 return {};
1707}
1708
Zachary Turner316109b2018-07-29 16:38:02 +00001709void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001710 // Converts an AST to a string.
1711 //
1712 // Converting an AST representing a C++ type to a string is tricky due
1713 // to the bad grammar of the C++ declaration inherited from C. You have
1714 // to construct a string from inside to outside. For example, if a type
1715 // X is a pointer to a function returning int, the order you create a
1716 // string becomes something like this:
1717 //
1718 // (1) X is a pointer: *X
1719 // (2) (1) is a function returning int: int (*X)()
1720 //
1721 // So you cannot construct a result just by appending strings to a result.
1722 //
1723 // To deal with this, we split the function into two. outputPre() writes
1724 // the "first half" of type declaration, and outputPost() writes the
1725 // "second half". For example, outputPre() writes a return type for a
1726 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00001727 Type::outputPre(OS, *S->SymbolType);
1728 outputName(OS, S->SymbolName);
1729 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001730
1731 // Null terminate the buffer.
1732 OS << '\0';
1733}
1734
1735char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1736 int *Status) {
Zachary Turner316109b2018-07-29 16:38:02 +00001737 Demangler D;
1738 StringView Name{MangledName};
1739 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001740
1741 if (D.Error)
1742 *Status = llvm::demangle_invalid_mangled_name;
1743 else
1744 *Status = llvm::demangle_success;
1745
Zachary Turner316109b2018-07-29 16:38:02 +00001746 OutputStream OS = OutputStream::create(Buf, N, 1024);
1747 D.output(S, OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001748 return OS.getBuffer();
1749}