blob: 7d95dedafaa11b4e7280247182534deea9dc4757 [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
423 // Print out namespaces or outer class BackReferences.
424 for (; TheName->Next; TheName = TheName->Next) {
425 OS << TheName->Str;
426 outputTemplateParams(OS, *TheName);
427 OS << "::";
428 }
429
430 // Print out a regular name.
431 if (TheName->Operator.empty()) {
432 OS << TheName->Str;
433 outputTemplateParams(OS, *TheName);
434 return;
435 }
436
437 // Print out ctor or dtor.
438 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
439 OS << TheName->Str;
440 outputTemplateParams(OS, *TheName);
441 OS << "::";
442 if (TheName->Operator == "dtor")
443 OS << "~";
444 OS << TheName->Str;
445 outputTemplateParams(OS, *TheName);
446 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
719} // namespace
720
721namespace {
722
723// Demangler class takes the main role in demangling symbols.
724// It has a set of functions to parse mangled symbols into Type instances.
725// It also has a set of functions to cnovert Type instances to strings.
726class Demangler {
727public:
728 Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
729
730 // You are supposed to call parse() first and then check if error is true. If
731 // it is false, call output() to write the formatted name to the given stream.
732 void parse();
733 void output();
734
735 // True if an error occurred.
736 bool Error = false;
737
738private:
739 Type *demangleVariableEncoding();
740 Type *demangleFunctionEncoding();
741
742 Qualifiers demanglePointerExtQualifiers();
743
744 // Parser functions. This is a recursive-descent parser.
745 Type *demangleType(QualifierMangleMode QMM);
746 Type *demangleBasicType();
747 UdtType *demangleClassType();
748 PointerType *demanglePointerType();
Zachary Turnerd742d642018-07-26 19:56:09 +0000749 MemberPointerType *demangleMemberPointerType();
Zachary Turner024e1762018-07-26 20:33:48 +0000750 FunctionType *demangleFunctionType(bool HasThisQuals, bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000751
752 ArrayType *demangleArrayType();
753
754 ParamList demangleParameterList();
755
756 int demangleNumber();
757 void demangleNamePiece(Name &Node, bool IsHead);
758
759 StringView demangleString(bool memorize);
760 void memorizeString(StringView s);
761 Name *demangleName();
762 void demangleOperator(Name *);
763 StringView demangleOperatorName();
Zachary Turner38b78a72018-07-26 20:20:10 +0000764 FuncClass demangleFunctionClass();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000765 CallingConv demangleCallingConvention();
766 StorageClass demangleVariableStorageClass();
767 ReferenceKind demangleReferenceKind();
Zachary Turner38b78a72018-07-26 20:20:10 +0000768 void demangleThrowSpecification();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000769
Zachary Turnerd742d642018-07-26 19:56:09 +0000770 std::pair<Qualifiers, bool> demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000771
Zachary Turner91ecedd2018-07-20 18:07:33 +0000772 // The result is written to this stream.
773 OutputStream OS;
774
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000775 // Mangled symbol. demangle* functions shorten this string
776 // as they parse it.
777 StringView MangledName;
778
779 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000780 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000781
782 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
783 Name *SymbolName = nullptr;
784
785 // Memory allocator.
786 ArenaAllocator Arena;
787
788 // The first 10 BackReferences in a mangled name can be back-referenced by
789 // special name @[0-9]. This is a storage for the first 10 BackReferences.
790 StringView BackReferences[10];
791 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000792};
793} // namespace
794
795// Parser entry point.
796void Demangler::parse() {
797 // MSVC-style mangled symbols must start with '?'.
798 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000799 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000800 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000801 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000802 SymbolType->Prim = PrimTy::Unknown;
803 }
804
805 // What follows is a main symbol name. This may include
806 // namespaces or class BackReferences.
807 SymbolName = demangleName();
808
809 // Read a variable.
810 if (startsWithDigit(MangledName)) {
811 SymbolType = demangleVariableEncoding();
812 return;
813 }
814
815 // Read a function.
816 SymbolType = demangleFunctionEncoding();
817}
818
819// <type-encoding> ::= <storage-class> <variable-type>
820// <storage-class> ::= 0 # private static member
821// ::= 1 # protected static member
822// ::= 2 # public static member
823// ::= 3 # global
824// ::= 4 # static local
825
826Type *Demangler::demangleVariableEncoding() {
827 StorageClass SC = demangleVariableStorageClass();
828
829 Type *Ty = demangleType(QualifierMangleMode::Drop);
830
831 Ty->Storage = SC;
832
833 // <variable-type> ::= <type> <cvr-qualifiers>
834 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
835 switch (Ty->Prim) {
836 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000837 case PrimTy::Ref:
838 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000839 Qualifiers ExtraChildQuals = Q_None;
840 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
841
Zachary Turnerd742d642018-07-26 19:56:09 +0000842 bool IsMember = false;
843 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000844
Zachary Turnerd742d642018-07-26 19:56:09 +0000845 if (Ty->Prim == PrimTy::MemberPtr) {
846 assert(IsMember);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000847 Name *BackRefName = demangleName();
848 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000849 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
850 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
851 } else {
852 PointerType *PTy = static_cast<PointerType *>(Ty);
853 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000854 }
855
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000856 break;
857 }
858 default:
Zachary Turnerd742d642018-07-26 19:56:09 +0000859 Ty->Quals = demangleQualifiers().first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000860 break;
861 }
862
863 return Ty;
864}
865
866// Sometimes numbers are encoded in mangled symbols. For example,
867// "int (*x)[20]" is a valid C type (x is a pointer to an array of
868// length 20), so we need some way to embed numbers as part of symbols.
869// This function parses it.
870//
871// <number> ::= [?] <non-negative integer>
872//
873// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
874// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
875//
876// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
877int Demangler::demangleNumber() {
878 bool neg = MangledName.consumeFront("?");
879
880 if (startsWithDigit(MangledName)) {
881 int32_t Ret = MangledName[0] - '0' + 1;
882 MangledName = MangledName.dropFront(1);
883 return neg ? -Ret : Ret;
884 }
885
886 int Ret = 0;
887 for (size_t i = 0; i < MangledName.size(); ++i) {
888 char C = MangledName[i];
889 if (C == '@') {
890 MangledName = MangledName.dropFront(i + 1);
891 return neg ? -Ret : Ret;
892 }
893 if ('A' <= C && C <= 'P') {
894 Ret = (Ret << 4) + (C - 'A');
895 continue;
896 }
897 break;
898 }
899
900 Error = true;
901 return 0;
902}
903
904// Read until the next '@'.
905StringView Demangler::demangleString(bool Memorize) {
906 for (size_t i = 0; i < MangledName.size(); ++i) {
907 if (MangledName[i] != '@')
908 continue;
909 StringView ret = MangledName.substr(0, i);
910 MangledName = MangledName.dropFront(i + 1);
911
912 if (Memorize)
913 memorizeString(ret);
914 return ret;
915 }
916
917 Error = true;
918 return "";
919}
920
921// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
922// Memorize it.
923void Demangler::memorizeString(StringView S) {
924 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
925 return;
926 for (size_t i = 0; i < BackRefCount; ++i)
927 if (S == BackReferences[i])
928 return;
929 BackReferences[BackRefCount++] = S;
930}
931
932void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
933 if (startsWithDigit(MangledName)) {
934 size_t I = MangledName[0] - '0';
935 if (I >= BackRefCount) {
936 Error = true;
937 return;
938 }
939 MangledName = MangledName.dropFront();
940 Node.Str = BackReferences[I];
941 } else if (MangledName.consumeFront("?$")) {
942 // Class template.
943 Node.Str = demangleString(false);
944 Node.TemplateParams = demangleParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000945 } else if (!IsHead && MangledName.consumeFront("?A")) {
946 // Anonymous namespace starts with ?A. So does overloaded operator[],
947 // but the distinguishing factor is that namespace themselves are not
948 // mangled, only the variables and functions inside of them are. So
949 // an anonymous namespace will never occur as the first item in the
950 // name.
951 Node.Str = "`anonymous namespace'";
952 if (!MangledName.consumeFront('@')) {
953 Error = true;
954 return;
955 }
956 } else if (MangledName.consumeFront("?")) {
957 // Overloaded operator.
958 demangleOperator(&Node);
959 } else {
960 // Non-template functions or classes.
961 Node.Str = demangleString(true);
962 }
963}
964
965// Parses a name in the form of A@B@C@@ which represents C::B::A.
966Name *Demangler::demangleName() {
967 Name *Head = nullptr;
968
969 while (!MangledName.consumeFront("@")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000970 Name *Elem = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000971
972 assert(!Error);
973 demangleNamePiece(*Elem, Head == nullptr);
974 if (Error)
975 return nullptr;
976
977 Elem->Next = Head;
978 Head = Elem;
Zachary Turnerd742d642018-07-26 19:56:09 +0000979 if (MangledName.empty()) {
980 Error = true;
981 return nullptr;
982 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000983 }
984
985 return Head;
986}
987
988void Demangler::demangleOperator(Name *OpName) {
989 OpName->Operator = demangleOperatorName();
990 if (!Error && !MangledName.empty() && MangledName.front() != '@')
991 demangleNamePiece(*OpName, false);
992}
993
994StringView Demangler::demangleOperatorName() {
995 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
996 RestoreOnError.shouldRestore(false);
997
998 switch (MangledName.popFront()) {
999 case '0':
1000 return "ctor";
1001 case '1':
1002 return "dtor";
1003 case '2':
1004 return " new";
1005 case '3':
1006 return " delete";
1007 case '4':
1008 return "=";
1009 case '5':
1010 return ">>";
1011 case '6':
1012 return "<<";
1013 case '7':
1014 return "!";
1015 case '8':
1016 return "==";
1017 case '9':
1018 return "!=";
1019 case 'A':
1020 return "[]";
1021 case 'C':
1022 return "->";
1023 case 'D':
1024 return "*";
1025 case 'E':
1026 return "++";
1027 case 'F':
1028 return "--";
1029 case 'G':
1030 return "-";
1031 case 'H':
1032 return "+";
1033 case 'I':
1034 return "&";
1035 case 'J':
1036 return "->*";
1037 case 'K':
1038 return "/";
1039 case 'L':
1040 return "%";
1041 case 'M':
1042 return "<";
1043 case 'N':
1044 return "<=";
1045 case 'O':
1046 return ">";
1047 case 'P':
1048 return ">=";
1049 case 'Q':
1050 return ",";
1051 case 'R':
1052 return "()";
1053 case 'S':
1054 return "~";
1055 case 'T':
1056 return "^";
1057 case 'U':
1058 return "|";
1059 case 'V':
1060 return "&&";
1061 case 'W':
1062 return "||";
1063 case 'X':
1064 return "*=";
1065 case 'Y':
1066 return "+=";
1067 case 'Z':
1068 return "-=";
1069 case '_': {
1070 if (MangledName.empty())
1071 break;
1072
1073 switch (MangledName.popFront()) {
1074 case '0':
1075 return "/=";
1076 case '1':
1077 return "%=";
1078 case '2':
1079 return ">>=";
1080 case '3':
1081 return "<<=";
1082 case '4':
1083 return "&=";
1084 case '5':
1085 return "|=";
1086 case '6':
1087 return "^=";
1088 case 'U':
1089 return " new[]";
1090 case 'V':
1091 return " delete[]";
1092 case '_':
1093 if (MangledName.consumeFront("L"))
1094 return " co_await";
1095 }
1096 }
1097 }
1098
1099 Error = true;
1100 RestoreOnError.shouldRestore(true);
1101 return "";
1102}
1103
Zachary Turner38b78a72018-07-26 20:20:10 +00001104FuncClass Demangler::demangleFunctionClass() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1106 RestoreOnError.shouldRestore(false);
1107
1108 switch (MangledName.popFront()) {
1109 case 'A':
1110 return Private;
1111 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001112 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001113 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001114 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001115 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001116 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001117 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001118 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001119 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001120 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001121 case 'I':
1122 return Protected;
1123 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001124 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001125 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001126 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001127 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001128 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001129 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001130 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001131 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001132 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001133 case 'Q':
1134 return Public;
1135 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001136 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001137 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001138 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001139 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001140 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001141 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001142 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001143 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001144 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001145 case 'Y':
1146 return Global;
1147 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001148 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001149 }
1150
1151 Error = true;
1152 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001153 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001154}
1155
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001156CallingConv Demangler::demangleCallingConvention() {
1157 switch (MangledName.popFront()) {
1158 case 'A':
1159 case 'B':
1160 return CallingConv::Cdecl;
1161 case 'C':
1162 case 'D':
1163 return CallingConv::Pascal;
1164 case 'E':
1165 case 'F':
1166 return CallingConv::Thiscall;
1167 case 'G':
1168 case 'H':
1169 return CallingConv::Stdcall;
1170 case 'I':
1171 case 'J':
1172 return CallingConv::Fastcall;
1173 case 'M':
1174 case 'N':
1175 return CallingConv::Clrcall;
1176 case 'O':
1177 case 'P':
1178 return CallingConv::Eabi;
1179 case 'Q':
1180 return CallingConv::Vectorcall;
1181 }
1182
1183 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001184}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001185
1186StorageClass Demangler::demangleVariableStorageClass() {
1187 assert(std::isdigit(MangledName.front()));
1188
1189 switch (MangledName.popFront()) {
1190 case '0':
1191 return StorageClass::PrivateStatic;
1192 case '1':
1193 return StorageClass::ProtectedStatic;
1194 case '2':
1195 return StorageClass::PublicStatic;
1196 case '3':
1197 return StorageClass::Global;
1198 case '4':
1199 return StorageClass::FunctionLocalStatic;
1200 }
1201 Error = true;
1202 return StorageClass::None;
1203}
1204
Zachary Turnerd742d642018-07-26 19:56:09 +00001205std::pair<Qualifiers, bool> Demangler::demangleQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001206
1207 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001208 // Member qualifiers
1209 case 'Q':
1210 return std::make_pair(Q_None, true);
1211 case 'R':
1212 return std::make_pair(Q_Const, true);
1213 case 'S':
1214 return std::make_pair(Q_Volatile, true);
1215 case 'T':
1216 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1217 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001218 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001219 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001220 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001221 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001222 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001223 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001224 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001225 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001226 }
1227 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001228 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001229}
1230
1231// <variable-type> ::= <type> <cvr-qualifiers>
1232// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1233Type *Demangler::demangleType(QualifierMangleMode QMM) {
1234 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001235 bool IsMember = false;
1236 bool IsMemberKnown = false;
1237 if (QMM == QualifierMangleMode::Mangle) {
1238 std::tie(Quals, IsMember) = demangleQualifiers();
1239 IsMemberKnown = true;
1240 } else if (QMM == QualifierMangleMode::Result) {
1241 if (MangledName.consumeFront('?')) {
1242 std::tie(Quals, IsMember) = demangleQualifiers();
1243 IsMemberKnown = true;
1244 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001245 }
1246
1247 Type *Ty = nullptr;
1248 switch (MangledName.front()) {
1249 case 'T': // union
1250 case 'U': // struct
1251 case 'V': // class
1252 case 'W': // enum
1253 Ty = demangleClassType();
1254 break;
1255 case 'A': // foo &
1256 case 'P': // foo *
1257 case 'Q': // foo *const
1258 case 'R': // foo *volatile
1259 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001260 if (!IsMemberKnown)
1261 IsMember = isMemberPointer(MangledName);
1262 if (IsMember)
1263 Ty = demangleMemberPointerType();
1264 else
1265 Ty = demanglePointerType();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001266 break;
1267 case 'Y':
1268 Ty = demangleArrayType();
1269 break;
1270 default:
1271 Ty = demangleBasicType();
1272 break;
1273 }
1274 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1275 return Ty;
1276}
1277
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001278ReferenceKind Demangler::demangleReferenceKind() {
1279 if (MangledName.consumeFront('G'))
1280 return ReferenceKind::LValueRef;
1281 else if (MangledName.consumeFront('H'))
1282 return ReferenceKind::RValueRef;
1283 return ReferenceKind::None;
1284}
1285
Zachary Turner38b78a72018-07-26 20:20:10 +00001286void Demangler::demangleThrowSpecification() {
1287 if (MangledName.consumeFront('Z'))
1288 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001289
Zachary Turner38b78a72018-07-26 20:20:10 +00001290 Error = true;
1291}
1292
Zachary Turner024e1762018-07-26 20:33:48 +00001293FunctionType *Demangler::demangleFunctionType(bool HasThisQuals,
1294 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001295 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001296 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001297 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001298
1299 if (HasThisQuals) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001300 FTy->Quals = demanglePointerExtQualifiers();
1301 FTy->RefKind = demangleReferenceKind();
Zachary Turnerd742d642018-07-26 19:56:09 +00001302 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers().first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001303 }
1304
1305 // Fields that appear on both member and non-member functions.
1306 FTy->CallConvention = demangleCallingConvention();
1307
1308 // <return-type> ::= <type>
1309 // ::= @ # structors (they have no declared return type)
1310 bool IsStructor = MangledName.consumeFront('@');
1311 if (!IsStructor)
1312 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1313
1314 FTy->Params = demangleParameterList();
1315
Zachary Turner38b78a72018-07-26 20:20:10 +00001316 demangleThrowSpecification();
1317
1318 return FTy;
1319}
1320
1321Type *Demangler::demangleFunctionEncoding() {
1322 FuncClass FC = demangleFunctionClass();
1323
1324 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner024e1762018-07-26 20:33:48 +00001325 FunctionType *FTy = demangleFunctionType(HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001326 FTy->FunctionClass = FC;
1327
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001328 return FTy;
1329}
1330
1331// Reads a primitive type.
1332Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001333 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001334
1335 switch (MangledName.popFront()) {
1336 case 'X':
1337 Ty->Prim = PrimTy::Void;
1338 break;
1339 case 'D':
1340 Ty->Prim = PrimTy::Char;
1341 break;
1342 case 'C':
1343 Ty->Prim = PrimTy::Schar;
1344 break;
1345 case 'E':
1346 Ty->Prim = PrimTy::Uchar;
1347 break;
1348 case 'F':
1349 Ty->Prim = PrimTy::Short;
1350 break;
1351 case 'G':
1352 Ty->Prim = PrimTy::Ushort;
1353 break;
1354 case 'H':
1355 Ty->Prim = PrimTy::Int;
1356 break;
1357 case 'I':
1358 Ty->Prim = PrimTy::Uint;
1359 break;
1360 case 'J':
1361 Ty->Prim = PrimTy::Long;
1362 break;
1363 case 'K':
1364 Ty->Prim = PrimTy::Ulong;
1365 break;
1366 case 'M':
1367 Ty->Prim = PrimTy::Float;
1368 break;
1369 case 'N':
1370 Ty->Prim = PrimTy::Double;
1371 break;
1372 case 'O':
1373 Ty->Prim = PrimTy::Ldouble;
1374 break;
1375 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001376 if (MangledName.empty()) {
1377 Error = true;
1378 return nullptr;
1379 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001380 switch (MangledName.popFront()) {
1381 case 'N':
1382 Ty->Prim = PrimTy::Bool;
1383 break;
1384 case 'J':
1385 Ty->Prim = PrimTy::Int64;
1386 break;
1387 case 'K':
1388 Ty->Prim = PrimTy::Uint64;
1389 break;
1390 case 'W':
1391 Ty->Prim = PrimTy::Wchar;
1392 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001393 default:
1394 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001395 }
1396 break;
1397 }
1398 }
1399 return Ty;
1400}
1401
1402UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001403 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001404
1405 switch (MangledName.popFront()) {
1406 case 'T':
1407 UTy->Prim = PrimTy::Union;
1408 break;
1409 case 'U':
1410 UTy->Prim = PrimTy::Struct;
1411 break;
1412 case 'V':
1413 UTy->Prim = PrimTy::Class;
1414 break;
1415 case 'W':
1416 if (MangledName.popFront() != '4') {
1417 Error = true;
1418 return nullptr;
1419 }
1420 UTy->Prim = PrimTy::Enum;
1421 break;
1422 default:
1423 assert(false);
1424 }
1425
1426 UTy->UdtName = demangleName();
1427 return UTy;
1428}
1429
Zachary Turnerd742d642018-07-26 19:56:09 +00001430static std::pair<Qualifiers, PointerAffinity>
1431demanglePointerCVQualifiers(StringView &MangledName) {
1432 switch (MangledName.popFront()) {
1433 case 'A':
1434 return std::make_pair(Q_None, PointerAffinity::Reference);
1435 case 'P':
1436 return std::make_pair(Q_None, PointerAffinity::Pointer);
1437 case 'Q':
1438 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1439 case 'R':
1440 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1441 case 'S':
1442 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1443 PointerAffinity::Pointer);
1444 default:
1445 assert(false && "Ty is not a pointer type!");
1446 }
1447 return std::make_pair(Q_None, PointerAffinity::Pointer);
1448}
1449
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001450// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1451// # the E is required for 64-bit non-static pointers
1452PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001453 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454
Zachary Turnerd742d642018-07-26 19:56:09 +00001455 PointerAffinity Affinity;
1456 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001457
Zachary Turnerd742d642018-07-26 19:56:09 +00001458 Pointer->Prim =
1459 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001460 if (MangledName.consumeFront("6")) {
Zachary Turner024e1762018-07-26 20:33:48 +00001461 Pointer->Pointee = demangleFunctionType(false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001462 return Pointer;
1463 }
1464
1465 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1466 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1467
1468 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1469 return Pointer;
1470}
1471
Zachary Turnerd742d642018-07-26 19:56:09 +00001472MemberPointerType *Demangler::demangleMemberPointerType() {
1473 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1474 Pointer->Prim = PrimTy::MemberPtr;
1475
1476 PointerAffinity Affinity;
1477 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1478 assert(Affinity == PointerAffinity::Pointer);
1479
1480 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1481 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1482
Zachary Turner38b78a72018-07-26 20:20:10 +00001483 if (MangledName.consumeFront("8")) {
1484 Pointer->MemberName = demangleName();
Zachary Turner024e1762018-07-26 20:33:48 +00001485 Pointer->Pointee = demangleFunctionType(true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001486 } else {
1487 Qualifiers PointeeQuals = Q_None;
1488 bool IsMember = false;
1489 std::tie(PointeeQuals, IsMember) = demangleQualifiers();
1490 assert(IsMember);
1491 Pointer->MemberName = demangleName();
Zachary Turnerd742d642018-07-26 19:56:09 +00001492
Zachary Turner38b78a72018-07-26 20:20:10 +00001493 Pointer->Pointee = demangleType(QualifierMangleMode::Drop);
1494 Pointer->Pointee->Quals = PointeeQuals;
1495 }
1496
Zachary Turnerd742d642018-07-26 19:56:09 +00001497 return Pointer;
1498}
1499
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001500Qualifiers Demangler::demanglePointerExtQualifiers() {
1501 Qualifiers Quals = Q_None;
1502 if (MangledName.consumeFront('E'))
1503 Quals = Qualifiers(Quals | Q_Pointer64);
1504 if (MangledName.consumeFront('I'))
1505 Quals = Qualifiers(Quals | Q_Restrict);
1506 if (MangledName.consumeFront('F'))
1507 Quals = Qualifiers(Quals | Q_Unaligned);
1508
1509 return Quals;
1510}
1511
1512ArrayType *Demangler::demangleArrayType() {
1513 assert(MangledName.front() == 'Y');
1514 MangledName.popFront();
1515
1516 int Dimension = demangleNumber();
1517 if (Dimension <= 0) {
1518 Error = true;
1519 return nullptr;
1520 }
1521
Zachary Turner9d72aa92018-07-20 18:35:06 +00001522 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001523 ArrayType *Dim = ATy;
1524 for (int I = 0; I < Dimension; ++I) {
1525 Dim->Prim = PrimTy::Array;
1526 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001527 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001528 Dim = Dim->NextDimension;
1529 }
1530
1531 if (MangledName.consumeFront("$$C")) {
1532 if (MangledName.consumeFront("B"))
1533 ATy->Quals = Q_Const;
1534 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1535 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1536 else if (!MangledName.consumeFront("A"))
1537 Error = true;
1538 }
1539
1540 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1541 Dim->ElementType = ATy->ElementType;
1542 return ATy;
1543}
1544
1545// Reads a function or a template parameters.
1546ParamList Demangler::demangleParameterList() {
1547 // Within the same parameter list, you can backreference the first 10 types.
1548 Type *BackRef[10];
1549 int Idx = 0;
1550
Zachary Turner38b78a72018-07-26 20:20:10 +00001551 // Empty parameter list.
1552 // FIXME: Will this cause problems if demangleParameterList() is called in the
1553 // context of a template parameter list?
1554 if (MangledName.consumeFront('X'))
1555 return {};
1556
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001557 ParamList *Head;
1558 ParamList **Current = &Head;
1559 while (!Error && !MangledName.startsWith('@') &&
1560 !MangledName.startsWith('Z')) {
1561 if (startsWithDigit(MangledName)) {
1562 int N = MangledName[0] - '0';
1563 if (N >= Idx) {
1564 Error = true;
1565 return {};
1566 }
1567 MangledName = MangledName.dropFront();
1568
Zachary Turner9d72aa92018-07-20 18:35:06 +00001569 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001570 (*Current)->Current = BackRef[N]->clone(Arena);
1571 Current = &(*Current)->Next;
1572 continue;
1573 }
1574
1575 size_t ArrayDimension = MangledName.size();
1576
Zachary Turner9d72aa92018-07-20 18:35:06 +00001577 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001578 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1579
1580 // Single-letter types are ignored for backreferences because
1581 // memorizing them doesn't save anything.
1582 if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
1583 BackRef[Idx++] = (*Current)->Current;
1584 Current = &(*Current)->Next;
1585 }
1586
Zachary Turner38b78a72018-07-26 20:20:10 +00001587 if (Error)
1588 return {};
1589
1590 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1591 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1592 // the following Z could be a throw specifier.
1593 if (MangledName.consumeFront('@'))
1594 return *Head;
1595
1596 if (MangledName.consumeFront('Z')) {
1597 Head->IsVariadic = true;
1598 return *Head;
1599 }
1600
1601 Error = true;
1602 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001603}
1604
1605void Demangler::output() {
1606 // Converts an AST to a string.
1607 //
1608 // Converting an AST representing a C++ type to a string is tricky due
1609 // to the bad grammar of the C++ declaration inherited from C. You have
1610 // to construct a string from inside to outside. For example, if a type
1611 // X is a pointer to a function returning int, the order you create a
1612 // string becomes something like this:
1613 //
1614 // (1) X is a pointer: *X
1615 // (2) (1) is a function returning int: int (*X)()
1616 //
1617 // So you cannot construct a result just by appending strings to a result.
1618 //
1619 // To deal with this, we split the function into two. outputPre() writes
1620 // the "first half" of type declaration, and outputPost() writes the
1621 // "second half". For example, outputPre() writes a return type for a
1622 // function and outputPost() writes an parameter list.
1623 Type::outputPre(OS, *SymbolType);
1624 outputName(OS, SymbolName);
1625 Type::outputPost(OS, *SymbolType);
1626
1627 // Null terminate the buffer.
1628 OS << '\0';
1629}
1630
1631char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1632 int *Status) {
1633 OutputStream OS = OutputStream::create(Buf, N, 1024);
1634
1635 Demangler D(OS, StringView(MangledName));
1636 D.parse();
1637
1638 if (D.Error)
1639 *Status = llvm::demangle_invalid_mangled_name;
1640 else
1641 *Status = llvm::demangle_success;
1642
1643 D.output();
1644 return OS.getBuffer();
1645}