blob: 6e187854d75147901326f7c2564decbbe84f75fd [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
Zachary Turnerd742d642018-07-26 19:56:09 +000024#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000025
26// This memory allocator is extremely fast, but it doesn't call dtors
27// for allocated objects. That means you can't use STL containers
28// (such as std::vector) with this allocator. But it pays off --
29// the demangler is 3x faster with this allocator compared to one with
30// STL containers.
31namespace {
32class ArenaAllocator {
33 struct AllocatorNode {
34 uint8_t *Buf = nullptr;
35 size_t Used = 0;
36 AllocatorNode *Next = nullptr;
37 };
38
39public:
40 ArenaAllocator() : Head(new AllocatorNode) { Head->Buf = new uint8_t[Unit]; }
41
42 ~ArenaAllocator() {
43 while (Head) {
44 assert(Head->Buf);
45 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000046 AllocatorNode *Next = Head->Next;
47 delete Head;
48 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000049 }
50 }
51
Zachary Turner9d72aa92018-07-20 18:35:06 +000052 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
53
54 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000055 assert(Size < Unit);
56 assert(Head && Head->Buf);
57
Zachary Turner9d72aa92018-07-20 18:35:06 +000058 size_t P = (size_t)Head->Buf + Head->Used;
59 uintptr_t AlignedP =
60 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
61 uint8_t *PP = (uint8_t *)AlignedP;
62 size_t Adjustment = AlignedP - P;
63
64 Head->Used += Size + Adjustment;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000065 if (Head->Used < Unit)
Zachary Turner9d72aa92018-07-20 18:35:06 +000066 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000067
68 AllocatorNode *NewHead = new AllocatorNode;
69 NewHead->Buf = new uint8_t[ArenaAllocator::Unit];
70 NewHead->Next = Head;
71 Head = NewHead;
72 NewHead->Used = Size;
Zachary Turner9d72aa92018-07-20 18:35:06 +000073 return new (NewHead->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000074 }
75
76private:
77 static constexpr size_t Unit = 4096;
78
79 AllocatorNode *Head = nullptr;
80};
81} // namespace
82
83static bool startsWithDigit(StringView S) {
84 return !S.empty() && std::isdigit(S.front());
85}
86
87// Writes a space if the last token does not end with a punctuation.
88static void outputSpaceIfNecessary(OutputStream &OS) {
89 if (OS.empty())
90 return;
91
92 char C = OS.back();
93 if (isalnum(C) || C == '>')
94 OS << " ";
95}
96
Zachary Turnerf435a7e2018-07-20 17:27:48 +000097// Storage classes
98enum Qualifiers : uint8_t {
99 Q_None = 0,
100 Q_Const = 1 << 0,
101 Q_Volatile = 1 << 1,
102 Q_Far = 1 << 2,
103 Q_Huge = 1 << 3,
104 Q_Unaligned = 1 << 4,
105 Q_Restrict = 1 << 5,
106 Q_Pointer64 = 1 << 6
107};
108
109enum class StorageClass : uint8_t {
110 None,
111 PrivateStatic,
112 ProtectedStatic,
113 PublicStatic,
114 Global,
115 FunctionLocalStatic
116};
117
118enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000119
120enum class PointerAffinity { Pointer, Reference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000121
122// Calling conventions
123enum class CallingConv : uint8_t {
124 None,
125 Cdecl,
126 Pascal,
127 Thiscall,
128 Stdcall,
129 Fastcall,
130 Clrcall,
131 Eabi,
132 Vectorcall,
133 Regcall,
134};
135
136enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
137
138// Types
139enum class PrimTy : uint8_t {
140 Unknown,
141 None,
142 Function,
143 Ptr,
144 Ref,
Zachary Turnerd742d642018-07-26 19:56:09 +0000145 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000146 Array,
147
148 Struct,
149 Union,
150 Class,
151 Enum,
152
153 Void,
154 Bool,
155 Char,
156 Schar,
157 Uchar,
158 Short,
159 Ushort,
160 Int,
161 Uint,
162 Long,
163 Ulong,
164 Int64,
165 Uint64,
166 Wchar,
167 Float,
168 Double,
169 Ldouble,
170};
171
172// Function classes
173enum FuncClass : uint8_t {
174 Public = 1 << 0,
175 Protected = 1 << 1,
176 Private = 1 << 2,
177 Global = 1 << 3,
178 Static = 1 << 4,
179 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000180 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000181};
182
183namespace {
184
185struct Type;
186
187// Represents a list of parameters (template params or function arguments.
188// It's represented as a linked list.
189struct ParamList {
Zachary Turner38b78a72018-07-26 20:20:10 +0000190 bool IsVariadic = false;
191
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000192 Type *Current = nullptr;
193
194 ParamList *Next = nullptr;
195};
196
197// The type class. Mangled symbols are first parsed and converted to
198// this type and then converted to string.
199struct Type {
200 virtual ~Type() {}
201
202 virtual Type *clone(ArenaAllocator &Arena) const;
203
204 // Write the "first half" of a given type. This is a static functions to
205 // give the code a chance to do processing that is common to a subset of
206 // subclasses
207 static void outputPre(OutputStream &OS, Type &Ty);
208
209 // Write the "second half" of a given type. This is a static functions to
210 // give the code a chance to do processing that is common to a subset of
211 // subclasses
212 static void outputPost(OutputStream &OS, Type &Ty);
213
214 virtual void outputPre(OutputStream &OS);
215 virtual void outputPost(OutputStream &OS);
216
217 // Primitive type such as Int.
218 PrimTy Prim = PrimTy::Unknown;
219
220 Qualifiers Quals = Q_None;
221 StorageClass Storage = StorageClass::None; // storage class
222};
223
224// Represents an identifier which may be a template.
225struct Name {
226 // Name read from an MangledName string.
227 StringView Str;
228
229 // Overloaded operators are represented as special BackReferences in mangled
230 // symbols. If this is an operator name, "op" has an operator name (e.g.
231 // ">>"). Otherwise, empty.
232 StringView Operator;
233
234 // Template parameters. Null if not a template.
235 ParamList TemplateParams;
236
237 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
238 Name *Next = nullptr;
239};
240
241struct PointerType : public Type {
242 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000243 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000244 void outputPost(OutputStream &OS) override;
245
Zachary Turnerd742d642018-07-26 19:56:09 +0000246 // Represents a type X in "a pointer to X", "a reference to X",
247 // "an array of X", or "a function returning X".
248 Type *Pointee = nullptr;
249};
250
251struct MemberPointerType : public Type {
252 Type *clone(ArenaAllocator &Arena) const override;
253 void outputPre(OutputStream &OS) override;
254 void outputPost(OutputStream &OS) override;
255
256 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000257
258 // Represents a type X in "a pointer to X", "a reference to X",
259 // "an array of X", or "a function returning X".
260 Type *Pointee = nullptr;
261};
262
263struct FunctionType : public Type {
264 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000265 void outputPre(OutputStream &OS) override;
266 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000267
Zachary Turner024e1762018-07-26 20:33:48 +0000268 // True if this FunctionType instance is the Pointee of a PointerType or
269 // MemberPointerType.
270 bool IsFunctionPointer = false;
271
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000272 Type *ReturnType = nullptr;
273 // If this is a reference, the type of reference.
274 ReferenceKind RefKind;
275
276 CallingConv CallConvention;
277 FuncClass FunctionClass;
278
279 ParamList Params;
280};
281
282struct UdtType : public Type {
283 Type *clone(ArenaAllocator &Arena) const override;
284 void outputPre(OutputStream &OS) override;
285
286 Name *UdtName = nullptr;
287};
288
289struct ArrayType : public Type {
290 Type *clone(ArenaAllocator &Arena) const override;
291 void outputPre(OutputStream &OS) override;
292 void outputPost(OutputStream &OS) override;
293
294 // Either NextDimension or ElementType will be valid.
295 ArrayType *NextDimension = nullptr;
296 uint32_t ArrayDimension = 0;
297
298 Type *ElementType = nullptr;
299};
300
301} // namespace
302
Zachary Turnerd742d642018-07-26 19:56:09 +0000303static bool isMemberPointer(StringView MangledName) {
304 switch (MangledName.popFront()) {
305 case 'A':
306 // 'A' indicates a reference, and you cannot have a reference to a member
307 // function or member variable.
308 return false;
309 case 'P':
310 case 'Q':
311 case 'R':
312 case 'S':
313 // These 4 values indicate some kind of pointer, but we still don't know
314 // what.
315 break;
316 default:
317 assert(false && "Ty is not a pointer type!");
318 }
319
320 // If it starts with a number, then 6 indicates a non-member function
321 // pointer, and 8 indicates a member function pointer.
322 if (startsWithDigit(MangledName)) {
323 assert(MangledName[0] == '6' || MangledName[0] == '8');
324 return (MangledName[0] == '8');
325 }
326
327 // Remove ext qualifiers since those can appear on either type and are
328 // therefore not indicative.
329 MangledName.consumeFront('E'); // 64-bit
330 MangledName.consumeFront('I'); // restrict
331 MangledName.consumeFront('F'); // unaligned
332
333 assert(!MangledName.empty());
334
335 // The next value should be either ABCD (non-member) or QRST (member).
336 switch (MangledName.front()) {
337 case 'A':
338 case 'B':
339 case 'C':
340 case 'D':
341 return false;
342 case 'Q':
343 case 'R':
344 case 'S':
345 case 'T':
346 return true;
347 default:
348 assert(false);
349 }
350 return false;
351}
352
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000353static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
354 outputSpaceIfNecessary(OS);
355
356 switch (CC) {
357 case CallingConv::Cdecl:
358 OS << "__cdecl";
359 break;
360 case CallingConv::Fastcall:
361 OS << "__fastcall";
362 break;
363 case CallingConv::Pascal:
364 OS << "__pascal";
365 break;
366 case CallingConv::Regcall:
367 OS << "__regcall";
368 break;
369 case CallingConv::Stdcall:
370 OS << "__stdcall";
371 break;
372 case CallingConv::Thiscall:
373 OS << "__thiscall";
374 break;
375 case CallingConv::Eabi:
376 OS << "__eabi";
377 break;
378 case CallingConv::Vectorcall:
379 OS << "__vectorcall";
380 break;
381 case CallingConv::Clrcall:
382 OS << "__clrcall";
383 break;
384 default:
385 break;
386 }
387}
388
389// Write a function or template parameter list.
390static void outputParameterList(OutputStream &OS, const ParamList &Params) {
Zachary Turner38b78a72018-07-26 20:20:10 +0000391 if (!Params.Current) {
392 OS << "void";
393 return;
394 }
395
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000396 const ParamList *Head = &Params;
397 while (Head) {
398 Type::outputPre(OS, *Head->Current);
399 Type::outputPost(OS, *Head->Current);
400
401 Head = Head->Next;
402
403 if (Head)
404 OS << ", ";
405 }
406}
407
408static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
409 if (!TheName.TemplateParams.Current)
410 return;
411
412 OS << "<";
413 outputParameterList(OS, TheName.TemplateParams);
414 OS << ">";
415}
416
417static void outputName(OutputStream &OS, const Name *TheName) {
418 if (!TheName)
419 return;
420
421 outputSpaceIfNecessary(OS);
422
Zachary Turnera7dffb12018-07-28 22:10:42 +0000423 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000424 // Print out namespaces or outer class BackReferences.
425 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000426 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000427 OS << TheName->Str;
428 outputTemplateParams(OS, *TheName);
429 OS << "::";
430 }
431
432 // Print out a regular name.
433 if (TheName->Operator.empty()) {
434 OS << TheName->Str;
435 outputTemplateParams(OS, *TheName);
436 return;
437 }
438
439 // Print out ctor or dtor.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000440 if (TheName->Operator == "dtor")
441 OS << "~";
442
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000443 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000444 OS << Previous->Str;
445 outputTemplateParams(OS, *Previous);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000446 return;
447 }
448
449 // Print out an overloaded operator.
450 if (!TheName->Str.empty())
451 OS << TheName->Str << "::";
452 OS << "operator" << TheName->Operator;
453}
454
455namespace {
456
457Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000458 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000459}
460
461// Write the "first half" of a given type.
462void Type::outputPre(OutputStream &OS, Type &Ty) {
463 // Function types require custom handling of const and static so we
464 // handle them separately. All other types use the same decoration
465 // for these modifiers, so handle them here in common code.
466 if (Ty.Prim == PrimTy::Function) {
467 Ty.outputPre(OS);
468 return;
469 }
470
471 switch (Ty.Storage) {
472 case StorageClass::PrivateStatic:
473 case StorageClass::PublicStatic:
474 case StorageClass::ProtectedStatic:
475 OS << "static ";
476 default:
477 break;
478 }
479 Ty.outputPre(OS);
480
481 if (Ty.Quals & Q_Const) {
482 outputSpaceIfNecessary(OS);
483 OS << "const";
484 }
485
486 if (Ty.Quals & Q_Volatile) {
487 outputSpaceIfNecessary(OS);
488 OS << "volatile";
489 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000490
491 if (Ty.Quals & Q_Restrict) {
492 outputSpaceIfNecessary(OS);
493 OS << "__restrict";
494 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000495}
496
497// Write the "second half" of a given type.
498void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
499
500void Type::outputPre(OutputStream &OS) {
501 switch (Prim) {
502 case PrimTy::Void:
503 OS << "void";
504 break;
505 case PrimTy::Bool:
506 OS << "bool";
507 break;
508 case PrimTy::Char:
509 OS << "char";
510 break;
511 case PrimTy::Schar:
512 OS << "signed char";
513 break;
514 case PrimTy::Uchar:
515 OS << "unsigned char";
516 break;
517 case PrimTy::Short:
518 OS << "short";
519 break;
520 case PrimTy::Ushort:
521 OS << "unsigned short";
522 break;
523 case PrimTy::Int:
524 OS << "int";
525 break;
526 case PrimTy::Uint:
527 OS << "unsigned int";
528 break;
529 case PrimTy::Long:
530 OS << "long";
531 break;
532 case PrimTy::Ulong:
533 OS << "unsigned long";
534 break;
535 case PrimTy::Int64:
536 OS << "__int64";
537 break;
538 case PrimTy::Uint64:
539 OS << "unsigned __int64";
540 break;
541 case PrimTy::Wchar:
542 OS << "wchar_t";
543 break;
544 case PrimTy::Float:
545 OS << "float";
546 break;
547 case PrimTy::Double:
548 OS << "double";
549 break;
550 case PrimTy::Ldouble:
551 OS << "long double";
552 break;
553 default:
554 assert(false && "Invalid primitive type!");
555 }
556}
557void Type::outputPost(OutputStream &OS) {}
558
559Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000560 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561}
562
Zachary Turner024e1762018-07-26 20:33:48 +0000563static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
564 const Name *MemberName,
565 const Type *Pointee) {
566 // "[]" and "()" (for function parameters) take precedence over "*",
567 // so "int *x(int)" means "x is a function returning int *". We need
568 // parentheses to supercede the default precedence. (e.g. we want to
569 // emit something like "int (*x)(int)".)
570 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
571 OS << "(";
572 if (Pointee->Prim == PrimTy::Function) {
573 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
574 assert(FTy->IsFunctionPointer);
575 outputCallingConvention(OS, FTy->CallConvention);
576 OS << " ";
577 }
578 }
579
580 if (MemberName) {
581 outputName(OS, MemberName);
582 OS << "::";
583 }
584
585 if (Affinity == PointerAffinity::Pointer)
586 OS << "*";
587 else
588 OS << "&";
589}
590
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000591void PointerType::outputPre(OutputStream &OS) {
592 Type::outputPre(OS, *Pointee);
593
594 outputSpaceIfNecessary(OS);
595
596 if (Quals & Q_Unaligned)
597 OS << "__unaligned ";
598
Zachary Turner024e1762018-07-26 20:33:48 +0000599 PointerAffinity Affinity = (Prim == PrimTy::Ptr) ? PointerAffinity::Pointer
600 : PointerAffinity::Reference;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000601
Zachary Turner024e1762018-07-26 20:33:48 +0000602 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000603
Zachary Turner91ecedd2018-07-20 18:07:33 +0000604 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000605 // if (Ty.Quals & Q_Pointer64)
606 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000607}
608
609void PointerType::outputPost(OutputStream &OS) {
610 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
611 OS << ")";
612
613 Type::outputPost(OS, *Pointee);
614}
615
Zachary Turnerd742d642018-07-26 19:56:09 +0000616Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
617 return Arena.alloc<MemberPointerType>(*this);
618}
619
620void MemberPointerType::outputPre(OutputStream &OS) {
621 Type::outputPre(OS, *Pointee);
622
623 outputSpaceIfNecessary(OS);
624
Zachary Turner024e1762018-07-26 20:33:48 +0000625 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000626
627 // FIXME: We should output this, but it requires updating lots of tests.
628 // if (Ty.Quals & Q_Pointer64)
629 // OS << " __ptr64";
630 if (Quals & Q_Restrict)
631 OS << " __restrict";
632}
633
634void MemberPointerType::outputPost(OutputStream &OS) {
635 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
636 OS << ")";
637
638 Type::outputPost(OS, *Pointee);
639}
640
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000641Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000642 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000643}
644
645void FunctionType::outputPre(OutputStream &OS) {
646 if (!(FunctionClass & Global)) {
647 if (FunctionClass & Static)
648 OS << "static ";
649 }
650
Zachary Turner38b78a72018-07-26 20:20:10 +0000651 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000652 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000653 OS << " ";
654 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000655
Zachary Turner024e1762018-07-26 20:33:48 +0000656 // Function pointers print the calling convention as void (__cdecl *)(params)
657 // rather than void __cdecl (*)(params). So we need to let the PointerType
658 // class handle this.
659 if (!IsFunctionPointer)
660 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000661}
662
663void FunctionType::outputPost(OutputStream &OS) {
664 OS << "(";
665 outputParameterList(OS, Params);
666 OS << ")";
667 if (Quals & Q_Const)
668 OS << " const";
669 if (Quals & Q_Volatile)
670 OS << " volatile";
Zachary Turner38b78a72018-07-26 20:20:10 +0000671
672 if (ReturnType)
673 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000674 return;
675}
676
677Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000678 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000679}
680
681void UdtType::outputPre(OutputStream &OS) {
682 switch (Prim) {
683 case PrimTy::Class:
684 OS << "class ";
685 break;
686 case PrimTy::Struct:
687 OS << "struct ";
688 break;
689 case PrimTy::Union:
690 OS << "union ";
691 break;
692 case PrimTy::Enum:
693 OS << "enum ";
694 break;
695 default:
696 assert(false && "Not a udt type!");
697 }
698
699 outputName(OS, UdtName);
700}
701
702Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000703 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000704}
705
706void ArrayType::outputPre(OutputStream &OS) {
707 Type::outputPre(OS, *ElementType);
708}
709
710void ArrayType::outputPost(OutputStream &OS) {
711 if (ArrayDimension > 0)
712 OS << "[" << ArrayDimension << "]";
713 if (NextDimension)
714 Type::outputPost(OS, *NextDimension);
715 else if (ElementType)
716 Type::outputPost(OS, *ElementType);
717}
718
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();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000758
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000759 void memorizeString(StringView s);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000760 Name *demangleFullyQualifiedTypeName();
761 Name *demangleFullyQualifiedSymbolName();
762
763 Name *demangleUnqualifiedTypeName();
764 Name *demangleUnqualifiedSymbolName();
765
766 Name *demangleNameScopeChain(Name *UnqualifiedName);
767 Name *demangleNameScopePiece();
768
769 Name *demangleBackRefName();
770 Name *demangleClassTemplateName();
771 Name *demangleOperatorName();
772 Name *demangleSimpleName(bool Memorize);
773 Name *demangleAnonymousNamespaceName();
774
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000775 void demangleOperator(Name *);
Zachary Turner38b78a72018-07-26 20:20:10 +0000776 FuncClass demangleFunctionClass();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000777 CallingConv demangleCallingConvention();
778 StorageClass demangleVariableStorageClass();
779 ReferenceKind demangleReferenceKind();
Zachary Turner38b78a72018-07-26 20:20:10 +0000780 void demangleThrowSpecification();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000781
Zachary Turnerd742d642018-07-26 19:56:09 +0000782 std::pair<Qualifiers, bool> demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000783
Zachary Turner91ecedd2018-07-20 18:07:33 +0000784 // The result is written to this stream.
785 OutputStream OS;
786
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000787 // Mangled symbol. demangle* functions shorten this string
788 // as they parse it.
789 StringView MangledName;
790
791 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000792 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000793
794 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
795 Name *SymbolName = nullptr;
796
797 // Memory allocator.
798 ArenaAllocator Arena;
799
Zachary Turner23df1312018-07-26 22:13:39 +0000800 // A single type uses one global back-ref table for all function params.
801 // This means back-refs can even go "into" other types. Examples:
802 //
803 // // Second int* is a back-ref to first.
804 // void foo(int *, int*);
805 //
806 // // Second int* is not a back-ref to first (first is not a function param).
807 // int* foo(int*);
808 //
809 // // Second int* is a back-ref to first (ALL function types share the same
810 // // back-ref map.
811 // using F = void(*)(int*);
812 // F G(int *);
813 Type *FunctionParamBackRefs[10];
814 size_t FunctionParamBackRefCount = 0;
815
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000816 // The first 10 BackReferences in a mangled name can be back-referenced by
817 // special name @[0-9]. This is a storage for the first 10 BackReferences.
818 StringView BackReferences[10];
819 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000820};
821} // namespace
822
823// Parser entry point.
824void Demangler::parse() {
825 // MSVC-style mangled symbols must start with '?'.
826 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000827 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000828 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000829 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000830 SymbolType->Prim = PrimTy::Unknown;
831 }
832
833 // What follows is a main symbol name. This may include
834 // namespaces or class BackReferences.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000835 SymbolName = demangleFullyQualifiedSymbolName();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000836
837 // Read a variable.
838 if (startsWithDigit(MangledName)) {
839 SymbolType = demangleVariableEncoding();
840 return;
841 }
842
843 // Read a function.
844 SymbolType = demangleFunctionEncoding();
845}
846
847// <type-encoding> ::= <storage-class> <variable-type>
848// <storage-class> ::= 0 # private static member
849// ::= 1 # protected static member
850// ::= 2 # public static member
851// ::= 3 # global
852// ::= 4 # static local
853
854Type *Demangler::demangleVariableEncoding() {
855 StorageClass SC = demangleVariableStorageClass();
856
857 Type *Ty = demangleType(QualifierMangleMode::Drop);
858
859 Ty->Storage = SC;
860
861 // <variable-type> ::= <type> <cvr-qualifiers>
862 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
863 switch (Ty->Prim) {
864 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +0000865 case PrimTy::Ref:
866 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000867 Qualifiers ExtraChildQuals = Q_None;
868 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
869
Zachary Turnerd742d642018-07-26 19:56:09 +0000870 bool IsMember = false;
871 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000872
Zachary Turnerd742d642018-07-26 19:56:09 +0000873 if (Ty->Prim == PrimTy::MemberPtr) {
874 assert(IsMember);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000875 Name *BackRefName = demangleFullyQualifiedTypeName();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000876 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +0000877 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
878 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
879 } else {
880 PointerType *PTy = static_cast<PointerType *>(Ty);
881 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000882 }
883
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000884 break;
885 }
886 default:
Zachary Turnerd742d642018-07-26 19:56:09 +0000887 Ty->Quals = demangleQualifiers().first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000888 break;
889 }
890
891 return Ty;
892}
893
894// Sometimes numbers are encoded in mangled symbols. For example,
895// "int (*x)[20]" is a valid C type (x is a pointer to an array of
896// length 20), so we need some way to embed numbers as part of symbols.
897// This function parses it.
898//
899// <number> ::= [?] <non-negative integer>
900//
901// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
902// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
903//
904// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
905int Demangler::demangleNumber() {
906 bool neg = MangledName.consumeFront("?");
907
908 if (startsWithDigit(MangledName)) {
909 int32_t Ret = MangledName[0] - '0' + 1;
910 MangledName = MangledName.dropFront(1);
911 return neg ? -Ret : Ret;
912 }
913
914 int Ret = 0;
915 for (size_t i = 0; i < MangledName.size(); ++i) {
916 char C = MangledName[i];
917 if (C == '@') {
918 MangledName = MangledName.dropFront(i + 1);
919 return neg ? -Ret : Ret;
920 }
921 if ('A' <= C && C <= 'P') {
922 Ret = (Ret << 4) + (C - 'A');
923 continue;
924 }
925 break;
926 }
927
928 Error = true;
929 return 0;
930}
931
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000932// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
933// Memorize it.
934void Demangler::memorizeString(StringView S) {
935 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
936 return;
937 for (size_t i = 0; i < BackRefCount; ++i)
938 if (S == BackReferences[i])
939 return;
940 BackReferences[BackRefCount++] = S;
941}
942
Zachary Turnera7dffb12018-07-28 22:10:42 +0000943Name *Demangler::demangleBackRefName() {
944 assert(startsWithDigit(MangledName));
945
946 size_t I = MangledName[0] - '0';
947 if (I >= BackRefCount) {
948 Error = true;
949 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000950 }
Zachary Turnera7dffb12018-07-28 22:10:42 +0000951
952 MangledName = MangledName.dropFront();
953 Name *Node = Arena.alloc<Name>();
954 Node->Str = BackReferences[I];
955 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000956}
957
Zachary Turnera7dffb12018-07-28 22:10:42 +0000958Name *Demangler::demangleClassTemplateName() {
959 assert(MangledName.startsWith("?$"));
960 MangledName.consumeFront("?$");
961
962 Name *Node = demangleSimpleName(false);
963 Node->TemplateParams = demangleTemplateParameterList();
964 return Node;
965}
966
967Name *Demangler::demangleOperatorName() {
968 assert(MangledName.startsWith('?'));
969 MangledName.consumeFront('?');
970
971 auto NameString = [this]() -> StringView {
972 switch (MangledName.popFront()) {
973 case '0':
974 return "ctor";
975 case '1':
976 return "dtor";
977 case '2':
978 return " new";
979 case '3':
980 return " delete";
981 case '4':
982 return "=";
983 case '5':
984 return ">>";
985 case '6':
986 return "<<";
987 case '7':
988 return "!";
989 case '8':
990 return "==";
991 case '9':
992 return "!=";
993 case 'A':
994 return "[]";
995 case 'C':
996 return "->";
997 case 'D':
998 return "*";
999 case 'E':
1000 return "++";
1001 case 'F':
1002 return "--";
1003 case 'G':
1004 return "-";
1005 case 'H':
1006 return "+";
1007 case 'I':
1008 return "&";
1009 case 'J':
1010 return "->*";
1011 case 'K':
1012 return "/";
1013 case 'L':
1014 return "%";
1015 case 'M':
1016 return "<";
1017 case 'N':
1018 return "<=";
1019 case 'O':
1020 return ">";
1021 case 'P':
1022 return ">=";
1023 case 'Q':
1024 return ",";
1025 case 'R':
1026 return "()";
1027 case 'S':
1028 return "~";
1029 case 'T':
1030 return "^";
1031 case 'U':
1032 return "|";
1033 case 'V':
1034 return "&&";
1035 case 'W':
1036 return "||";
1037 case 'X':
1038 return "*=";
1039 case 'Y':
1040 return "+=";
1041 case 'Z':
1042 return "-=";
1043 case '_': {
1044 if (MangledName.empty())
1045 break;
1046
1047 switch (MangledName.popFront()) {
1048 case '0':
1049 return "/=";
1050 case '1':
1051 return "%=";
1052 case '2':
1053 return ">>=";
1054 case '3':
1055 return "<<=";
1056 case '4':
1057 return "&=";
1058 case '5':
1059 return "|=";
1060 case '6':
1061 return "^=";
1062 case 'U':
1063 return " new[]";
1064 case 'V':
1065 return " delete[]";
1066 case '_':
1067 if (MangledName.consumeFront("L"))
1068 return " co_await";
1069 }
1070 }
1071 }
1072 Error = true;
1073 return "";
1074 };
1075
1076 Name *Node = Arena.alloc<Name>();
1077 Node->Operator = NameString();
1078 return Node;
1079}
1080
1081Name *Demangler::demangleSimpleName(bool Memorize) {
1082 Name *Node = Arena.alloc<Name>();
1083 for (size_t i = 0; i < MangledName.size(); ++i) {
1084 if (MangledName[i] != '@')
1085 continue;
1086 Node->Str = MangledName.substr(0, i);
1087 MangledName = MangledName.dropFront(i + 1);
1088
1089 if (Memorize)
1090 memorizeString(Node->Str);
1091 return Node;
1092 }
1093
1094 Error = true;
1095 return nullptr;
1096}
1097
1098Name *Demangler::demangleAnonymousNamespaceName() {
1099 assert(MangledName.startsWith("?A"));
1100 MangledName.consumeFront("?A");
1101
1102 Name *Node = Arena.alloc<Name>();
1103 Node->Str = "`anonymous namespace'";
1104 if (MangledName.consumeFront('@'))
1105 return Node;
1106
1107 Error = true;
1108 return nullptr;
1109}
1110
1111// Parses a type name in the form of A@B@C@@ which represents C::B::A.
1112Name *Demangler::demangleFullyQualifiedTypeName() {
1113 Name *TypeName = demangleUnqualifiedTypeName();
1114 assert(TypeName);
1115
1116 Name *QualName = demangleNameScopeChain(TypeName);
1117 assert(QualName);
1118 return QualName;
1119}
1120
1121// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1122// Symbol names have slightly different rules regarding what can appear
1123// so we separate out the implementations for flexibility.
1124Name *Demangler::demangleFullyQualifiedSymbolName() {
1125 Name *SymbolName = demangleUnqualifiedSymbolName();
1126 assert(SymbolName);
1127
1128 Name *QualName = demangleNameScopeChain(SymbolName);
1129 assert(QualName);
1130 return QualName;
1131}
1132
1133Name *Demangler::demangleUnqualifiedTypeName() {
1134 // An inner-most name can be a back-reference, because a fully-qualified name
1135 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1136 // them (for example template parameters), and these nested parameters can
1137 // refer to previously mangled types.
1138 if (startsWithDigit(MangledName))
1139 return demangleBackRefName();
1140
1141 if (MangledName.startsWith("?$"))
1142 return demangleClassTemplateName();
1143
1144 return demangleSimpleName(true);
1145}
1146
1147Name *Demangler::demangleUnqualifiedSymbolName() {
1148 if (MangledName.startsWith('?'))
1149 return demangleOperatorName();
1150 return demangleSimpleName(true);
1151}
1152
1153Name *Demangler::demangleNameScopePiece() {
1154 if (startsWithDigit(MangledName))
1155 return demangleBackRefName();
1156
1157 if (MangledName.startsWith("?$"))
1158 return demangleClassTemplateName();
1159
1160 if (MangledName.startsWith("?A"))
1161 return demangleAnonymousNamespaceName();
1162
1163 return demangleSimpleName(true);
1164}
1165
1166Name *Demangler::demangleNameScopeChain(Name *UnqualifiedName) {
1167 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001168
1169 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001170 if (MangledName.empty()) {
1171 Error = true;
1172 return nullptr;
1173 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001174
1175 assert(!Error);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001176 Name *Elem = demangleNameScopePiece();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001177 if (Error)
1178 return nullptr;
1179
1180 Elem->Next = Head;
1181 Head = Elem;
1182 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001183 return Head;
1184}
1185
Zachary Turner38b78a72018-07-26 20:20:10 +00001186FuncClass Demangler::demangleFunctionClass() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001187 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1188 RestoreOnError.shouldRestore(false);
1189
1190 switch (MangledName.popFront()) {
1191 case 'A':
1192 return Private;
1193 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001194 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001195 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001196 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001197 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001198 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001199 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001200 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001201 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001202 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001203 case 'I':
1204 return Protected;
1205 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001206 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001207 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001208 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001209 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001210 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001211 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001212 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001213 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001214 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001215 case 'Q':
1216 return Public;
1217 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001218 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001219 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001220 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001221 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001222 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001223 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001224 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001225 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001226 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001227 case 'Y':
1228 return Global;
1229 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001230 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001231 }
1232
1233 Error = true;
1234 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001235 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001236}
1237
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001238CallingConv Demangler::demangleCallingConvention() {
1239 switch (MangledName.popFront()) {
1240 case 'A':
1241 case 'B':
1242 return CallingConv::Cdecl;
1243 case 'C':
1244 case 'D':
1245 return CallingConv::Pascal;
1246 case 'E':
1247 case 'F':
1248 return CallingConv::Thiscall;
1249 case 'G':
1250 case 'H':
1251 return CallingConv::Stdcall;
1252 case 'I':
1253 case 'J':
1254 return CallingConv::Fastcall;
1255 case 'M':
1256 case 'N':
1257 return CallingConv::Clrcall;
1258 case 'O':
1259 case 'P':
1260 return CallingConv::Eabi;
1261 case 'Q':
1262 return CallingConv::Vectorcall;
1263 }
1264
1265 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001266}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001267
1268StorageClass Demangler::demangleVariableStorageClass() {
1269 assert(std::isdigit(MangledName.front()));
1270
1271 switch (MangledName.popFront()) {
1272 case '0':
1273 return StorageClass::PrivateStatic;
1274 case '1':
1275 return StorageClass::ProtectedStatic;
1276 case '2':
1277 return StorageClass::PublicStatic;
1278 case '3':
1279 return StorageClass::Global;
1280 case '4':
1281 return StorageClass::FunctionLocalStatic;
1282 }
1283 Error = true;
1284 return StorageClass::None;
1285}
1286
Zachary Turnerd742d642018-07-26 19:56:09 +00001287std::pair<Qualifiers, bool> Demangler::demangleQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001288
1289 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001290 // Member qualifiers
1291 case 'Q':
1292 return std::make_pair(Q_None, true);
1293 case 'R':
1294 return std::make_pair(Q_Const, true);
1295 case 'S':
1296 return std::make_pair(Q_Volatile, true);
1297 case 'T':
1298 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1299 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001300 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001301 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001302 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001303 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001304 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001305 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001306 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001307 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001308 }
1309 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001310 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001311}
1312
1313// <variable-type> ::= <type> <cvr-qualifiers>
1314// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1315Type *Demangler::demangleType(QualifierMangleMode QMM) {
1316 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001317 bool IsMember = false;
1318 bool IsMemberKnown = false;
1319 if (QMM == QualifierMangleMode::Mangle) {
1320 std::tie(Quals, IsMember) = demangleQualifiers();
1321 IsMemberKnown = true;
1322 } else if (QMM == QualifierMangleMode::Result) {
1323 if (MangledName.consumeFront('?')) {
1324 std::tie(Quals, IsMember) = demangleQualifiers();
1325 IsMemberKnown = true;
1326 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001327 }
1328
1329 Type *Ty = nullptr;
1330 switch (MangledName.front()) {
1331 case 'T': // union
1332 case 'U': // struct
1333 case 'V': // class
1334 case 'W': // enum
1335 Ty = demangleClassType();
1336 break;
1337 case 'A': // foo &
1338 case 'P': // foo *
1339 case 'Q': // foo *const
1340 case 'R': // foo *volatile
1341 case 'S': // foo *const volatile
Zachary Turnerd742d642018-07-26 19:56:09 +00001342 if (!IsMemberKnown)
1343 IsMember = isMemberPointer(MangledName);
1344 if (IsMember)
1345 Ty = demangleMemberPointerType();
1346 else
1347 Ty = demanglePointerType();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001348 break;
1349 case 'Y':
1350 Ty = demangleArrayType();
1351 break;
1352 default:
1353 Ty = demangleBasicType();
1354 break;
1355 }
1356 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1357 return Ty;
1358}
1359
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001360ReferenceKind Demangler::demangleReferenceKind() {
1361 if (MangledName.consumeFront('G'))
1362 return ReferenceKind::LValueRef;
1363 else if (MangledName.consumeFront('H'))
1364 return ReferenceKind::RValueRef;
1365 return ReferenceKind::None;
1366}
1367
Zachary Turner38b78a72018-07-26 20:20:10 +00001368void Demangler::demangleThrowSpecification() {
1369 if (MangledName.consumeFront('Z'))
1370 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001371
Zachary Turner38b78a72018-07-26 20:20:10 +00001372 Error = true;
1373}
1374
Zachary Turner024e1762018-07-26 20:33:48 +00001375FunctionType *Demangler::demangleFunctionType(bool HasThisQuals,
1376 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001377 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001378 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001379 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001380
1381 if (HasThisQuals) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001382 FTy->Quals = demanglePointerExtQualifiers();
1383 FTy->RefKind = demangleReferenceKind();
Zachary Turnerd742d642018-07-26 19:56:09 +00001384 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers().first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001385 }
1386
1387 // Fields that appear on both member and non-member functions.
1388 FTy->CallConvention = demangleCallingConvention();
1389
1390 // <return-type> ::= <type>
1391 // ::= @ # structors (they have no declared return type)
1392 bool IsStructor = MangledName.consumeFront('@');
1393 if (!IsStructor)
1394 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1395
Zachary Turner23df1312018-07-26 22:13:39 +00001396 FTy->Params = demangleFunctionParameterList();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001397
Zachary Turner38b78a72018-07-26 20:20:10 +00001398 demangleThrowSpecification();
1399
1400 return FTy;
1401}
1402
1403Type *Demangler::demangleFunctionEncoding() {
1404 FuncClass FC = demangleFunctionClass();
1405
1406 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner024e1762018-07-26 20:33:48 +00001407 FunctionType *FTy = demangleFunctionType(HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001408 FTy->FunctionClass = FC;
1409
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001410 return FTy;
1411}
1412
1413// Reads a primitive type.
1414Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001415 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001416
1417 switch (MangledName.popFront()) {
1418 case 'X':
1419 Ty->Prim = PrimTy::Void;
1420 break;
1421 case 'D':
1422 Ty->Prim = PrimTy::Char;
1423 break;
1424 case 'C':
1425 Ty->Prim = PrimTy::Schar;
1426 break;
1427 case 'E':
1428 Ty->Prim = PrimTy::Uchar;
1429 break;
1430 case 'F':
1431 Ty->Prim = PrimTy::Short;
1432 break;
1433 case 'G':
1434 Ty->Prim = PrimTy::Ushort;
1435 break;
1436 case 'H':
1437 Ty->Prim = PrimTy::Int;
1438 break;
1439 case 'I':
1440 Ty->Prim = PrimTy::Uint;
1441 break;
1442 case 'J':
1443 Ty->Prim = PrimTy::Long;
1444 break;
1445 case 'K':
1446 Ty->Prim = PrimTy::Ulong;
1447 break;
1448 case 'M':
1449 Ty->Prim = PrimTy::Float;
1450 break;
1451 case 'N':
1452 Ty->Prim = PrimTy::Double;
1453 break;
1454 case 'O':
1455 Ty->Prim = PrimTy::Ldouble;
1456 break;
1457 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001458 if (MangledName.empty()) {
1459 Error = true;
1460 return nullptr;
1461 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001462 switch (MangledName.popFront()) {
1463 case 'N':
1464 Ty->Prim = PrimTy::Bool;
1465 break;
1466 case 'J':
1467 Ty->Prim = PrimTy::Int64;
1468 break;
1469 case 'K':
1470 Ty->Prim = PrimTy::Uint64;
1471 break;
1472 case 'W':
1473 Ty->Prim = PrimTy::Wchar;
1474 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001475 default:
1476 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001477 }
1478 break;
1479 }
1480 }
1481 return Ty;
1482}
1483
1484UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001485 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001486
1487 switch (MangledName.popFront()) {
1488 case 'T':
1489 UTy->Prim = PrimTy::Union;
1490 break;
1491 case 'U':
1492 UTy->Prim = PrimTy::Struct;
1493 break;
1494 case 'V':
1495 UTy->Prim = PrimTy::Class;
1496 break;
1497 case 'W':
1498 if (MangledName.popFront() != '4') {
1499 Error = true;
1500 return nullptr;
1501 }
1502 UTy->Prim = PrimTy::Enum;
1503 break;
1504 default:
1505 assert(false);
1506 }
1507
Zachary Turnera7dffb12018-07-28 22:10:42 +00001508 UTy->UdtName = demangleFullyQualifiedTypeName();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001509 return UTy;
1510}
1511
Zachary Turnerd742d642018-07-26 19:56:09 +00001512static std::pair<Qualifiers, PointerAffinity>
1513demanglePointerCVQualifiers(StringView &MangledName) {
1514 switch (MangledName.popFront()) {
1515 case 'A':
1516 return std::make_pair(Q_None, PointerAffinity::Reference);
1517 case 'P':
1518 return std::make_pair(Q_None, PointerAffinity::Pointer);
1519 case 'Q':
1520 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1521 case 'R':
1522 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1523 case 'S':
1524 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1525 PointerAffinity::Pointer);
1526 default:
1527 assert(false && "Ty is not a pointer type!");
1528 }
1529 return std::make_pair(Q_None, PointerAffinity::Pointer);
1530}
1531
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001532// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1533// # the E is required for 64-bit non-static pointers
1534PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001535 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001536
Zachary Turnerd742d642018-07-26 19:56:09 +00001537 PointerAffinity Affinity;
1538 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001539
Zachary Turnerd742d642018-07-26 19:56:09 +00001540 Pointer->Prim =
1541 (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001542 if (MangledName.consumeFront("6")) {
Zachary Turner024e1762018-07-26 20:33:48 +00001543 Pointer->Pointee = demangleFunctionType(false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001544 return Pointer;
1545 }
1546
1547 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1548 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1549
1550 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1551 return Pointer;
1552}
1553
Zachary Turnerd742d642018-07-26 19:56:09 +00001554MemberPointerType *Demangler::demangleMemberPointerType() {
1555 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1556 Pointer->Prim = PrimTy::MemberPtr;
1557
1558 PointerAffinity Affinity;
1559 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1560 assert(Affinity == PointerAffinity::Pointer);
1561
1562 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1563 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1564
Zachary Turner38b78a72018-07-26 20:20:10 +00001565 if (MangledName.consumeFront("8")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001566 Pointer->MemberName = demangleFullyQualifiedSymbolName();
Zachary Turner024e1762018-07-26 20:33:48 +00001567 Pointer->Pointee = demangleFunctionType(true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001568 } else {
1569 Qualifiers PointeeQuals = Q_None;
1570 bool IsMember = false;
1571 std::tie(PointeeQuals, IsMember) = demangleQualifiers();
1572 assert(IsMember);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001573 Pointer->MemberName = demangleFullyQualifiedSymbolName();
Zachary Turnerd742d642018-07-26 19:56:09 +00001574
Zachary Turner38b78a72018-07-26 20:20:10 +00001575 Pointer->Pointee = demangleType(QualifierMangleMode::Drop);
1576 Pointer->Pointee->Quals = PointeeQuals;
1577 }
1578
Zachary Turnerd742d642018-07-26 19:56:09 +00001579 return Pointer;
1580}
1581
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001582Qualifiers Demangler::demanglePointerExtQualifiers() {
1583 Qualifiers Quals = Q_None;
1584 if (MangledName.consumeFront('E'))
1585 Quals = Qualifiers(Quals | Q_Pointer64);
1586 if (MangledName.consumeFront('I'))
1587 Quals = Qualifiers(Quals | Q_Restrict);
1588 if (MangledName.consumeFront('F'))
1589 Quals = Qualifiers(Quals | Q_Unaligned);
1590
1591 return Quals;
1592}
1593
1594ArrayType *Demangler::demangleArrayType() {
1595 assert(MangledName.front() == 'Y');
1596 MangledName.popFront();
1597
1598 int Dimension = demangleNumber();
1599 if (Dimension <= 0) {
1600 Error = true;
1601 return nullptr;
1602 }
1603
Zachary Turner9d72aa92018-07-20 18:35:06 +00001604 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001605 ArrayType *Dim = ATy;
1606 for (int I = 0; I < Dimension; ++I) {
1607 Dim->Prim = PrimTy::Array;
1608 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001609 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001610 Dim = Dim->NextDimension;
1611 }
1612
1613 if (MangledName.consumeFront("$$C")) {
1614 if (MangledName.consumeFront("B"))
1615 ATy->Quals = Q_Const;
1616 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1617 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1618 else if (!MangledName.consumeFront("A"))
1619 Error = true;
1620 }
1621
1622 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1623 Dim->ElementType = ATy->ElementType;
1624 return ATy;
1625}
1626
1627// Reads a function or a template parameters.
Zachary Turner23df1312018-07-26 22:13:39 +00001628ParamList Demangler::demangleFunctionParameterList() {
Zachary Turner38b78a72018-07-26 20:20:10 +00001629 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001630 if (MangledName.consumeFront('X'))
1631 return {};
1632
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001633 ParamList *Head;
1634 ParamList **Current = &Head;
1635 while (!Error && !MangledName.startsWith('@') &&
1636 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001637
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001638 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001639 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001640 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001641 Error = true;
1642 return {};
1643 }
1644 MangledName = MangledName.dropFront();
1645
Zachary Turner9d72aa92018-07-20 18:35:06 +00001646 *Current = Arena.alloc<ParamList>();
Zachary Turner23df1312018-07-26 22:13:39 +00001647 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001648 Current = &(*Current)->Next;
1649 continue;
1650 }
1651
Zachary Turner23df1312018-07-26 22:13:39 +00001652 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001653
Zachary Turner9d72aa92018-07-20 18:35:06 +00001654 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001655 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1656
Zachary Turner23df1312018-07-26 22:13:39 +00001657 size_t CharsConsumed = OldSize - MangledName.size();
1658 assert(CharsConsumed != 0);
1659
1660 // Single-letter types are ignored for backreferences because memorizing
1661 // them doesn't save anything.
1662 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1663 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1664
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001665 Current = &(*Current)->Next;
1666 }
1667
Zachary Turner38b78a72018-07-26 20:20:10 +00001668 if (Error)
1669 return {};
1670
1671 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1672 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1673 // the following Z could be a throw specifier.
1674 if (MangledName.consumeFront('@'))
1675 return *Head;
1676
1677 if (MangledName.consumeFront('Z')) {
1678 Head->IsVariadic = true;
1679 return *Head;
1680 }
1681
1682 Error = true;
1683 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001684}
1685
Zachary Turner23df1312018-07-26 22:13:39 +00001686ParamList Demangler::demangleTemplateParameterList() {
1687 ParamList *Head;
1688 ParamList **Current = &Head;
1689 while (!Error && !MangledName.startsWith('@')) {
1690
1691 // Template parameter lists don't participate in back-referencing.
1692 *Current = Arena.alloc<ParamList>();
1693 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1694
1695 Current = &(*Current)->Next;
1696 }
1697
1698 if (Error)
1699 return {};
1700
1701 // Template parameter lists cannot be variadic, so it can only be terminated
1702 // by @.
1703 if (MangledName.consumeFront('@'))
1704 return *Head;
1705 Error = true;
1706 return {};
1707}
1708
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001709void Demangler::output() {
1710 // Converts an AST to a string.
1711 //
1712 // Converting an AST representing a C++ type to a string is tricky due
1713 // to the bad grammar of the C++ declaration inherited from C. You have
1714 // to construct a string from inside to outside. For example, if a type
1715 // X is a pointer to a function returning int, the order you create a
1716 // string becomes something like this:
1717 //
1718 // (1) X is a pointer: *X
1719 // (2) (1) is a function returning int: int (*X)()
1720 //
1721 // So you cannot construct a result just by appending strings to a result.
1722 //
1723 // To deal with this, we split the function into two. outputPre() writes
1724 // the "first half" of type declaration, and outputPost() writes the
1725 // "second half". For example, outputPre() writes a return type for a
1726 // function and outputPost() writes an parameter list.
1727 Type::outputPre(OS, *SymbolType);
1728 outputName(OS, SymbolName);
1729 Type::outputPost(OS, *SymbolType);
1730
1731 // Null terminate the buffer.
1732 OS << '\0';
1733}
1734
1735char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1736 int *Status) {
1737 OutputStream OS = OutputStream::create(Buf, N, 1024);
1738
1739 Demangler D(OS, StringView(MangledName));
1740 D.parse();
1741
1742 if (D.Error)
1743 *Status = llvm::demangle_invalid_mangled_name;
1744 else
1745 *Status = llvm::demangle_success;
1746
1747 D.output();
1748 return OS.getBuffer();
1749}