blob: 5aa90395c7d25462bd62bb16c876dfdf6aa9d036 [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
198enum FuncClass : uint8_t {
199 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 Turnerf435a7e2018-07-20 17:27:48 +0000206};
207
Zachary Turner58d29cf2018-08-08 00:43:31 +0000208enum NameBackrefBehavior : uint8_t {
209 NBB_None = 0, // don't save any names as backrefs.
210 NBB_Template = 1 << 0, // save template instanations.
211 NBB_Simple = 1 << 1, // save simple names.
212};
213
Zachary Turner44ebbc22018-08-01 18:32:47 +0000214enum class SymbolCategory { Function, Variable };
215
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000216namespace {
217
Zachary Turner172aea12018-08-02 17:08:03 +0000218struct NameResolver {
Zachary Turnerae672182018-08-02 17:33:33 +0000219 virtual ~NameResolver() = default;
Zachary Turner172aea12018-08-02 17:08:03 +0000220 virtual StringView resolve(StringView S) = 0;
221};
222
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000223struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000224struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000225
Zachary Turnerd30700f2018-07-31 17:16:44 +0000226struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000227 bool IsVariadic = false;
228
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000229 Type *Current = nullptr;
230
Zachary Turnerd30700f2018-07-31 17:16:44 +0000231 FunctionParams *Next = nullptr;
232};
Zachary Turner931e8792018-07-30 23:02:10 +0000233
Zachary Turnerd30700f2018-07-31 17:16:44 +0000234struct TemplateParams {
235 bool IsTemplateTemplate = false;
236 bool IsAliasTemplate = false;
237
238 // Type can be null if this is a template template parameter. In that case
239 // only Name will be valid.
240 Type *ParamType = nullptr;
241
242 // Name can be valid if this is a template template parameter (see above) or
243 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
244 // Name contains the name of the function and Type contains the signature.
245 Name *ParamName = nullptr;
246
247 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000248};
249
250// The type class. Mangled symbols are first parsed and converted to
251// this type and then converted to string.
252struct Type {
253 virtual ~Type() {}
254
255 virtual Type *clone(ArenaAllocator &Arena) const;
256
257 // Write the "first half" of a given type. This is a static functions to
258 // give the code a chance to do processing that is common to a subset of
259 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000260 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000261
262 // Write the "second half" of a given type. This is a static functions to
263 // give the code a chance to do processing that is common to a subset of
264 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000265 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000266
Zachary Turner172aea12018-08-02 17:08:03 +0000267 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
268 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000269
270 // Primitive type such as Int.
271 PrimTy Prim = PrimTy::Unknown;
272
273 Qualifiers Quals = Q_None;
274 StorageClass Storage = StorageClass::None; // storage class
275};
276
277// Represents an identifier which may be a template.
278struct Name {
279 // Name read from an MangledName string.
280 StringView Str;
281
Zachary Turner44ebbc22018-08-01 18:32:47 +0000282 bool IsTemplateInstantiation = false;
283 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000284 bool IsBackReference = false;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000285
Zachary Turner44ebbc22018-08-01 18:32:47 +0000286 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000287 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000288
289 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
290 Name *Next = nullptr;
291};
292
293struct PointerType : public Type {
294 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000295 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
296 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000297
Zachary Turner931e8792018-07-30 23:02:10 +0000298 PointerAffinity Affinity;
299
Zachary Turnerd742d642018-07-26 19:56:09 +0000300 // Represents a type X in "a pointer to X", "a reference to X",
301 // "an array of X", or "a function returning X".
302 Type *Pointee = nullptr;
303};
304
305struct MemberPointerType : 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 Turnerd742d642018-07-26 19:56:09 +0000309
310 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000311
312 // 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 FunctionType : 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 Turnerf435a7e2018-07-20 17:27:48 +0000321
Zachary Turner024e1762018-07-26 20:33:48 +0000322 // True if this FunctionType instance is the Pointee of a PointerType or
323 // MemberPointerType.
324 bool IsFunctionPointer = false;
325
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000326 Type *ReturnType = nullptr;
327 // If this is a reference, the type of reference.
328 ReferenceKind RefKind;
329
330 CallingConv CallConvention;
331 FuncClass FunctionClass;
332
Zachary Turnerd30700f2018-07-31 17:16:44 +0000333 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000334};
335
336struct UdtType : public Type {
337 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000338 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000339
340 Name *UdtName = nullptr;
341};
342
343struct ArrayType : public Type {
344 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000345 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
346 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000347
348 // Either NextDimension or ElementType will be valid.
349 ArrayType *NextDimension = nullptr;
350 uint32_t ArrayDimension = 0;
351
352 Type *ElementType = nullptr;
353};
354
355} // namespace
356
Zachary Turnerd742d642018-07-26 19:56:09 +0000357static bool isMemberPointer(StringView MangledName) {
358 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000359 case '$':
360 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
361 // rvalue reference to a member.
362 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000363 case 'A':
364 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000365 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000366 return false;
367 case 'P':
368 case 'Q':
369 case 'R':
370 case 'S':
371 // These 4 values indicate some kind of pointer, but we still don't know
372 // what.
373 break;
374 default:
375 assert(false && "Ty is not a pointer type!");
376 }
377
378 // If it starts with a number, then 6 indicates a non-member function
379 // pointer, and 8 indicates a member function pointer.
380 if (startsWithDigit(MangledName)) {
381 assert(MangledName[0] == '6' || MangledName[0] == '8');
382 return (MangledName[0] == '8');
383 }
384
385 // Remove ext qualifiers since those can appear on either type and are
386 // therefore not indicative.
387 MangledName.consumeFront('E'); // 64-bit
388 MangledName.consumeFront('I'); // restrict
389 MangledName.consumeFront('F'); // unaligned
390
391 assert(!MangledName.empty());
392
393 // The next value should be either ABCD (non-member) or QRST (member).
394 switch (MangledName.front()) {
395 case 'A':
396 case 'B':
397 case 'C':
398 case 'D':
399 return false;
400 case 'Q':
401 case 'R':
402 case 'S':
403 case 'T':
404 return true;
405 default:
406 assert(false);
407 }
408 return false;
409}
410
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000411static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
412 outputSpaceIfNecessary(OS);
413
414 switch (CC) {
415 case CallingConv::Cdecl:
416 OS << "__cdecl";
417 break;
418 case CallingConv::Fastcall:
419 OS << "__fastcall";
420 break;
421 case CallingConv::Pascal:
422 OS << "__pascal";
423 break;
424 case CallingConv::Regcall:
425 OS << "__regcall";
426 break;
427 case CallingConv::Stdcall:
428 OS << "__stdcall";
429 break;
430 case CallingConv::Thiscall:
431 OS << "__thiscall";
432 break;
433 case CallingConv::Eabi:
434 OS << "__eabi";
435 break;
436 case CallingConv::Vectorcall:
437 OS << "__vectorcall";
438 break;
439 case CallingConv::Clrcall:
440 OS << "__clrcall";
441 break;
442 default:
443 break;
444 }
445}
446
Zachary Turner71c91f92018-07-30 03:12:34 +0000447static bool startsWithLocalScopePattern(StringView S) {
448 if (!S.consumeFront('?'))
449 return false;
450 if (S.size() < 2)
451 return false;
452
453 size_t End = S.find('?');
454 if (End == StringView::npos)
455 return false;
456 StringView Candidate = S.substr(0, End);
457 if (Candidate.empty())
458 return false;
459
460 // \?[0-9]\?
461 // ?@? is the discriminator 0.
462 if (Candidate.size() == 1)
463 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
464
465 // If it's not 0-9, then it's an encoded number terminated with an @
466 if (Candidate.back() != '@')
467 return false;
468 Candidate = Candidate.dropBack();
469
470 // An encoded number starts with B-P and all subsequent digits are in A-P.
471 // Note that the reason the first digit cannot be A is two fold. First, it
472 // would create an ambiguity with ?A which delimits the beginning of an
473 // anonymous namespace. Second, A represents 0, and you don't start a multi
474 // digit number with a leading 0. Presumably the anonymous namespace
475 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
476 if (Candidate[0] < 'B' || Candidate[0] > 'P')
477 return false;
478 Candidate = Candidate.dropFront();
479 while (!Candidate.empty()) {
480 if (Candidate[0] < 'A' || Candidate[0] > 'P')
481 return false;
482 Candidate = Candidate.dropFront();
483 }
484
485 return true;
486}
487
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000488// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000489static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
490 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000491 if (!Params.Current) {
492 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000493 return;
494 }
495
Zachary Turnerd30700f2018-07-31 17:16:44 +0000496 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000497 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000498 Type::outputPre(OS, *Head->Current, Resolver);
499 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000500
501 Head = Head->Next;
502
503 if (Head)
504 OS << ", ";
505 }
506}
507
Zachary Turner172aea12018-08-02 17:08:03 +0000508static void outputName(OutputStream &OS, const Name *TheName,
509 NameResolver &Resolver);
510
511static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
512 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000513 if (!Params.ParamType && !Params.ParamName) {
514 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000515 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000516 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000517
518 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000519 const TemplateParams *Head = &Params;
520 while (Head) {
521 // Type can be null if this is a template template parameter,
522 // and Name can be null if this is a simple type.
523
524 if (Head->ParamType && Head->ParamName) {
525 // Function pointer.
526 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000527 Type::outputPre(OS, *Head->ParamType, Resolver);
528 outputName(OS, Head->ParamName, Resolver);
529 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000530 } else if (Head->ParamType) {
531 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000532 Type::outputPre(OS, *Head->ParamType, Resolver);
533 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000534 } else {
535 // Template alias.
Zachary Turner172aea12018-08-02 17:08:03 +0000536 outputName(OS, Head->ParamName, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000537 }
538
539 Head = Head->Next;
540
541 if (Head)
542 OS << ", ";
543 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000544 OS << ">";
545}
546
Zachary Turner172aea12018-08-02 17:08:03 +0000547static void outputNameComponent(OutputStream &OS, const Name &N,
548 NameResolver &Resolver) {
549 StringView S = N.Str;
550
551 if (N.IsBackReference)
552 S = Resolver.resolve(N.Str);
553 OS << S;
554
555 if (N.IsTemplateInstantiation)
556 outputParameterList(OS, *N.TParams, Resolver);
557}
558
559static void outputName(OutputStream &OS, const Name *TheName,
560 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561 if (!TheName)
562 return;
563
564 outputSpaceIfNecessary(OS);
565
Zachary Turnera7dffb12018-07-28 22:10:42 +0000566 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000567 // Print out namespaces or outer class BackReferences.
568 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000569 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000570 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000571 OS << "::";
572 }
573
574 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000575 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000576 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000577 return;
578 }
579
580 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000581 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000582 OS << "~";
583
Zachary Turner44ebbc22018-08-01 18:32:47 +0000584 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turner172aea12018-08-02 17:08:03 +0000585 outputNameComponent(OS, *Previous, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000586 return;
587 }
588
589 // Print out an overloaded operator.
Zachary Turner172aea12018-08-02 17:08:03 +0000590 OS << "operator";
591 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000592}
593
594namespace {
595
596Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000597 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000598}
599
600// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000601void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000602 // Function types require custom handling of const and static so we
603 // handle them separately. All other types use the same decoration
604 // for these modifiers, so handle them here in common code.
605 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000606 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000607 return;
608 }
609
610 switch (Ty.Storage) {
611 case StorageClass::PrivateStatic:
612 case StorageClass::PublicStatic:
613 case StorageClass::ProtectedStatic:
614 OS << "static ";
615 default:
616 break;
617 }
Zachary Turner172aea12018-08-02 17:08:03 +0000618 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000619
620 if (Ty.Quals & Q_Const) {
621 outputSpaceIfNecessary(OS);
622 OS << "const";
623 }
624
625 if (Ty.Quals & Q_Volatile) {
626 outputSpaceIfNecessary(OS);
627 OS << "volatile";
628 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000629
630 if (Ty.Quals & Q_Restrict) {
631 outputSpaceIfNecessary(OS);
632 OS << "__restrict";
633 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000634}
635
636// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000637void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
638 Ty.outputPost(OS, Resolver);
639}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000640
Zachary Turner172aea12018-08-02 17:08:03 +0000641void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000642 switch (Prim) {
643 case PrimTy::Void:
644 OS << "void";
645 break;
646 case PrimTy::Bool:
647 OS << "bool";
648 break;
649 case PrimTy::Char:
650 OS << "char";
651 break;
652 case PrimTy::Schar:
653 OS << "signed char";
654 break;
655 case PrimTy::Uchar:
656 OS << "unsigned char";
657 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000658 case PrimTy::Char16:
659 OS << "char16_t";
660 break;
661 case PrimTy::Char32:
662 OS << "char32_t";
663 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000664 case PrimTy::Short:
665 OS << "short";
666 break;
667 case PrimTy::Ushort:
668 OS << "unsigned short";
669 break;
670 case PrimTy::Int:
671 OS << "int";
672 break;
673 case PrimTy::Uint:
674 OS << "unsigned int";
675 break;
676 case PrimTy::Long:
677 OS << "long";
678 break;
679 case PrimTy::Ulong:
680 OS << "unsigned long";
681 break;
682 case PrimTy::Int64:
683 OS << "__int64";
684 break;
685 case PrimTy::Uint64:
686 OS << "unsigned __int64";
687 break;
688 case PrimTy::Wchar:
689 OS << "wchar_t";
690 break;
691 case PrimTy::Float:
692 OS << "float";
693 break;
694 case PrimTy::Double:
695 OS << "double";
696 break;
697 case PrimTy::Ldouble:
698 OS << "long double";
699 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000700 case PrimTy::Nullptr:
701 OS << "std::nullptr_t";
702 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000703 default:
704 assert(false && "Invalid primitive type!");
705 }
706}
Zachary Turner172aea12018-08-02 17:08:03 +0000707void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000708
709Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000710 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000711}
712
Zachary Turner024e1762018-07-26 20:33:48 +0000713static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +0000714 const Name *MemberName, const Type *Pointee,
715 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +0000716 // "[]" and "()" (for function parameters) take precedence over "*",
717 // so "int *x(int)" means "x is a function returning int *". We need
718 // parentheses to supercede the default precedence. (e.g. we want to
719 // emit something like "int (*x)(int)".)
720 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
721 OS << "(";
722 if (Pointee->Prim == PrimTy::Function) {
723 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
724 assert(FTy->IsFunctionPointer);
725 outputCallingConvention(OS, FTy->CallConvention);
726 OS << " ";
727 }
728 }
729
730 if (MemberName) {
Zachary Turner172aea12018-08-02 17:08:03 +0000731 outputName(OS, MemberName, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +0000732 OS << "::";
733 }
734
735 if (Affinity == PointerAffinity::Pointer)
736 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000737 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000738 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000739 else
740 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000741}
742
Zachary Turner172aea12018-08-02 17:08:03 +0000743void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
744 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000745
746 outputSpaceIfNecessary(OS);
747
748 if (Quals & Q_Unaligned)
749 OS << "__unaligned ";
750
Zachary Turner172aea12018-08-02 17:08:03 +0000751 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000752
Zachary Turner91ecedd2018-07-20 18:07:33 +0000753 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000754 // if (Ty.Quals & Q_Pointer64)
755 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000756}
757
Zachary Turner172aea12018-08-02 17:08:03 +0000758void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000759 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
760 OS << ")";
761
Zachary Turner172aea12018-08-02 17:08:03 +0000762 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000763}
764
Zachary Turnerd742d642018-07-26 19:56:09 +0000765Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
766 return Arena.alloc<MemberPointerType>(*this);
767}
768
Zachary Turner172aea12018-08-02 17:08:03 +0000769void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
770 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000771
772 outputSpaceIfNecessary(OS);
773
Zachary Turner172aea12018-08-02 17:08:03 +0000774 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
775 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000776
777 // FIXME: We should output this, but it requires updating lots of tests.
778 // if (Ty.Quals & Q_Pointer64)
779 // OS << " __ptr64";
780 if (Quals & Q_Restrict)
781 OS << " __restrict";
782}
783
Zachary Turner172aea12018-08-02 17:08:03 +0000784void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +0000785 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
786 OS << ")";
787
Zachary Turner172aea12018-08-02 17:08:03 +0000788 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000789}
790
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000791Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000792 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000793}
794
Zachary Turner172aea12018-08-02 17:08:03 +0000795void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000796 if (!(FunctionClass & Global)) {
797 if (FunctionClass & Static)
798 OS << "static ";
799 }
800
Zachary Turner38b78a72018-07-26 20:20:10 +0000801 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +0000802 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +0000803 OS << " ";
804 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000805
Zachary Turner024e1762018-07-26 20:33:48 +0000806 // Function pointers print the calling convention as void (__cdecl *)(params)
807 // rather than void __cdecl (*)(params). So we need to let the PointerType
808 // class handle this.
809 if (!IsFunctionPointer)
810 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000811}
812
Zachary Turner172aea12018-08-02 17:08:03 +0000813void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000814 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +0000815 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000816 OS << ")";
817 if (Quals & Q_Const)
818 OS << " const";
819 if (Quals & Q_Volatile)
820 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000821 if (Quals & Q_Restrict)
822 OS << " __restrict";
823 if (Quals & Q_Unaligned)
824 OS << " __unaligned";
825
826 if (RefKind == ReferenceKind::LValueRef)
827 OS << " &";
828 else if (RefKind == ReferenceKind::RValueRef)
829 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000830
831 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +0000832 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000833 return;
834}
835
836Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000837 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000838}
839
Zachary Turner172aea12018-08-02 17:08:03 +0000840void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000841 switch (Prim) {
842 case PrimTy::Class:
843 OS << "class ";
844 break;
845 case PrimTy::Struct:
846 OS << "struct ";
847 break;
848 case PrimTy::Union:
849 OS << "union ";
850 break;
851 case PrimTy::Enum:
852 OS << "enum ";
853 break;
854 default:
855 assert(false && "Not a udt type!");
856 }
857
Zachary Turner172aea12018-08-02 17:08:03 +0000858 outputName(OS, UdtName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000859}
860
861Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000862 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000863}
864
Zachary Turner172aea12018-08-02 17:08:03 +0000865void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
866 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000867}
868
Zachary Turner172aea12018-08-02 17:08:03 +0000869void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000870 if (ArrayDimension > 0)
871 OS << "[" << ArrayDimension << "]";
872 if (NextDimension)
Zachary Turner172aea12018-08-02 17:08:03 +0000873 Type::outputPost(OS, *NextDimension, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000874 else if (ElementType)
Zachary Turner172aea12018-08-02 17:08:03 +0000875 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000876}
877
Zachary Turner316109b2018-07-29 16:38:02 +0000878struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000879 SymbolCategory Category;
880
Zachary Turner316109b2018-07-29 16:38:02 +0000881 Name *SymbolName = nullptr;
882 Type *SymbolType = nullptr;
883};
884
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000885} // namespace
886
887namespace {
888
Zachary Turnerd346cba2018-08-08 17:17:04 +0000889struct BackrefContext {
890 static constexpr size_t Max = 10;
891
892 Type *FunctionParams[Max];
893 size_t FunctionParamCount = 0;
894
895 // The first 10 BackReferences in a mangled name can be back-referenced by
896 // special name @[0-9]. This is a storage for the first 10 BackReferences.
897 StringView Names[Max];
898 size_t NamesCount = 0;
899};
900
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000901// Demangler class takes the main role in demangling symbols.
902// It has a set of functions to parse mangled symbols into Type instances.
903// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +0000904class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000905public:
Zachary Turner316109b2018-07-29 16:38:02 +0000906 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +0000907 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000908
909 // You are supposed to call parse() first and then check if error is true. If
910 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000911 Symbol *parse(StringView &MangledName);
912 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000913
Zachary Turner172aea12018-08-02 17:08:03 +0000914 StringView resolve(StringView N) override;
915
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000916 // True if an error occurred.
917 bool Error = false;
918
Zachary Turner3a758e22018-08-01 18:33:04 +0000919 void dumpBackReferences();
920
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000921private:
Zachary Turner316109b2018-07-29 16:38:02 +0000922 Type *demangleVariableEncoding(StringView &MangledName);
923 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000924
Zachary Turner316109b2018-07-29 16:38:02 +0000925 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000926
927 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000928 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
929 Type *demangleBasicType(StringView &MangledName);
930 UdtType *demangleClassType(StringView &MangledName);
931 PointerType *demanglePointerType(StringView &MangledName);
932 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
933 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
934 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000935
Zachary Turner316109b2018-07-29 16:38:02 +0000936 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000937
Zachary Turnerd30700f2018-07-31 17:16:44 +0000938 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
939 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000940
Zachary Turner316109b2018-07-29 16:38:02 +0000941 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000942
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000943 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000944
945 /// Allocate a copy of \p Borrowed into memory that we own.
946 StringView copyString(StringView Borrowed);
947
Zachary Turner316109b2018-07-29 16:38:02 +0000948 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
949 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000950
Zachary Turner44ebbc22018-08-01 18:32:47 +0000951 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
Zachary Turner58d29cf2018-08-08 00:43:31 +0000952 Name *demangleUnqualifiedSymbolName(StringView &MangledName,
953 NameBackrefBehavior NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000954
Zachary Turner316109b2018-07-29 16:38:02 +0000955 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
956 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000957
Zachary Turner316109b2018-07-29 16:38:02 +0000958 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +0000959 Name *demangleTemplateInstantiationName(StringView &MangledName,
960 NameBackrefBehavior NBB);
Zachary Turner316109b2018-07-29 16:38:02 +0000961 Name *demangleOperatorName(StringView &MangledName);
962 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
963 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000964 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000965
Zachary Turner931e8792018-07-30 23:02:10 +0000966 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
967
Zachary Turner316109b2018-07-29 16:38:02 +0000968 FuncClass demangleFunctionClass(StringView &MangledName);
969 CallingConv demangleCallingConvention(StringView &MangledName);
970 StorageClass demangleVariableStorageClass(StringView &MangledName);
971 ReferenceKind demangleReferenceKind(StringView &MangledName);
972 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000973
Zachary Turner316109b2018-07-29 16:38:02 +0000974 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000975
976 // Memory allocator.
977 ArenaAllocator Arena;
978
Zachary Turner23df1312018-07-26 22:13:39 +0000979 // A single type uses one global back-ref table for all function params.
980 // This means back-refs can even go "into" other types. Examples:
981 //
982 // // Second int* is a back-ref to first.
983 // void foo(int *, int*);
984 //
985 // // Second int* is not a back-ref to first (first is not a function param).
986 // int* foo(int*);
987 //
988 // // Second int* is a back-ref to first (ALL function types share the same
989 // // back-ref map.
990 // using F = void(*)(int*);
991 // F G(int *);
Zachary Turnerd346cba2018-08-08 17:17:04 +0000992 BackrefContext Backrefs;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000993};
994} // namespace
995
Zachary Turner71c91f92018-07-30 03:12:34 +0000996StringView Demangler::copyString(StringView Borrowed) {
997 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
998 std::strcpy(Stable, Borrowed.begin());
999
1000 return {Stable, Borrowed.size()};
1001}
1002
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001003// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +00001004Symbol *Demangler::parse(StringView &MangledName) {
1005 Symbol *S = Arena.alloc<Symbol>();
1006
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001007 // MSVC-style mangled symbols must start with '?'.
1008 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001009 S->SymbolName = Arena.alloc<Name>();
1010 S->SymbolName->Str = MangledName;
1011 S->SymbolType = Arena.alloc<Type>();
1012 S->SymbolType->Prim = PrimTy::Unknown;
1013 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001014 }
1015
1016 // What follows is a main symbol name. This may include
1017 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +00001018 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001019 if (Error)
1020 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001021 // Read a variable.
Zachary Turner44ebbc22018-08-01 18:32:47 +00001022 if (startsWithDigit(MangledName)) {
1023 S->Category = SymbolCategory::Variable;
1024 S->SymbolType = demangleVariableEncoding(MangledName);
1025 } else {
1026 S->Category = SymbolCategory::Function;
1027 S->SymbolType = demangleFunctionEncoding(MangledName);
1028 }
1029
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001030 if (Error)
1031 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001032
Zachary Turner316109b2018-07-29 16:38:02 +00001033 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001034}
1035
1036// <type-encoding> ::= <storage-class> <variable-type>
1037// <storage-class> ::= 0 # private static member
1038// ::= 1 # protected static member
1039// ::= 2 # public static member
1040// ::= 3 # global
1041// ::= 4 # static local
1042
Zachary Turner316109b2018-07-29 16:38:02 +00001043Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1044 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001045
Zachary Turner316109b2018-07-29 16:38:02 +00001046 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001047
1048 Ty->Storage = SC;
1049
1050 // <variable-type> ::= <type> <cvr-qualifiers>
1051 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1052 switch (Ty->Prim) {
1053 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001054 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001055 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001056 Ty->Quals =
1057 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001058
Zachary Turnerd742d642018-07-26 19:56:09 +00001059 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001060 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001061
Zachary Turnerd742d642018-07-26 19:56:09 +00001062 if (Ty->Prim == PrimTy::MemberPtr) {
1063 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001064 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001065 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001066 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1067 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1068 } else {
1069 PointerType *PTy = static_cast<PointerType *>(Ty);
1070 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001071 }
1072
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001073 break;
1074 }
1075 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001076 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001077 break;
1078 }
1079
1080 return Ty;
1081}
1082
1083// Sometimes numbers are encoded in mangled symbols. For example,
1084// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1085// length 20), so we need some way to embed numbers as part of symbols.
1086// This function parses it.
1087//
1088// <number> ::= [?] <non-negative integer>
1089//
1090// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1091// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1092//
1093// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001094int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001095 bool neg = MangledName.consumeFront("?");
1096
1097 if (startsWithDigit(MangledName)) {
1098 int32_t Ret = MangledName[0] - '0' + 1;
1099 MangledName = MangledName.dropFront(1);
1100 return neg ? -Ret : Ret;
1101 }
1102
1103 int Ret = 0;
1104 for (size_t i = 0; i < MangledName.size(); ++i) {
1105 char C = MangledName[i];
1106 if (C == '@') {
1107 MangledName = MangledName.dropFront(i + 1);
1108 return neg ? -Ret : Ret;
1109 }
1110 if ('A' <= C && C <= 'P') {
1111 Ret = (Ret << 4) + (C - 'A');
1112 continue;
1113 }
1114 break;
1115 }
1116
1117 Error = true;
1118 return 0;
1119}
1120
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001121// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1122// Memorize it.
1123void Demangler::memorizeString(StringView S) {
Zachary Turnerd346cba2018-08-08 17:17:04 +00001124 if (Backrefs.NamesCount >= BackrefContext::Max)
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001125 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001126 for (size_t i = 0; i < Backrefs.NamesCount; ++i)
1127 if (S == Backrefs.Names[i])
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001128 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001129 Backrefs.Names[Backrefs.NamesCount++] = S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001130}
1131
Zachary Turner316109b2018-07-29 16:38:02 +00001132Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001133 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001134 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001135 Node->IsBackReference = true;
1136 Node->Str = {MangledName.begin(), 1};
1137 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001138 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001139}
1140
Zachary Turner58d29cf2018-08-08 00:43:31 +00001141Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName,
1142 NameBackrefBehavior NBB) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001143 assert(MangledName.startsWith("?$"));
1144 MangledName.consumeFront("?$");
1145
Zachary Turnerd346cba2018-08-08 17:17:04 +00001146 BackrefContext OuterContext;
1147 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001148
Zachary Turnerd346cba2018-08-08 17:17:04 +00001149 Name *Node = demangleUnqualifiedSymbolName(MangledName, NBB_None);
1150 if (!Error)
1151 Node->TParams = demangleTemplateParameterList(MangledName);
1152
1153 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001154 if (Error)
1155 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001156
Zachary Turner44ebbc22018-08-01 18:32:47 +00001157 Node->IsTemplateInstantiation = true;
1158
Zachary Turner58d29cf2018-08-08 00:43:31 +00001159 if (NBB & NBB_Template) {
1160 // Render this class template name into a string buffer so that we can
1161 // memorize it for the purpose of back-referencing.
1162 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1163 outputName(OS, Node, *this);
1164 OS << '\0';
1165 char *Name = OS.getBuffer();
Zachary Turner71c91f92018-07-30 03:12:34 +00001166
Zachary Turner58d29cf2018-08-08 00:43:31 +00001167 StringView Owned = copyString(Name);
1168 memorizeString(Owned);
1169 std::free(Name);
1170 }
Zachary Turner71c91f92018-07-30 03:12:34 +00001171
Zachary Turnera7dffb12018-07-28 22:10:42 +00001172 return Node;
1173}
1174
Zachary Turner316109b2018-07-29 16:38:02 +00001175Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001176 assert(MangledName.startsWith('?'));
1177 MangledName.consumeFront('?');
1178
Zachary Turner316109b2018-07-29 16:38:02 +00001179 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001180 switch (MangledName.popFront()) {
1181 case '0':
1182 return "ctor";
1183 case '1':
1184 return "dtor";
1185 case '2':
1186 return " new";
1187 case '3':
1188 return " delete";
1189 case '4':
1190 return "=";
1191 case '5':
1192 return ">>";
1193 case '6':
1194 return "<<";
1195 case '7':
1196 return "!";
1197 case '8':
1198 return "==";
1199 case '9':
1200 return "!=";
1201 case 'A':
1202 return "[]";
1203 case 'C':
1204 return "->";
1205 case 'D':
1206 return "*";
1207 case 'E':
1208 return "++";
1209 case 'F':
1210 return "--";
1211 case 'G':
1212 return "-";
1213 case 'H':
1214 return "+";
1215 case 'I':
1216 return "&";
1217 case 'J':
1218 return "->*";
1219 case 'K':
1220 return "/";
1221 case 'L':
1222 return "%";
1223 case 'M':
1224 return "<";
1225 case 'N':
1226 return "<=";
1227 case 'O':
1228 return ">";
1229 case 'P':
1230 return ">=";
1231 case 'Q':
1232 return ",";
1233 case 'R':
1234 return "()";
1235 case 'S':
1236 return "~";
1237 case 'T':
1238 return "^";
1239 case 'U':
1240 return "|";
1241 case 'V':
1242 return "&&";
1243 case 'W':
1244 return "||";
1245 case 'X':
1246 return "*=";
1247 case 'Y':
1248 return "+=";
1249 case 'Z':
1250 return "-=";
1251 case '_': {
1252 if (MangledName.empty())
1253 break;
1254
1255 switch (MangledName.popFront()) {
1256 case '0':
1257 return "/=";
1258 case '1':
1259 return "%=";
1260 case '2':
1261 return ">>=";
1262 case '3':
1263 return "<<=";
1264 case '4':
1265 return "&=";
1266 case '5':
1267 return "|=";
1268 case '6':
1269 return "^=";
1270 case 'U':
1271 return " new[]";
1272 case 'V':
1273 return " delete[]";
1274 case '_':
1275 if (MangledName.consumeFront("L"))
1276 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001277 if (MangledName.consumeFront("K")) {
1278 size_t EndPos = MangledName.find('@');
1279 if (EndPos == StringView::npos)
1280 break;
1281 StringView OpName = demangleSimpleString(MangledName, false);
1282 size_t FullSize = OpName.size() + 3; // <space>""OpName
1283 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1284 Buffer[0] = ' ';
1285 Buffer[1] = '"';
1286 Buffer[2] = '"';
1287 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1288 return {Buffer, FullSize};
1289 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001290 }
1291 }
1292 }
1293 Error = true;
1294 return "";
1295 };
1296
1297 Name *Node = Arena.alloc<Name>();
Zachary Turner44ebbc22018-08-01 18:32:47 +00001298 Node->Str = NameString();
1299 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001300 return Node;
1301}
1302
Zachary Turner316109b2018-07-29 16:38:02 +00001303Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001304 StringView S = demangleSimpleString(MangledName, Memorize);
1305 if (Error)
1306 return nullptr;
1307
Zachary Turnera7dffb12018-07-28 22:10:42 +00001308 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001309 Node->Str = S;
1310 return Node;
1311}
1312
1313StringView Demangler::demangleSimpleString(StringView &MangledName,
1314 bool Memorize) {
1315 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001316 for (size_t i = 0; i < MangledName.size(); ++i) {
1317 if (MangledName[i] != '@')
1318 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001319 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001320 MangledName = MangledName.dropFront(i + 1);
1321
1322 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001323 memorizeString(S);
1324 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001325 }
1326
1327 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001328 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001329}
1330
Zachary Turner316109b2018-07-29 16:38:02 +00001331Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001332 assert(MangledName.startsWith("?A"));
1333 MangledName.consumeFront("?A");
1334
1335 Name *Node = Arena.alloc<Name>();
1336 Node->Str = "`anonymous namespace'";
1337 if (MangledName.consumeFront('@'))
1338 return Node;
1339
1340 Error = true;
1341 return nullptr;
1342}
1343
Zachary Turner71c91f92018-07-30 03:12:34 +00001344Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1345 assert(startsWithLocalScopePattern(MangledName));
1346
1347 Name *Node = Arena.alloc<Name>();
1348 MangledName.consumeFront('?');
1349 int ScopeIdentifier = demangleNumber(MangledName);
1350
1351 // One ? to terminate the number
1352 MangledName.consumeFront('?');
1353
1354 assert(!Error);
1355 Symbol *Scope = parse(MangledName);
1356 if (Error)
1357 return nullptr;
1358
1359 // Render the parent symbol's name into a buffer.
1360 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1361 OS << '`';
1362 output(Scope, OS);
1363 OS << '\'';
1364 OS << "::`" << ScopeIdentifier << "'";
1365 OS << '\0';
1366 char *Result = OS.getBuffer();
1367 Node->Str = copyString(Result);
1368 std::free(Result);
1369 return Node;
1370}
1371
Zachary Turnera7dffb12018-07-28 22:10:42 +00001372// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001373Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001374 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001375 if (Error)
1376 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001377 assert(TypeName);
1378
Zachary Turner316109b2018-07-29 16:38:02 +00001379 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001380 if (Error)
1381 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001382 assert(QualName);
1383 return QualName;
1384}
1385
1386// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1387// Symbol names have slightly different rules regarding what can appear
1388// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001389Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00001390 // This is the final component of a symbol name (i.e. the leftmost component
1391 // of a mangled name. Since the only possible template instantiation that
1392 // can appear in this context is a function template, and since those are
1393 // not saved for the purposes of name backreferences, only backref simple
1394 // names.
1395 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001396 if (Error)
1397 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001398 assert(SymbolName);
1399
Zachary Turner316109b2018-07-29 16:38:02 +00001400 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001401 if (Error)
1402 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001403 assert(QualName);
1404 return QualName;
1405}
1406
Zachary Turner44ebbc22018-08-01 18:32:47 +00001407Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1408 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001409 // An inner-most name can be a back-reference, because a fully-qualified name
1410 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1411 // them (for example template parameters), and these nested parameters can
1412 // refer to previously mangled types.
1413 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001414 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001415
1416 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001417 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001418
Zachary Turner44ebbc22018-08-01 18:32:47 +00001419 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001420}
1421
Zachary Turner44ebbc22018-08-01 18:32:47 +00001422Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00001423 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001424 if (startsWithDigit(MangledName))
1425 return demangleBackRefName(MangledName);
1426 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001427 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001428 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001429 return demangleOperatorName(MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001430 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001431}
1432
Zachary Turner316109b2018-07-29 16:38:02 +00001433Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001434 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001435 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001436
1437 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001438 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001439
1440 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001441 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001442
Zachary Turner71c91f92018-07-30 03:12:34 +00001443 if (startsWithLocalScopePattern(MangledName))
1444 return demangleLocallyScopedNamePiece(MangledName);
1445
Zachary Turner316109b2018-07-29 16:38:02 +00001446 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001447}
1448
Zachary Turner316109b2018-07-29 16:38:02 +00001449Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1450 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001451 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001452
1453 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001454 if (MangledName.empty()) {
1455 Error = true;
1456 return nullptr;
1457 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001458
1459 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001460 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001461 if (Error)
1462 return nullptr;
1463
1464 Elem->Next = Head;
1465 Head = Elem;
1466 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001467 return Head;
1468}
1469
Zachary Turner316109b2018-07-29 16:38:02 +00001470FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001471 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1472 RestoreOnError.shouldRestore(false);
1473
1474 switch (MangledName.popFront()) {
1475 case 'A':
1476 return Private;
1477 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001478 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001479 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001480 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001481 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001482 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001483 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001484 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001485 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001486 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001487 case 'I':
1488 return Protected;
1489 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001490 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001491 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001492 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001493 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001494 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001495 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001496 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001497 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001498 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001499 case 'Q':
1500 return Public;
1501 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001502 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001503 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001504 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001505 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001506 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001507 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001508 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001509 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001510 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001511 case 'Y':
1512 return Global;
1513 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001514 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001515 }
1516
1517 Error = true;
1518 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001519 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001520}
1521
Zachary Turner316109b2018-07-29 16:38:02 +00001522CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001523 switch (MangledName.popFront()) {
1524 case 'A':
1525 case 'B':
1526 return CallingConv::Cdecl;
1527 case 'C':
1528 case 'D':
1529 return CallingConv::Pascal;
1530 case 'E':
1531 case 'F':
1532 return CallingConv::Thiscall;
1533 case 'G':
1534 case 'H':
1535 return CallingConv::Stdcall;
1536 case 'I':
1537 case 'J':
1538 return CallingConv::Fastcall;
1539 case 'M':
1540 case 'N':
1541 return CallingConv::Clrcall;
1542 case 'O':
1543 case 'P':
1544 return CallingConv::Eabi;
1545 case 'Q':
1546 return CallingConv::Vectorcall;
1547 }
1548
1549 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001550}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001551
Zachary Turner316109b2018-07-29 16:38:02 +00001552StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001553 assert(std::isdigit(MangledName.front()));
1554
1555 switch (MangledName.popFront()) {
1556 case '0':
1557 return StorageClass::PrivateStatic;
1558 case '1':
1559 return StorageClass::ProtectedStatic;
1560 case '2':
1561 return StorageClass::PublicStatic;
1562 case '3':
1563 return StorageClass::Global;
1564 case '4':
1565 return StorageClass::FunctionLocalStatic;
1566 }
1567 Error = true;
1568 return StorageClass::None;
1569}
1570
Zachary Turner316109b2018-07-29 16:38:02 +00001571std::pair<Qualifiers, bool>
1572Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001573
1574 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001575 // Member qualifiers
1576 case 'Q':
1577 return std::make_pair(Q_None, true);
1578 case 'R':
1579 return std::make_pair(Q_Const, true);
1580 case 'S':
1581 return std::make_pair(Q_Volatile, true);
1582 case 'T':
1583 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1584 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001585 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001586 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001587 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001588 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001589 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001590 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001591 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001592 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001593 }
1594 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001595 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001596}
1597
Zachary Turner931e8792018-07-30 23:02:10 +00001598static bool isTagType(StringView S) {
1599 switch (S.front()) {
1600 case 'T': // union
1601 case 'U': // struct
1602 case 'V': // class
1603 case 'W': // enum
1604 return true;
1605 }
1606 return false;
1607}
1608
1609static bool isPointerType(StringView S) {
1610 if (S.startsWith("$$Q")) // foo &&
1611 return true;
1612
1613 switch (S.front()) {
1614 case 'A': // foo &
1615 case 'P': // foo *
1616 case 'Q': // foo *const
1617 case 'R': // foo *volatile
1618 case 'S': // foo *const volatile
1619 return true;
1620 }
1621 return false;
1622}
1623
1624static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1625
1626static bool isFunctionType(StringView S) {
1627 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1628}
1629
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001630// <variable-type> ::= <type> <cvr-qualifiers>
1631// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001632Type *Demangler::demangleType(StringView &MangledName,
1633 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001634 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001635 bool IsMember = false;
1636 bool IsMemberKnown = false;
1637 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001638 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001639 IsMemberKnown = true;
1640 } else if (QMM == QualifierMangleMode::Result) {
1641 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001642 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001643 IsMemberKnown = true;
1644 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001645 }
1646
1647 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001648 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001649 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001650 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001651 if (!IsMemberKnown)
1652 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001653
Zachary Turnerd742d642018-07-26 19:56:09 +00001654 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001655 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001656 else
Zachary Turner316109b2018-07-29 16:38:02 +00001657 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001658 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001659 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001660 else if (isFunctionType(MangledName)) {
1661 if (MangledName.consumeFront("$$A8@@"))
1662 Ty = demangleFunctionType(MangledName, true, false);
1663 else {
1664 assert(MangledName.startsWith("$$A6"));
1665 MangledName.consumeFront("$$A6");
1666 Ty = demangleFunctionType(MangledName, false, false);
1667 }
1668 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001669 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001670 assert(Ty && !Error);
1671 if (!Ty || Error)
1672 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001673 }
Zachary Turner931e8792018-07-30 23:02:10 +00001674
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001675 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1676 return Ty;
1677}
1678
Zachary Turner316109b2018-07-29 16:38:02 +00001679ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001680 if (MangledName.consumeFront('G'))
1681 return ReferenceKind::LValueRef;
1682 else if (MangledName.consumeFront('H'))
1683 return ReferenceKind::RValueRef;
1684 return ReferenceKind::None;
1685}
1686
Zachary Turner316109b2018-07-29 16:38:02 +00001687void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001688 if (MangledName.consumeFront('Z'))
1689 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001690
Zachary Turner38b78a72018-07-26 20:20:10 +00001691 Error = true;
1692}
1693
Zachary Turner316109b2018-07-29 16:38:02 +00001694FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1695 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001696 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001697 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001698 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001699 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001700
1701 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001702 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1703 FTy->RefKind = demangleReferenceKind(MangledName);
1704 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001705 }
1706
1707 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001708 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001709
1710 // <return-type> ::= <type>
1711 // ::= @ # structors (they have no declared return type)
1712 bool IsStructor = MangledName.consumeFront('@');
1713 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001714 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001715
Zachary Turner316109b2018-07-29 16:38:02 +00001716 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001717
Zachary Turner316109b2018-07-29 16:38:02 +00001718 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001719
1720 return FTy;
1721}
1722
Zachary Turner316109b2018-07-29 16:38:02 +00001723Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1724 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001725
1726 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001727 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001728 FTy->FunctionClass = FC;
1729
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001730 return FTy;
1731}
1732
1733// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001734Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001735 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001736
Zachary Turner931e8792018-07-30 23:02:10 +00001737 if (MangledName.consumeFront("$$T")) {
1738 Ty->Prim = PrimTy::Nullptr;
1739 return Ty;
1740 }
1741
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001742 switch (MangledName.popFront()) {
1743 case 'X':
1744 Ty->Prim = PrimTy::Void;
1745 break;
1746 case 'D':
1747 Ty->Prim = PrimTy::Char;
1748 break;
1749 case 'C':
1750 Ty->Prim = PrimTy::Schar;
1751 break;
1752 case 'E':
1753 Ty->Prim = PrimTy::Uchar;
1754 break;
1755 case 'F':
1756 Ty->Prim = PrimTy::Short;
1757 break;
1758 case 'G':
1759 Ty->Prim = PrimTy::Ushort;
1760 break;
1761 case 'H':
1762 Ty->Prim = PrimTy::Int;
1763 break;
1764 case 'I':
1765 Ty->Prim = PrimTy::Uint;
1766 break;
1767 case 'J':
1768 Ty->Prim = PrimTy::Long;
1769 break;
1770 case 'K':
1771 Ty->Prim = PrimTy::Ulong;
1772 break;
1773 case 'M':
1774 Ty->Prim = PrimTy::Float;
1775 break;
1776 case 'N':
1777 Ty->Prim = PrimTy::Double;
1778 break;
1779 case 'O':
1780 Ty->Prim = PrimTy::Ldouble;
1781 break;
1782 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001783 if (MangledName.empty()) {
1784 Error = true;
1785 return nullptr;
1786 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001787 switch (MangledName.popFront()) {
1788 case 'N':
1789 Ty->Prim = PrimTy::Bool;
1790 break;
1791 case 'J':
1792 Ty->Prim = PrimTy::Int64;
1793 break;
1794 case 'K':
1795 Ty->Prim = PrimTy::Uint64;
1796 break;
1797 case 'W':
1798 Ty->Prim = PrimTy::Wchar;
1799 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001800 case 'S':
1801 Ty->Prim = PrimTy::Char16;
1802 break;
1803 case 'U':
1804 Ty->Prim = PrimTy::Char32;
1805 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001806 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001807 Error = true;
1808 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001809 }
1810 break;
1811 }
Zachary Turner931e8792018-07-30 23:02:10 +00001812 default:
1813 Error = true;
1814 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001815 }
1816 return Ty;
1817}
1818
Zachary Turner316109b2018-07-29 16:38:02 +00001819UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001820 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001821
1822 switch (MangledName.popFront()) {
1823 case 'T':
1824 UTy->Prim = PrimTy::Union;
1825 break;
1826 case 'U':
1827 UTy->Prim = PrimTy::Struct;
1828 break;
1829 case 'V':
1830 UTy->Prim = PrimTy::Class;
1831 break;
1832 case 'W':
1833 if (MangledName.popFront() != '4') {
1834 Error = true;
1835 return nullptr;
1836 }
1837 UTy->Prim = PrimTy::Enum;
1838 break;
1839 default:
1840 assert(false);
1841 }
1842
Zachary Turner316109b2018-07-29 16:38:02 +00001843 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001844 return UTy;
1845}
1846
Zachary Turnerd742d642018-07-26 19:56:09 +00001847static std::pair<Qualifiers, PointerAffinity>
1848demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001849 if (MangledName.consumeFront("$$Q"))
1850 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1851
Zachary Turnerd742d642018-07-26 19:56:09 +00001852 switch (MangledName.popFront()) {
1853 case 'A':
1854 return std::make_pair(Q_None, PointerAffinity::Reference);
1855 case 'P':
1856 return std::make_pair(Q_None, PointerAffinity::Pointer);
1857 case 'Q':
1858 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1859 case 'R':
1860 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1861 case 'S':
1862 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1863 PointerAffinity::Pointer);
1864 default:
1865 assert(false && "Ty is not a pointer type!");
1866 }
1867 return std::make_pair(Q_None, PointerAffinity::Pointer);
1868}
1869
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001870// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1871// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001872PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001873 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001874
Zachary Turner931e8792018-07-30 23:02:10 +00001875 std::tie(Pointer->Quals, Pointer->Affinity) =
1876 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001877
Zachary Turner931e8792018-07-30 23:02:10 +00001878 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001879 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001880 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001881 return Pointer;
1882 }
1883
Zachary Turner316109b2018-07-29 16:38:02 +00001884 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001885 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1886
Zachary Turner316109b2018-07-29 16:38:02 +00001887 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001888 return Pointer;
1889}
1890
Zachary Turner316109b2018-07-29 16:38:02 +00001891MemberPointerType *
1892Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001893 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1894 Pointer->Prim = PrimTy::MemberPtr;
1895
1896 PointerAffinity Affinity;
1897 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1898 assert(Affinity == PointerAffinity::Pointer);
1899
Zachary Turner316109b2018-07-29 16:38:02 +00001900 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001901 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1902
Zachary Turner38b78a72018-07-26 20:20:10 +00001903 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001904 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1905 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001906 } else {
1907 Qualifiers PointeeQuals = Q_None;
1908 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001909 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001910 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001911 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001912
Zachary Turner316109b2018-07-29 16:38:02 +00001913 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001914 Pointer->Pointee->Quals = PointeeQuals;
1915 }
1916
Zachary Turnerd742d642018-07-26 19:56:09 +00001917 return Pointer;
1918}
1919
Zachary Turner316109b2018-07-29 16:38:02 +00001920Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001921 Qualifiers Quals = Q_None;
1922 if (MangledName.consumeFront('E'))
1923 Quals = Qualifiers(Quals | Q_Pointer64);
1924 if (MangledName.consumeFront('I'))
1925 Quals = Qualifiers(Quals | Q_Restrict);
1926 if (MangledName.consumeFront('F'))
1927 Quals = Qualifiers(Quals | Q_Unaligned);
1928
1929 return Quals;
1930}
1931
Zachary Turner316109b2018-07-29 16:38:02 +00001932ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001933 assert(MangledName.front() == 'Y');
1934 MangledName.popFront();
1935
Zachary Turner316109b2018-07-29 16:38:02 +00001936 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001937 if (Dimension <= 0) {
1938 Error = true;
1939 return nullptr;
1940 }
1941
Zachary Turner9d72aa92018-07-20 18:35:06 +00001942 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001943 ArrayType *Dim = ATy;
1944 for (int I = 0; I < Dimension; ++I) {
1945 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001946 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001947 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001948 Dim = Dim->NextDimension;
1949 }
1950
1951 if (MangledName.consumeFront("$$C")) {
1952 if (MangledName.consumeFront("B"))
1953 ATy->Quals = Q_Const;
1954 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1955 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1956 else if (!MangledName.consumeFront("A"))
1957 Error = true;
1958 }
1959
Zachary Turner316109b2018-07-29 16:38:02 +00001960 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001961 Dim->ElementType = ATy->ElementType;
1962 return ATy;
1963}
1964
1965// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001966FunctionParams
1967Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001968 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001969 if (MangledName.consumeFront('X'))
1970 return {};
1971
Zachary Turnerd30700f2018-07-31 17:16:44 +00001972 FunctionParams *Head;
1973 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001974 while (!Error && !MangledName.startsWith('@') &&
1975 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001976
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001977 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001978 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00001979 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001980 Error = true;
1981 return {};
1982 }
1983 MangledName = MangledName.dropFront();
1984
Zachary Turnerd30700f2018-07-31 17:16:44 +00001985 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00001986 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001987 Current = &(*Current)->Next;
1988 continue;
1989 }
1990
Zachary Turner23df1312018-07-26 22:13:39 +00001991 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001992
Zachary Turnerd30700f2018-07-31 17:16:44 +00001993 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001994 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001995
Zachary Turner23df1312018-07-26 22:13:39 +00001996 size_t CharsConsumed = OldSize - MangledName.size();
1997 assert(CharsConsumed != 0);
1998
1999 // Single-letter types are ignored for backreferences because memorizing
2000 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002001 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2002 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2003 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002004
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002005 Current = &(*Current)->Next;
2006 }
2007
Zachary Turner38b78a72018-07-26 20:20:10 +00002008 if (Error)
2009 return {};
2010
2011 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2012 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2013 // the following Z could be a throw specifier.
2014 if (MangledName.consumeFront('@'))
2015 return *Head;
2016
2017 if (MangledName.consumeFront('Z')) {
2018 Head->IsVariadic = true;
2019 return *Head;
2020 }
2021
2022 Error = true;
2023 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002024}
2025
Zachary Turnerd30700f2018-07-31 17:16:44 +00002026TemplateParams *
2027Demangler::demangleTemplateParameterList(StringView &MangledName) {
2028 TemplateParams *Head;
2029 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002030 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002031 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002032 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002033
2034 // Empty parameter pack.
2035 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2036 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002037 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002038 }
2039
Zachary Turnerd30700f2018-07-31 17:16:44 +00002040 if (MangledName.consumeFront("$$Y")) {
2041 (*Current)->IsTemplateTemplate = true;
2042 (*Current)->IsAliasTemplate = true;
2043 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
2044 } else if (MangledName.consumeFront("$1?")) {
2045 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
2046 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
2047 } else {
2048 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002049 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002050 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002051 if (Error)
2052 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002053
2054 Current = &(*Current)->Next;
2055 }
2056
2057 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002058 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002059
2060 // Template parameter lists cannot be variadic, so it can only be terminated
2061 // by @.
2062 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002063 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002064 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002065 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002066}
2067
Zachary Turner172aea12018-08-02 17:08:03 +00002068StringView Demangler::resolve(StringView N) {
2069 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002070 size_t Digit = N[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002071 if (Digit >= Backrefs.NamesCount)
Zachary Turner172aea12018-08-02 17:08:03 +00002072 return N;
Zachary Turnerd346cba2018-08-08 17:17:04 +00002073 return Backrefs.Names[Digit];
Zachary Turner172aea12018-08-02 17:08:03 +00002074}
2075
Zachary Turner316109b2018-07-29 16:38:02 +00002076void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002077 // Converts an AST to a string.
2078 //
2079 // Converting an AST representing a C++ type to a string is tricky due
2080 // to the bad grammar of the C++ declaration inherited from C. You have
2081 // to construct a string from inside to outside. For example, if a type
2082 // X is a pointer to a function returning int, the order you create a
2083 // string becomes something like this:
2084 //
2085 // (1) X is a pointer: *X
2086 // (2) (1) is a function returning int: int (*X)()
2087 //
2088 // So you cannot construct a result just by appending strings to a result.
2089 //
2090 // To deal with this, we split the function into two. outputPre() writes
2091 // the "first half" of type declaration, and outputPost() writes the
2092 // "second half". For example, outputPre() writes a return type for a
2093 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002094 Type::outputPre(OS, *S->SymbolType, *this);
2095 outputName(OS, S->SymbolName, *this);
2096 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002097}
2098
Zachary Turner3a758e22018-08-01 18:33:04 +00002099void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002100 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00002101 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002102
2103 // Create an output stream so we can render each type.
2104 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00002105 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00002106 OS.setCurrentPosition(0);
2107
Zachary Turnerd346cba2018-08-08 17:17:04 +00002108 Type *T = Backrefs.FunctionParams[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002109 Type::outputPre(OS, *T, *this);
2110 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002111
Zachary Turner7563ebe2018-08-02 17:08:24 +00002112 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002113 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002114 }
2115 std::free(OS.getBuffer());
2116
Zachary Turnerd346cba2018-08-08 17:17:04 +00002117 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002118 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00002119 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
2120 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
2121 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
2122 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002123 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00002124 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002125 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002126}
2127
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002128char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002129 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002130 Demangler D;
2131 StringView Name{MangledName};
2132 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002133
Zachary Turner3a758e22018-08-01 18:33:04 +00002134 if (Flags & MSDF_DumpBackrefs)
2135 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002136 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002137 if (D.Error) {
2138 OS << MangledName;
2139 *Status = llvm::demangle_invalid_mangled_name;
2140 } else {
2141 D.output(S, OS);
2142 *Status = llvm::demangle_success;
2143 }
2144
Zachary Turner71c91f92018-07-30 03:12:34 +00002145 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002146 return OS.getBuffer();
2147}