blob: 99a1f23503ae350dcf69fb80964b1661fc4a6c1b [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 Turner5ae08b82018-08-01 18:44:12 +000024#include <cstdio>
Zachary Turnerd742d642018-07-26 19:56:09 +000025#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000026
27// This memory allocator is extremely fast, but it doesn't call dtors
28// for allocated objects. That means you can't use STL containers
29// (such as std::vector) with this allocator. But it pays off --
30// the demangler is 3x faster with this allocator compared to one with
31// STL containers.
32namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000033 constexpr size_t AllocUnit = 4096;
34
Zachary Turnerf435a7e2018-07-20 17:27:48 +000035class ArenaAllocator {
36 struct AllocatorNode {
37 uint8_t *Buf = nullptr;
38 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000039 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000040 AllocatorNode *Next = nullptr;
41 };
42
Zachary Turner71c91f92018-07-30 03:12:34 +000043 void addNode(size_t Capacity) {
44 AllocatorNode *NewHead = new AllocatorNode;
45 NewHead->Buf = new uint8_t[Capacity];
46 NewHead->Next = Head;
47 NewHead->Capacity = Capacity;
48 Head = NewHead;
49 NewHead->Used = 0;
50 }
51
Zachary Turnerf435a7e2018-07-20 17:27:48 +000052public:
Zachary Turnera6869512018-07-30 03:25:27 +000053 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000054
55 ~ArenaAllocator() {
56 while (Head) {
57 assert(Head->Buf);
58 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000059 AllocatorNode *Next = Head->Next;
60 delete Head;
61 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000062 }
63 }
64
Zachary Turner71c91f92018-07-30 03:12:34 +000065 char *allocUnalignedBuffer(size_t Length) {
66 uint8_t *Buf = Head->Buf + Head->Used;
67
68 Head->Used += Length;
69 if (Head->Used > Head->Capacity) {
70 // It's possible we need a buffer which is larger than our default unit
71 // size, so we need to be careful to add a node with capacity that is at
72 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000073 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000074 Head->Used = Length;
75 Buf = Head->Buf;
76 }
77
78 return reinterpret_cast<char *>(Buf);
79 }
80
Zachary Turner9d72aa92018-07-20 18:35:06 +000081 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
82
83 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000084 assert(Head && Head->Buf);
85
Zachary Turner9d72aa92018-07-20 18:35:06 +000086 size_t P = (size_t)Head->Buf + Head->Used;
87 uintptr_t AlignedP =
88 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
89 uint8_t *PP = (uint8_t *)AlignedP;
90 size_t Adjustment = AlignedP - P;
91
92 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000093 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000094 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000095
Zachary Turnera6869512018-07-30 03:25:27 +000096 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000097 Head->Used = Size;
98 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000099 }
100
101private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000102 AllocatorNode *Head = nullptr;
103};
104} // namespace
105
106static bool startsWithDigit(StringView S) {
107 return !S.empty() && std::isdigit(S.front());
108}
109
110// Writes a space if the last token does not end with a punctuation.
111static void outputSpaceIfNecessary(OutputStream &OS) {
112 if (OS.empty())
113 return;
114
115 char C = OS.back();
116 if (isalnum(C) || C == '>')
117 OS << " ";
118}
119
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000120// Storage classes
121enum Qualifiers : uint8_t {
122 Q_None = 0,
123 Q_Const = 1 << 0,
124 Q_Volatile = 1 << 1,
125 Q_Far = 1 << 2,
126 Q_Huge = 1 << 3,
127 Q_Unaligned = 1 << 4,
128 Q_Restrict = 1 << 5,
129 Q_Pointer64 = 1 << 6
130};
131
132enum class StorageClass : uint8_t {
133 None,
134 PrivateStatic,
135 ProtectedStatic,
136 PublicStatic,
137 Global,
138 FunctionLocalStatic
139};
140
141enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000142
Zachary Turner931e8792018-07-30 23:02:10 +0000143enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000144
145// Calling conventions
146enum class CallingConv : uint8_t {
147 None,
148 Cdecl,
149 Pascal,
150 Thiscall,
151 Stdcall,
152 Fastcall,
153 Clrcall,
154 Eabi,
155 Vectorcall,
156 Regcall,
157};
158
159enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
160
161// Types
162enum class PrimTy : uint8_t {
163 Unknown,
164 None,
165 Function,
166 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000167 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000168 Array,
169
170 Struct,
171 Union,
172 Class,
173 Enum,
174
175 Void,
176 Bool,
177 Char,
178 Schar,
179 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000180 Char16,
181 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000182 Short,
183 Ushort,
184 Int,
185 Uint,
186 Long,
187 Ulong,
188 Int64,
189 Uint64,
190 Wchar,
191 Float,
192 Double,
193 Ldouble,
Zachary Turner931e8792018-07-30 23:02:10 +0000194 Nullptr
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000195};
196
197// Function classes
Zachary Turner29ec67b2018-08-10 21:09:05 +0000198enum FuncClass : uint16_t {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000199 Public = 1 << 0,
200 Protected = 1 << 1,
201 Private = 1 << 2,
202 Global = 1 << 3,
203 Static = 1 << 4,
204 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000205 Far = 1 << 6,
Zachary Turner29ec67b2018-08-10 21:09:05 +0000206 ExternC = 1 << 7,
207 NoPrototype = 1 << 8,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000208};
209
Zachary Turner58d29cf2018-08-08 00:43:31 +0000210enum NameBackrefBehavior : uint8_t {
211 NBB_None = 0, // don't save any names as backrefs.
212 NBB_Template = 1 << 0, // save template instanations.
213 NBB_Simple = 1 << 1, // save simple names.
214};
215
Zachary Turner83313f82018-08-16 16:17:17 +0000216enum class SymbolCategory { Function, Variable, Unknown };
Zachary Turner44ebbc22018-08-01 18:32:47 +0000217
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000218namespace {
219
Zachary Turner172aea12018-08-02 17:08:03 +0000220struct NameResolver {
Zachary Turnerae672182018-08-02 17:33:33 +0000221 virtual ~NameResolver() = default;
Zachary Turner172aea12018-08-02 17:08:03 +0000222 virtual StringView resolve(StringView S) = 0;
223};
224
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000225struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000226struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000227
Zachary Turnerd30700f2018-07-31 17:16:44 +0000228struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000229 bool IsVariadic = false;
230
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000231 Type *Current = nullptr;
232
Zachary Turnerd30700f2018-07-31 17:16:44 +0000233 FunctionParams *Next = nullptr;
234};
Zachary Turner931e8792018-07-30 23:02:10 +0000235
Zachary Turnerd30700f2018-07-31 17:16:44 +0000236struct TemplateParams {
237 bool IsTemplateTemplate = false;
238 bool IsAliasTemplate = false;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000239 bool IsIntegerLiteral = false;
240 bool IntegerLiteralIsNegative = false;
241 bool IsEmptyParameterPack = false;
242 bool PointerToSymbol = false;
243 bool ReferenceToSymbol = false;
244
245 // If IsIntegerLiteral is true, this is a non-type template parameter
246 // whose value is contained in this field.
247 uint64_t IntegralValue = 0;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000248
249 // Type can be null if this is a template template parameter. In that case
250 // only Name will be valid.
251 Type *ParamType = nullptr;
252
253 // Name can be valid if this is a template template parameter (see above) or
254 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
255 // Name contains the name of the function and Type contains the signature.
256 Name *ParamName = nullptr;
257
258 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000259};
260
261// The type class. Mangled symbols are first parsed and converted to
262// this type and then converted to string.
263struct Type {
264 virtual ~Type() {}
265
266 virtual Type *clone(ArenaAllocator &Arena) const;
267
268 // Write the "first half" of a given type. This is a static functions to
269 // give the code a chance to do processing that is common to a subset of
270 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000271 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000272
273 // Write the "second half" of a given type. This is a static functions to
274 // give the code a chance to do processing that is common to a subset of
275 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000276 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000277
Zachary Turner172aea12018-08-02 17:08:03 +0000278 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
279 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000280
281 // Primitive type such as Int.
282 PrimTy Prim = PrimTy::Unknown;
283
284 Qualifiers Quals = Q_None;
285 StorageClass Storage = StorageClass::None; // storage class
286};
287
288// Represents an identifier which may be a template.
289struct Name {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000290 bool IsTemplateInstantiation = false;
291 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000292 bool IsBackReference = false;
Zachary Turnera17721c2018-08-10 15:04:56 +0000293 bool IsConversionOperator = false;
294
295 // Name read from an MangledName string.
296 StringView Str;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000297
Zachary Turner44ebbc22018-08-01 18:32:47 +0000298 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000299 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000300
301 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
302 Name *Next = nullptr;
303};
304
305struct PointerType : public Type {
306 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000307 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
308 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000309
Zachary Turner931e8792018-07-30 23:02:10 +0000310 PointerAffinity Affinity;
311
Zachary Turnerd742d642018-07-26 19:56:09 +0000312 // Represents a type X in "a pointer to X", "a reference to X",
313 // "an array of X", or "a function returning X".
314 Type *Pointee = nullptr;
315};
316
317struct MemberPointerType : public Type {
318 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000319 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
320 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000321
322 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000323
324 // Represents a type X in "a pointer to X", "a reference to X",
325 // "an array of X", or "a function returning X".
326 Type *Pointee = nullptr;
327};
328
329struct FunctionType : public Type {
330 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000331 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
332 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000333
Zachary Turner024e1762018-07-26 20:33:48 +0000334 // True if this FunctionType instance is the Pointee of a PointerType or
335 // MemberPointerType.
336 bool IsFunctionPointer = false;
337
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000338 Type *ReturnType = nullptr;
339 // If this is a reference, the type of reference.
340 ReferenceKind RefKind;
341
342 CallingConv CallConvention;
343 FuncClass FunctionClass;
344
Zachary Turnerd30700f2018-07-31 17:16:44 +0000345 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000346};
347
348struct UdtType : public Type {
349 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000350 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000351
352 Name *UdtName = nullptr;
353};
354
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000355struct ArrayDimension {
356 uint64_t Dim = 0;
357 ArrayDimension *Next = nullptr;
358};
359
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000360struct ArrayType : public Type {
361 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000362 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
363 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000364
365 // Either NextDimension or ElementType will be valid.
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000366 ArrayDimension *Dims = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000367
368 Type *ElementType = nullptr;
369};
370
371} // namespace
372
Zachary Turnerd742d642018-07-26 19:56:09 +0000373static bool isMemberPointer(StringView MangledName) {
374 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000375 case '$':
376 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
377 // rvalue reference to a member.
378 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000379 case 'A':
380 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000381 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000382 return false;
383 case 'P':
384 case 'Q':
385 case 'R':
386 case 'S':
387 // These 4 values indicate some kind of pointer, but we still don't know
388 // what.
389 break;
390 default:
391 assert(false && "Ty is not a pointer type!");
392 }
393
394 // If it starts with a number, then 6 indicates a non-member function
395 // pointer, and 8 indicates a member function pointer.
396 if (startsWithDigit(MangledName)) {
397 assert(MangledName[0] == '6' || MangledName[0] == '8');
398 return (MangledName[0] == '8');
399 }
400
401 // Remove ext qualifiers since those can appear on either type and are
402 // therefore not indicative.
403 MangledName.consumeFront('E'); // 64-bit
404 MangledName.consumeFront('I'); // restrict
405 MangledName.consumeFront('F'); // unaligned
406
407 assert(!MangledName.empty());
408
409 // The next value should be either ABCD (non-member) or QRST (member).
410 switch (MangledName.front()) {
411 case 'A':
412 case 'B':
413 case 'C':
414 case 'D':
415 return false;
416 case 'Q':
417 case 'R':
418 case 'S':
419 case 'T':
420 return true;
421 default:
422 assert(false);
423 }
424 return false;
425}
426
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000427static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
428 outputSpaceIfNecessary(OS);
429
430 switch (CC) {
431 case CallingConv::Cdecl:
432 OS << "__cdecl";
433 break;
434 case CallingConv::Fastcall:
435 OS << "__fastcall";
436 break;
437 case CallingConv::Pascal:
438 OS << "__pascal";
439 break;
440 case CallingConv::Regcall:
441 OS << "__regcall";
442 break;
443 case CallingConv::Stdcall:
444 OS << "__stdcall";
445 break;
446 case CallingConv::Thiscall:
447 OS << "__thiscall";
448 break;
449 case CallingConv::Eabi:
450 OS << "__eabi";
451 break;
452 case CallingConv::Vectorcall:
453 OS << "__vectorcall";
454 break;
455 case CallingConv::Clrcall:
456 OS << "__clrcall";
457 break;
458 default:
459 break;
460 }
461}
462
Zachary Turner71c91f92018-07-30 03:12:34 +0000463static bool startsWithLocalScopePattern(StringView S) {
464 if (!S.consumeFront('?'))
465 return false;
466 if (S.size() < 2)
467 return false;
468
469 size_t End = S.find('?');
470 if (End == StringView::npos)
471 return false;
472 StringView Candidate = S.substr(0, End);
473 if (Candidate.empty())
474 return false;
475
476 // \?[0-9]\?
477 // ?@? is the discriminator 0.
478 if (Candidate.size() == 1)
479 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
480
481 // If it's not 0-9, then it's an encoded number terminated with an @
482 if (Candidate.back() != '@')
483 return false;
484 Candidate = Candidate.dropBack();
485
486 // An encoded number starts with B-P and all subsequent digits are in A-P.
487 // Note that the reason the first digit cannot be A is two fold. First, it
488 // would create an ambiguity with ?A which delimits the beginning of an
489 // anonymous namespace. Second, A represents 0, and you don't start a multi
490 // digit number with a leading 0. Presumably the anonymous namespace
491 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
492 if (Candidate[0] < 'B' || Candidate[0] > 'P')
493 return false;
494 Candidate = Candidate.dropFront();
495 while (!Candidate.empty()) {
496 if (Candidate[0] < 'A' || Candidate[0] > 'P')
497 return false;
498 Candidate = Candidate.dropFront();
499 }
500
501 return true;
502}
503
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000504// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000505static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
506 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000507 if (!Params.Current) {
508 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000509 return;
510 }
511
Zachary Turnerd30700f2018-07-31 17:16:44 +0000512 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000513 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000514 Type::outputPre(OS, *Head->Current, Resolver);
515 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000516
517 Head = Head->Next;
518
519 if (Head)
520 OS << ", ";
521 }
522}
523
Zachary Turnera17721c2018-08-10 15:04:56 +0000524static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000525 NameResolver &Resolver);
526
527static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
528 NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000529 if (Params.IsEmptyParameterPack) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000530 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000531 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000532 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000533
534 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000535 const TemplateParams *Head = &Params;
536 while (Head) {
537 // Type can be null if this is a template template parameter,
538 // and Name can be null if this is a simple type.
539
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000540 if (Head->IsIntegerLiteral) {
541 if (Head->IntegerLiteralIsNegative)
542 OS << '-';
543 OS << Head->IntegralValue;
544 } else if (Head->PointerToSymbol || Head->ReferenceToSymbol) {
545 if (Head->PointerToSymbol)
546 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000547 Type::outputPre(OS, *Head->ParamType, Resolver);
Zachary Turnera17721c2018-08-10 15:04:56 +0000548 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turner172aea12018-08-02 17:08:03 +0000549 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000550 } else if (Head->ParamType) {
551 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000552 Type::outputPre(OS, *Head->ParamType, Resolver);
553 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000554 } else {
555 // Template alias.
Zachary Turnera17721c2018-08-10 15:04:56 +0000556 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000557 }
558
559 Head = Head->Next;
560
561 if (Head)
562 OS << ", ";
563 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000564 OS << ">";
565}
566
Zachary Turner172aea12018-08-02 17:08:03 +0000567static void outputNameComponent(OutputStream &OS, const Name &N,
568 NameResolver &Resolver) {
Zachary Turnera17721c2018-08-10 15:04:56 +0000569 if (N.IsConversionOperator) {
570 OS << " conv";
571 } else {
572 StringView S = N.Str;
Zachary Turner172aea12018-08-02 17:08:03 +0000573
Zachary Turnera17721c2018-08-10 15:04:56 +0000574 if (N.IsBackReference)
575 S = Resolver.resolve(N.Str);
576 OS << S;
577 }
Zachary Turner172aea12018-08-02 17:08:03 +0000578
Zachary Turnera17721c2018-08-10 15:04:56 +0000579 if (N.IsTemplateInstantiation && N.TParams)
Zachary Turner172aea12018-08-02 17:08:03 +0000580 outputParameterList(OS, *N.TParams, Resolver);
581}
582
Zachary Turnera17721c2018-08-10 15:04:56 +0000583static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000584 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000585 if (!TheName)
586 return;
587
588 outputSpaceIfNecessary(OS);
589
Zachary Turnera7dffb12018-07-28 22:10:42 +0000590 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000591 // Print out namespaces or outer class BackReferences.
592 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000593 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000594 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000595 OS << "::";
596 }
597
598 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000599 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000600 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000601 return;
602 }
603
604 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000605 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000606 OS << "~";
607
Zachary Turner44ebbc22018-08-01 18:32:47 +0000608 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turner172aea12018-08-02 17:08:03 +0000609 outputNameComponent(OS, *Previous, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000610 return;
611 }
612
Zachary Turnera17721c2018-08-10 15:04:56 +0000613 if (TheName->IsConversionOperator) {
614 OS << "operator";
615 if (TheName->IsTemplateInstantiation && TheName->TParams)
616 outputParameterList(OS, *TheName->TParams, Resolver);
617 OS << " ";
618 if (Ty) {
619 const FunctionType *FTy = static_cast<const FunctionType *>(Ty);
620 Type::outputPre(OS, *FTy->ReturnType, Resolver);
621 Type::outputPost(OS, *FTy->ReturnType, Resolver);
622 } else {
623 OS << "<conversion>";
624 }
625 } else {
626 // Print out an overloaded operator.
627 OS << "operator";
628 outputNameComponent(OS, *TheName, Resolver);
629 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000630}
631
632namespace {
633
634Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000635 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000636}
637
638// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000639void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000640 // Function types require custom handling of const and static so we
641 // handle them separately. All other types use the same decoration
642 // for these modifiers, so handle them here in common code.
643 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000644 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000645 return;
646 }
647
648 switch (Ty.Storage) {
649 case StorageClass::PrivateStatic:
650 case StorageClass::PublicStatic:
651 case StorageClass::ProtectedStatic:
652 OS << "static ";
653 default:
654 break;
655 }
Zachary Turner172aea12018-08-02 17:08:03 +0000656 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000657
658 if (Ty.Quals & Q_Const) {
659 outputSpaceIfNecessary(OS);
660 OS << "const";
661 }
662
663 if (Ty.Quals & Q_Volatile) {
664 outputSpaceIfNecessary(OS);
665 OS << "volatile";
666 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000667
668 if (Ty.Quals & Q_Restrict) {
669 outputSpaceIfNecessary(OS);
670 OS << "__restrict";
671 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000672}
673
674// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000675void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
676 Ty.outputPost(OS, Resolver);
677}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000678
Zachary Turner172aea12018-08-02 17:08:03 +0000679void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000680 switch (Prim) {
681 case PrimTy::Void:
682 OS << "void";
683 break;
684 case PrimTy::Bool:
685 OS << "bool";
686 break;
687 case PrimTy::Char:
688 OS << "char";
689 break;
690 case PrimTy::Schar:
691 OS << "signed char";
692 break;
693 case PrimTy::Uchar:
694 OS << "unsigned char";
695 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000696 case PrimTy::Char16:
697 OS << "char16_t";
698 break;
699 case PrimTy::Char32:
700 OS << "char32_t";
701 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000702 case PrimTy::Short:
703 OS << "short";
704 break;
705 case PrimTy::Ushort:
706 OS << "unsigned short";
707 break;
708 case PrimTy::Int:
709 OS << "int";
710 break;
711 case PrimTy::Uint:
712 OS << "unsigned int";
713 break;
714 case PrimTy::Long:
715 OS << "long";
716 break;
717 case PrimTy::Ulong:
718 OS << "unsigned long";
719 break;
720 case PrimTy::Int64:
721 OS << "__int64";
722 break;
723 case PrimTy::Uint64:
724 OS << "unsigned __int64";
725 break;
726 case PrimTy::Wchar:
727 OS << "wchar_t";
728 break;
729 case PrimTy::Float:
730 OS << "float";
731 break;
732 case PrimTy::Double:
733 OS << "double";
734 break;
735 case PrimTy::Ldouble:
736 OS << "long double";
737 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000738 case PrimTy::Nullptr:
739 OS << "std::nullptr_t";
740 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000741 default:
742 assert(false && "Invalid primitive type!");
743 }
744}
Zachary Turner172aea12018-08-02 17:08:03 +0000745void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000746
747Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000748 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000749}
750
Zachary Turner024e1762018-07-26 20:33:48 +0000751static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +0000752 const Name *MemberName, const Type *Pointee,
753 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +0000754 // "[]" and "()" (for function parameters) take precedence over "*",
755 // so "int *x(int)" means "x is a function returning int *". We need
756 // parentheses to supercede the default precedence. (e.g. we want to
757 // emit something like "int (*x)(int)".)
758 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
759 OS << "(";
760 if (Pointee->Prim == PrimTy::Function) {
761 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
762 assert(FTy->IsFunctionPointer);
763 outputCallingConvention(OS, FTy->CallConvention);
764 OS << " ";
765 }
766 }
767
768 if (MemberName) {
Zachary Turnera17721c2018-08-10 15:04:56 +0000769 outputName(OS, MemberName, Pointee, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +0000770 OS << "::";
771 }
772
773 if (Affinity == PointerAffinity::Pointer)
774 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000775 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000776 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000777 else
778 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000779}
780
Zachary Turner172aea12018-08-02 17:08:03 +0000781void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
782 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000783
784 outputSpaceIfNecessary(OS);
785
786 if (Quals & Q_Unaligned)
787 OS << "__unaligned ";
788
Zachary Turner172aea12018-08-02 17:08:03 +0000789 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000790
Zachary Turner91ecedd2018-07-20 18:07:33 +0000791 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000792 // if (Ty.Quals & Q_Pointer64)
793 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000794}
795
Zachary Turner172aea12018-08-02 17:08:03 +0000796void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000797 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
798 OS << ")";
799
Zachary Turner172aea12018-08-02 17:08:03 +0000800 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000801}
802
Zachary Turnerd742d642018-07-26 19:56:09 +0000803Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
804 return Arena.alloc<MemberPointerType>(*this);
805}
806
Zachary Turner172aea12018-08-02 17:08:03 +0000807void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
808 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000809
810 outputSpaceIfNecessary(OS);
811
Zachary Turner172aea12018-08-02 17:08:03 +0000812 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
813 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000814
815 // FIXME: We should output this, but it requires updating lots of tests.
816 // if (Ty.Quals & Q_Pointer64)
817 // OS << " __ptr64";
Zachary Turnerd742d642018-07-26 19:56:09 +0000818}
819
Zachary Turner172aea12018-08-02 17:08:03 +0000820void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +0000821 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
822 OS << ")";
823
Zachary Turner172aea12018-08-02 17:08:03 +0000824 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000825}
826
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000827Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000828 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000829}
830
Zachary Turner172aea12018-08-02 17:08:03 +0000831void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000832 if (!(FunctionClass & Global)) {
833 if (FunctionClass & Static)
834 OS << "static ";
835 }
Zachary Turner29ec67b2018-08-10 21:09:05 +0000836 if (FunctionClass & ExternC) {
837 OS << "extern \"C\" ";
838 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000839
Zachary Turner38b78a72018-07-26 20:20:10 +0000840 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +0000841 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +0000842 OS << " ";
843 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000844
Zachary Turner024e1762018-07-26 20:33:48 +0000845 // Function pointers print the calling convention as void (__cdecl *)(params)
846 // rather than void __cdecl (*)(params). So we need to let the PointerType
847 // class handle this.
848 if (!IsFunctionPointer)
849 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000850}
851
Zachary Turner172aea12018-08-02 17:08:03 +0000852void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turner29ec67b2018-08-10 21:09:05 +0000853 // extern "C" functions don't have a prototype.
854 if (FunctionClass & NoPrototype)
855 return;
856
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000857 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +0000858 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000859 OS << ")";
860 if (Quals & Q_Const)
861 OS << " const";
862 if (Quals & Q_Volatile)
863 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000864 if (Quals & Q_Restrict)
865 OS << " __restrict";
866 if (Quals & Q_Unaligned)
867 OS << " __unaligned";
868
869 if (RefKind == ReferenceKind::LValueRef)
870 OS << " &";
871 else if (RefKind == ReferenceKind::RValueRef)
872 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000873
874 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +0000875 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000876 return;
877}
878
879Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000880 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000881}
882
Zachary Turner172aea12018-08-02 17:08:03 +0000883void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000884 switch (Prim) {
885 case PrimTy::Class:
886 OS << "class ";
887 break;
888 case PrimTy::Struct:
889 OS << "struct ";
890 break;
891 case PrimTy::Union:
892 OS << "union ";
893 break;
894 case PrimTy::Enum:
895 OS << "enum ";
896 break;
897 default:
898 assert(false && "Not a udt type!");
899 }
900
Zachary Turnera17721c2018-08-10 15:04:56 +0000901 outputName(OS, UdtName, this, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000902}
903
904Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000905 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000906}
907
Zachary Turner172aea12018-08-02 17:08:03 +0000908void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
909 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000910}
911
Zachary Turner172aea12018-08-02 17:08:03 +0000912void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000913 ArrayDimension *D = Dims;
914 while (D) {
915 OS << "[";
916 if (D->Dim > 0)
917 OS << D->Dim;
918 OS << "]";
919 D = D->Next;
920 }
921
922 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000923}
924
Zachary Turner316109b2018-07-29 16:38:02 +0000925struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000926 SymbolCategory Category;
927
Zachary Turner316109b2018-07-29 16:38:02 +0000928 Name *SymbolName = nullptr;
929 Type *SymbolType = nullptr;
930};
931
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000932} // namespace
933
934namespace {
935
Zachary Turnerd346cba2018-08-08 17:17:04 +0000936struct BackrefContext {
937 static constexpr size_t Max = 10;
938
939 Type *FunctionParams[Max];
940 size_t FunctionParamCount = 0;
941
942 // The first 10 BackReferences in a mangled name can be back-referenced by
943 // special name @[0-9]. This is a storage for the first 10 BackReferences.
944 StringView Names[Max];
945 size_t NamesCount = 0;
946};
947
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000948// Demangler class takes the main role in demangling symbols.
949// It has a set of functions to parse mangled symbols into Type instances.
950// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +0000951class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000952public:
Zachary Turner316109b2018-07-29 16:38:02 +0000953 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +0000954 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000955
956 // You are supposed to call parse() first and then check if error is true. If
957 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000958 Symbol *parse(StringView &MangledName);
959 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000960
Zachary Turner172aea12018-08-02 17:08:03 +0000961 StringView resolve(StringView N) override;
962
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000963 // True if an error occurred.
964 bool Error = false;
965
Zachary Turner3a758e22018-08-01 18:33:04 +0000966 void dumpBackReferences();
967
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000968private:
Zachary Turner316109b2018-07-29 16:38:02 +0000969 Type *demangleVariableEncoding(StringView &MangledName);
970 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000971
Zachary Turner316109b2018-07-29 16:38:02 +0000972 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000973
974 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000975 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
976 Type *demangleBasicType(StringView &MangledName);
977 UdtType *demangleClassType(StringView &MangledName);
978 PointerType *demanglePointerType(StringView &MangledName);
979 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
980 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
981 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000982
Zachary Turner316109b2018-07-29 16:38:02 +0000983 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000984
Zachary Turnerd30700f2018-07-31 17:16:44 +0000985 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
986 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000987
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000988 std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000989
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000990 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000991
992 /// Allocate a copy of \p Borrowed into memory that we own.
993 StringView copyString(StringView Borrowed);
994
Zachary Turner316109b2018-07-29 16:38:02 +0000995 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
996 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000997
Zachary Turner44ebbc22018-08-01 18:32:47 +0000998 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
Zachary Turner58d29cf2018-08-08 00:43:31 +0000999 Name *demangleUnqualifiedSymbolName(StringView &MangledName,
1000 NameBackrefBehavior NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001001
Zachary Turner316109b2018-07-29 16:38:02 +00001002 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
1003 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001004
Zachary Turner316109b2018-07-29 16:38:02 +00001005 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001006 Name *demangleTemplateInstantiationName(StringView &MangledName,
1007 NameBackrefBehavior NBB);
Zachary Turner316109b2018-07-29 16:38:02 +00001008 Name *demangleOperatorName(StringView &MangledName);
1009 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
1010 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001011 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001012
Zachary Turner931e8792018-07-30 23:02:10 +00001013 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
1014
Zachary Turner316109b2018-07-29 16:38:02 +00001015 FuncClass demangleFunctionClass(StringView &MangledName);
1016 CallingConv demangleCallingConvention(StringView &MangledName);
1017 StorageClass demangleVariableStorageClass(StringView &MangledName);
1018 ReferenceKind demangleReferenceKind(StringView &MangledName);
1019 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001020
Zachary Turner316109b2018-07-29 16:38:02 +00001021 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001022
1023 // Memory allocator.
1024 ArenaAllocator Arena;
1025
Zachary Turner23df1312018-07-26 22:13:39 +00001026 // A single type uses one global back-ref table for all function params.
1027 // This means back-refs can even go "into" other types. Examples:
1028 //
1029 // // Second int* is a back-ref to first.
1030 // void foo(int *, int*);
1031 //
1032 // // Second int* is not a back-ref to first (first is not a function param).
1033 // int* foo(int*);
1034 //
1035 // // Second int* is a back-ref to first (ALL function types share the same
1036 // // back-ref map.
1037 // using F = void(*)(int*);
1038 // F G(int *);
Zachary Turnerd346cba2018-08-08 17:17:04 +00001039 BackrefContext Backrefs;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001040};
1041} // namespace
1042
Zachary Turner71c91f92018-07-30 03:12:34 +00001043StringView Demangler::copyString(StringView Borrowed) {
1044 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
1045 std::strcpy(Stable, Borrowed.begin());
1046
1047 return {Stable, Borrowed.size()};
1048}
1049
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001050// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +00001051Symbol *Demangler::parse(StringView &MangledName) {
1052 Symbol *S = Arena.alloc<Symbol>();
1053
Zachary Turner83313f82018-08-16 16:17:17 +00001054 // We can't demangle MD5 names, just output them as-is.
1055 if (MangledName.startsWith("??@")) {
1056 S->Category = SymbolCategory::Unknown;
1057 S->SymbolName = Arena.alloc<Name>();
1058 S->SymbolName->Str = MangledName;
1059 MangledName = StringView();
1060 return S;
1061 }
1062
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001063 // MSVC-style mangled symbols must start with '?'.
1064 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001065 S->SymbolName = Arena.alloc<Name>();
1066 S->SymbolName->Str = MangledName;
1067 S->SymbolType = Arena.alloc<Type>();
1068 S->SymbolType->Prim = PrimTy::Unknown;
1069 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001070 }
1071
1072 // What follows is a main symbol name. This may include
1073 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +00001074 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001075 if (Error)
1076 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001077 // Read a variable.
Zachary Turner29ec67b2018-08-10 21:09:05 +00001078 if (startsWithDigit(MangledName) && !MangledName.startsWith('9')) {
1079 // 9 is a special marker for an extern "C" function with
1080 // no prototype.
Zachary Turner44ebbc22018-08-01 18:32:47 +00001081 S->Category = SymbolCategory::Variable;
1082 S->SymbolType = demangleVariableEncoding(MangledName);
1083 } else {
1084 S->Category = SymbolCategory::Function;
1085 S->SymbolType = demangleFunctionEncoding(MangledName);
1086 }
1087
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001088 if (Error)
1089 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001090
Zachary Turner316109b2018-07-29 16:38:02 +00001091 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001092}
1093
1094// <type-encoding> ::= <storage-class> <variable-type>
1095// <storage-class> ::= 0 # private static member
1096// ::= 1 # protected static member
1097// ::= 2 # public static member
1098// ::= 3 # global
1099// ::= 4 # static local
1100
Zachary Turner316109b2018-07-29 16:38:02 +00001101Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1102 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001103
Zachary Turner316109b2018-07-29 16:38:02 +00001104 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105
1106 Ty->Storage = SC;
1107
1108 // <variable-type> ::= <type> <cvr-qualifiers>
1109 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1110 switch (Ty->Prim) {
1111 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001112 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001113 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001114 Ty->Quals =
1115 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001116
Zachary Turnerd742d642018-07-26 19:56:09 +00001117 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001118 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001119
Zachary Turnerd742d642018-07-26 19:56:09 +00001120 if (Ty->Prim == PrimTy::MemberPtr) {
1121 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001122 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001123 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001124 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1125 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1126 } else {
1127 PointerType *PTy = static_cast<PointerType *>(Ty);
1128 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001129 }
1130
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001131 break;
1132 }
1133 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001134 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001135 break;
1136 }
1137
1138 return Ty;
1139}
1140
1141// Sometimes numbers are encoded in mangled symbols. For example,
1142// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1143// length 20), so we need some way to embed numbers as part of symbols.
1144// This function parses it.
1145//
1146// <number> ::= [?] <non-negative integer>
1147//
1148// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1149// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1150//
1151// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001152std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
1153 bool IsNegative = MangledName.consumeFront('?');
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001154
1155 if (startsWithDigit(MangledName)) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001156 uint64_t Ret = MangledName[0] - '0' + 1;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001157 MangledName = MangledName.dropFront(1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001158 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001159 }
1160
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001161 uint64_t Ret = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001162 for (size_t i = 0; i < MangledName.size(); ++i) {
1163 char C = MangledName[i];
1164 if (C == '@') {
1165 MangledName = MangledName.dropFront(i + 1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001166 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001167 }
1168 if ('A' <= C && C <= 'P') {
1169 Ret = (Ret << 4) + (C - 'A');
1170 continue;
1171 }
1172 break;
1173 }
1174
1175 Error = true;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001176 return {0ULL, false};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001177}
1178
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001179// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1180// Memorize it.
1181void Demangler::memorizeString(StringView S) {
Zachary Turnerd346cba2018-08-08 17:17:04 +00001182 if (Backrefs.NamesCount >= BackrefContext::Max)
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001183 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001184 for (size_t i = 0; i < Backrefs.NamesCount; ++i)
1185 if (S == Backrefs.Names[i])
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001186 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001187 Backrefs.Names[Backrefs.NamesCount++] = S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001188}
1189
Zachary Turner316109b2018-07-29 16:38:02 +00001190Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001191 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001192 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001193 Node->IsBackReference = true;
1194 Node->Str = {MangledName.begin(), 1};
1195 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001196 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001197}
1198
Zachary Turner58d29cf2018-08-08 00:43:31 +00001199Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName,
1200 NameBackrefBehavior NBB) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001201 assert(MangledName.startsWith("?$"));
1202 MangledName.consumeFront("?$");
1203
Zachary Turnerd346cba2018-08-08 17:17:04 +00001204 BackrefContext OuterContext;
1205 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001206
Zachary Turnerd346cba2018-08-08 17:17:04 +00001207 Name *Node = demangleUnqualifiedSymbolName(MangledName, NBB_None);
1208 if (!Error)
1209 Node->TParams = demangleTemplateParameterList(MangledName);
1210
1211 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001212 if (Error)
1213 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001214
Zachary Turner44ebbc22018-08-01 18:32:47 +00001215 Node->IsTemplateInstantiation = true;
1216
Zachary Turner58d29cf2018-08-08 00:43:31 +00001217 if (NBB & NBB_Template) {
1218 // Render this class template name into a string buffer so that we can
1219 // memorize it for the purpose of back-referencing.
1220 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turnera17721c2018-08-10 15:04:56 +00001221 outputName(OS, Node, nullptr, *this);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001222 OS << '\0';
1223 char *Name = OS.getBuffer();
Zachary Turner71c91f92018-07-30 03:12:34 +00001224
Zachary Turner58d29cf2018-08-08 00:43:31 +00001225 StringView Owned = copyString(Name);
1226 memorizeString(Owned);
1227 std::free(Name);
1228 }
Zachary Turner71c91f92018-07-30 03:12:34 +00001229
Zachary Turnera7dffb12018-07-28 22:10:42 +00001230 return Node;
1231}
1232
Zachary Turner316109b2018-07-29 16:38:02 +00001233Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001234 assert(MangledName.startsWith('?'));
1235 MangledName.consumeFront('?');
1236
Zachary Turner316109b2018-07-29 16:38:02 +00001237 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001238 switch (MangledName.popFront()) {
1239 case '0':
1240 return "ctor";
1241 case '1':
1242 return "dtor";
1243 case '2':
1244 return " new";
1245 case '3':
1246 return " delete";
1247 case '4':
1248 return "=";
1249 case '5':
1250 return ">>";
1251 case '6':
1252 return "<<";
1253 case '7':
1254 return "!";
1255 case '8':
1256 return "==";
1257 case '9':
1258 return "!=";
1259 case 'A':
1260 return "[]";
1261 case 'C':
1262 return "->";
1263 case 'D':
1264 return "*";
1265 case 'E':
1266 return "++";
1267 case 'F':
1268 return "--";
1269 case 'G':
1270 return "-";
1271 case 'H':
1272 return "+";
1273 case 'I':
1274 return "&";
1275 case 'J':
1276 return "->*";
1277 case 'K':
1278 return "/";
1279 case 'L':
1280 return "%";
1281 case 'M':
1282 return "<";
1283 case 'N':
1284 return "<=";
1285 case 'O':
1286 return ">";
1287 case 'P':
1288 return ">=";
1289 case 'Q':
1290 return ",";
1291 case 'R':
1292 return "()";
1293 case 'S':
1294 return "~";
1295 case 'T':
1296 return "^";
1297 case 'U':
1298 return "|";
1299 case 'V':
1300 return "&&";
1301 case 'W':
1302 return "||";
1303 case 'X':
1304 return "*=";
1305 case 'Y':
1306 return "+=";
1307 case 'Z':
1308 return "-=";
1309 case '_': {
1310 if (MangledName.empty())
1311 break;
1312
1313 switch (MangledName.popFront()) {
1314 case '0':
1315 return "/=";
1316 case '1':
1317 return "%=";
1318 case '2':
1319 return ">>=";
1320 case '3':
1321 return "<<=";
1322 case '4':
1323 return "&=";
1324 case '5':
1325 return "|=";
1326 case '6':
1327 return "^=";
1328 case 'U':
1329 return " new[]";
1330 case 'V':
1331 return " delete[]";
1332 case '_':
1333 if (MangledName.consumeFront("L"))
1334 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001335 if (MangledName.consumeFront("K")) {
1336 size_t EndPos = MangledName.find('@');
1337 if (EndPos == StringView::npos)
1338 break;
1339 StringView OpName = demangleSimpleString(MangledName, false);
1340 size_t FullSize = OpName.size() + 3; // <space>""OpName
1341 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1342 Buffer[0] = ' ';
1343 Buffer[1] = '"';
1344 Buffer[2] = '"';
1345 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1346 return {Buffer, FullSize};
1347 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001348 }
1349 }
1350 }
1351 Error = true;
1352 return "";
1353 };
1354
1355 Name *Node = Arena.alloc<Name>();
Zachary Turnera17721c2018-08-10 15:04:56 +00001356 if (MangledName.consumeFront('B')) {
1357 // Handle conversion operator specially.
1358 Node->IsConversionOperator = true;
1359 } else {
1360 Node->Str = NameString();
1361 }
Zachary Turner44ebbc22018-08-01 18:32:47 +00001362 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001363 return Node;
1364}
1365
Zachary Turner316109b2018-07-29 16:38:02 +00001366Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001367 StringView S = demangleSimpleString(MangledName, Memorize);
1368 if (Error)
1369 return nullptr;
1370
Zachary Turnera7dffb12018-07-28 22:10:42 +00001371 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001372 Node->Str = S;
1373 return Node;
1374}
1375
1376StringView Demangler::demangleSimpleString(StringView &MangledName,
1377 bool Memorize) {
1378 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001379 for (size_t i = 0; i < MangledName.size(); ++i) {
1380 if (MangledName[i] != '@')
1381 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001382 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001383 MangledName = MangledName.dropFront(i + 1);
1384
1385 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001386 memorizeString(S);
1387 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001388 }
1389
1390 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001391 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001392}
1393
Zachary Turner316109b2018-07-29 16:38:02 +00001394Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001395 assert(MangledName.startsWith("?A"));
1396 MangledName.consumeFront("?A");
1397
1398 Name *Node = Arena.alloc<Name>();
1399 Node->Str = "`anonymous namespace'";
1400 if (MangledName.consumeFront('@'))
1401 return Node;
1402
1403 Error = true;
1404 return nullptr;
1405}
1406
Zachary Turner71c91f92018-07-30 03:12:34 +00001407Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1408 assert(startsWithLocalScopePattern(MangledName));
1409
1410 Name *Node = Arena.alloc<Name>();
1411 MangledName.consumeFront('?');
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001412 auto Number = demangleNumber(MangledName);
1413 assert(!Number.second);
Zachary Turner71c91f92018-07-30 03:12:34 +00001414
1415 // One ? to terminate the number
1416 MangledName.consumeFront('?');
1417
1418 assert(!Error);
1419 Symbol *Scope = parse(MangledName);
1420 if (Error)
1421 return nullptr;
1422
1423 // Render the parent symbol's name into a buffer.
1424 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1425 OS << '`';
1426 output(Scope, OS);
1427 OS << '\'';
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001428 OS << "::`" << Number.first << "'";
Zachary Turner71c91f92018-07-30 03:12:34 +00001429 OS << '\0';
1430 char *Result = OS.getBuffer();
1431 Node->Str = copyString(Result);
1432 std::free(Result);
1433 return Node;
1434}
1435
Zachary Turnera7dffb12018-07-28 22:10:42 +00001436// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001437Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001438 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001439 if (Error)
1440 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001441 assert(TypeName);
1442
Zachary Turner316109b2018-07-29 16:38:02 +00001443 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001444 if (Error)
1445 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001446 assert(QualName);
1447 return QualName;
1448}
1449
1450// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1451// Symbol names have slightly different rules regarding what can appear
1452// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001453Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00001454 // This is the final component of a symbol name (i.e. the leftmost component
1455 // of a mangled name. Since the only possible template instantiation that
1456 // can appear in this context is a function template, and since those are
1457 // not saved for the purposes of name backreferences, only backref simple
1458 // names.
1459 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001460 if (Error)
1461 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001462 assert(SymbolName);
1463
Zachary Turner316109b2018-07-29 16:38:02 +00001464 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001465 if (Error)
1466 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001467 assert(QualName);
1468 return QualName;
1469}
1470
Zachary Turner44ebbc22018-08-01 18:32:47 +00001471Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1472 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001473 // An inner-most name can be a back-reference, because a fully-qualified name
1474 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1475 // them (for example template parameters), and these nested parameters can
1476 // refer to previously mangled types.
1477 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001478 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001479
1480 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001481 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001482
Zachary Turner44ebbc22018-08-01 18:32:47 +00001483 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001484}
1485
Zachary Turner44ebbc22018-08-01 18:32:47 +00001486Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00001487 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001488 if (startsWithDigit(MangledName))
1489 return demangleBackRefName(MangledName);
1490 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001491 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001492 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001493 return demangleOperatorName(MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001494 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001495}
1496
Zachary Turner316109b2018-07-29 16:38:02 +00001497Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001498 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001499 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001500
1501 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001502 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001503
1504 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001505 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001506
Zachary Turner71c91f92018-07-30 03:12:34 +00001507 if (startsWithLocalScopePattern(MangledName))
1508 return demangleLocallyScopedNamePiece(MangledName);
1509
Zachary Turner316109b2018-07-29 16:38:02 +00001510 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001511}
1512
Zachary Turner316109b2018-07-29 16:38:02 +00001513Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1514 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001515 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001516
1517 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001518 if (MangledName.empty()) {
1519 Error = true;
1520 return nullptr;
1521 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001522
1523 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001524 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001525 if (Error)
1526 return nullptr;
1527
1528 Elem->Next = Head;
1529 Head = Elem;
1530 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001531 return Head;
1532}
1533
Zachary Turner316109b2018-07-29 16:38:02 +00001534FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001535 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1536 RestoreOnError.shouldRestore(false);
1537
Zachary Turner29ec67b2018-08-10 21:09:05 +00001538 FuncClass TempFlags = FuncClass(0);
1539 if (MangledName.consumeFront("$$J0"))
1540 TempFlags = ExternC;
1541
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001542 switch (MangledName.popFront()) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00001543 case '9':
1544 return FuncClass(TempFlags | ExternC | NoPrototype);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001545 case 'A':
1546 return Private;
1547 case 'B':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001548 return FuncClass(TempFlags | Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001549 case 'C':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001550 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001551 case 'D':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001552 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001553 case 'E':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001554 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001555 case 'F':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001556 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001557 case 'I':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001558 return FuncClass(TempFlags | Protected);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001559 case 'J':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001560 return FuncClass(TempFlags | Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001561 case 'K':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001562 return FuncClass(TempFlags | Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001563 case 'L':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001564 return FuncClass(TempFlags | Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001565 case 'M':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001566 return FuncClass(TempFlags | Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001567 case 'N':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001568 return FuncClass(TempFlags | Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001569 case 'Q':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001570 return FuncClass(TempFlags | Public);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001571 case 'R':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001572 return FuncClass(TempFlags | Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001573 case 'S':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001574 return FuncClass(TempFlags | Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001575 case 'T':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001576 return FuncClass(TempFlags | Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001577 case 'U':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001578 return FuncClass(TempFlags | Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001579 case 'V':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001580 return FuncClass(TempFlags | Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001581 case 'Y':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001582 return FuncClass(TempFlags | Global);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001583 case 'Z':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001584 return FuncClass(TempFlags | Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001585 }
1586
1587 Error = true;
1588 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001589 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001590}
1591
Zachary Turner316109b2018-07-29 16:38:02 +00001592CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001593 switch (MangledName.popFront()) {
1594 case 'A':
1595 case 'B':
1596 return CallingConv::Cdecl;
1597 case 'C':
1598 case 'D':
1599 return CallingConv::Pascal;
1600 case 'E':
1601 case 'F':
1602 return CallingConv::Thiscall;
1603 case 'G':
1604 case 'H':
1605 return CallingConv::Stdcall;
1606 case 'I':
1607 case 'J':
1608 return CallingConv::Fastcall;
1609 case 'M':
1610 case 'N':
1611 return CallingConv::Clrcall;
1612 case 'O':
1613 case 'P':
1614 return CallingConv::Eabi;
1615 case 'Q':
1616 return CallingConv::Vectorcall;
1617 }
1618
1619 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001620}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001621
Zachary Turner316109b2018-07-29 16:38:02 +00001622StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001623 assert(std::isdigit(MangledName.front()));
1624
1625 switch (MangledName.popFront()) {
1626 case '0':
1627 return StorageClass::PrivateStatic;
1628 case '1':
1629 return StorageClass::ProtectedStatic;
1630 case '2':
1631 return StorageClass::PublicStatic;
1632 case '3':
1633 return StorageClass::Global;
1634 case '4':
1635 return StorageClass::FunctionLocalStatic;
1636 }
1637 Error = true;
1638 return StorageClass::None;
1639}
1640
Zachary Turner316109b2018-07-29 16:38:02 +00001641std::pair<Qualifiers, bool>
1642Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001643
1644 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001645 // Member qualifiers
1646 case 'Q':
1647 return std::make_pair(Q_None, true);
1648 case 'R':
1649 return std::make_pair(Q_Const, true);
1650 case 'S':
1651 return std::make_pair(Q_Volatile, true);
1652 case 'T':
1653 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1654 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001655 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001656 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001657 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001658 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001659 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001660 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001661 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001662 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001663 }
1664 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001665 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001666}
1667
Zachary Turner931e8792018-07-30 23:02:10 +00001668static bool isTagType(StringView S) {
1669 switch (S.front()) {
1670 case 'T': // union
1671 case 'U': // struct
1672 case 'V': // class
1673 case 'W': // enum
1674 return true;
1675 }
1676 return false;
1677}
1678
1679static bool isPointerType(StringView S) {
1680 if (S.startsWith("$$Q")) // foo &&
1681 return true;
1682
1683 switch (S.front()) {
1684 case 'A': // foo &
1685 case 'P': // foo *
1686 case 'Q': // foo *const
1687 case 'R': // foo *volatile
1688 case 'S': // foo *const volatile
1689 return true;
1690 }
1691 return false;
1692}
1693
1694static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1695
1696static bool isFunctionType(StringView S) {
1697 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1698}
1699
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001700// <variable-type> ::= <type> <cvr-qualifiers>
1701// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001702Type *Demangler::demangleType(StringView &MangledName,
1703 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001704 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001705 bool IsMember = false;
1706 bool IsMemberKnown = false;
1707 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001708 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001709 IsMemberKnown = true;
1710 } else if (QMM == QualifierMangleMode::Result) {
1711 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001712 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001713 IsMemberKnown = true;
1714 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001715 }
1716
1717 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001718 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001719 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001720 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001721 if (!IsMemberKnown)
1722 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001723
Zachary Turnerd742d642018-07-26 19:56:09 +00001724 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001725 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001726 else
Zachary Turner316109b2018-07-29 16:38:02 +00001727 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001728 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001729 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001730 else if (isFunctionType(MangledName)) {
1731 if (MangledName.consumeFront("$$A8@@"))
1732 Ty = demangleFunctionType(MangledName, true, false);
1733 else {
1734 assert(MangledName.startsWith("$$A6"));
1735 MangledName.consumeFront("$$A6");
1736 Ty = demangleFunctionType(MangledName, false, false);
1737 }
1738 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001739 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001740 assert(Ty && !Error);
1741 if (!Ty || Error)
1742 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001743 }
Zachary Turner931e8792018-07-30 23:02:10 +00001744
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001745 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1746 return Ty;
1747}
1748
Zachary Turner316109b2018-07-29 16:38:02 +00001749ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001750 if (MangledName.consumeFront('G'))
1751 return ReferenceKind::LValueRef;
1752 else if (MangledName.consumeFront('H'))
1753 return ReferenceKind::RValueRef;
1754 return ReferenceKind::None;
1755}
1756
Zachary Turner316109b2018-07-29 16:38:02 +00001757void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001758 if (MangledName.consumeFront('Z'))
1759 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001760
Zachary Turner38b78a72018-07-26 20:20:10 +00001761 Error = true;
1762}
1763
Zachary Turner316109b2018-07-29 16:38:02 +00001764FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1765 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001766 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001767 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001768 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001769 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001770
1771 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001772 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1773 FTy->RefKind = demangleReferenceKind(MangledName);
1774 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001775 }
1776
1777 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001778 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001779
1780 // <return-type> ::= <type>
1781 // ::= @ # structors (they have no declared return type)
1782 bool IsStructor = MangledName.consumeFront('@');
1783 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001784 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001785
Zachary Turner316109b2018-07-29 16:38:02 +00001786 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001787
Zachary Turner316109b2018-07-29 16:38:02 +00001788 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001789
1790 return FTy;
1791}
1792
Zachary Turner316109b2018-07-29 16:38:02 +00001793Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1794 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner29ec67b2018-08-10 21:09:05 +00001795 FunctionType *FTy = nullptr;
1796 if (FC & NoPrototype) {
1797 // This is an extern "C" function whose full signature hasn't been mangled.
1798 // This happens when we need to mangle a local symbol inside of an extern
1799 // "C" function.
1800 FTy = Arena.alloc<FunctionType>();
1801 } else {
1802 bool HasThisQuals = !(FC & (Global | Static));
1803 FTy = demangleFunctionType(MangledName, HasThisQuals, false);
1804 }
Zachary Turner38b78a72018-07-26 20:20:10 +00001805 FTy->FunctionClass = FC;
1806
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001807 return FTy;
1808}
1809
1810// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001811Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001812 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001813
Zachary Turner931e8792018-07-30 23:02:10 +00001814 if (MangledName.consumeFront("$$T")) {
1815 Ty->Prim = PrimTy::Nullptr;
1816 return Ty;
1817 }
1818
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001819 switch (MangledName.popFront()) {
1820 case 'X':
1821 Ty->Prim = PrimTy::Void;
1822 break;
1823 case 'D':
1824 Ty->Prim = PrimTy::Char;
1825 break;
1826 case 'C':
1827 Ty->Prim = PrimTy::Schar;
1828 break;
1829 case 'E':
1830 Ty->Prim = PrimTy::Uchar;
1831 break;
1832 case 'F':
1833 Ty->Prim = PrimTy::Short;
1834 break;
1835 case 'G':
1836 Ty->Prim = PrimTy::Ushort;
1837 break;
1838 case 'H':
1839 Ty->Prim = PrimTy::Int;
1840 break;
1841 case 'I':
1842 Ty->Prim = PrimTy::Uint;
1843 break;
1844 case 'J':
1845 Ty->Prim = PrimTy::Long;
1846 break;
1847 case 'K':
1848 Ty->Prim = PrimTy::Ulong;
1849 break;
1850 case 'M':
1851 Ty->Prim = PrimTy::Float;
1852 break;
1853 case 'N':
1854 Ty->Prim = PrimTy::Double;
1855 break;
1856 case 'O':
1857 Ty->Prim = PrimTy::Ldouble;
1858 break;
1859 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001860 if (MangledName.empty()) {
1861 Error = true;
1862 return nullptr;
1863 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001864 switch (MangledName.popFront()) {
1865 case 'N':
1866 Ty->Prim = PrimTy::Bool;
1867 break;
1868 case 'J':
1869 Ty->Prim = PrimTy::Int64;
1870 break;
1871 case 'K':
1872 Ty->Prim = PrimTy::Uint64;
1873 break;
1874 case 'W':
1875 Ty->Prim = PrimTy::Wchar;
1876 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001877 case 'S':
1878 Ty->Prim = PrimTy::Char16;
1879 break;
1880 case 'U':
1881 Ty->Prim = PrimTy::Char32;
1882 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001883 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001884 Error = true;
1885 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001886 }
1887 break;
1888 }
Zachary Turner931e8792018-07-30 23:02:10 +00001889 default:
1890 Error = true;
1891 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001892 }
1893 return Ty;
1894}
1895
Zachary Turner316109b2018-07-29 16:38:02 +00001896UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001897 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001898
1899 switch (MangledName.popFront()) {
1900 case 'T':
1901 UTy->Prim = PrimTy::Union;
1902 break;
1903 case 'U':
1904 UTy->Prim = PrimTy::Struct;
1905 break;
1906 case 'V':
1907 UTy->Prim = PrimTy::Class;
1908 break;
1909 case 'W':
1910 if (MangledName.popFront() != '4') {
1911 Error = true;
1912 return nullptr;
1913 }
1914 UTy->Prim = PrimTy::Enum;
1915 break;
1916 default:
1917 assert(false);
1918 }
1919
Zachary Turner316109b2018-07-29 16:38:02 +00001920 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001921 return UTy;
1922}
1923
Zachary Turnerd742d642018-07-26 19:56:09 +00001924static std::pair<Qualifiers, PointerAffinity>
1925demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001926 if (MangledName.consumeFront("$$Q"))
1927 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1928
Zachary Turnerd742d642018-07-26 19:56:09 +00001929 switch (MangledName.popFront()) {
1930 case 'A':
1931 return std::make_pair(Q_None, PointerAffinity::Reference);
1932 case 'P':
1933 return std::make_pair(Q_None, PointerAffinity::Pointer);
1934 case 'Q':
1935 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1936 case 'R':
1937 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1938 case 'S':
1939 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1940 PointerAffinity::Pointer);
1941 default:
1942 assert(false && "Ty is not a pointer type!");
1943 }
1944 return std::make_pair(Q_None, PointerAffinity::Pointer);
1945}
1946
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001947// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1948// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001949PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001950 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001951
Zachary Turner931e8792018-07-30 23:02:10 +00001952 std::tie(Pointer->Quals, Pointer->Affinity) =
1953 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001954
Zachary Turner931e8792018-07-30 23:02:10 +00001955 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001956 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001957 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001958 return Pointer;
1959 }
1960
Zachary Turner316109b2018-07-29 16:38:02 +00001961 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001962 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1963
Zachary Turner316109b2018-07-29 16:38:02 +00001964 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001965 return Pointer;
1966}
1967
Zachary Turner316109b2018-07-29 16:38:02 +00001968MemberPointerType *
1969Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001970 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1971 Pointer->Prim = PrimTy::MemberPtr;
1972
1973 PointerAffinity Affinity;
1974 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1975 assert(Affinity == PointerAffinity::Pointer);
1976
Zachary Turner316109b2018-07-29 16:38:02 +00001977 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001978 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1979
Zachary Turner38b78a72018-07-26 20:20:10 +00001980 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001981 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1982 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001983 } else {
1984 Qualifiers PointeeQuals = Q_None;
1985 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001986 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001987 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001988 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001989
Zachary Turner316109b2018-07-29 16:38:02 +00001990 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001991 Pointer->Pointee->Quals = PointeeQuals;
1992 }
1993
Zachary Turnerd742d642018-07-26 19:56:09 +00001994 return Pointer;
1995}
1996
Zachary Turner316109b2018-07-29 16:38:02 +00001997Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001998 Qualifiers Quals = Q_None;
1999 if (MangledName.consumeFront('E'))
2000 Quals = Qualifiers(Quals | Q_Pointer64);
2001 if (MangledName.consumeFront('I'))
2002 Quals = Qualifiers(Quals | Q_Restrict);
2003 if (MangledName.consumeFront('F'))
2004 Quals = Qualifiers(Quals | Q_Unaligned);
2005
2006 return Quals;
2007}
2008
Zachary Turner316109b2018-07-29 16:38:02 +00002009ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002010 assert(MangledName.front() == 'Y');
2011 MangledName.popFront();
2012
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002013 uint64_t Rank = 0;
2014 bool IsNegative = false;
2015 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2016 if (IsNegative || Rank == 0) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002017 Error = true;
2018 return nullptr;
2019 }
2020
Zachary Turner9d72aa92018-07-20 18:35:06 +00002021 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002022 ATy->Prim = PrimTy::Array;
2023 ATy->Dims = Arena.alloc<ArrayDimension>();
2024 ArrayDimension *Dim = ATy->Dims;
2025 for (uint64_t I = 0; I < Rank; ++I) {
2026 std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
2027 if (IsNegative) {
2028 Error = true;
2029 return nullptr;
2030 }
2031 if (I + 1 < Rank) {
2032 Dim->Next = Arena.alloc<ArrayDimension>();
2033 Dim = Dim->Next;
2034 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002035 }
2036
2037 if (MangledName.consumeFront("$$C")) {
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002038 bool IsMember = false;
2039 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2040 if (IsMember) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002041 Error = true;
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002042 return nullptr;
2043 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002044 }
2045
Zachary Turner316109b2018-07-29 16:38:02 +00002046 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002047 return ATy;
2048}
2049
2050// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002051FunctionParams
2052Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002053 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00002054 if (MangledName.consumeFront('X'))
2055 return {};
2056
Zachary Turnerd30700f2018-07-31 17:16:44 +00002057 FunctionParams *Head;
2058 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002059 while (!Error && !MangledName.startsWith('@') &&
2060 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002061
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002062 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00002063 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002064 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002065 Error = true;
2066 return {};
2067 }
2068 MangledName = MangledName.dropFront();
2069
Zachary Turnerd30700f2018-07-31 17:16:44 +00002070 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00002071 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002072 Current = &(*Current)->Next;
2073 continue;
2074 }
2075
Zachary Turner23df1312018-07-26 22:13:39 +00002076 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002077
Zachary Turnerd30700f2018-07-31 17:16:44 +00002078 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00002079 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002080
Zachary Turner23df1312018-07-26 22:13:39 +00002081 size_t CharsConsumed = OldSize - MangledName.size();
2082 assert(CharsConsumed != 0);
2083
2084 // Single-letter types are ignored for backreferences because memorizing
2085 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002086 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2087 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2088 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002089
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002090 Current = &(*Current)->Next;
2091 }
2092
Zachary Turner38b78a72018-07-26 20:20:10 +00002093 if (Error)
2094 return {};
2095
2096 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2097 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2098 // the following Z could be a throw specifier.
2099 if (MangledName.consumeFront('@'))
2100 return *Head;
2101
2102 if (MangledName.consumeFront('Z')) {
2103 Head->IsVariadic = true;
2104 return *Head;
2105 }
2106
2107 Error = true;
2108 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002109}
2110
Zachary Turnerd30700f2018-07-31 17:16:44 +00002111TemplateParams *
2112Demangler::demangleTemplateParameterList(StringView &MangledName) {
2113 TemplateParams *Head;
2114 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002115 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002116 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002117 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002118
2119 // Empty parameter pack.
2120 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2121 MangledName.consumeFront("$$$V")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002122 (*Current)->IsEmptyParameterPack = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002123 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002124 }
2125
Zachary Turnerd30700f2018-07-31 17:16:44 +00002126 if (MangledName.consumeFront("$$Y")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002127 // Template alias
Zachary Turnerd30700f2018-07-31 17:16:44 +00002128 (*Current)->IsTemplateTemplate = true;
2129 (*Current)->IsAliasTemplate = true;
2130 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002131 } else if (MangledName.consumeFront("$$B")) {
2132 // Array
2133 (*Current)->ParamType =
2134 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner073620b2018-08-10 19:57:36 +00002135 } else if (MangledName.consumeFront("$$C")) {
2136 // Type has qualifiers.
2137 (*Current)->ParamType =
2138 demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002139 } else if (MangledName.startsWith("$1?")) {
2140 MangledName.consumeFront("$1");
2141 // Pointer to symbol
2142 Symbol *S = parse(MangledName);
2143 (*Current)->ParamName = S->SymbolName;
2144 (*Current)->ParamType = S->SymbolType;
2145 (*Current)->PointerToSymbol = true;
2146 } else if (MangledName.startsWith("$E?")) {
2147 MangledName.consumeFront("$E");
2148 // Reference to symbol
2149 Symbol *S = parse(MangledName);
2150 (*Current)->ParamName = S->SymbolName;
2151 (*Current)->ParamType = S->SymbolType;
2152 (*Current)->ReferenceToSymbol = true;
2153 } else if (MangledName.consumeFront("$0")) {
2154 // Integral non-type template parameter
2155 bool IsNegative = false;
2156 uint64_t Value = 0;
2157 std::tie(Value, IsNegative) = demangleNumber(MangledName);
2158
2159 (*Current)->IsIntegerLiteral = true;
2160 (*Current)->IntegerLiteralIsNegative = IsNegative;
2161 (*Current)->IntegralValue = Value;
Zachary Turnerd30700f2018-07-31 17:16:44 +00002162 } else {
2163 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002164 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002165 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002166 if (Error)
2167 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002168
2169 Current = &(*Current)->Next;
2170 }
2171
2172 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002173 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002174
2175 // Template parameter lists cannot be variadic, so it can only be terminated
2176 // by @.
2177 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002178 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002179 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002180 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002181}
2182
Zachary Turner172aea12018-08-02 17:08:03 +00002183StringView Demangler::resolve(StringView N) {
2184 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002185 size_t Digit = N[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002186 if (Digit >= Backrefs.NamesCount)
Zachary Turner172aea12018-08-02 17:08:03 +00002187 return N;
Zachary Turnerd346cba2018-08-08 17:17:04 +00002188 return Backrefs.Names[Digit];
Zachary Turner172aea12018-08-02 17:08:03 +00002189}
2190
Zachary Turner316109b2018-07-29 16:38:02 +00002191void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turner83313f82018-08-16 16:17:17 +00002192 if (S->Category == SymbolCategory::Unknown) {
2193 outputName(OS, S->SymbolName, S->SymbolType, *this);
2194 return;
2195 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002196 // Converts an AST to a string.
2197 //
2198 // Converting an AST representing a C++ type to a string is tricky due
2199 // to the bad grammar of the C++ declaration inherited from C. You have
2200 // to construct a string from inside to outside. For example, if a type
2201 // X is a pointer to a function returning int, the order you create a
2202 // string becomes something like this:
2203 //
2204 // (1) X is a pointer: *X
2205 // (2) (1) is a function returning int: int (*X)()
2206 //
2207 // So you cannot construct a result just by appending strings to a result.
2208 //
2209 // To deal with this, we split the function into two. outputPre() writes
2210 // the "first half" of type declaration, and outputPost() writes the
2211 // "second half". For example, outputPre() writes a return type for a
2212 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002213 Type::outputPre(OS, *S->SymbolType, *this);
Zachary Turnera17721c2018-08-10 15:04:56 +00002214 outputName(OS, S->SymbolName, S->SymbolType, *this);
Zachary Turner172aea12018-08-02 17:08:03 +00002215 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002216}
2217
Zachary Turner3a758e22018-08-01 18:33:04 +00002218void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002219 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00002220 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002221
2222 // Create an output stream so we can render each type.
2223 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00002224 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00002225 OS.setCurrentPosition(0);
2226
Zachary Turnerd346cba2018-08-08 17:17:04 +00002227 Type *T = Backrefs.FunctionParams[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002228 Type::outputPre(OS, *T, *this);
2229 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002230
Zachary Turner7563ebe2018-08-02 17:08:24 +00002231 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002232 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002233 }
2234 std::free(OS.getBuffer());
2235
Zachary Turnerd346cba2018-08-08 17:17:04 +00002236 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002237 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00002238 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
2239 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
2240 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
2241 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002242 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00002243 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002244 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002245}
2246
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002247char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002248 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002249 Demangler D;
2250 StringView Name{MangledName};
2251 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002252
Zachary Turner3a758e22018-08-01 18:33:04 +00002253 if (Flags & MSDF_DumpBackrefs)
2254 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002255 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002256 if (D.Error) {
2257 OS << MangledName;
2258 *Status = llvm::demangle_invalid_mangled_name;
2259 } else {
2260 D.output(S, OS);
2261 *Status = llvm::demangle_success;
2262 }
2263
Zachary Turner71c91f92018-07-30 03:12:34 +00002264 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002265 return OS.getBuffer();
2266}