blob: f5a54cae500e6947c0998e097f7658d690dfe07f [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 {
Zachary Turnerae672182018-08-02 17:33:33 +0000213 virtual ~NameResolver() = default;
Zachary Turner172aea12018-08-02 17:08:03 +0000214 virtual StringView resolve(StringView S) = 0;
215};
216
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000217struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000218struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000219
Zachary Turnerd30700f2018-07-31 17:16:44 +0000220struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000221 bool IsVariadic = false;
222
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000223 Type *Current = nullptr;
224
Zachary Turnerd30700f2018-07-31 17:16:44 +0000225 FunctionParams *Next = nullptr;
226};
Zachary Turner931e8792018-07-30 23:02:10 +0000227
Zachary Turnerd30700f2018-07-31 17:16:44 +0000228struct TemplateParams {
229 bool IsTemplateTemplate = false;
230 bool IsAliasTemplate = false;
231
232 // Type can be null if this is a template template parameter. In that case
233 // only Name will be valid.
234 Type *ParamType = nullptr;
235
236 // Name can be valid if this is a template template parameter (see above) or
237 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
238 // Name contains the name of the function and Type contains the signature.
239 Name *ParamName = nullptr;
240
241 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000242};
243
244// The type class. Mangled symbols are first parsed and converted to
245// this type and then converted to string.
246struct Type {
247 virtual ~Type() {}
248
249 virtual Type *clone(ArenaAllocator &Arena) const;
250
251 // Write the "first half" of a given type. This is a static functions to
252 // give the code a chance to do processing that is common to a subset of
253 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000254 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000255
256 // Write the "second half" of a given type. This is a static functions to
257 // give the code a chance to do processing that is common to a subset of
258 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000259 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000260
Zachary Turner172aea12018-08-02 17:08:03 +0000261 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
262 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000263
264 // Primitive type such as Int.
265 PrimTy Prim = PrimTy::Unknown;
266
267 Qualifiers Quals = Q_None;
268 StorageClass Storage = StorageClass::None; // storage class
269};
270
271// Represents an identifier which may be a template.
272struct Name {
273 // Name read from an MangledName string.
274 StringView Str;
275
Zachary Turner44ebbc22018-08-01 18:32:47 +0000276 bool IsTemplateInstantiation = false;
277 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000278 bool IsBackReference = false;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000279
Zachary Turner44ebbc22018-08-01 18:32:47 +0000280 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000281 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000282
283 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
284 Name *Next = nullptr;
285};
286
287struct PointerType : public Type {
288 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000289 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
290 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000291
Zachary Turner931e8792018-07-30 23:02:10 +0000292 PointerAffinity Affinity;
293
Zachary Turnerd742d642018-07-26 19:56:09 +0000294 // Represents a type X in "a pointer to X", "a reference to X",
295 // "an array of X", or "a function returning X".
296 Type *Pointee = nullptr;
297};
298
299struct MemberPointerType : public Type {
300 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000301 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
302 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000303
304 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000305
306 // Represents a type X in "a pointer to X", "a reference to X",
307 // "an array of X", or "a function returning X".
308 Type *Pointee = nullptr;
309};
310
311struct FunctionType : public Type {
312 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000313 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
314 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000315
Zachary Turner024e1762018-07-26 20:33:48 +0000316 // True if this FunctionType instance is the Pointee of a PointerType or
317 // MemberPointerType.
318 bool IsFunctionPointer = false;
319
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000320 Type *ReturnType = nullptr;
321 // If this is a reference, the type of reference.
322 ReferenceKind RefKind;
323
324 CallingConv CallConvention;
325 FuncClass FunctionClass;
326
Zachary Turnerd30700f2018-07-31 17:16:44 +0000327 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000328};
329
330struct UdtType : public Type {
331 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000332 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000333
334 Name *UdtName = nullptr;
335};
336
337struct ArrayType : public Type {
338 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000339 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
340 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000341
342 // Either NextDimension or ElementType will be valid.
343 ArrayType *NextDimension = nullptr;
344 uint32_t ArrayDimension = 0;
345
346 Type *ElementType = nullptr;
347};
348
349} // namespace
350
Zachary Turnerd742d642018-07-26 19:56:09 +0000351static bool isMemberPointer(StringView MangledName) {
352 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000353 case '$':
354 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
355 // rvalue reference to a member.
356 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000357 case 'A':
358 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000359 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000360 return false;
361 case 'P':
362 case 'Q':
363 case 'R':
364 case 'S':
365 // These 4 values indicate some kind of pointer, but we still don't know
366 // what.
367 break;
368 default:
369 assert(false && "Ty is not a pointer type!");
370 }
371
372 // If it starts with a number, then 6 indicates a non-member function
373 // pointer, and 8 indicates a member function pointer.
374 if (startsWithDigit(MangledName)) {
375 assert(MangledName[0] == '6' || MangledName[0] == '8');
376 return (MangledName[0] == '8');
377 }
378
379 // Remove ext qualifiers since those can appear on either type and are
380 // therefore not indicative.
381 MangledName.consumeFront('E'); // 64-bit
382 MangledName.consumeFront('I'); // restrict
383 MangledName.consumeFront('F'); // unaligned
384
385 assert(!MangledName.empty());
386
387 // The next value should be either ABCD (non-member) or QRST (member).
388 switch (MangledName.front()) {
389 case 'A':
390 case 'B':
391 case 'C':
392 case 'D':
393 return false;
394 case 'Q':
395 case 'R':
396 case 'S':
397 case 'T':
398 return true;
399 default:
400 assert(false);
401 }
402 return false;
403}
404
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000405static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
406 outputSpaceIfNecessary(OS);
407
408 switch (CC) {
409 case CallingConv::Cdecl:
410 OS << "__cdecl";
411 break;
412 case CallingConv::Fastcall:
413 OS << "__fastcall";
414 break;
415 case CallingConv::Pascal:
416 OS << "__pascal";
417 break;
418 case CallingConv::Regcall:
419 OS << "__regcall";
420 break;
421 case CallingConv::Stdcall:
422 OS << "__stdcall";
423 break;
424 case CallingConv::Thiscall:
425 OS << "__thiscall";
426 break;
427 case CallingConv::Eabi:
428 OS << "__eabi";
429 break;
430 case CallingConv::Vectorcall:
431 OS << "__vectorcall";
432 break;
433 case CallingConv::Clrcall:
434 OS << "__clrcall";
435 break;
436 default:
437 break;
438 }
439}
440
Zachary Turner71c91f92018-07-30 03:12:34 +0000441static bool startsWithLocalScopePattern(StringView S) {
442 if (!S.consumeFront('?'))
443 return false;
444 if (S.size() < 2)
445 return false;
446
447 size_t End = S.find('?');
448 if (End == StringView::npos)
449 return false;
450 StringView Candidate = S.substr(0, End);
451 if (Candidate.empty())
452 return false;
453
454 // \?[0-9]\?
455 // ?@? is the discriminator 0.
456 if (Candidate.size() == 1)
457 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
458
459 // If it's not 0-9, then it's an encoded number terminated with an @
460 if (Candidate.back() != '@')
461 return false;
462 Candidate = Candidate.dropBack();
463
464 // An encoded number starts with B-P and all subsequent digits are in A-P.
465 // Note that the reason the first digit cannot be A is two fold. First, it
466 // would create an ambiguity with ?A which delimits the beginning of an
467 // anonymous namespace. Second, A represents 0, and you don't start a multi
468 // digit number with a leading 0. Presumably the anonymous namespace
469 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
470 if (Candidate[0] < 'B' || Candidate[0] > 'P')
471 return false;
472 Candidate = Candidate.dropFront();
473 while (!Candidate.empty()) {
474 if (Candidate[0] < 'A' || Candidate[0] > 'P')
475 return false;
476 Candidate = Candidate.dropFront();
477 }
478
479 return true;
480}
481
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000482// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000483static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
484 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000485 if (!Params.Current) {
486 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000487 return;
488 }
489
Zachary Turnerd30700f2018-07-31 17:16:44 +0000490 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000491 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000492 Type::outputPre(OS, *Head->Current, Resolver);
493 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000494
495 Head = Head->Next;
496
497 if (Head)
498 OS << ", ";
499 }
500}
501
Zachary Turner172aea12018-08-02 17:08:03 +0000502static void outputName(OutputStream &OS, const Name *TheName,
503 NameResolver &Resolver);
504
505static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
506 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000507 if (!Params.ParamType && !Params.ParamName) {
508 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000509 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000510 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000511
512 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000513 const TemplateParams *Head = &Params;
514 while (Head) {
515 // Type can be null if this is a template template parameter,
516 // and Name can be null if this is a simple type.
517
518 if (Head->ParamType && Head->ParamName) {
519 // Function pointer.
520 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000521 Type::outputPre(OS, *Head->ParamType, Resolver);
522 outputName(OS, Head->ParamName, Resolver);
523 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000524 } else if (Head->ParamType) {
525 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000526 Type::outputPre(OS, *Head->ParamType, Resolver);
527 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000528 } else {
529 // Template alias.
Zachary Turner172aea12018-08-02 17:08:03 +0000530 outputName(OS, Head->ParamName, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000531 }
532
533 Head = Head->Next;
534
535 if (Head)
536 OS << ", ";
537 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000538 OS << ">";
539}
540
Zachary Turner172aea12018-08-02 17:08:03 +0000541static void outputNameComponent(OutputStream &OS, const Name &N,
542 NameResolver &Resolver) {
543 StringView S = N.Str;
544
545 if (N.IsBackReference)
546 S = Resolver.resolve(N.Str);
547 OS << S;
548
549 if (N.IsTemplateInstantiation)
550 outputParameterList(OS, *N.TParams, Resolver);
551}
552
553static void outputName(OutputStream &OS, const Name *TheName,
554 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000555 if (!TheName)
556 return;
557
558 outputSpaceIfNecessary(OS);
559
Zachary Turnera7dffb12018-07-28 22:10:42 +0000560 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561 // Print out namespaces or outer class BackReferences.
562 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000563 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000564 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000565 OS << "::";
566 }
567
568 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000569 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000570 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000571 return;
572 }
573
574 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000575 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000576 OS << "~";
577
Zachary Turner44ebbc22018-08-01 18:32:47 +0000578 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turner172aea12018-08-02 17:08:03 +0000579 outputNameComponent(OS, *Previous, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000580 return;
581 }
582
583 // Print out an overloaded operator.
Zachary Turner172aea12018-08-02 17:08:03 +0000584 OS << "operator";
585 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000586}
587
588namespace {
589
590Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000591 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000592}
593
594// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000595void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000596 // Function types require custom handling of const and static so we
597 // handle them separately. All other types use the same decoration
598 // for these modifiers, so handle them here in common code.
599 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000600 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000601 return;
602 }
603
604 switch (Ty.Storage) {
605 case StorageClass::PrivateStatic:
606 case StorageClass::PublicStatic:
607 case StorageClass::ProtectedStatic:
608 OS << "static ";
609 default:
610 break;
611 }
Zachary Turner172aea12018-08-02 17:08:03 +0000612 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000613
614 if (Ty.Quals & Q_Const) {
615 outputSpaceIfNecessary(OS);
616 OS << "const";
617 }
618
619 if (Ty.Quals & Q_Volatile) {
620 outputSpaceIfNecessary(OS);
621 OS << "volatile";
622 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000623
624 if (Ty.Quals & Q_Restrict) {
625 outputSpaceIfNecessary(OS);
626 OS << "__restrict";
627 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000628}
629
630// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000631void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
632 Ty.outputPost(OS, Resolver);
633}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000634
Zachary Turner172aea12018-08-02 17:08:03 +0000635void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000636 switch (Prim) {
637 case PrimTy::Void:
638 OS << "void";
639 break;
640 case PrimTy::Bool:
641 OS << "bool";
642 break;
643 case PrimTy::Char:
644 OS << "char";
645 break;
646 case PrimTy::Schar:
647 OS << "signed char";
648 break;
649 case PrimTy::Uchar:
650 OS << "unsigned char";
651 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000652 case PrimTy::Char16:
653 OS << "char16_t";
654 break;
655 case PrimTy::Char32:
656 OS << "char32_t";
657 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000658 case PrimTy::Short:
659 OS << "short";
660 break;
661 case PrimTy::Ushort:
662 OS << "unsigned short";
663 break;
664 case PrimTy::Int:
665 OS << "int";
666 break;
667 case PrimTy::Uint:
668 OS << "unsigned int";
669 break;
670 case PrimTy::Long:
671 OS << "long";
672 break;
673 case PrimTy::Ulong:
674 OS << "unsigned long";
675 break;
676 case PrimTy::Int64:
677 OS << "__int64";
678 break;
679 case PrimTy::Uint64:
680 OS << "unsigned __int64";
681 break;
682 case PrimTy::Wchar:
683 OS << "wchar_t";
684 break;
685 case PrimTy::Float:
686 OS << "float";
687 break;
688 case PrimTy::Double:
689 OS << "double";
690 break;
691 case PrimTy::Ldouble:
692 OS << "long double";
693 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000694 case PrimTy::Nullptr:
695 OS << "std::nullptr_t";
696 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000697 default:
698 assert(false && "Invalid primitive type!");
699 }
700}
Zachary Turner172aea12018-08-02 17:08:03 +0000701void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000702
703Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000704 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000705}
706
Zachary Turner024e1762018-07-26 20:33:48 +0000707static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +0000708 const Name *MemberName, const Type *Pointee,
709 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +0000710 // "[]" and "()" (for function parameters) take precedence over "*",
711 // so "int *x(int)" means "x is a function returning int *". We need
712 // parentheses to supercede the default precedence. (e.g. we want to
713 // emit something like "int (*x)(int)".)
714 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
715 OS << "(";
716 if (Pointee->Prim == PrimTy::Function) {
717 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
718 assert(FTy->IsFunctionPointer);
719 outputCallingConvention(OS, FTy->CallConvention);
720 OS << " ";
721 }
722 }
723
724 if (MemberName) {
Zachary Turner172aea12018-08-02 17:08:03 +0000725 outputName(OS, MemberName, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +0000726 OS << "::";
727 }
728
729 if (Affinity == PointerAffinity::Pointer)
730 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000731 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000732 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000733 else
734 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000735}
736
Zachary Turner172aea12018-08-02 17:08:03 +0000737void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
738 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000739
740 outputSpaceIfNecessary(OS);
741
742 if (Quals & Q_Unaligned)
743 OS << "__unaligned ";
744
Zachary Turner172aea12018-08-02 17:08:03 +0000745 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000746
Zachary Turner91ecedd2018-07-20 18:07:33 +0000747 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000748 // if (Ty.Quals & Q_Pointer64)
749 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000750}
751
Zachary Turner172aea12018-08-02 17:08:03 +0000752void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000753 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
754 OS << ")";
755
Zachary Turner172aea12018-08-02 17:08:03 +0000756 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000757}
758
Zachary Turnerd742d642018-07-26 19:56:09 +0000759Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
760 return Arena.alloc<MemberPointerType>(*this);
761}
762
Zachary Turner172aea12018-08-02 17:08:03 +0000763void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
764 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000765
766 outputSpaceIfNecessary(OS);
767
Zachary Turner172aea12018-08-02 17:08:03 +0000768 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
769 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000770
771 // FIXME: We should output this, but it requires updating lots of tests.
772 // if (Ty.Quals & Q_Pointer64)
773 // OS << " __ptr64";
774 if (Quals & Q_Restrict)
775 OS << " __restrict";
776}
777
Zachary Turner172aea12018-08-02 17:08:03 +0000778void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +0000779 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
780 OS << ")";
781
Zachary Turner172aea12018-08-02 17:08:03 +0000782 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000783}
784
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000785Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000786 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000787}
788
Zachary Turner172aea12018-08-02 17:08:03 +0000789void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000790 if (!(FunctionClass & Global)) {
791 if (FunctionClass & Static)
792 OS << "static ";
793 }
794
Zachary Turner38b78a72018-07-26 20:20:10 +0000795 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +0000796 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +0000797 OS << " ";
798 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000799
Zachary Turner024e1762018-07-26 20:33:48 +0000800 // Function pointers print the calling convention as void (__cdecl *)(params)
801 // rather than void __cdecl (*)(params). So we need to let the PointerType
802 // class handle this.
803 if (!IsFunctionPointer)
804 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000805}
806
Zachary Turner172aea12018-08-02 17:08:03 +0000807void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000808 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +0000809 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000810 OS << ")";
811 if (Quals & Q_Const)
812 OS << " const";
813 if (Quals & Q_Volatile)
814 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000815 if (Quals & Q_Restrict)
816 OS << " __restrict";
817 if (Quals & Q_Unaligned)
818 OS << " __unaligned";
819
820 if (RefKind == ReferenceKind::LValueRef)
821 OS << " &";
822 else if (RefKind == ReferenceKind::RValueRef)
823 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000824
825 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +0000826 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000827 return;
828}
829
830Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000831 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000832}
833
Zachary Turner172aea12018-08-02 17:08:03 +0000834void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000835 switch (Prim) {
836 case PrimTy::Class:
837 OS << "class ";
838 break;
839 case PrimTy::Struct:
840 OS << "struct ";
841 break;
842 case PrimTy::Union:
843 OS << "union ";
844 break;
845 case PrimTy::Enum:
846 OS << "enum ";
847 break;
848 default:
849 assert(false && "Not a udt type!");
850 }
851
Zachary Turner172aea12018-08-02 17:08:03 +0000852 outputName(OS, UdtName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000853}
854
855Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000856 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000857}
858
Zachary Turner172aea12018-08-02 17:08:03 +0000859void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
860 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000861}
862
Zachary Turner172aea12018-08-02 17:08:03 +0000863void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000864 if (ArrayDimension > 0)
865 OS << "[" << ArrayDimension << "]";
866 if (NextDimension)
Zachary Turner172aea12018-08-02 17:08:03 +0000867 Type::outputPost(OS, *NextDimension, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000868 else if (ElementType)
Zachary Turner172aea12018-08-02 17:08:03 +0000869 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000870}
871
Zachary Turner316109b2018-07-29 16:38:02 +0000872struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000873 SymbolCategory Category;
874
Zachary Turner316109b2018-07-29 16:38:02 +0000875 Name *SymbolName = nullptr;
876 Type *SymbolType = nullptr;
877};
878
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000879} // namespace
880
881namespace {
882
883// Demangler class takes the main role in demangling symbols.
884// It has a set of functions to parse mangled symbols into Type instances.
885// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +0000886class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000887public:
Zachary Turner316109b2018-07-29 16:38:02 +0000888 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +0000889 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000890
891 // You are supposed to call parse() first and then check if error is true. If
892 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000893 Symbol *parse(StringView &MangledName);
894 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000895
Zachary Turner172aea12018-08-02 17:08:03 +0000896 StringView resolve(StringView N) override;
897
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000898 // True if an error occurred.
899 bool Error = false;
900
Zachary Turner3a758e22018-08-01 18:33:04 +0000901 void dumpBackReferences();
902
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000903private:
Zachary Turner316109b2018-07-29 16:38:02 +0000904 Type *demangleVariableEncoding(StringView &MangledName);
905 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000906
Zachary Turner316109b2018-07-29 16:38:02 +0000907 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000908
909 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000910 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
911 Type *demangleBasicType(StringView &MangledName);
912 UdtType *demangleClassType(StringView &MangledName);
913 PointerType *demanglePointerType(StringView &MangledName);
914 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
915 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
916 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000917
Zachary Turner316109b2018-07-29 16:38:02 +0000918 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000919
Zachary Turnerd30700f2018-07-31 17:16:44 +0000920 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
921 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000922
Zachary Turner316109b2018-07-29 16:38:02 +0000923 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000924
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000925 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000926
927 /// Allocate a copy of \p Borrowed into memory that we own.
928 StringView copyString(StringView Borrowed);
929
Zachary Turner316109b2018-07-29 16:38:02 +0000930 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
931 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000932
Zachary Turner44ebbc22018-08-01 18:32:47 +0000933 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
934 Name *demangleUnqualifiedSymbolName(StringView &MangledName, bool Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000935
Zachary Turner316109b2018-07-29 16:38:02 +0000936 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
937 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000938
Zachary Turner316109b2018-07-29 16:38:02 +0000939 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +0000940 Name *demangleTemplateInstantiationName(StringView &MangledName);
Zachary Turner316109b2018-07-29 16:38:02 +0000941 Name *demangleOperatorName(StringView &MangledName);
942 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
943 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000944 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000945
Zachary Turner931e8792018-07-30 23:02:10 +0000946 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
947
Zachary Turner316109b2018-07-29 16:38:02 +0000948 FuncClass demangleFunctionClass(StringView &MangledName);
949 CallingConv demangleCallingConvention(StringView &MangledName);
950 StorageClass demangleVariableStorageClass(StringView &MangledName);
951 ReferenceKind demangleReferenceKind(StringView &MangledName);
952 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000953
Zachary Turner316109b2018-07-29 16:38:02 +0000954 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000955
956 // Memory allocator.
957 ArenaAllocator Arena;
958
Zachary Turner23df1312018-07-26 22:13:39 +0000959 // A single type uses one global back-ref table for all function params.
960 // This means back-refs can even go "into" other types. Examples:
961 //
962 // // Second int* is a back-ref to first.
963 // void foo(int *, int*);
964 //
965 // // Second int* is not a back-ref to first (first is not a function param).
966 // int* foo(int*);
967 //
968 // // Second int* is a back-ref to first (ALL function types share the same
969 // // back-ref map.
970 // using F = void(*)(int*);
971 // F G(int *);
972 Type *FunctionParamBackRefs[10];
973 size_t FunctionParamBackRefCount = 0;
974
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000975 // The first 10 BackReferences in a mangled name can be back-referenced by
976 // special name @[0-9]. This is a storage for the first 10 BackReferences.
977 StringView BackReferences[10];
978 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000979};
980} // namespace
981
Zachary Turner71c91f92018-07-30 03:12:34 +0000982StringView Demangler::copyString(StringView Borrowed) {
983 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
984 std::strcpy(Stable, Borrowed.begin());
985
986 return {Stable, Borrowed.size()};
987}
988
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000989// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000990Symbol *Demangler::parse(StringView &MangledName) {
991 Symbol *S = Arena.alloc<Symbol>();
992
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000993 // MSVC-style mangled symbols must start with '?'.
994 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000995 S->SymbolName = Arena.alloc<Name>();
996 S->SymbolName->Str = MangledName;
997 S->SymbolType = Arena.alloc<Type>();
998 S->SymbolType->Prim = PrimTy::Unknown;
999 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001000 }
1001
1002 // What follows is a main symbol name. This may include
1003 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +00001004 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001005 if (Error)
1006 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001007 // Read a variable.
Zachary Turner44ebbc22018-08-01 18:32:47 +00001008 if (startsWithDigit(MangledName)) {
1009 S->Category = SymbolCategory::Variable;
1010 S->SymbolType = demangleVariableEncoding(MangledName);
1011 } else {
1012 S->Category = SymbolCategory::Function;
1013 S->SymbolType = demangleFunctionEncoding(MangledName);
1014 }
1015
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001016 if (Error)
1017 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001018
Zachary Turner316109b2018-07-29 16:38:02 +00001019 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001020}
1021
1022// <type-encoding> ::= <storage-class> <variable-type>
1023// <storage-class> ::= 0 # private static member
1024// ::= 1 # protected static member
1025// ::= 2 # public static member
1026// ::= 3 # global
1027// ::= 4 # static local
1028
Zachary Turner316109b2018-07-29 16:38:02 +00001029Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1030 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001031
Zachary Turner316109b2018-07-29 16:38:02 +00001032 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001033
1034 Ty->Storage = SC;
1035
1036 // <variable-type> ::= <type> <cvr-qualifiers>
1037 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1038 switch (Ty->Prim) {
1039 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001040 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001041 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001042 Ty->Quals =
1043 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001044
Zachary Turnerd742d642018-07-26 19:56:09 +00001045 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001046 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001047
Zachary Turnerd742d642018-07-26 19:56:09 +00001048 if (Ty->Prim == PrimTy::MemberPtr) {
1049 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001050 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001051 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001052 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1053 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1054 } else {
1055 PointerType *PTy = static_cast<PointerType *>(Ty);
1056 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001057 }
1058
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001059 break;
1060 }
1061 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001062 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001063 break;
1064 }
1065
1066 return Ty;
1067}
1068
1069// Sometimes numbers are encoded in mangled symbols. For example,
1070// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1071// length 20), so we need some way to embed numbers as part of symbols.
1072// This function parses it.
1073//
1074// <number> ::= [?] <non-negative integer>
1075//
1076// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1077// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1078//
1079// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001080int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001081 bool neg = MangledName.consumeFront("?");
1082
1083 if (startsWithDigit(MangledName)) {
1084 int32_t Ret = MangledName[0] - '0' + 1;
1085 MangledName = MangledName.dropFront(1);
1086 return neg ? -Ret : Ret;
1087 }
1088
1089 int Ret = 0;
1090 for (size_t i = 0; i < MangledName.size(); ++i) {
1091 char C = MangledName[i];
1092 if (C == '@') {
1093 MangledName = MangledName.dropFront(i + 1);
1094 return neg ? -Ret : Ret;
1095 }
1096 if ('A' <= C && C <= 'P') {
1097 Ret = (Ret << 4) + (C - 'A');
1098 continue;
1099 }
1100 break;
1101 }
1102
1103 Error = true;
1104 return 0;
1105}
1106
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001107// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1108// Memorize it.
1109void Demangler::memorizeString(StringView S) {
1110 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1111 return;
1112 for (size_t i = 0; i < BackRefCount; ++i)
1113 if (S == BackReferences[i])
1114 return;
1115 BackReferences[BackRefCount++] = S;
1116}
1117
Zachary Turner316109b2018-07-29 16:38:02 +00001118Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001119 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001120 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001121 Node->IsBackReference = true;
1122 Node->Str = {MangledName.begin(), 1};
1123 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001124 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001125}
1126
Zachary Turner44ebbc22018-08-01 18:32:47 +00001127Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001128 assert(MangledName.startsWith("?$"));
1129 MangledName.consumeFront("?$");
1130
Zachary Turner44ebbc22018-08-01 18:32:47 +00001131 Name *Node = demangleUnqualifiedSymbolName(MangledName, false);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001132 if (Error)
1133 return nullptr;
1134
Zachary Turnerd30700f2018-07-31 17:16:44 +00001135 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001136 if (Error)
1137 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001138
Zachary Turner44ebbc22018-08-01 18:32:47 +00001139 Node->IsTemplateInstantiation = true;
1140
Zachary Turner71c91f92018-07-30 03:12:34 +00001141 // Render this class template name into a string buffer so that we can
1142 // memorize it for the purpose of back-referencing.
1143 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turner172aea12018-08-02 17:08:03 +00001144 outputName(OS, Node, *this);
Zachary Turner71c91f92018-07-30 03:12:34 +00001145 OS << '\0';
1146 char *Name = OS.getBuffer();
1147
1148 StringView Owned = copyString(Name);
1149 memorizeString(Owned);
1150 std::free(Name);
1151
Zachary Turnera7dffb12018-07-28 22:10:42 +00001152 return Node;
1153}
1154
Zachary Turner316109b2018-07-29 16:38:02 +00001155Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001156 assert(MangledName.startsWith('?'));
1157 MangledName.consumeFront('?');
1158
Zachary Turner316109b2018-07-29 16:38:02 +00001159 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001160 switch (MangledName.popFront()) {
1161 case '0':
1162 return "ctor";
1163 case '1':
1164 return "dtor";
1165 case '2':
1166 return " new";
1167 case '3':
1168 return " delete";
1169 case '4':
1170 return "=";
1171 case '5':
1172 return ">>";
1173 case '6':
1174 return "<<";
1175 case '7':
1176 return "!";
1177 case '8':
1178 return "==";
1179 case '9':
1180 return "!=";
1181 case 'A':
1182 return "[]";
1183 case 'C':
1184 return "->";
1185 case 'D':
1186 return "*";
1187 case 'E':
1188 return "++";
1189 case 'F':
1190 return "--";
1191 case 'G':
1192 return "-";
1193 case 'H':
1194 return "+";
1195 case 'I':
1196 return "&";
1197 case 'J':
1198 return "->*";
1199 case 'K':
1200 return "/";
1201 case 'L':
1202 return "%";
1203 case 'M':
1204 return "<";
1205 case 'N':
1206 return "<=";
1207 case 'O':
1208 return ">";
1209 case 'P':
1210 return ">=";
1211 case 'Q':
1212 return ",";
1213 case 'R':
1214 return "()";
1215 case 'S':
1216 return "~";
1217 case 'T':
1218 return "^";
1219 case 'U':
1220 return "|";
1221 case 'V':
1222 return "&&";
1223 case 'W':
1224 return "||";
1225 case 'X':
1226 return "*=";
1227 case 'Y':
1228 return "+=";
1229 case 'Z':
1230 return "-=";
1231 case '_': {
1232 if (MangledName.empty())
1233 break;
1234
1235 switch (MangledName.popFront()) {
1236 case '0':
1237 return "/=";
1238 case '1':
1239 return "%=";
1240 case '2':
1241 return ">>=";
1242 case '3':
1243 return "<<=";
1244 case '4':
1245 return "&=";
1246 case '5':
1247 return "|=";
1248 case '6':
1249 return "^=";
1250 case 'U':
1251 return " new[]";
1252 case 'V':
1253 return " delete[]";
1254 case '_':
1255 if (MangledName.consumeFront("L"))
1256 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001257 if (MangledName.consumeFront("K")) {
1258 size_t EndPos = MangledName.find('@');
1259 if (EndPos == StringView::npos)
1260 break;
1261 StringView OpName = demangleSimpleString(MangledName, false);
1262 size_t FullSize = OpName.size() + 3; // <space>""OpName
1263 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1264 Buffer[0] = ' ';
1265 Buffer[1] = '"';
1266 Buffer[2] = '"';
1267 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1268 return {Buffer, FullSize};
1269 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001270 }
1271 }
1272 }
1273 Error = true;
1274 return "";
1275 };
1276
1277 Name *Node = Arena.alloc<Name>();
Zachary Turner44ebbc22018-08-01 18:32:47 +00001278 Node->Str = NameString();
1279 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001280 return Node;
1281}
1282
Zachary Turner316109b2018-07-29 16:38:02 +00001283Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001284 StringView S = demangleSimpleString(MangledName, Memorize);
1285 if (Error)
1286 return nullptr;
1287
Zachary Turnera7dffb12018-07-28 22:10:42 +00001288 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001289 Node->Str = S;
1290 return Node;
1291}
1292
1293StringView Demangler::demangleSimpleString(StringView &MangledName,
1294 bool Memorize) {
1295 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001296 for (size_t i = 0; i < MangledName.size(); ++i) {
1297 if (MangledName[i] != '@')
1298 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001299 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001300 MangledName = MangledName.dropFront(i + 1);
1301
1302 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001303 memorizeString(S);
1304 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001305 }
1306
1307 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001308 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001309}
1310
Zachary Turner316109b2018-07-29 16:38:02 +00001311Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001312 assert(MangledName.startsWith("?A"));
1313 MangledName.consumeFront("?A");
1314
1315 Name *Node = Arena.alloc<Name>();
1316 Node->Str = "`anonymous namespace'";
1317 if (MangledName.consumeFront('@'))
1318 return Node;
1319
1320 Error = true;
1321 return nullptr;
1322}
1323
Zachary Turner71c91f92018-07-30 03:12:34 +00001324Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1325 assert(startsWithLocalScopePattern(MangledName));
1326
1327 Name *Node = Arena.alloc<Name>();
1328 MangledName.consumeFront('?');
1329 int ScopeIdentifier = demangleNumber(MangledName);
1330
1331 // One ? to terminate the number
1332 MangledName.consumeFront('?');
1333
1334 assert(!Error);
1335 Symbol *Scope = parse(MangledName);
1336 if (Error)
1337 return nullptr;
1338
1339 // Render the parent symbol's name into a buffer.
1340 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1341 OS << '`';
1342 output(Scope, OS);
1343 OS << '\'';
1344 OS << "::`" << ScopeIdentifier << "'";
1345 OS << '\0';
1346 char *Result = OS.getBuffer();
1347 Node->Str = copyString(Result);
1348 std::free(Result);
1349 return Node;
1350}
1351
Zachary Turnera7dffb12018-07-28 22:10:42 +00001352// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001353Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001354 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001355 if (Error)
1356 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001357 assert(TypeName);
1358
Zachary Turner316109b2018-07-29 16:38:02 +00001359 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001360 if (Error)
1361 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001362 assert(QualName);
1363 return QualName;
1364}
1365
1366// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1367// Symbol names have slightly different rules regarding what can appear
1368// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001369Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001370 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001371 if (Error)
1372 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001373 assert(SymbolName);
1374
Zachary Turner316109b2018-07-29 16:38:02 +00001375 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001376 if (Error)
1377 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001378 assert(QualName);
1379 return QualName;
1380}
1381
Zachary Turner44ebbc22018-08-01 18:32:47 +00001382Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1383 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001384 // An inner-most name can be a back-reference, because a fully-qualified name
1385 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1386 // them (for example template parameters), and these nested parameters can
1387 // refer to previously mangled types.
1388 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001389 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001390
1391 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001392 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001393
Zachary Turner44ebbc22018-08-01 18:32:47 +00001394 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001395}
1396
Zachary Turner44ebbc22018-08-01 18:32:47 +00001397Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
1398 bool Memorize) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001399 if (startsWithDigit(MangledName))
1400 return demangleBackRefName(MangledName);
1401 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001402 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001403 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001404 return demangleOperatorName(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001405 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001406}
1407
Zachary Turner316109b2018-07-29 16:38:02 +00001408Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001409 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001410 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001411
1412 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001413 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001414
1415 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001416 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001417
Zachary Turner71c91f92018-07-30 03:12:34 +00001418 if (startsWithLocalScopePattern(MangledName))
1419 return demangleLocallyScopedNamePiece(MangledName);
1420
Zachary Turner316109b2018-07-29 16:38:02 +00001421 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001422}
1423
Zachary Turner316109b2018-07-29 16:38:02 +00001424Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1425 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001426 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001427
1428 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001429 if (MangledName.empty()) {
1430 Error = true;
1431 return nullptr;
1432 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001433
1434 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001435 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001436 if (Error)
1437 return nullptr;
1438
1439 Elem->Next = Head;
1440 Head = Elem;
1441 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001442 return Head;
1443}
1444
Zachary Turner316109b2018-07-29 16:38:02 +00001445FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001446 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1447 RestoreOnError.shouldRestore(false);
1448
1449 switch (MangledName.popFront()) {
1450 case 'A':
1451 return Private;
1452 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001453 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001455 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001456 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001457 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001458 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001459 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001460 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001461 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001462 case 'I':
1463 return Protected;
1464 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001465 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001466 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001467 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001468 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001469 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001470 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001471 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001472 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001473 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001474 case 'Q':
1475 return Public;
1476 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001477 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001478 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001479 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001480 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001481 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001482 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001483 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001484 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001485 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001486 case 'Y':
1487 return Global;
1488 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001489 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001490 }
1491
1492 Error = true;
1493 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001494 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001495}
1496
Zachary Turner316109b2018-07-29 16:38:02 +00001497CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001498 switch (MangledName.popFront()) {
1499 case 'A':
1500 case 'B':
1501 return CallingConv::Cdecl;
1502 case 'C':
1503 case 'D':
1504 return CallingConv::Pascal;
1505 case 'E':
1506 case 'F':
1507 return CallingConv::Thiscall;
1508 case 'G':
1509 case 'H':
1510 return CallingConv::Stdcall;
1511 case 'I':
1512 case 'J':
1513 return CallingConv::Fastcall;
1514 case 'M':
1515 case 'N':
1516 return CallingConv::Clrcall;
1517 case 'O':
1518 case 'P':
1519 return CallingConv::Eabi;
1520 case 'Q':
1521 return CallingConv::Vectorcall;
1522 }
1523
1524 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001525}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001526
Zachary Turner316109b2018-07-29 16:38:02 +00001527StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001528 assert(std::isdigit(MangledName.front()));
1529
1530 switch (MangledName.popFront()) {
1531 case '0':
1532 return StorageClass::PrivateStatic;
1533 case '1':
1534 return StorageClass::ProtectedStatic;
1535 case '2':
1536 return StorageClass::PublicStatic;
1537 case '3':
1538 return StorageClass::Global;
1539 case '4':
1540 return StorageClass::FunctionLocalStatic;
1541 }
1542 Error = true;
1543 return StorageClass::None;
1544}
1545
Zachary Turner316109b2018-07-29 16:38:02 +00001546std::pair<Qualifiers, bool>
1547Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001548
1549 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001550 // Member qualifiers
1551 case 'Q':
1552 return std::make_pair(Q_None, true);
1553 case 'R':
1554 return std::make_pair(Q_Const, true);
1555 case 'S':
1556 return std::make_pair(Q_Volatile, true);
1557 case 'T':
1558 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1559 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001560 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001561 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001562 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001563 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001564 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001565 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001566 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001567 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001568 }
1569 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001570 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001571}
1572
Zachary Turner931e8792018-07-30 23:02:10 +00001573static bool isTagType(StringView S) {
1574 switch (S.front()) {
1575 case 'T': // union
1576 case 'U': // struct
1577 case 'V': // class
1578 case 'W': // enum
1579 return true;
1580 }
1581 return false;
1582}
1583
1584static bool isPointerType(StringView S) {
1585 if (S.startsWith("$$Q")) // foo &&
1586 return true;
1587
1588 switch (S.front()) {
1589 case 'A': // foo &
1590 case 'P': // foo *
1591 case 'Q': // foo *const
1592 case 'R': // foo *volatile
1593 case 'S': // foo *const volatile
1594 return true;
1595 }
1596 return false;
1597}
1598
1599static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1600
1601static bool isFunctionType(StringView S) {
1602 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1603}
1604
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001605// <variable-type> ::= <type> <cvr-qualifiers>
1606// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001607Type *Demangler::demangleType(StringView &MangledName,
1608 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001609 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001610 bool IsMember = false;
1611 bool IsMemberKnown = false;
1612 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001613 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001614 IsMemberKnown = true;
1615 } else if (QMM == QualifierMangleMode::Result) {
1616 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001617 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001618 IsMemberKnown = true;
1619 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001620 }
1621
1622 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001623 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001624 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001625 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001626 if (!IsMemberKnown)
1627 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001628
Zachary Turnerd742d642018-07-26 19:56:09 +00001629 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001630 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001631 else
Zachary Turner316109b2018-07-29 16:38:02 +00001632 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001633 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001634 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001635 else if (isFunctionType(MangledName)) {
1636 if (MangledName.consumeFront("$$A8@@"))
1637 Ty = demangleFunctionType(MangledName, true, false);
1638 else {
1639 assert(MangledName.startsWith("$$A6"));
1640 MangledName.consumeFront("$$A6");
1641 Ty = demangleFunctionType(MangledName, false, false);
1642 }
1643 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001644 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001645 assert(Ty && !Error);
1646 if (!Ty || Error)
1647 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001648 }
Zachary Turner931e8792018-07-30 23:02:10 +00001649
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001650 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1651 return Ty;
1652}
1653
Zachary Turner316109b2018-07-29 16:38:02 +00001654ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001655 if (MangledName.consumeFront('G'))
1656 return ReferenceKind::LValueRef;
1657 else if (MangledName.consumeFront('H'))
1658 return ReferenceKind::RValueRef;
1659 return ReferenceKind::None;
1660}
1661
Zachary Turner316109b2018-07-29 16:38:02 +00001662void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001663 if (MangledName.consumeFront('Z'))
1664 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001665
Zachary Turner38b78a72018-07-26 20:20:10 +00001666 Error = true;
1667}
1668
Zachary Turner316109b2018-07-29 16:38:02 +00001669FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1670 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001671 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001672 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001673 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001674 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001675
1676 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001677 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1678 FTy->RefKind = demangleReferenceKind(MangledName);
1679 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001680 }
1681
1682 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001683 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001684
1685 // <return-type> ::= <type>
1686 // ::= @ # structors (they have no declared return type)
1687 bool IsStructor = MangledName.consumeFront('@');
1688 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001689 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001690
Zachary Turner316109b2018-07-29 16:38:02 +00001691 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001692
Zachary Turner316109b2018-07-29 16:38:02 +00001693 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001694
1695 return FTy;
1696}
1697
Zachary Turner316109b2018-07-29 16:38:02 +00001698Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1699 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001700
1701 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001702 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001703 FTy->FunctionClass = FC;
1704
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001705 return FTy;
1706}
1707
1708// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001709Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001710 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001711
Zachary Turner931e8792018-07-30 23:02:10 +00001712 if (MangledName.consumeFront("$$T")) {
1713 Ty->Prim = PrimTy::Nullptr;
1714 return Ty;
1715 }
1716
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001717 switch (MangledName.popFront()) {
1718 case 'X':
1719 Ty->Prim = PrimTy::Void;
1720 break;
1721 case 'D':
1722 Ty->Prim = PrimTy::Char;
1723 break;
1724 case 'C':
1725 Ty->Prim = PrimTy::Schar;
1726 break;
1727 case 'E':
1728 Ty->Prim = PrimTy::Uchar;
1729 break;
1730 case 'F':
1731 Ty->Prim = PrimTy::Short;
1732 break;
1733 case 'G':
1734 Ty->Prim = PrimTy::Ushort;
1735 break;
1736 case 'H':
1737 Ty->Prim = PrimTy::Int;
1738 break;
1739 case 'I':
1740 Ty->Prim = PrimTy::Uint;
1741 break;
1742 case 'J':
1743 Ty->Prim = PrimTy::Long;
1744 break;
1745 case 'K':
1746 Ty->Prim = PrimTy::Ulong;
1747 break;
1748 case 'M':
1749 Ty->Prim = PrimTy::Float;
1750 break;
1751 case 'N':
1752 Ty->Prim = PrimTy::Double;
1753 break;
1754 case 'O':
1755 Ty->Prim = PrimTy::Ldouble;
1756 break;
1757 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001758 if (MangledName.empty()) {
1759 Error = true;
1760 return nullptr;
1761 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001762 switch (MangledName.popFront()) {
1763 case 'N':
1764 Ty->Prim = PrimTy::Bool;
1765 break;
1766 case 'J':
1767 Ty->Prim = PrimTy::Int64;
1768 break;
1769 case 'K':
1770 Ty->Prim = PrimTy::Uint64;
1771 break;
1772 case 'W':
1773 Ty->Prim = PrimTy::Wchar;
1774 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001775 case 'S':
1776 Ty->Prim = PrimTy::Char16;
1777 break;
1778 case 'U':
1779 Ty->Prim = PrimTy::Char32;
1780 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001781 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001782 Error = true;
1783 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001784 }
1785 break;
1786 }
Zachary Turner931e8792018-07-30 23:02:10 +00001787 default:
1788 Error = true;
1789 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001790 }
1791 return Ty;
1792}
1793
Zachary Turner316109b2018-07-29 16:38:02 +00001794UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001795 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001796
1797 switch (MangledName.popFront()) {
1798 case 'T':
1799 UTy->Prim = PrimTy::Union;
1800 break;
1801 case 'U':
1802 UTy->Prim = PrimTy::Struct;
1803 break;
1804 case 'V':
1805 UTy->Prim = PrimTy::Class;
1806 break;
1807 case 'W':
1808 if (MangledName.popFront() != '4') {
1809 Error = true;
1810 return nullptr;
1811 }
1812 UTy->Prim = PrimTy::Enum;
1813 break;
1814 default:
1815 assert(false);
1816 }
1817
Zachary Turner316109b2018-07-29 16:38:02 +00001818 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001819 return UTy;
1820}
1821
Zachary Turnerd742d642018-07-26 19:56:09 +00001822static std::pair<Qualifiers, PointerAffinity>
1823demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001824 if (MangledName.consumeFront("$$Q"))
1825 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1826
Zachary Turnerd742d642018-07-26 19:56:09 +00001827 switch (MangledName.popFront()) {
1828 case 'A':
1829 return std::make_pair(Q_None, PointerAffinity::Reference);
1830 case 'P':
1831 return std::make_pair(Q_None, PointerAffinity::Pointer);
1832 case 'Q':
1833 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1834 case 'R':
1835 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1836 case 'S':
1837 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1838 PointerAffinity::Pointer);
1839 default:
1840 assert(false && "Ty is not a pointer type!");
1841 }
1842 return std::make_pair(Q_None, PointerAffinity::Pointer);
1843}
1844
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001845// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1846// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001847PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001848 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001849
Zachary Turner931e8792018-07-30 23:02:10 +00001850 std::tie(Pointer->Quals, Pointer->Affinity) =
1851 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001852
Zachary Turner931e8792018-07-30 23:02:10 +00001853 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001854 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001855 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001856 return Pointer;
1857 }
1858
Zachary Turner316109b2018-07-29 16:38:02 +00001859 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001860 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1861
Zachary Turner316109b2018-07-29 16:38:02 +00001862 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001863 return Pointer;
1864}
1865
Zachary Turner316109b2018-07-29 16:38:02 +00001866MemberPointerType *
1867Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001868 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1869 Pointer->Prim = PrimTy::MemberPtr;
1870
1871 PointerAffinity Affinity;
1872 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1873 assert(Affinity == PointerAffinity::Pointer);
1874
Zachary Turner316109b2018-07-29 16:38:02 +00001875 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001876 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1877
Zachary Turner38b78a72018-07-26 20:20:10 +00001878 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001879 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1880 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001881 } else {
1882 Qualifiers PointeeQuals = Q_None;
1883 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001884 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001885 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001886 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001887
Zachary Turner316109b2018-07-29 16:38:02 +00001888 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001889 Pointer->Pointee->Quals = PointeeQuals;
1890 }
1891
Zachary Turnerd742d642018-07-26 19:56:09 +00001892 return Pointer;
1893}
1894
Zachary Turner316109b2018-07-29 16:38:02 +00001895Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001896 Qualifiers Quals = Q_None;
1897 if (MangledName.consumeFront('E'))
1898 Quals = Qualifiers(Quals | Q_Pointer64);
1899 if (MangledName.consumeFront('I'))
1900 Quals = Qualifiers(Quals | Q_Restrict);
1901 if (MangledName.consumeFront('F'))
1902 Quals = Qualifiers(Quals | Q_Unaligned);
1903
1904 return Quals;
1905}
1906
Zachary Turner316109b2018-07-29 16:38:02 +00001907ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001908 assert(MangledName.front() == 'Y');
1909 MangledName.popFront();
1910
Zachary Turner316109b2018-07-29 16:38:02 +00001911 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001912 if (Dimension <= 0) {
1913 Error = true;
1914 return nullptr;
1915 }
1916
Zachary Turner9d72aa92018-07-20 18:35:06 +00001917 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001918 ArrayType *Dim = ATy;
1919 for (int I = 0; I < Dimension; ++I) {
1920 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001921 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001922 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001923 Dim = Dim->NextDimension;
1924 }
1925
1926 if (MangledName.consumeFront("$$C")) {
1927 if (MangledName.consumeFront("B"))
1928 ATy->Quals = Q_Const;
1929 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1930 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1931 else if (!MangledName.consumeFront("A"))
1932 Error = true;
1933 }
1934
Zachary Turner316109b2018-07-29 16:38:02 +00001935 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001936 Dim->ElementType = ATy->ElementType;
1937 return ATy;
1938}
1939
1940// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001941FunctionParams
1942Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001943 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001944 if (MangledName.consumeFront('X'))
1945 return {};
1946
Zachary Turnerd30700f2018-07-31 17:16:44 +00001947 FunctionParams *Head;
1948 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001949 while (!Error && !MangledName.startsWith('@') &&
1950 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001951
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001952 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001953 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001954 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001955 Error = true;
1956 return {};
1957 }
1958 MangledName = MangledName.dropFront();
1959
Zachary Turnerd30700f2018-07-31 17:16:44 +00001960 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001961 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001962 Current = &(*Current)->Next;
1963 continue;
1964 }
1965
Zachary Turner23df1312018-07-26 22:13:39 +00001966 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001967
Zachary Turnerd30700f2018-07-31 17:16:44 +00001968 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001969 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001970
Zachary Turner23df1312018-07-26 22:13:39 +00001971 size_t CharsConsumed = OldSize - MangledName.size();
1972 assert(CharsConsumed != 0);
1973
1974 // Single-letter types are ignored for backreferences because memorizing
1975 // them doesn't save anything.
1976 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1977 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1978
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001979 Current = &(*Current)->Next;
1980 }
1981
Zachary Turner38b78a72018-07-26 20:20:10 +00001982 if (Error)
1983 return {};
1984
1985 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1986 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1987 // the following Z could be a throw specifier.
1988 if (MangledName.consumeFront('@'))
1989 return *Head;
1990
1991 if (MangledName.consumeFront('Z')) {
1992 Head->IsVariadic = true;
1993 return *Head;
1994 }
1995
1996 Error = true;
1997 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001998}
1999
Zachary Turnerd30700f2018-07-31 17:16:44 +00002000TemplateParams *
2001Demangler::demangleTemplateParameterList(StringView &MangledName) {
2002 TemplateParams *Head;
2003 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002004 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002005 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002006 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002007
2008 // Empty parameter pack.
2009 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2010 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002011 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002012 }
2013
Zachary Turnerd30700f2018-07-31 17:16:44 +00002014 if (MangledName.consumeFront("$$Y")) {
2015 (*Current)->IsTemplateTemplate = true;
2016 (*Current)->IsAliasTemplate = true;
2017 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
2018 } else if (MangledName.consumeFront("$1?")) {
2019 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
2020 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
2021 } else {
2022 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002023 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002024 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002025 if (Error)
2026 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002027
2028 Current = &(*Current)->Next;
2029 }
2030
2031 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002032 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002033
2034 // Template parameter lists cannot be variadic, so it can only be terminated
2035 // by @.
2036 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002037 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002038 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002039 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002040}
2041
Zachary Turner172aea12018-08-02 17:08:03 +00002042StringView Demangler::resolve(StringView N) {
2043 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002044 size_t Digit = N[0] - '0';
Zachary Turner172aea12018-08-02 17:08:03 +00002045 if (Digit >= BackRefCount)
2046 return N;
2047 return BackReferences[Digit];
2048}
2049
Zachary Turner316109b2018-07-29 16:38:02 +00002050void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002051 // Converts an AST to a string.
2052 //
2053 // Converting an AST representing a C++ type to a string is tricky due
2054 // to the bad grammar of the C++ declaration inherited from C. You have
2055 // to construct a string from inside to outside. For example, if a type
2056 // X is a pointer to a function returning int, the order you create a
2057 // string becomes something like this:
2058 //
2059 // (1) X is a pointer: *X
2060 // (2) (1) is a function returning int: int (*X)()
2061 //
2062 // So you cannot construct a result just by appending strings to a result.
2063 //
2064 // To deal with this, we split the function into two. outputPre() writes
2065 // the "first half" of type declaration, and outputPost() writes the
2066 // "second half". For example, outputPre() writes a return type for a
2067 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002068 Type::outputPre(OS, *S->SymbolType, *this);
2069 outputName(OS, S->SymbolName, *this);
2070 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002071}
2072
Zachary Turner3a758e22018-08-01 18:33:04 +00002073void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002074 std::printf("%d function parameter backreferences\n",
2075 (int)FunctionParamBackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002076
2077 // Create an output stream so we can render each type.
2078 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
2079 for (size_t I = 0; I < FunctionParamBackRefCount; ++I) {
2080 OS.setCurrentPosition(0);
2081
2082 Type *T = FunctionParamBackRefs[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002083 Type::outputPre(OS, *T, *this);
2084 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002085
Zachary Turner7563ebe2018-08-02 17:08:24 +00002086 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002087 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002088 }
2089 std::free(OS.getBuffer());
2090
2091 if (FunctionParamBackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002092 std::printf("\n");
2093 std::printf("%d name backreferences\n", (int)BackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002094 for (size_t I = 0; I < BackRefCount; ++I) {
Zachary Turner7563ebe2018-08-02 17:08:24 +00002095 std::printf(" [%d] - %.*s\n", (int)I, (int)BackReferences[I].size(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002096 BackReferences[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002097 }
2098 if (BackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002099 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002100}
2101
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002102char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002103 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002104 Demangler D;
2105 StringView Name{MangledName};
2106 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002107
Zachary Turner3a758e22018-08-01 18:33:04 +00002108 if (Flags & MSDF_DumpBackrefs)
2109 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002110 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002111 if (D.Error) {
2112 OS << MangledName;
2113 *Status = llvm::demangle_invalid_mangled_name;
2114 } else {
2115 D.output(S, OS);
2116 *Status = llvm::demangle_success;
2117 }
2118
Zachary Turner71c91f92018-07-30 03:12:34 +00002119 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002120 return OS.getBuffer();
2121}