blob: 76f64c8d6be74cb19dbe6ff7b80edffbb9415d91 [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 Turner44ebbc22018-08-01 18:32:47 +0000208enum class SymbolCategory { Function, Variable };
209
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000210namespace {
211
Zachary Turner172aea12018-08-02 17:08:03 +0000212struct NameResolver {
213 virtual StringView resolve(StringView S) = 0;
214};
215
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000216struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000217struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000218
Zachary Turnerd30700f2018-07-31 17:16:44 +0000219struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000220 bool IsVariadic = false;
221
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000222 Type *Current = nullptr;
223
Zachary Turnerd30700f2018-07-31 17:16:44 +0000224 FunctionParams *Next = nullptr;
225};
Zachary Turner931e8792018-07-30 23:02:10 +0000226
Zachary Turnerd30700f2018-07-31 17:16:44 +0000227struct TemplateParams {
228 bool IsTemplateTemplate = false;
229 bool IsAliasTemplate = false;
230
231 // Type can be null if this is a template template parameter. In that case
232 // only Name will be valid.
233 Type *ParamType = nullptr;
234
235 // Name can be valid if this is a template template parameter (see above) or
236 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
237 // Name contains the name of the function and Type contains the signature.
238 Name *ParamName = nullptr;
239
240 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000241};
242
243// The type class. Mangled symbols are first parsed and converted to
244// this type and then converted to string.
245struct Type {
246 virtual ~Type() {}
247
248 virtual Type *clone(ArenaAllocator &Arena) const;
249
250 // Write the "first half" of a given type. This is a static functions to
251 // give the code a chance to do processing that is common to a subset of
252 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000253 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000254
255 // Write the "second half" of a given type. This is a static functions to
256 // give the code a chance to do processing that is common to a subset of
257 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000258 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000259
Zachary Turner172aea12018-08-02 17:08:03 +0000260 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
261 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000262
263 // Primitive type such as Int.
264 PrimTy Prim = PrimTy::Unknown;
265
266 Qualifiers Quals = Q_None;
267 StorageClass Storage = StorageClass::None; // storage class
268};
269
270// Represents an identifier which may be a template.
271struct Name {
272 // Name read from an MangledName string.
273 StringView Str;
274
Zachary Turner44ebbc22018-08-01 18:32:47 +0000275 bool IsTemplateInstantiation = false;
276 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000277 bool IsBackReference = false;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000278
Zachary Turner44ebbc22018-08-01 18:32:47 +0000279 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000280 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000281
282 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
283 Name *Next = nullptr;
284};
285
286struct PointerType : public Type {
287 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000288 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
289 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000290
Zachary Turner931e8792018-07-30 23:02:10 +0000291 PointerAffinity Affinity;
292
Zachary Turnerd742d642018-07-26 19:56:09 +0000293 // Represents a type X in "a pointer to X", "a reference to X",
294 // "an array of X", or "a function returning X".
295 Type *Pointee = nullptr;
296};
297
298struct MemberPointerType : public Type {
299 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000300 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
301 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000302
303 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000304
305 // Represents a type X in "a pointer to X", "a reference to X",
306 // "an array of X", or "a function returning X".
307 Type *Pointee = nullptr;
308};
309
310struct FunctionType : public Type {
311 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000312 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
313 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000314
Zachary Turner024e1762018-07-26 20:33:48 +0000315 // True if this FunctionType instance is the Pointee of a PointerType or
316 // MemberPointerType.
317 bool IsFunctionPointer = false;
318
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000319 Type *ReturnType = nullptr;
320 // If this is a reference, the type of reference.
321 ReferenceKind RefKind;
322
323 CallingConv CallConvention;
324 FuncClass FunctionClass;
325
Zachary Turnerd30700f2018-07-31 17:16:44 +0000326 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000327};
328
329struct UdtType : public Type {
330 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000331 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000332
333 Name *UdtName = nullptr;
334};
335
336struct ArrayType : public Type {
337 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000338 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
339 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000340
341 // Either NextDimension or ElementType will be valid.
342 ArrayType *NextDimension = nullptr;
343 uint32_t ArrayDimension = 0;
344
345 Type *ElementType = nullptr;
346};
347
348} // namespace
349
Zachary Turnerd742d642018-07-26 19:56:09 +0000350static bool isMemberPointer(StringView MangledName) {
351 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000352 case '$':
353 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
354 // rvalue reference to a member.
355 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000356 case 'A':
357 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000358 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000359 return false;
360 case 'P':
361 case 'Q':
362 case 'R':
363 case 'S':
364 // These 4 values indicate some kind of pointer, but we still don't know
365 // what.
366 break;
367 default:
368 assert(false && "Ty is not a pointer type!");
369 }
370
371 // If it starts with a number, then 6 indicates a non-member function
372 // pointer, and 8 indicates a member function pointer.
373 if (startsWithDigit(MangledName)) {
374 assert(MangledName[0] == '6' || MangledName[0] == '8');
375 return (MangledName[0] == '8');
376 }
377
378 // Remove ext qualifiers since those can appear on either type and are
379 // therefore not indicative.
380 MangledName.consumeFront('E'); // 64-bit
381 MangledName.consumeFront('I'); // restrict
382 MangledName.consumeFront('F'); // unaligned
383
384 assert(!MangledName.empty());
385
386 // The next value should be either ABCD (non-member) or QRST (member).
387 switch (MangledName.front()) {
388 case 'A':
389 case 'B':
390 case 'C':
391 case 'D':
392 return false;
393 case 'Q':
394 case 'R':
395 case 'S':
396 case 'T':
397 return true;
398 default:
399 assert(false);
400 }
401 return false;
402}
403
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000404static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
405 outputSpaceIfNecessary(OS);
406
407 switch (CC) {
408 case CallingConv::Cdecl:
409 OS << "__cdecl";
410 break;
411 case CallingConv::Fastcall:
412 OS << "__fastcall";
413 break;
414 case CallingConv::Pascal:
415 OS << "__pascal";
416 break;
417 case CallingConv::Regcall:
418 OS << "__regcall";
419 break;
420 case CallingConv::Stdcall:
421 OS << "__stdcall";
422 break;
423 case CallingConv::Thiscall:
424 OS << "__thiscall";
425 break;
426 case CallingConv::Eabi:
427 OS << "__eabi";
428 break;
429 case CallingConv::Vectorcall:
430 OS << "__vectorcall";
431 break;
432 case CallingConv::Clrcall:
433 OS << "__clrcall";
434 break;
435 default:
436 break;
437 }
438}
439
Zachary Turner71c91f92018-07-30 03:12:34 +0000440static bool startsWithLocalScopePattern(StringView S) {
441 if (!S.consumeFront('?'))
442 return false;
443 if (S.size() < 2)
444 return false;
445
446 size_t End = S.find('?');
447 if (End == StringView::npos)
448 return false;
449 StringView Candidate = S.substr(0, End);
450 if (Candidate.empty())
451 return false;
452
453 // \?[0-9]\?
454 // ?@? is the discriminator 0.
455 if (Candidate.size() == 1)
456 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
457
458 // If it's not 0-9, then it's an encoded number terminated with an @
459 if (Candidate.back() != '@')
460 return false;
461 Candidate = Candidate.dropBack();
462
463 // An encoded number starts with B-P and all subsequent digits are in A-P.
464 // Note that the reason the first digit cannot be A is two fold. First, it
465 // would create an ambiguity with ?A which delimits the beginning of an
466 // anonymous namespace. Second, A represents 0, and you don't start a multi
467 // digit number with a leading 0. Presumably the anonymous namespace
468 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
469 if (Candidate[0] < 'B' || Candidate[0] > 'P')
470 return false;
471 Candidate = Candidate.dropFront();
472 while (!Candidate.empty()) {
473 if (Candidate[0] < 'A' || Candidate[0] > 'P')
474 return false;
475 Candidate = Candidate.dropFront();
476 }
477
478 return true;
479}
480
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000481// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000482static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
483 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000484 if (!Params.Current) {
485 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000486 return;
487 }
488
Zachary Turnerd30700f2018-07-31 17:16:44 +0000489 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000490 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000491 Type::outputPre(OS, *Head->Current, Resolver);
492 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000493
494 Head = Head->Next;
495
496 if (Head)
497 OS << ", ";
498 }
499}
500
Zachary Turner172aea12018-08-02 17:08:03 +0000501static void outputName(OutputStream &OS, const Name *TheName,
502 NameResolver &Resolver);
503
504static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
505 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000506 if (!Params.ParamType && !Params.ParamName) {
507 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000508 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000509 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000510
511 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000512 const TemplateParams *Head = &Params;
513 while (Head) {
514 // Type can be null if this is a template template parameter,
515 // and Name can be null if this is a simple type.
516
517 if (Head->ParamType && Head->ParamName) {
518 // Function pointer.
519 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000520 Type::outputPre(OS, *Head->ParamType, Resolver);
521 outputName(OS, Head->ParamName, Resolver);
522 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000523 } else if (Head->ParamType) {
524 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000525 Type::outputPre(OS, *Head->ParamType, Resolver);
526 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000527 } else {
528 // Template alias.
Zachary Turner172aea12018-08-02 17:08:03 +0000529 outputName(OS, Head->ParamName, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000530 }
531
532 Head = Head->Next;
533
534 if (Head)
535 OS << ", ";
536 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000537 OS << ">";
538}
539
Zachary Turner172aea12018-08-02 17:08:03 +0000540static void outputNameComponent(OutputStream &OS, const Name &N,
541 NameResolver &Resolver) {
542 StringView S = N.Str;
543
544 if (N.IsBackReference)
545 S = Resolver.resolve(N.Str);
546 OS << S;
547
548 if (N.IsTemplateInstantiation)
549 outputParameterList(OS, *N.TParams, Resolver);
550}
551
552static void outputName(OutputStream &OS, const Name *TheName,
553 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000554 if (!TheName)
555 return;
556
557 outputSpaceIfNecessary(OS);
558
Zachary Turnera7dffb12018-07-28 22:10:42 +0000559 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000560 // Print out namespaces or outer class BackReferences.
561 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000562 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000563 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000564 OS << "::";
565 }
566
567 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000568 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000569 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000570 return;
571 }
572
573 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000574 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000575 OS << "~";
576
Zachary Turner44ebbc22018-08-01 18:32:47 +0000577 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turner172aea12018-08-02 17:08:03 +0000578 outputNameComponent(OS, *Previous, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000579 return;
580 }
581
582 // Print out an overloaded operator.
Zachary Turner172aea12018-08-02 17:08:03 +0000583 OS << "operator";
584 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000585}
586
587namespace {
588
589Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000590 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000591}
592
593// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000594void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000595 // Function types require custom handling of const and static so we
596 // handle them separately. All other types use the same decoration
597 // for these modifiers, so handle them here in common code.
598 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000599 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000600 return;
601 }
602
603 switch (Ty.Storage) {
604 case StorageClass::PrivateStatic:
605 case StorageClass::PublicStatic:
606 case StorageClass::ProtectedStatic:
607 OS << "static ";
608 default:
609 break;
610 }
Zachary Turner172aea12018-08-02 17:08:03 +0000611 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000612
613 if (Ty.Quals & Q_Const) {
614 outputSpaceIfNecessary(OS);
615 OS << "const";
616 }
617
618 if (Ty.Quals & Q_Volatile) {
619 outputSpaceIfNecessary(OS);
620 OS << "volatile";
621 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000622
623 if (Ty.Quals & Q_Restrict) {
624 outputSpaceIfNecessary(OS);
625 OS << "__restrict";
626 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000627}
628
629// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000630void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
631 Ty.outputPost(OS, Resolver);
632}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000633
Zachary Turner172aea12018-08-02 17:08:03 +0000634void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000635 switch (Prim) {
636 case PrimTy::Void:
637 OS << "void";
638 break;
639 case PrimTy::Bool:
640 OS << "bool";
641 break;
642 case PrimTy::Char:
643 OS << "char";
644 break;
645 case PrimTy::Schar:
646 OS << "signed char";
647 break;
648 case PrimTy::Uchar:
649 OS << "unsigned char";
650 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000651 case PrimTy::Char16:
652 OS << "char16_t";
653 break;
654 case PrimTy::Char32:
655 OS << "char32_t";
656 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000657 case PrimTy::Short:
658 OS << "short";
659 break;
660 case PrimTy::Ushort:
661 OS << "unsigned short";
662 break;
663 case PrimTy::Int:
664 OS << "int";
665 break;
666 case PrimTy::Uint:
667 OS << "unsigned int";
668 break;
669 case PrimTy::Long:
670 OS << "long";
671 break;
672 case PrimTy::Ulong:
673 OS << "unsigned long";
674 break;
675 case PrimTy::Int64:
676 OS << "__int64";
677 break;
678 case PrimTy::Uint64:
679 OS << "unsigned __int64";
680 break;
681 case PrimTy::Wchar:
682 OS << "wchar_t";
683 break;
684 case PrimTy::Float:
685 OS << "float";
686 break;
687 case PrimTy::Double:
688 OS << "double";
689 break;
690 case PrimTy::Ldouble:
691 OS << "long double";
692 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000693 case PrimTy::Nullptr:
694 OS << "std::nullptr_t";
695 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000696 default:
697 assert(false && "Invalid primitive type!");
698 }
699}
Zachary Turner172aea12018-08-02 17:08:03 +0000700void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000701
702Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000703 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000704}
705
Zachary Turner024e1762018-07-26 20:33:48 +0000706static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +0000707 const Name *MemberName, const Type *Pointee,
708 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +0000709 // "[]" and "()" (for function parameters) take precedence over "*",
710 // so "int *x(int)" means "x is a function returning int *". We need
711 // parentheses to supercede the default precedence. (e.g. we want to
712 // emit something like "int (*x)(int)".)
713 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
714 OS << "(";
715 if (Pointee->Prim == PrimTy::Function) {
716 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
717 assert(FTy->IsFunctionPointer);
718 outputCallingConvention(OS, FTy->CallConvention);
719 OS << " ";
720 }
721 }
722
723 if (MemberName) {
Zachary Turner172aea12018-08-02 17:08:03 +0000724 outputName(OS, MemberName, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +0000725 OS << "::";
726 }
727
728 if (Affinity == PointerAffinity::Pointer)
729 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000730 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000731 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000732 else
733 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000734}
735
Zachary Turner172aea12018-08-02 17:08:03 +0000736void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
737 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000738
739 outputSpaceIfNecessary(OS);
740
741 if (Quals & Q_Unaligned)
742 OS << "__unaligned ";
743
Zachary Turner172aea12018-08-02 17:08:03 +0000744 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000745
Zachary Turner91ecedd2018-07-20 18:07:33 +0000746 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000747 // if (Ty.Quals & Q_Pointer64)
748 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000749}
750
Zachary Turner172aea12018-08-02 17:08:03 +0000751void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000752 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
753 OS << ")";
754
Zachary Turner172aea12018-08-02 17:08:03 +0000755 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000756}
757
Zachary Turnerd742d642018-07-26 19:56:09 +0000758Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
759 return Arena.alloc<MemberPointerType>(*this);
760}
761
Zachary Turner172aea12018-08-02 17:08:03 +0000762void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
763 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000764
765 outputSpaceIfNecessary(OS);
766
Zachary Turner172aea12018-08-02 17:08:03 +0000767 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
768 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000769
770 // FIXME: We should output this, but it requires updating lots of tests.
771 // if (Ty.Quals & Q_Pointer64)
772 // OS << " __ptr64";
773 if (Quals & Q_Restrict)
774 OS << " __restrict";
775}
776
Zachary Turner172aea12018-08-02 17:08:03 +0000777void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +0000778 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
779 OS << ")";
780
Zachary Turner172aea12018-08-02 17:08:03 +0000781 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000782}
783
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000784Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000785 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000786}
787
Zachary Turner172aea12018-08-02 17:08:03 +0000788void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000789 if (!(FunctionClass & Global)) {
790 if (FunctionClass & Static)
791 OS << "static ";
792 }
793
Zachary Turner38b78a72018-07-26 20:20:10 +0000794 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +0000795 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +0000796 OS << " ";
797 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000798
Zachary Turner024e1762018-07-26 20:33:48 +0000799 // Function pointers print the calling convention as void (__cdecl *)(params)
800 // rather than void __cdecl (*)(params). So we need to let the PointerType
801 // class handle this.
802 if (!IsFunctionPointer)
803 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000804}
805
Zachary Turner172aea12018-08-02 17:08:03 +0000806void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000807 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +0000808 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000809 OS << ")";
810 if (Quals & Q_Const)
811 OS << " const";
812 if (Quals & Q_Volatile)
813 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000814 if (Quals & Q_Restrict)
815 OS << " __restrict";
816 if (Quals & Q_Unaligned)
817 OS << " __unaligned";
818
819 if (RefKind == ReferenceKind::LValueRef)
820 OS << " &";
821 else if (RefKind == ReferenceKind::RValueRef)
822 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000823
824 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +0000825 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000826 return;
827}
828
829Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000830 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000831}
832
Zachary Turner172aea12018-08-02 17:08:03 +0000833void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000834 switch (Prim) {
835 case PrimTy::Class:
836 OS << "class ";
837 break;
838 case PrimTy::Struct:
839 OS << "struct ";
840 break;
841 case PrimTy::Union:
842 OS << "union ";
843 break;
844 case PrimTy::Enum:
845 OS << "enum ";
846 break;
847 default:
848 assert(false && "Not a udt type!");
849 }
850
Zachary Turner172aea12018-08-02 17:08:03 +0000851 outputName(OS, UdtName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000852}
853
854Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000855 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000856}
857
Zachary Turner172aea12018-08-02 17:08:03 +0000858void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
859 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000860}
861
Zachary Turner172aea12018-08-02 17:08:03 +0000862void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000863 if (ArrayDimension > 0)
864 OS << "[" << ArrayDimension << "]";
865 if (NextDimension)
Zachary Turner172aea12018-08-02 17:08:03 +0000866 Type::outputPost(OS, *NextDimension, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000867 else if (ElementType)
Zachary Turner172aea12018-08-02 17:08:03 +0000868 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000869}
870
Zachary Turner316109b2018-07-29 16:38:02 +0000871struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000872 SymbolCategory Category;
873
Zachary Turner316109b2018-07-29 16:38:02 +0000874 Name *SymbolName = nullptr;
875 Type *SymbolType = nullptr;
876};
877
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000878} // namespace
879
880namespace {
881
882// Demangler class takes the main role in demangling symbols.
883// It has a set of functions to parse mangled symbols into Type instances.
884// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +0000885class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000886public:
Zachary Turner316109b2018-07-29 16:38:02 +0000887 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000888
889 // You are supposed to call parse() first and then check if error is true. If
890 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000891 Symbol *parse(StringView &MangledName);
892 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000893
Zachary Turner172aea12018-08-02 17:08:03 +0000894 StringView resolve(StringView N) override;
895
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000896 // True if an error occurred.
897 bool Error = false;
898
Zachary Turner3a758e22018-08-01 18:33:04 +0000899 void dumpBackReferences();
900
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000901private:
Zachary Turner316109b2018-07-29 16:38:02 +0000902 Type *demangleVariableEncoding(StringView &MangledName);
903 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000904
Zachary Turner316109b2018-07-29 16:38:02 +0000905 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000906
907 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000908 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
909 Type *demangleBasicType(StringView &MangledName);
910 UdtType *demangleClassType(StringView &MangledName);
911 PointerType *demanglePointerType(StringView &MangledName);
912 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
913 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
914 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000915
Zachary Turner316109b2018-07-29 16:38:02 +0000916 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000917
Zachary Turnerd30700f2018-07-31 17:16:44 +0000918 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
919 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000920
Zachary Turner316109b2018-07-29 16:38:02 +0000921 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000922
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000923 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000924
925 /// Allocate a copy of \p Borrowed into memory that we own.
926 StringView copyString(StringView Borrowed);
927
Zachary Turner316109b2018-07-29 16:38:02 +0000928 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
929 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000930
Zachary Turner44ebbc22018-08-01 18:32:47 +0000931 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
932 Name *demangleUnqualifiedSymbolName(StringView &MangledName, bool Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000933
Zachary Turner316109b2018-07-29 16:38:02 +0000934 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
935 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000936
Zachary Turner316109b2018-07-29 16:38:02 +0000937 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +0000938 Name *demangleTemplateInstantiationName(StringView &MangledName);
Zachary Turner316109b2018-07-29 16:38:02 +0000939 Name *demangleOperatorName(StringView &MangledName);
940 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
941 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000942 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000943
Zachary Turner931e8792018-07-30 23:02:10 +0000944 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
945
Zachary Turner316109b2018-07-29 16:38:02 +0000946 FuncClass demangleFunctionClass(StringView &MangledName);
947 CallingConv demangleCallingConvention(StringView &MangledName);
948 StorageClass demangleVariableStorageClass(StringView &MangledName);
949 ReferenceKind demangleReferenceKind(StringView &MangledName);
950 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000951
Zachary Turner316109b2018-07-29 16:38:02 +0000952 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000953
954 // Memory allocator.
955 ArenaAllocator Arena;
956
Zachary Turner23df1312018-07-26 22:13:39 +0000957 // A single type uses one global back-ref table for all function params.
958 // This means back-refs can even go "into" other types. Examples:
959 //
960 // // Second int* is a back-ref to first.
961 // void foo(int *, int*);
962 //
963 // // Second int* is not a back-ref to first (first is not a function param).
964 // int* foo(int*);
965 //
966 // // Second int* is a back-ref to first (ALL function types share the same
967 // // back-ref map.
968 // using F = void(*)(int*);
969 // F G(int *);
970 Type *FunctionParamBackRefs[10];
971 size_t FunctionParamBackRefCount = 0;
972
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000973 // The first 10 BackReferences in a mangled name can be back-referenced by
974 // special name @[0-9]. This is a storage for the first 10 BackReferences.
975 StringView BackReferences[10];
976 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000977};
978} // namespace
979
Zachary Turner71c91f92018-07-30 03:12:34 +0000980StringView Demangler::copyString(StringView Borrowed) {
981 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
982 std::strcpy(Stable, Borrowed.begin());
983
984 return {Stable, Borrowed.size()};
985}
986
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000987// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000988Symbol *Demangler::parse(StringView &MangledName) {
989 Symbol *S = Arena.alloc<Symbol>();
990
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000991 // MSVC-style mangled symbols must start with '?'.
992 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000993 S->SymbolName = Arena.alloc<Name>();
994 S->SymbolName->Str = MangledName;
995 S->SymbolType = Arena.alloc<Type>();
996 S->SymbolType->Prim = PrimTy::Unknown;
997 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000998 }
999
1000 // What follows is a main symbol name. This may include
1001 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +00001002 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001003 if (Error)
1004 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001005 // Read a variable.
Zachary Turner44ebbc22018-08-01 18:32:47 +00001006 if (startsWithDigit(MangledName)) {
1007 S->Category = SymbolCategory::Variable;
1008 S->SymbolType = demangleVariableEncoding(MangledName);
1009 } else {
1010 S->Category = SymbolCategory::Function;
1011 S->SymbolType = demangleFunctionEncoding(MangledName);
1012 }
1013
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001014 if (Error)
1015 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001016
Zachary Turner316109b2018-07-29 16:38:02 +00001017 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001018}
1019
1020// <type-encoding> ::= <storage-class> <variable-type>
1021// <storage-class> ::= 0 # private static member
1022// ::= 1 # protected static member
1023// ::= 2 # public static member
1024// ::= 3 # global
1025// ::= 4 # static local
1026
Zachary Turner316109b2018-07-29 16:38:02 +00001027Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1028 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001029
Zachary Turner316109b2018-07-29 16:38:02 +00001030 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001031
1032 Ty->Storage = SC;
1033
1034 // <variable-type> ::= <type> <cvr-qualifiers>
1035 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1036 switch (Ty->Prim) {
1037 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001038 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001039 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001040 Ty->Quals =
1041 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001042
Zachary Turnerd742d642018-07-26 19:56:09 +00001043 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001044 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001045
Zachary Turnerd742d642018-07-26 19:56:09 +00001046 if (Ty->Prim == PrimTy::MemberPtr) {
1047 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001048 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001049 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001050 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1051 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1052 } else {
1053 PointerType *PTy = static_cast<PointerType *>(Ty);
1054 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001055 }
1056
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001057 break;
1058 }
1059 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001060 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001061 break;
1062 }
1063
1064 return Ty;
1065}
1066
1067// Sometimes numbers are encoded in mangled symbols. For example,
1068// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1069// length 20), so we need some way to embed numbers as part of symbols.
1070// This function parses it.
1071//
1072// <number> ::= [?] <non-negative integer>
1073//
1074// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1075// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1076//
1077// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001078int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001079 bool neg = MangledName.consumeFront("?");
1080
1081 if (startsWithDigit(MangledName)) {
1082 int32_t Ret = MangledName[0] - '0' + 1;
1083 MangledName = MangledName.dropFront(1);
1084 return neg ? -Ret : Ret;
1085 }
1086
1087 int Ret = 0;
1088 for (size_t i = 0; i < MangledName.size(); ++i) {
1089 char C = MangledName[i];
1090 if (C == '@') {
1091 MangledName = MangledName.dropFront(i + 1);
1092 return neg ? -Ret : Ret;
1093 }
1094 if ('A' <= C && C <= 'P') {
1095 Ret = (Ret << 4) + (C - 'A');
1096 continue;
1097 }
1098 break;
1099 }
1100
1101 Error = true;
1102 return 0;
1103}
1104
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1106// Memorize it.
1107void Demangler::memorizeString(StringView S) {
1108 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1109 return;
1110 for (size_t i = 0; i < BackRefCount; ++i)
1111 if (S == BackReferences[i])
1112 return;
1113 BackReferences[BackRefCount++] = S;
1114}
1115
Zachary Turner316109b2018-07-29 16:38:02 +00001116Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001117 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001118 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001119 Node->IsBackReference = true;
1120 Node->Str = {MangledName.begin(), 1};
1121 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001122 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001123}
1124
Zachary Turner44ebbc22018-08-01 18:32:47 +00001125Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001126 assert(MangledName.startsWith("?$"));
1127 MangledName.consumeFront("?$");
1128
Zachary Turner44ebbc22018-08-01 18:32:47 +00001129 Name *Node = demangleUnqualifiedSymbolName(MangledName, false);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001130 if (Error)
1131 return nullptr;
1132
Zachary Turnerd30700f2018-07-31 17:16:44 +00001133 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001134 if (Error)
1135 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001136
Zachary Turner44ebbc22018-08-01 18:32:47 +00001137 Node->IsTemplateInstantiation = true;
1138
Zachary Turner71c91f92018-07-30 03:12:34 +00001139 // Render this class template name into a string buffer so that we can
1140 // memorize it for the purpose of back-referencing.
1141 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turner172aea12018-08-02 17:08:03 +00001142 outputName(OS, Node, *this);
Zachary Turner71c91f92018-07-30 03:12:34 +00001143 OS << '\0';
1144 char *Name = OS.getBuffer();
1145
1146 StringView Owned = copyString(Name);
1147 memorizeString(Owned);
1148 std::free(Name);
1149
Zachary Turnera7dffb12018-07-28 22:10:42 +00001150 return Node;
1151}
1152
Zachary Turner316109b2018-07-29 16:38:02 +00001153Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001154 assert(MangledName.startsWith('?'));
1155 MangledName.consumeFront('?');
1156
Zachary Turner316109b2018-07-29 16:38:02 +00001157 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001158 switch (MangledName.popFront()) {
1159 case '0':
1160 return "ctor";
1161 case '1':
1162 return "dtor";
1163 case '2':
1164 return " new";
1165 case '3':
1166 return " delete";
1167 case '4':
1168 return "=";
1169 case '5':
1170 return ">>";
1171 case '6':
1172 return "<<";
1173 case '7':
1174 return "!";
1175 case '8':
1176 return "==";
1177 case '9':
1178 return "!=";
1179 case 'A':
1180 return "[]";
1181 case 'C':
1182 return "->";
1183 case 'D':
1184 return "*";
1185 case 'E':
1186 return "++";
1187 case 'F':
1188 return "--";
1189 case 'G':
1190 return "-";
1191 case 'H':
1192 return "+";
1193 case 'I':
1194 return "&";
1195 case 'J':
1196 return "->*";
1197 case 'K':
1198 return "/";
1199 case 'L':
1200 return "%";
1201 case 'M':
1202 return "<";
1203 case 'N':
1204 return "<=";
1205 case 'O':
1206 return ">";
1207 case 'P':
1208 return ">=";
1209 case 'Q':
1210 return ",";
1211 case 'R':
1212 return "()";
1213 case 'S':
1214 return "~";
1215 case 'T':
1216 return "^";
1217 case 'U':
1218 return "|";
1219 case 'V':
1220 return "&&";
1221 case 'W':
1222 return "||";
1223 case 'X':
1224 return "*=";
1225 case 'Y':
1226 return "+=";
1227 case 'Z':
1228 return "-=";
1229 case '_': {
1230 if (MangledName.empty())
1231 break;
1232
1233 switch (MangledName.popFront()) {
1234 case '0':
1235 return "/=";
1236 case '1':
1237 return "%=";
1238 case '2':
1239 return ">>=";
1240 case '3':
1241 return "<<=";
1242 case '4':
1243 return "&=";
1244 case '5':
1245 return "|=";
1246 case '6':
1247 return "^=";
1248 case 'U':
1249 return " new[]";
1250 case 'V':
1251 return " delete[]";
1252 case '_':
1253 if (MangledName.consumeFront("L"))
1254 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001255 if (MangledName.consumeFront("K")) {
1256 size_t EndPos = MangledName.find('@');
1257 if (EndPos == StringView::npos)
1258 break;
1259 StringView OpName = demangleSimpleString(MangledName, false);
1260 size_t FullSize = OpName.size() + 3; // <space>""OpName
1261 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1262 Buffer[0] = ' ';
1263 Buffer[1] = '"';
1264 Buffer[2] = '"';
1265 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1266 return {Buffer, FullSize};
1267 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001268 }
1269 }
1270 }
1271 Error = true;
1272 return "";
1273 };
1274
1275 Name *Node = Arena.alloc<Name>();
Zachary Turner44ebbc22018-08-01 18:32:47 +00001276 Node->Str = NameString();
1277 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001278 return Node;
1279}
1280
Zachary Turner316109b2018-07-29 16:38:02 +00001281Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001282 StringView S = demangleSimpleString(MangledName, Memorize);
1283 if (Error)
1284 return nullptr;
1285
Zachary Turnera7dffb12018-07-28 22:10:42 +00001286 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001287 Node->Str = S;
1288 return Node;
1289}
1290
1291StringView Demangler::demangleSimpleString(StringView &MangledName,
1292 bool Memorize) {
1293 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001294 for (size_t i = 0; i < MangledName.size(); ++i) {
1295 if (MangledName[i] != '@')
1296 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001297 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001298 MangledName = MangledName.dropFront(i + 1);
1299
1300 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001301 memorizeString(S);
1302 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001303 }
1304
1305 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001306 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001307}
1308
Zachary Turner316109b2018-07-29 16:38:02 +00001309Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001310 assert(MangledName.startsWith("?A"));
1311 MangledName.consumeFront("?A");
1312
1313 Name *Node = Arena.alloc<Name>();
1314 Node->Str = "`anonymous namespace'";
1315 if (MangledName.consumeFront('@'))
1316 return Node;
1317
1318 Error = true;
1319 return nullptr;
1320}
1321
Zachary Turner71c91f92018-07-30 03:12:34 +00001322Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1323 assert(startsWithLocalScopePattern(MangledName));
1324
1325 Name *Node = Arena.alloc<Name>();
1326 MangledName.consumeFront('?');
1327 int ScopeIdentifier = demangleNumber(MangledName);
1328
1329 // One ? to terminate the number
1330 MangledName.consumeFront('?');
1331
1332 assert(!Error);
1333 Symbol *Scope = parse(MangledName);
1334 if (Error)
1335 return nullptr;
1336
1337 // Render the parent symbol's name into a buffer.
1338 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1339 OS << '`';
1340 output(Scope, OS);
1341 OS << '\'';
1342 OS << "::`" << ScopeIdentifier << "'";
1343 OS << '\0';
1344 char *Result = OS.getBuffer();
1345 Node->Str = copyString(Result);
1346 std::free(Result);
1347 return Node;
1348}
1349
Zachary Turnera7dffb12018-07-28 22:10:42 +00001350// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001351Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001352 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001353 if (Error)
1354 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001355 assert(TypeName);
1356
Zachary Turner316109b2018-07-29 16:38:02 +00001357 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001358 if (Error)
1359 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001360 assert(QualName);
1361 return QualName;
1362}
1363
1364// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1365// Symbol names have slightly different rules regarding what can appear
1366// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001367Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001368 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001369 if (Error)
1370 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001371 assert(SymbolName);
1372
Zachary Turner316109b2018-07-29 16:38:02 +00001373 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001374 if (Error)
1375 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001376 assert(QualName);
1377 return QualName;
1378}
1379
Zachary Turner44ebbc22018-08-01 18:32:47 +00001380Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1381 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001382 // An inner-most name can be a back-reference, because a fully-qualified name
1383 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1384 // them (for example template parameters), and these nested parameters can
1385 // refer to previously mangled types.
1386 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001387 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001388
1389 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001390 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001391
Zachary Turner44ebbc22018-08-01 18:32:47 +00001392 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001393}
1394
Zachary Turner44ebbc22018-08-01 18:32:47 +00001395Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
1396 bool Memorize) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001397 if (startsWithDigit(MangledName))
1398 return demangleBackRefName(MangledName);
1399 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001400 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001401 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001402 return demangleOperatorName(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001403 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001404}
1405
Zachary Turner316109b2018-07-29 16:38:02 +00001406Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001407 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001408 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001409
1410 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001411 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001412
1413 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001414 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001415
Zachary Turner71c91f92018-07-30 03:12:34 +00001416 if (startsWithLocalScopePattern(MangledName))
1417 return demangleLocallyScopedNamePiece(MangledName);
1418
Zachary Turner316109b2018-07-29 16:38:02 +00001419 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001420}
1421
Zachary Turner316109b2018-07-29 16:38:02 +00001422Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1423 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001424 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001425
1426 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001427 if (MangledName.empty()) {
1428 Error = true;
1429 return nullptr;
1430 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001431
1432 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001433 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001434 if (Error)
1435 return nullptr;
1436
1437 Elem->Next = Head;
1438 Head = Elem;
1439 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001440 return Head;
1441}
1442
Zachary Turner316109b2018-07-29 16:38:02 +00001443FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001444 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1445 RestoreOnError.shouldRestore(false);
1446
1447 switch (MangledName.popFront()) {
1448 case 'A':
1449 return Private;
1450 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001451 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001452 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001453 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001455 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001456 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001457 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001458 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001459 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001460 case 'I':
1461 return Protected;
1462 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001463 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001464 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001465 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001466 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001467 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001468 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001469 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001470 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001471 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001472 case 'Q':
1473 return Public;
1474 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001475 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001476 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001477 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001478 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001479 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001480 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001481 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001482 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001483 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001484 case 'Y':
1485 return Global;
1486 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001487 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001488 }
1489
1490 Error = true;
1491 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001492 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001493}
1494
Zachary Turner316109b2018-07-29 16:38:02 +00001495CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001496 switch (MangledName.popFront()) {
1497 case 'A':
1498 case 'B':
1499 return CallingConv::Cdecl;
1500 case 'C':
1501 case 'D':
1502 return CallingConv::Pascal;
1503 case 'E':
1504 case 'F':
1505 return CallingConv::Thiscall;
1506 case 'G':
1507 case 'H':
1508 return CallingConv::Stdcall;
1509 case 'I':
1510 case 'J':
1511 return CallingConv::Fastcall;
1512 case 'M':
1513 case 'N':
1514 return CallingConv::Clrcall;
1515 case 'O':
1516 case 'P':
1517 return CallingConv::Eabi;
1518 case 'Q':
1519 return CallingConv::Vectorcall;
1520 }
1521
1522 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001523}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001524
Zachary Turner316109b2018-07-29 16:38:02 +00001525StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001526 assert(std::isdigit(MangledName.front()));
1527
1528 switch (MangledName.popFront()) {
1529 case '0':
1530 return StorageClass::PrivateStatic;
1531 case '1':
1532 return StorageClass::ProtectedStatic;
1533 case '2':
1534 return StorageClass::PublicStatic;
1535 case '3':
1536 return StorageClass::Global;
1537 case '4':
1538 return StorageClass::FunctionLocalStatic;
1539 }
1540 Error = true;
1541 return StorageClass::None;
1542}
1543
Zachary Turner316109b2018-07-29 16:38:02 +00001544std::pair<Qualifiers, bool>
1545Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001546
1547 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001548 // Member qualifiers
1549 case 'Q':
1550 return std::make_pair(Q_None, true);
1551 case 'R':
1552 return std::make_pair(Q_Const, true);
1553 case 'S':
1554 return std::make_pair(Q_Volatile, true);
1555 case 'T':
1556 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1557 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001558 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001559 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001560 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001561 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001562 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001563 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001564 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001565 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001566 }
1567 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001568 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001569}
1570
Zachary Turner931e8792018-07-30 23:02:10 +00001571static bool isTagType(StringView S) {
1572 switch (S.front()) {
1573 case 'T': // union
1574 case 'U': // struct
1575 case 'V': // class
1576 case 'W': // enum
1577 return true;
1578 }
1579 return false;
1580}
1581
1582static bool isPointerType(StringView S) {
1583 if (S.startsWith("$$Q")) // foo &&
1584 return true;
1585
1586 switch (S.front()) {
1587 case 'A': // foo &
1588 case 'P': // foo *
1589 case 'Q': // foo *const
1590 case 'R': // foo *volatile
1591 case 'S': // foo *const volatile
1592 return true;
1593 }
1594 return false;
1595}
1596
1597static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1598
1599static bool isFunctionType(StringView S) {
1600 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1601}
1602
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001603// <variable-type> ::= <type> <cvr-qualifiers>
1604// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001605Type *Demangler::demangleType(StringView &MangledName,
1606 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001607 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001608 bool IsMember = false;
1609 bool IsMemberKnown = false;
1610 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001611 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001612 IsMemberKnown = true;
1613 } else if (QMM == QualifierMangleMode::Result) {
1614 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001615 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001616 IsMemberKnown = true;
1617 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001618 }
1619
1620 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001621 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001622 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001623 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001624 if (!IsMemberKnown)
1625 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001626
Zachary Turnerd742d642018-07-26 19:56:09 +00001627 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001628 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001629 else
Zachary Turner316109b2018-07-29 16:38:02 +00001630 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001631 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001632 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001633 else if (isFunctionType(MangledName)) {
1634 if (MangledName.consumeFront("$$A8@@"))
1635 Ty = demangleFunctionType(MangledName, true, false);
1636 else {
1637 assert(MangledName.startsWith("$$A6"));
1638 MangledName.consumeFront("$$A6");
1639 Ty = demangleFunctionType(MangledName, false, false);
1640 }
1641 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001642 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001643 assert(Ty && !Error);
1644 if (!Ty || Error)
1645 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001646 }
Zachary Turner931e8792018-07-30 23:02:10 +00001647
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001648 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1649 return Ty;
1650}
1651
Zachary Turner316109b2018-07-29 16:38:02 +00001652ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001653 if (MangledName.consumeFront('G'))
1654 return ReferenceKind::LValueRef;
1655 else if (MangledName.consumeFront('H'))
1656 return ReferenceKind::RValueRef;
1657 return ReferenceKind::None;
1658}
1659
Zachary Turner316109b2018-07-29 16:38:02 +00001660void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001661 if (MangledName.consumeFront('Z'))
1662 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001663
Zachary Turner38b78a72018-07-26 20:20:10 +00001664 Error = true;
1665}
1666
Zachary Turner316109b2018-07-29 16:38:02 +00001667FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1668 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001669 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001670 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001671 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001672 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001673
1674 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001675 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1676 FTy->RefKind = demangleReferenceKind(MangledName);
1677 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001678 }
1679
1680 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001681 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001682
1683 // <return-type> ::= <type>
1684 // ::= @ # structors (they have no declared return type)
1685 bool IsStructor = MangledName.consumeFront('@');
1686 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001687 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001688
Zachary Turner316109b2018-07-29 16:38:02 +00001689 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001690
Zachary Turner316109b2018-07-29 16:38:02 +00001691 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001692
1693 return FTy;
1694}
1695
Zachary Turner316109b2018-07-29 16:38:02 +00001696Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1697 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001698
1699 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001700 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001701 FTy->FunctionClass = FC;
1702
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001703 return FTy;
1704}
1705
1706// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001707Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001708 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001709
Zachary Turner931e8792018-07-30 23:02:10 +00001710 if (MangledName.consumeFront("$$T")) {
1711 Ty->Prim = PrimTy::Nullptr;
1712 return Ty;
1713 }
1714
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001715 switch (MangledName.popFront()) {
1716 case 'X':
1717 Ty->Prim = PrimTy::Void;
1718 break;
1719 case 'D':
1720 Ty->Prim = PrimTy::Char;
1721 break;
1722 case 'C':
1723 Ty->Prim = PrimTy::Schar;
1724 break;
1725 case 'E':
1726 Ty->Prim = PrimTy::Uchar;
1727 break;
1728 case 'F':
1729 Ty->Prim = PrimTy::Short;
1730 break;
1731 case 'G':
1732 Ty->Prim = PrimTy::Ushort;
1733 break;
1734 case 'H':
1735 Ty->Prim = PrimTy::Int;
1736 break;
1737 case 'I':
1738 Ty->Prim = PrimTy::Uint;
1739 break;
1740 case 'J':
1741 Ty->Prim = PrimTy::Long;
1742 break;
1743 case 'K':
1744 Ty->Prim = PrimTy::Ulong;
1745 break;
1746 case 'M':
1747 Ty->Prim = PrimTy::Float;
1748 break;
1749 case 'N':
1750 Ty->Prim = PrimTy::Double;
1751 break;
1752 case 'O':
1753 Ty->Prim = PrimTy::Ldouble;
1754 break;
1755 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001756 if (MangledName.empty()) {
1757 Error = true;
1758 return nullptr;
1759 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001760 switch (MangledName.popFront()) {
1761 case 'N':
1762 Ty->Prim = PrimTy::Bool;
1763 break;
1764 case 'J':
1765 Ty->Prim = PrimTy::Int64;
1766 break;
1767 case 'K':
1768 Ty->Prim = PrimTy::Uint64;
1769 break;
1770 case 'W':
1771 Ty->Prim = PrimTy::Wchar;
1772 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001773 case 'S':
1774 Ty->Prim = PrimTy::Char16;
1775 break;
1776 case 'U':
1777 Ty->Prim = PrimTy::Char32;
1778 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001779 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001780 Error = true;
1781 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001782 }
1783 break;
1784 }
Zachary Turner931e8792018-07-30 23:02:10 +00001785 default:
1786 Error = true;
1787 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001788 }
1789 return Ty;
1790}
1791
Zachary Turner316109b2018-07-29 16:38:02 +00001792UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001793 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001794
1795 switch (MangledName.popFront()) {
1796 case 'T':
1797 UTy->Prim = PrimTy::Union;
1798 break;
1799 case 'U':
1800 UTy->Prim = PrimTy::Struct;
1801 break;
1802 case 'V':
1803 UTy->Prim = PrimTy::Class;
1804 break;
1805 case 'W':
1806 if (MangledName.popFront() != '4') {
1807 Error = true;
1808 return nullptr;
1809 }
1810 UTy->Prim = PrimTy::Enum;
1811 break;
1812 default:
1813 assert(false);
1814 }
1815
Zachary Turner316109b2018-07-29 16:38:02 +00001816 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001817 return UTy;
1818}
1819
Zachary Turnerd742d642018-07-26 19:56:09 +00001820static std::pair<Qualifiers, PointerAffinity>
1821demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001822 if (MangledName.consumeFront("$$Q"))
1823 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1824
Zachary Turnerd742d642018-07-26 19:56:09 +00001825 switch (MangledName.popFront()) {
1826 case 'A':
1827 return std::make_pair(Q_None, PointerAffinity::Reference);
1828 case 'P':
1829 return std::make_pair(Q_None, PointerAffinity::Pointer);
1830 case 'Q':
1831 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1832 case 'R':
1833 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1834 case 'S':
1835 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1836 PointerAffinity::Pointer);
1837 default:
1838 assert(false && "Ty is not a pointer type!");
1839 }
1840 return std::make_pair(Q_None, PointerAffinity::Pointer);
1841}
1842
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001843// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1844// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001845PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001846 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001847
Zachary Turner931e8792018-07-30 23:02:10 +00001848 std::tie(Pointer->Quals, Pointer->Affinity) =
1849 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001850
Zachary Turner931e8792018-07-30 23:02:10 +00001851 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001852 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001853 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001854 return Pointer;
1855 }
1856
Zachary Turner316109b2018-07-29 16:38:02 +00001857 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001858 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1859
Zachary Turner316109b2018-07-29 16:38:02 +00001860 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001861 return Pointer;
1862}
1863
Zachary Turner316109b2018-07-29 16:38:02 +00001864MemberPointerType *
1865Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001866 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1867 Pointer->Prim = PrimTy::MemberPtr;
1868
1869 PointerAffinity Affinity;
1870 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1871 assert(Affinity == PointerAffinity::Pointer);
1872
Zachary Turner316109b2018-07-29 16:38:02 +00001873 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001874 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1875
Zachary Turner38b78a72018-07-26 20:20:10 +00001876 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001877 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1878 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001879 } else {
1880 Qualifiers PointeeQuals = Q_None;
1881 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001882 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001883 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001884 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001885
Zachary Turner316109b2018-07-29 16:38:02 +00001886 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001887 Pointer->Pointee->Quals = PointeeQuals;
1888 }
1889
Zachary Turnerd742d642018-07-26 19:56:09 +00001890 return Pointer;
1891}
1892
Zachary Turner316109b2018-07-29 16:38:02 +00001893Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001894 Qualifiers Quals = Q_None;
1895 if (MangledName.consumeFront('E'))
1896 Quals = Qualifiers(Quals | Q_Pointer64);
1897 if (MangledName.consumeFront('I'))
1898 Quals = Qualifiers(Quals | Q_Restrict);
1899 if (MangledName.consumeFront('F'))
1900 Quals = Qualifiers(Quals | Q_Unaligned);
1901
1902 return Quals;
1903}
1904
Zachary Turner316109b2018-07-29 16:38:02 +00001905ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001906 assert(MangledName.front() == 'Y');
1907 MangledName.popFront();
1908
Zachary Turner316109b2018-07-29 16:38:02 +00001909 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001910 if (Dimension <= 0) {
1911 Error = true;
1912 return nullptr;
1913 }
1914
Zachary Turner9d72aa92018-07-20 18:35:06 +00001915 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001916 ArrayType *Dim = ATy;
1917 for (int I = 0; I < Dimension; ++I) {
1918 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001919 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001920 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001921 Dim = Dim->NextDimension;
1922 }
1923
1924 if (MangledName.consumeFront("$$C")) {
1925 if (MangledName.consumeFront("B"))
1926 ATy->Quals = Q_Const;
1927 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1928 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1929 else if (!MangledName.consumeFront("A"))
1930 Error = true;
1931 }
1932
Zachary Turner316109b2018-07-29 16:38:02 +00001933 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001934 Dim->ElementType = ATy->ElementType;
1935 return ATy;
1936}
1937
1938// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001939FunctionParams
1940Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001941 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001942 if (MangledName.consumeFront('X'))
1943 return {};
1944
Zachary Turnerd30700f2018-07-31 17:16:44 +00001945 FunctionParams *Head;
1946 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001947 while (!Error && !MangledName.startsWith('@') &&
1948 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001949
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001950 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001951 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001952 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001953 Error = true;
1954 return {};
1955 }
1956 MangledName = MangledName.dropFront();
1957
Zachary Turnerd30700f2018-07-31 17:16:44 +00001958 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001959 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001960 Current = &(*Current)->Next;
1961 continue;
1962 }
1963
Zachary Turner23df1312018-07-26 22:13:39 +00001964 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001965
Zachary Turnerd30700f2018-07-31 17:16:44 +00001966 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001967 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001968
Zachary Turner23df1312018-07-26 22:13:39 +00001969 size_t CharsConsumed = OldSize - MangledName.size();
1970 assert(CharsConsumed != 0);
1971
1972 // Single-letter types are ignored for backreferences because memorizing
1973 // them doesn't save anything.
1974 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1975 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1976
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001977 Current = &(*Current)->Next;
1978 }
1979
Zachary Turner38b78a72018-07-26 20:20:10 +00001980 if (Error)
1981 return {};
1982
1983 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1984 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1985 // the following Z could be a throw specifier.
1986 if (MangledName.consumeFront('@'))
1987 return *Head;
1988
1989 if (MangledName.consumeFront('Z')) {
1990 Head->IsVariadic = true;
1991 return *Head;
1992 }
1993
1994 Error = true;
1995 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001996}
1997
Zachary Turnerd30700f2018-07-31 17:16:44 +00001998TemplateParams *
1999Demangler::demangleTemplateParameterList(StringView &MangledName) {
2000 TemplateParams *Head;
2001 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002002 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002003 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002004 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002005
2006 // Empty parameter pack.
2007 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2008 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002009 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002010 }
2011
Zachary Turnerd30700f2018-07-31 17:16:44 +00002012 if (MangledName.consumeFront("$$Y")) {
2013 (*Current)->IsTemplateTemplate = true;
2014 (*Current)->IsAliasTemplate = true;
2015 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
2016 } else if (MangledName.consumeFront("$1?")) {
2017 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
2018 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
2019 } else {
2020 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002021 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002022 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002023 if (Error)
2024 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002025
2026 Current = &(*Current)->Next;
2027 }
2028
2029 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002030 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002031
2032 // Template parameter lists cannot be variadic, so it can only be terminated
2033 // by @.
2034 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002035 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002036 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002037 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002038}
2039
Zachary Turner172aea12018-08-02 17:08:03 +00002040StringView Demangler::resolve(StringView N) {
2041 assert(N.size() == 1 && isdigit(N[0]));
2042 int Digit = N[0] - '0';
2043 if (Digit >= BackRefCount)
2044 return N;
2045 return BackReferences[Digit];
2046}
2047
Zachary Turner316109b2018-07-29 16:38:02 +00002048void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002049 // Converts an AST to a string.
2050 //
2051 // Converting an AST representing a C++ type to a string is tricky due
2052 // to the bad grammar of the C++ declaration inherited from C. You have
2053 // to construct a string from inside to outside. For example, if a type
2054 // X is a pointer to a function returning int, the order you create a
2055 // string becomes something like this:
2056 //
2057 // (1) X is a pointer: *X
2058 // (2) (1) is a function returning int: int (*X)()
2059 //
2060 // So you cannot construct a result just by appending strings to a result.
2061 //
2062 // To deal with this, we split the function into two. outputPre() writes
2063 // the "first half" of type declaration, and outputPost() writes the
2064 // "second half". For example, outputPre() writes a return type for a
2065 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002066 Type::outputPre(OS, *S->SymbolType, *this);
2067 outputName(OS, S->SymbolName, *this);
2068 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002069}
2070
Zachary Turner3a758e22018-08-01 18:33:04 +00002071void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002072 std::printf("%d function parameter backreferences\n",
2073 (int)FunctionParamBackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002074
2075 // Create an output stream so we can render each type.
2076 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
2077 for (size_t I = 0; I < FunctionParamBackRefCount; ++I) {
2078 OS.setCurrentPosition(0);
2079
2080 Type *T = FunctionParamBackRefs[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002081 Type::outputPre(OS, *T, *this);
2082 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002083
Zachary Turner7563ebe2018-08-02 17:08:24 +00002084 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002085 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002086 }
2087 std::free(OS.getBuffer());
2088
2089 if (FunctionParamBackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002090 std::printf("\n");
2091 std::printf("%d name backreferences\n", (int)BackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002092 for (size_t I = 0; I < BackRefCount; ++I) {
Zachary Turner7563ebe2018-08-02 17:08:24 +00002093 std::printf(" [%d] - %.*s\n", (int)I, (int)BackReferences[I].size(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002094 BackReferences[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002095 }
2096 if (BackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002097 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002098}
2099
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002100char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002101 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002102 Demangler D;
2103 StringView Name{MangledName};
2104 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002105
Zachary Turner3a758e22018-08-01 18:33:04 +00002106 if (Flags & MSDF_DumpBackrefs)
2107 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002108 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002109 if (D.Error) {
2110 OS << MangledName;
2111 *Status = llvm::demangle_invalid_mangled_name;
2112 } else {
2113 D.output(S, OS);
2114 *Status = llvm::demangle_success;
2115 }
2116
Zachary Turner71c91f92018-07-30 03:12:34 +00002117 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002118 return OS.getBuffer();
2119}