blob: 596359b7d99027d168e956c8560f64b12c7d8b9e [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
Zachary Turner23df1312018-07-26 22:13:39 +0000754 ParamList demangleTemplateParameterList();
755 ParamList demangleFunctionParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000756
757 int demangleNumber();
758 void demangleNamePiece(Name &Node, bool IsHead);
759
760 StringView demangleString(bool memorize);
761 void memorizeString(StringView s);
762 Name *demangleName();
763 void demangleOperator(Name *);
764 StringView demangleOperatorName();
Zachary Turner38b78a72018-07-26 20:20:10 +0000765 FuncClass demangleFunctionClass();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000766 CallingConv demangleCallingConvention();
767 StorageClass demangleVariableStorageClass();
768 ReferenceKind demangleReferenceKind();
Zachary Turner38b78a72018-07-26 20:20:10 +0000769 void demangleThrowSpecification();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000770
Zachary Turnerd742d642018-07-26 19:56:09 +0000771 std::pair<Qualifiers, bool> demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000772
Zachary Turner91ecedd2018-07-20 18:07:33 +0000773 // The result is written to this stream.
774 OutputStream OS;
775
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000776 // Mangled symbol. demangle* functions shorten this string
777 // as they parse it.
778 StringView MangledName;
779
780 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000781 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000782
783 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
784 Name *SymbolName = nullptr;
785
786 // Memory allocator.
787 ArenaAllocator Arena;
788
Zachary Turner23df1312018-07-26 22:13:39 +0000789 // A single type uses one global back-ref table for all function params.
790 // This means back-refs can even go "into" other types. Examples:
791 //
792 // // Second int* is a back-ref to first.
793 // void foo(int *, int*);
794 //
795 // // Second int* is not a back-ref to first (first is not a function param).
796 // int* foo(int*);
797 //
798 // // Second int* is a back-ref to first (ALL function types share the same
799 // // back-ref map.
800 // using F = void(*)(int*);
801 // F G(int *);
802 Type *FunctionParamBackRefs[10];
803 size_t FunctionParamBackRefCount = 0;
804
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000805 // The first 10 BackReferences in a mangled name can be back-referenced by
806 // special name @[0-9]. This is a storage for the first 10 BackReferences.
807 StringView BackReferences[10];
808 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000809};
810} // namespace
811
812// Parser entry point.
813void Demangler::parse() {
814 // MSVC-style mangled symbols must start with '?'.
815 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000816 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000817 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000818 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000819 SymbolType->Prim = PrimTy::Unknown;
820 }
821
822 // What follows is a main symbol name. This may include
823 // namespaces or class BackReferences.
824 SymbolName = demangleName();
825
826 // Read a variable.
827 if (startsWithDigit(MangledName)) {
828 SymbolType = demangleVariableEncoding();
829 return;
830 }
831
832 // Read a function.
833 SymbolType = demangleFunctionEncoding();
834}
835
836// <type-encoding> ::= <storage-class> <variable-type>
837// <storage-class> ::= 0 # private static member
838// ::= 1 # protected static member
839// ::= 2 # public static member
840// ::= 3 # global
841// ::= 4 # static local
842
843Type *Demangler::demangleVariableEncoding() {
844 StorageClass SC = demangleVariableStorageClass();
845
846 Type *Ty = demangleType(QualifierMangleMode::Drop);
847
848 Ty->Storage = SC;
849
850 // <variable-type> ::= <type> <cvr-qualifiers>
851 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
852 switch (Ty->Prim) {
853 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000854 case PrimTy::Ref:
855 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000856 Qualifiers ExtraChildQuals = Q_None;
857 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
858
Zachary Turnerd742d642018-07-26 19:56:09 +0000859 bool IsMember = false;
860 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000861
Zachary Turnerd742d642018-07-26 19:56:09 +0000862 if (Ty->Prim == PrimTy::MemberPtr) {
863 assert(IsMember);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000864 Name *BackRefName = demangleName();
865 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000866 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
867 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
868 } else {
869 PointerType *PTy = static_cast<PointerType *>(Ty);
870 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000871 }
872
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000873 break;
874 }
875 default:
Zachary Turnerd742d642018-07-26 19:56:09 +0000876 Ty->Quals = demangleQualifiers().first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000877 break;
878 }
879
880 return Ty;
881}
882
883// Sometimes numbers are encoded in mangled symbols. For example,
884// "int (*x)[20]" is a valid C type (x is a pointer to an array of
885// length 20), so we need some way to embed numbers as part of symbols.
886// This function parses it.
887//
888// <number> ::= [?] <non-negative integer>
889//
890// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
891// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
892//
893// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
894int Demangler::demangleNumber() {
895 bool neg = MangledName.consumeFront("?");
896
897 if (startsWithDigit(MangledName)) {
898 int32_t Ret = MangledName[0] - '0' + 1;
899 MangledName = MangledName.dropFront(1);
900 return neg ? -Ret : Ret;
901 }
902
903 int Ret = 0;
904 for (size_t i = 0; i < MangledName.size(); ++i) {
905 char C = MangledName[i];
906 if (C == '@') {
907 MangledName = MangledName.dropFront(i + 1);
908 return neg ? -Ret : Ret;
909 }
910 if ('A' <= C && C <= 'P') {
911 Ret = (Ret << 4) + (C - 'A');
912 continue;
913 }
914 break;
915 }
916
917 Error = true;
918 return 0;
919}
920
921// Read until the next '@'.
922StringView Demangler::demangleString(bool Memorize) {
923 for (size_t i = 0; i < MangledName.size(); ++i) {
924 if (MangledName[i] != '@')
925 continue;
926 StringView ret = MangledName.substr(0, i);
927 MangledName = MangledName.dropFront(i + 1);
928
929 if (Memorize)
930 memorizeString(ret);
931 return ret;
932 }
933
934 Error = true;
935 return "";
936}
937
938// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
939// Memorize it.
940void Demangler::memorizeString(StringView S) {
941 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
942 return;
943 for (size_t i = 0; i < BackRefCount; ++i)
944 if (S == BackReferences[i])
945 return;
946 BackReferences[BackRefCount++] = S;
947}
948
949void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
950 if (startsWithDigit(MangledName)) {
951 size_t I = MangledName[0] - '0';
952 if (I >= BackRefCount) {
953 Error = true;
954 return;
955 }
956 MangledName = MangledName.dropFront();
957 Node.Str = BackReferences[I];
958 } else if (MangledName.consumeFront("?$")) {
959 // Class template.
960 Node.Str = demangleString(false);
Zachary Turner23df1312018-07-26 22:13:39 +0000961 Node.TemplateParams = demangleTemplateParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000962 } else if (!IsHead && MangledName.consumeFront("?A")) {
963 // Anonymous namespace starts with ?A. So does overloaded operator[],
964 // but the distinguishing factor is that namespace themselves are not
965 // mangled, only the variables and functions inside of them are. So
966 // an anonymous namespace will never occur as the first item in the
967 // name.
968 Node.Str = "`anonymous namespace'";
969 if (!MangledName.consumeFront('@')) {
970 Error = true;
971 return;
972 }
973 } else if (MangledName.consumeFront("?")) {
974 // Overloaded operator.
975 demangleOperator(&Node);
976 } else {
977 // Non-template functions or classes.
978 Node.Str = demangleString(true);
979 }
980}
981
982// Parses a name in the form of A@B@C@@ which represents C::B::A.
983Name *Demangler::demangleName() {
984 Name *Head = nullptr;
985
986 while (!MangledName.consumeFront("@")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000987 Name *Elem = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000988
989 assert(!Error);
990 demangleNamePiece(*Elem, Head == nullptr);
991 if (Error)
992 return nullptr;
993
994 Elem->Next = Head;
995 Head = Elem;
Zachary Turnerd742d642018-07-26 19:56:09 +0000996 if (MangledName.empty()) {
997 Error = true;
998 return nullptr;
999 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001000 }
1001
1002 return Head;
1003}
1004
1005void Demangler::demangleOperator(Name *OpName) {
1006 OpName->Operator = demangleOperatorName();
1007 if (!Error && !MangledName.empty() && MangledName.front() != '@')
1008 demangleNamePiece(*OpName, false);
1009}
1010
1011StringView Demangler::demangleOperatorName() {
1012 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1013 RestoreOnError.shouldRestore(false);
1014
1015 switch (MangledName.popFront()) {
1016 case '0':
1017 return "ctor";
1018 case '1':
1019 return "dtor";
1020 case '2':
1021 return " new";
1022 case '3':
1023 return " delete";
1024 case '4':
1025 return "=";
1026 case '5':
1027 return ">>";
1028 case '6':
1029 return "<<";
1030 case '7':
1031 return "!";
1032 case '8':
1033 return "==";
1034 case '9':
1035 return "!=";
1036 case 'A':
1037 return "[]";
1038 case 'C':
1039 return "->";
1040 case 'D':
1041 return "*";
1042 case 'E':
1043 return "++";
1044 case 'F':
1045 return "--";
1046 case 'G':
1047 return "-";
1048 case 'H':
1049 return "+";
1050 case 'I':
1051 return "&";
1052 case 'J':
1053 return "->*";
1054 case 'K':
1055 return "/";
1056 case 'L':
1057 return "%";
1058 case 'M':
1059 return "<";
1060 case 'N':
1061 return "<=";
1062 case 'O':
1063 return ">";
1064 case 'P':
1065 return ">=";
1066 case 'Q':
1067 return ",";
1068 case 'R':
1069 return "()";
1070 case 'S':
1071 return "~";
1072 case 'T':
1073 return "^";
1074 case 'U':
1075 return "|";
1076 case 'V':
1077 return "&&";
1078 case 'W':
1079 return "||";
1080 case 'X':
1081 return "*=";
1082 case 'Y':
1083 return "+=";
1084 case 'Z':
1085 return "-=";
1086 case '_': {
1087 if (MangledName.empty())
1088 break;
1089
1090 switch (MangledName.popFront()) {
1091 case '0':
1092 return "/=";
1093 case '1':
1094 return "%=";
1095 case '2':
1096 return ">>=";
1097 case '3':
1098 return "<<=";
1099 case '4':
1100 return "&=";
1101 case '5':
1102 return "|=";
1103 case '6':
1104 return "^=";
1105 case 'U':
1106 return " new[]";
1107 case 'V':
1108 return " delete[]";
1109 case '_':
1110 if (MangledName.consumeFront("L"))
1111 return " co_await";
1112 }
1113 }
1114 }
1115
1116 Error = true;
1117 RestoreOnError.shouldRestore(true);
1118 return "";
1119}
1120
Zachary Turner38b78a72018-07-26 20:20:10 +00001121FuncClass Demangler::demangleFunctionClass() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001122 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1123 RestoreOnError.shouldRestore(false);
1124
1125 switch (MangledName.popFront()) {
1126 case 'A':
1127 return Private;
1128 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001129 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001130 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001131 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001132 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001133 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001134 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001135 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001136 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001137 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001138 case 'I':
1139 return Protected;
1140 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001141 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001142 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001143 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001144 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001145 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001146 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001147 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001148 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001149 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001150 case 'Q':
1151 return Public;
1152 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001153 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001154 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001155 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001156 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001157 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001158 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001159 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001160 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001161 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001162 case 'Y':
1163 return Global;
1164 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001165 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001166 }
1167
1168 Error = true;
1169 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001170 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001171}
1172
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001173CallingConv Demangler::demangleCallingConvention() {
1174 switch (MangledName.popFront()) {
1175 case 'A':
1176 case 'B':
1177 return CallingConv::Cdecl;
1178 case 'C':
1179 case 'D':
1180 return CallingConv::Pascal;
1181 case 'E':
1182 case 'F':
1183 return CallingConv::Thiscall;
1184 case 'G':
1185 case 'H':
1186 return CallingConv::Stdcall;
1187 case 'I':
1188 case 'J':
1189 return CallingConv::Fastcall;
1190 case 'M':
1191 case 'N':
1192 return CallingConv::Clrcall;
1193 case 'O':
1194 case 'P':
1195 return CallingConv::Eabi;
1196 case 'Q':
1197 return CallingConv::Vectorcall;
1198 }
1199
1200 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001201}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001202
1203StorageClass Demangler::demangleVariableStorageClass() {
1204 assert(std::isdigit(MangledName.front()));
1205
1206 switch (MangledName.popFront()) {
1207 case '0':
1208 return StorageClass::PrivateStatic;
1209 case '1':
1210 return StorageClass::ProtectedStatic;
1211 case '2':
1212 return StorageClass::PublicStatic;
1213 case '3':
1214 return StorageClass::Global;
1215 case '4':
1216 return StorageClass::FunctionLocalStatic;
1217 }
1218 Error = true;
1219 return StorageClass::None;
1220}
1221
Zachary Turnerd742d642018-07-26 19:56:09 +00001222std::pair<Qualifiers, bool> Demangler::demangleQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001223
1224 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001225 // Member qualifiers
1226 case 'Q':
1227 return std::make_pair(Q_None, true);
1228 case 'R':
1229 return std::make_pair(Q_Const, true);
1230 case 'S':
1231 return std::make_pair(Q_Volatile, true);
1232 case 'T':
1233 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1234 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001235 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001236 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001237 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001238 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001239 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001240 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001241 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001242 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001243 }
1244 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001245 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001246}
1247
1248// <variable-type> ::= <type> <cvr-qualifiers>
1249// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1250Type *Demangler::demangleType(QualifierMangleMode QMM) {
1251 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001252 bool IsMember = false;
1253 bool IsMemberKnown = false;
1254 if (QMM == QualifierMangleMode::Mangle) {
1255 std::tie(Quals, IsMember) = demangleQualifiers();
1256 IsMemberKnown = true;
1257 } else if (QMM == QualifierMangleMode::Result) {
1258 if (MangledName.consumeFront('?')) {
1259 std::tie(Quals, IsMember) = demangleQualifiers();
1260 IsMemberKnown = true;
1261 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001262 }
1263
1264 Type *Ty = nullptr;
1265 switch (MangledName.front()) {
1266 case 'T': // union
1267 case 'U': // struct
1268 case 'V': // class
1269 case 'W': // enum
1270 Ty = demangleClassType();
1271 break;
1272 case 'A': // foo &
1273 case 'P': // foo *
1274 case 'Q': // foo *const
1275 case 'R': // foo *volatile
1276 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001277 if (!IsMemberKnown)
1278 IsMember = isMemberPointer(MangledName);
1279 if (IsMember)
1280 Ty = demangleMemberPointerType();
1281 else
1282 Ty = demanglePointerType();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001283 break;
1284 case 'Y':
1285 Ty = demangleArrayType();
1286 break;
1287 default:
1288 Ty = demangleBasicType();
1289 break;
1290 }
1291 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1292 return Ty;
1293}
1294
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001295ReferenceKind Demangler::demangleReferenceKind() {
1296 if (MangledName.consumeFront('G'))
1297 return ReferenceKind::LValueRef;
1298 else if (MangledName.consumeFront('H'))
1299 return ReferenceKind::RValueRef;
1300 return ReferenceKind::None;
1301}
1302
Zachary Turner38b78a72018-07-26 20:20:10 +00001303void Demangler::demangleThrowSpecification() {
1304 if (MangledName.consumeFront('Z'))
1305 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001306
Zachary Turner38b78a72018-07-26 20:20:10 +00001307 Error = true;
1308}
1309
Zachary Turner024e1762018-07-26 20:33:48 +00001310FunctionType *Demangler::demangleFunctionType(bool HasThisQuals,
1311 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001312 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001313 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001314 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001315
1316 if (HasThisQuals) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001317 FTy->Quals = demanglePointerExtQualifiers();
1318 FTy->RefKind = demangleReferenceKind();
Zachary Turnerd742d642018-07-26 19:56:09 +00001319 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers().first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001320 }
1321
1322 // Fields that appear on both member and non-member functions.
1323 FTy->CallConvention = demangleCallingConvention();
1324
1325 // <return-type> ::= <type>
1326 // ::= @ # structors (they have no declared return type)
1327 bool IsStructor = MangledName.consumeFront('@');
1328 if (!IsStructor)
1329 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1330
Zachary Turner23df1312018-07-26 22:13:39 +00001331 FTy->Params = demangleFunctionParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001332
Zachary Turner38b78a72018-07-26 20:20:10 +00001333 demangleThrowSpecification();
1334
1335 return FTy;
1336}
1337
1338Type *Demangler::demangleFunctionEncoding() {
1339 FuncClass FC = demangleFunctionClass();
1340
1341 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner024e1762018-07-26 20:33:48 +00001342 FunctionType *FTy = demangleFunctionType(HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001343 FTy->FunctionClass = FC;
1344
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001345 return FTy;
1346}
1347
1348// Reads a primitive type.
1349Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001350 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001351
1352 switch (MangledName.popFront()) {
1353 case 'X':
1354 Ty->Prim = PrimTy::Void;
1355 break;
1356 case 'D':
1357 Ty->Prim = PrimTy::Char;
1358 break;
1359 case 'C':
1360 Ty->Prim = PrimTy::Schar;
1361 break;
1362 case 'E':
1363 Ty->Prim = PrimTy::Uchar;
1364 break;
1365 case 'F':
1366 Ty->Prim = PrimTy::Short;
1367 break;
1368 case 'G':
1369 Ty->Prim = PrimTy::Ushort;
1370 break;
1371 case 'H':
1372 Ty->Prim = PrimTy::Int;
1373 break;
1374 case 'I':
1375 Ty->Prim = PrimTy::Uint;
1376 break;
1377 case 'J':
1378 Ty->Prim = PrimTy::Long;
1379 break;
1380 case 'K':
1381 Ty->Prim = PrimTy::Ulong;
1382 break;
1383 case 'M':
1384 Ty->Prim = PrimTy::Float;
1385 break;
1386 case 'N':
1387 Ty->Prim = PrimTy::Double;
1388 break;
1389 case 'O':
1390 Ty->Prim = PrimTy::Ldouble;
1391 break;
1392 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001393 if (MangledName.empty()) {
1394 Error = true;
1395 return nullptr;
1396 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001397 switch (MangledName.popFront()) {
1398 case 'N':
1399 Ty->Prim = PrimTy::Bool;
1400 break;
1401 case 'J':
1402 Ty->Prim = PrimTy::Int64;
1403 break;
1404 case 'K':
1405 Ty->Prim = PrimTy::Uint64;
1406 break;
1407 case 'W':
1408 Ty->Prim = PrimTy::Wchar;
1409 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001410 default:
1411 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001412 }
1413 break;
1414 }
1415 }
1416 return Ty;
1417}
1418
1419UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001420 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001421
1422 switch (MangledName.popFront()) {
1423 case 'T':
1424 UTy->Prim = PrimTy::Union;
1425 break;
1426 case 'U':
1427 UTy->Prim = PrimTy::Struct;
1428 break;
1429 case 'V':
1430 UTy->Prim = PrimTy::Class;
1431 break;
1432 case 'W':
1433 if (MangledName.popFront() != '4') {
1434 Error = true;
1435 return nullptr;
1436 }
1437 UTy->Prim = PrimTy::Enum;
1438 break;
1439 default:
1440 assert(false);
1441 }
1442
1443 UTy->UdtName = demangleName();
1444 return UTy;
1445}
1446
Zachary Turnerd742d642018-07-26 19:56:09 +00001447static std::pair<Qualifiers, PointerAffinity>
1448demanglePointerCVQualifiers(StringView &MangledName) {
1449 switch (MangledName.popFront()) {
1450 case 'A':
1451 return std::make_pair(Q_None, PointerAffinity::Reference);
1452 case 'P':
1453 return std::make_pair(Q_None, PointerAffinity::Pointer);
1454 case 'Q':
1455 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1456 case 'R':
1457 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1458 case 'S':
1459 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1460 PointerAffinity::Pointer);
1461 default:
1462 assert(false && "Ty is not a pointer type!");
1463 }
1464 return std::make_pair(Q_None, PointerAffinity::Pointer);
1465}
1466
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001467// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1468// # the E is required for 64-bit non-static pointers
1469PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001470 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001471
Zachary Turnerd742d642018-07-26 19:56:09 +00001472 PointerAffinity Affinity;
1473 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001474
Zachary Turnerd742d642018-07-26 19:56:09 +00001475 Pointer->Prim =
1476 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001477 if (MangledName.consumeFront("6")) {
Zachary Turner024e1762018-07-26 20:33:48 +00001478 Pointer->Pointee = demangleFunctionType(false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001479 return Pointer;
1480 }
1481
1482 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1483 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1484
1485 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1486 return Pointer;
1487}
1488
Zachary Turnerd742d642018-07-26 19:56:09 +00001489MemberPointerType *Demangler::demangleMemberPointerType() {
1490 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1491 Pointer->Prim = PrimTy::MemberPtr;
1492
1493 PointerAffinity Affinity;
1494 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1495 assert(Affinity == PointerAffinity::Pointer);
1496
1497 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1498 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1499
Zachary Turner38b78a72018-07-26 20:20:10 +00001500 if (MangledName.consumeFront("8")) {
1501 Pointer->MemberName = demangleName();
Zachary Turner024e1762018-07-26 20:33:48 +00001502 Pointer->Pointee = demangleFunctionType(true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001503 } else {
1504 Qualifiers PointeeQuals = Q_None;
1505 bool IsMember = false;
1506 std::tie(PointeeQuals, IsMember) = demangleQualifiers();
1507 assert(IsMember);
1508 Pointer->MemberName = demangleName();
Zachary Turnerd742d642018-07-26 19:56:09 +00001509
Zachary Turner38b78a72018-07-26 20:20:10 +00001510 Pointer->Pointee = demangleType(QualifierMangleMode::Drop);
1511 Pointer->Pointee->Quals = PointeeQuals;
1512 }
1513
Zachary Turnerd742d642018-07-26 19:56:09 +00001514 return Pointer;
1515}
1516
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001517Qualifiers Demangler::demanglePointerExtQualifiers() {
1518 Qualifiers Quals = Q_None;
1519 if (MangledName.consumeFront('E'))
1520 Quals = Qualifiers(Quals | Q_Pointer64);
1521 if (MangledName.consumeFront('I'))
1522 Quals = Qualifiers(Quals | Q_Restrict);
1523 if (MangledName.consumeFront('F'))
1524 Quals = Qualifiers(Quals | Q_Unaligned);
1525
1526 return Quals;
1527}
1528
1529ArrayType *Demangler::demangleArrayType() {
1530 assert(MangledName.front() == 'Y');
1531 MangledName.popFront();
1532
1533 int Dimension = demangleNumber();
1534 if (Dimension <= 0) {
1535 Error = true;
1536 return nullptr;
1537 }
1538
Zachary Turner9d72aa92018-07-20 18:35:06 +00001539 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001540 ArrayType *Dim = ATy;
1541 for (int I = 0; I < Dimension; ++I) {
1542 Dim->Prim = PrimTy::Array;
1543 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001544 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001545 Dim = Dim->NextDimension;
1546 }
1547
1548 if (MangledName.consumeFront("$$C")) {
1549 if (MangledName.consumeFront("B"))
1550 ATy->Quals = Q_Const;
1551 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1552 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1553 else if (!MangledName.consumeFront("A"))
1554 Error = true;
1555 }
1556
1557 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1558 Dim->ElementType = ATy->ElementType;
1559 return ATy;
1560}
1561
1562// Reads a function or a template parameters.
Zachary Turner23df1312018-07-26 22:13:39 +00001563ParamList Demangler::demangleFunctionParameterList() {
Zachary Turner38b78a72018-07-26 20:20:10 +00001564 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001565 if (MangledName.consumeFront('X'))
1566 return {};
1567
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001568 ParamList *Head;
1569 ParamList **Current = &Head;
1570 while (!Error && !MangledName.startsWith('@') &&
1571 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001572
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001573 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001574 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001575 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001576 Error = true;
1577 return {};
1578 }
1579 MangledName = MangledName.dropFront();
1580
Zachary Turner9d72aa92018-07-20 18:35:06 +00001581 *Current = Arena.alloc<ParamList>();
Zachary Turner23df1312018-07-26 22:13:39 +00001582 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001583 Current = &(*Current)->Next;
1584 continue;
1585 }
1586
Zachary Turner23df1312018-07-26 22:13:39 +00001587 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001588
Zachary Turner9d72aa92018-07-20 18:35:06 +00001589 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001590 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1591
Zachary Turner23df1312018-07-26 22:13:39 +00001592 size_t CharsConsumed = OldSize - MangledName.size();
1593 assert(CharsConsumed != 0);
1594
1595 // Single-letter types are ignored for backreferences because memorizing
1596 // them doesn't save anything.
1597 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1598 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1599
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001600 Current = &(*Current)->Next;
1601 }
1602
Zachary Turner38b78a72018-07-26 20:20:10 +00001603 if (Error)
1604 return {};
1605
1606 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1607 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1608 // the following Z could be a throw specifier.
1609 if (MangledName.consumeFront('@'))
1610 return *Head;
1611
1612 if (MangledName.consumeFront('Z')) {
1613 Head->IsVariadic = true;
1614 return *Head;
1615 }
1616
1617 Error = true;
1618 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001619}
1620
Zachary Turner23df1312018-07-26 22:13:39 +00001621ParamList Demangler::demangleTemplateParameterList() {
1622 ParamList *Head;
1623 ParamList **Current = &Head;
1624 while (!Error && !MangledName.startsWith('@')) {
1625
1626 // Template parameter lists don't participate in back-referencing.
1627 *Current = Arena.alloc<ParamList>();
1628 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1629
1630 Current = &(*Current)->Next;
1631 }
1632
1633 if (Error)
1634 return {};
1635
1636 // Template parameter lists cannot be variadic, so it can only be terminated
1637 // by @.
1638 if (MangledName.consumeFront('@'))
1639 return *Head;
1640 Error = true;
1641 return {};
1642}
1643
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001644void Demangler::output() {
1645 // Converts an AST to a string.
1646 //
1647 // Converting an AST representing a C++ type to a string is tricky due
1648 // to the bad grammar of the C++ declaration inherited from C. You have
1649 // to construct a string from inside to outside. For example, if a type
1650 // X is a pointer to a function returning int, the order you create a
1651 // string becomes something like this:
1652 //
1653 // (1) X is a pointer: *X
1654 // (2) (1) is a function returning int: int (*X)()
1655 //
1656 // So you cannot construct a result just by appending strings to a result.
1657 //
1658 // To deal with this, we split the function into two. outputPre() writes
1659 // the "first half" of type declaration, and outputPost() writes the
1660 // "second half". For example, outputPre() writes a return type for a
1661 // function and outputPost() writes an parameter list.
1662 Type::outputPre(OS, *SymbolType);
1663 outputName(OS, SymbolName);
1664 Type::outputPost(OS, *SymbolType);
1665
1666 // Null terminate the buffer.
1667 OS << '\0';
1668}
1669
1670char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1671 int *Status) {
1672 OutputStream OS = OutputStream::create(Buf, N, 1024);
1673
1674 Demangler D(OS, StringView(MangledName));
1675 D.parse();
1676
1677 if (D.Error)
1678 *Status = llvm::demangle_invalid_mangled_name;
1679 else
1680 *Status = llvm::demangle_success;
1681
1682 D.output();
1683 return OS.getBuffer();
1684}