blob: d5bb9a4d1f46efebec6018edcd46e756e7f0fa87 [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
Zachary Turner5ae08b82018-08-01 18:44:12 +000024#include <cstdio>
Zachary Turnerd742d642018-07-26 19:56:09 +000025#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000026
27// This memory allocator is extremely fast, but it doesn't call dtors
28// for allocated objects. That means you can't use STL containers
29// (such as std::vector) with this allocator. But it pays off --
30// the demangler is 3x faster with this allocator compared to one with
31// STL containers.
32namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000033 constexpr size_t AllocUnit = 4096;
34
Zachary Turnerf435a7e2018-07-20 17:27:48 +000035class ArenaAllocator {
36 struct AllocatorNode {
37 uint8_t *Buf = nullptr;
38 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000039 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000040 AllocatorNode *Next = nullptr;
41 };
42
Zachary Turner71c91f92018-07-30 03:12:34 +000043 void addNode(size_t Capacity) {
44 AllocatorNode *NewHead = new AllocatorNode;
45 NewHead->Buf = new uint8_t[Capacity];
46 NewHead->Next = Head;
47 NewHead->Capacity = Capacity;
48 Head = NewHead;
49 NewHead->Used = 0;
50 }
51
Zachary Turnerf435a7e2018-07-20 17:27:48 +000052public:
Zachary Turnera6869512018-07-30 03:25:27 +000053 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000054
55 ~ArenaAllocator() {
56 while (Head) {
57 assert(Head->Buf);
58 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000059 AllocatorNode *Next = Head->Next;
60 delete Head;
61 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000062 }
63 }
64
Zachary Turner71c91f92018-07-30 03:12:34 +000065 char *allocUnalignedBuffer(size_t Length) {
66 uint8_t *Buf = Head->Buf + Head->Used;
67
68 Head->Used += Length;
69 if (Head->Used > Head->Capacity) {
70 // It's possible we need a buffer which is larger than our default unit
71 // size, so we need to be careful to add a node with capacity that is at
72 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000073 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000074 Head->Used = Length;
75 Buf = Head->Buf;
76 }
77
78 return reinterpret_cast<char *>(Buf);
79 }
80
Zachary Turner9d72aa92018-07-20 18:35:06 +000081 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
82
83 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000084 assert(Head && Head->Buf);
85
Zachary Turner9d72aa92018-07-20 18:35:06 +000086 size_t P = (size_t)Head->Buf + Head->Used;
87 uintptr_t AlignedP =
88 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
89 uint8_t *PP = (uint8_t *)AlignedP;
90 size_t Adjustment = AlignedP - P;
91
92 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000093 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000094 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000095
Zachary Turnera6869512018-07-30 03:25:27 +000096 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000097 Head->Used = Size;
98 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000099 }
100
101private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000102 AllocatorNode *Head = nullptr;
103};
104} // namespace
105
106static bool startsWithDigit(StringView S) {
107 return !S.empty() && std::isdigit(S.front());
108}
109
110// Writes a space if the last token does not end with a punctuation.
111static void outputSpaceIfNecessary(OutputStream &OS) {
112 if (OS.empty())
113 return;
114
115 char C = OS.back();
116 if (isalnum(C) || C == '>')
117 OS << " ";
118}
119
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000120// Storage classes
121enum Qualifiers : uint8_t {
122 Q_None = 0,
123 Q_Const = 1 << 0,
124 Q_Volatile = 1 << 1,
125 Q_Far = 1 << 2,
126 Q_Huge = 1 << 3,
127 Q_Unaligned = 1 << 4,
128 Q_Restrict = 1 << 5,
129 Q_Pointer64 = 1 << 6
130};
131
132enum class StorageClass : uint8_t {
133 None,
134 PrivateStatic,
135 ProtectedStatic,
136 PublicStatic,
137 Global,
138 FunctionLocalStatic
139};
140
141enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000142
Zachary Turner931e8792018-07-30 23:02:10 +0000143enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000144
145// Calling conventions
146enum class CallingConv : uint8_t {
147 None,
148 Cdecl,
149 Pascal,
150 Thiscall,
151 Stdcall,
152 Fastcall,
153 Clrcall,
154 Eabi,
155 Vectorcall,
156 Regcall,
157};
158
159enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
160
161// Types
162enum class PrimTy : uint8_t {
163 Unknown,
164 None,
165 Function,
166 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000167 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000168 Array,
169
170 Struct,
171 Union,
172 Class,
173 Enum,
174
175 Void,
176 Bool,
177 Char,
178 Schar,
179 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000180 Char16,
181 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000182 Short,
183 Ushort,
184 Int,
185 Uint,
186 Long,
187 Ulong,
188 Int64,
189 Uint64,
190 Wchar,
191 Float,
192 Double,
193 Ldouble,
Zachary Turner931e8792018-07-30 23:02:10 +0000194 Nullptr
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000195};
196
197// Function classes
Zachary Turner29ec67b2018-08-10 21:09:05 +0000198enum FuncClass : uint16_t {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000199 Public = 1 << 0,
200 Protected = 1 << 1,
201 Private = 1 << 2,
202 Global = 1 << 3,
203 Static = 1 << 4,
204 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000205 Far = 1 << 6,
Zachary Turner29ec67b2018-08-10 21:09:05 +0000206 ExternC = 1 << 7,
207 NoPrototype = 1 << 8,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000208};
209
Zachary Turner58d29cf2018-08-08 00:43:31 +0000210enum NameBackrefBehavior : uint8_t {
211 NBB_None = 0, // don't save any names as backrefs.
212 NBB_Template = 1 << 0, // save template instanations.
213 NBB_Simple = 1 << 1, // save simple names.
214};
215
Zachary Turner970fdc32018-08-16 16:17:36 +0000216enum class SymbolCategory { Unknown, Function, Variable, StringLiteral };
Zachary Turner44ebbc22018-08-01 18:32:47 +0000217
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000218namespace {
219
Zachary Turner172aea12018-08-02 17:08:03 +0000220struct NameResolver {
Zachary Turnerae672182018-08-02 17:33:33 +0000221 virtual ~NameResolver() = default;
Zachary Turner172aea12018-08-02 17:08:03 +0000222 virtual StringView resolve(StringView S) = 0;
223};
224
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000225struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000226struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000227
Zachary Turnerd30700f2018-07-31 17:16:44 +0000228struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000229 bool IsVariadic = false;
230
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000231 Type *Current = nullptr;
232
Zachary Turnerd30700f2018-07-31 17:16:44 +0000233 FunctionParams *Next = nullptr;
234};
Zachary Turner931e8792018-07-30 23:02:10 +0000235
Zachary Turnerd30700f2018-07-31 17:16:44 +0000236struct TemplateParams {
237 bool IsTemplateTemplate = false;
238 bool IsAliasTemplate = false;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000239 bool IsIntegerLiteral = false;
240 bool IntegerLiteralIsNegative = false;
241 bool IsEmptyParameterPack = false;
242 bool PointerToSymbol = false;
243 bool ReferenceToSymbol = false;
244
245 // If IsIntegerLiteral is true, this is a non-type template parameter
246 // whose value is contained in this field.
247 uint64_t IntegralValue = 0;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000248
249 // Type can be null if this is a template template parameter. In that case
250 // only Name will be valid.
251 Type *ParamType = nullptr;
252
253 // Name can be valid if this is a template template parameter (see above) or
254 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
255 // Name contains the name of the function and Type contains the signature.
256 Name *ParamName = nullptr;
257
258 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000259};
260
261// The type class. Mangled symbols are first parsed and converted to
262// this type and then converted to string.
263struct Type {
264 virtual ~Type() {}
265
266 virtual Type *clone(ArenaAllocator &Arena) const;
267
268 // Write the "first half" of a given type. This is a static functions to
269 // give the code a chance to do processing that is common to a subset of
270 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000271 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000272
273 // Write the "second half" of a given type. This is a static functions to
274 // give the code a chance to do processing that is common to a subset of
275 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000276 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000277
Zachary Turner172aea12018-08-02 17:08:03 +0000278 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
279 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000280
281 // Primitive type such as Int.
282 PrimTy Prim = PrimTy::Unknown;
283
284 Qualifiers Quals = Q_None;
285 StorageClass Storage = StorageClass::None; // storage class
286};
287
288// Represents an identifier which may be a template.
289struct Name {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000290 bool IsTemplateInstantiation = false;
291 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000292 bool IsBackReference = false;
Zachary Turnera17721c2018-08-10 15:04:56 +0000293 bool IsConversionOperator = false;
Zachary Turner970fdc32018-08-16 16:17:36 +0000294 bool IsStringLiteral = false;
295 bool IsLongStringLiteral = false;
296
297 // If IsStringLiteral is true, this is the character type.
298 PrimTy StringLiteralType = PrimTy::None;
Zachary Turnera17721c2018-08-10 15:04:56 +0000299
300 // Name read from an MangledName string.
301 StringView Str;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000302
Zachary Turner44ebbc22018-08-01 18:32:47 +0000303 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000304 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000305
306 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
307 Name *Next = nullptr;
308};
309
310struct PointerType : 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 Turner931e8792018-07-30 23:02:10 +0000315 PointerAffinity Affinity;
316
Zachary Turnerd742d642018-07-26 19:56:09 +0000317 // Represents a type X in "a pointer to X", "a reference to X",
318 // "an array of X", or "a function returning X".
319 Type *Pointee = nullptr;
320};
321
322struct MemberPointerType : public Type {
323 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000324 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
325 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000326
327 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000328
329 // Represents a type X in "a pointer to X", "a reference to X",
330 // "an array of X", or "a function returning X".
331 Type *Pointee = nullptr;
332};
333
334struct FunctionType : public Type {
335 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000336 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
337 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000338
Zachary Turner024e1762018-07-26 20:33:48 +0000339 // True if this FunctionType instance is the Pointee of a PointerType or
340 // MemberPointerType.
341 bool IsFunctionPointer = false;
342
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000343 Type *ReturnType = nullptr;
344 // If this is a reference, the type of reference.
345 ReferenceKind RefKind;
346
347 CallingConv CallConvention;
348 FuncClass FunctionClass;
349
Zachary Turnerd30700f2018-07-31 17:16:44 +0000350 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000351};
352
353struct UdtType : public Type {
354 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000355 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000356
357 Name *UdtName = nullptr;
358};
359
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000360struct ArrayDimension {
361 uint64_t Dim = 0;
362 ArrayDimension *Next = nullptr;
363};
364
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000365struct ArrayType : public Type {
366 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000367 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
368 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000369
370 // Either NextDimension or ElementType will be valid.
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000371 ArrayDimension *Dims = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000372
373 Type *ElementType = nullptr;
374};
375
376} // namespace
377
Zachary Turnerd742d642018-07-26 19:56:09 +0000378static bool isMemberPointer(StringView MangledName) {
379 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000380 case '$':
381 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
382 // rvalue reference to a member.
383 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000384 case 'A':
385 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000386 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000387 return false;
388 case 'P':
389 case 'Q':
390 case 'R':
391 case 'S':
392 // These 4 values indicate some kind of pointer, but we still don't know
393 // what.
394 break;
395 default:
396 assert(false && "Ty is not a pointer type!");
397 }
398
399 // If it starts with a number, then 6 indicates a non-member function
400 // pointer, and 8 indicates a member function pointer.
401 if (startsWithDigit(MangledName)) {
402 assert(MangledName[0] == '6' || MangledName[0] == '8');
403 return (MangledName[0] == '8');
404 }
405
406 // Remove ext qualifiers since those can appear on either type and are
407 // therefore not indicative.
408 MangledName.consumeFront('E'); // 64-bit
409 MangledName.consumeFront('I'); // restrict
410 MangledName.consumeFront('F'); // unaligned
411
412 assert(!MangledName.empty());
413
414 // The next value should be either ABCD (non-member) or QRST (member).
415 switch (MangledName.front()) {
416 case 'A':
417 case 'B':
418 case 'C':
419 case 'D':
420 return false;
421 case 'Q':
422 case 'R':
423 case 'S':
424 case 'T':
425 return true;
426 default:
427 assert(false);
428 }
429 return false;
430}
431
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000432static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
433 outputSpaceIfNecessary(OS);
434
435 switch (CC) {
436 case CallingConv::Cdecl:
437 OS << "__cdecl";
438 break;
439 case CallingConv::Fastcall:
440 OS << "__fastcall";
441 break;
442 case CallingConv::Pascal:
443 OS << "__pascal";
444 break;
445 case CallingConv::Regcall:
446 OS << "__regcall";
447 break;
448 case CallingConv::Stdcall:
449 OS << "__stdcall";
450 break;
451 case CallingConv::Thiscall:
452 OS << "__thiscall";
453 break;
454 case CallingConv::Eabi:
455 OS << "__eabi";
456 break;
457 case CallingConv::Vectorcall:
458 OS << "__vectorcall";
459 break;
460 case CallingConv::Clrcall:
461 OS << "__clrcall";
462 break;
463 default:
464 break;
465 }
466}
467
Zachary Turner71c91f92018-07-30 03:12:34 +0000468static bool startsWithLocalScopePattern(StringView S) {
469 if (!S.consumeFront('?'))
470 return false;
471 if (S.size() < 2)
472 return false;
473
474 size_t End = S.find('?');
475 if (End == StringView::npos)
476 return false;
477 StringView Candidate = S.substr(0, End);
478 if (Candidate.empty())
479 return false;
480
481 // \?[0-9]\?
482 // ?@? is the discriminator 0.
483 if (Candidate.size() == 1)
484 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
485
486 // If it's not 0-9, then it's an encoded number terminated with an @
487 if (Candidate.back() != '@')
488 return false;
489 Candidate = Candidate.dropBack();
490
491 // An encoded number starts with B-P and all subsequent digits are in A-P.
492 // Note that the reason the first digit cannot be A is two fold. First, it
493 // would create an ambiguity with ?A which delimits the beginning of an
494 // anonymous namespace. Second, A represents 0, and you don't start a multi
495 // digit number with a leading 0. Presumably the anonymous namespace
496 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
497 if (Candidate[0] < 'B' || Candidate[0] > 'P')
498 return false;
499 Candidate = Candidate.dropFront();
500 while (!Candidate.empty()) {
501 if (Candidate[0] < 'A' || Candidate[0] > 'P')
502 return false;
503 Candidate = Candidate.dropFront();
504 }
505
506 return true;
507}
508
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000509// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000510static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
511 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000512 if (!Params.Current) {
513 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000514 return;
515 }
516
Zachary Turnerd30700f2018-07-31 17:16:44 +0000517 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000518 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000519 Type::outputPre(OS, *Head->Current, Resolver);
520 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000521
522 Head = Head->Next;
523
524 if (Head)
525 OS << ", ";
526 }
527}
528
Zachary Turner970fdc32018-08-16 16:17:36 +0000529static void outputStringLiteral(OutputStream &OS, const Name &TheString) {
530 assert(TheString.IsStringLiteral);
531 switch (TheString.StringLiteralType) {
532 case PrimTy::Wchar:
533 OS << "const wchar_t * {L\"";
534 break;
535 case PrimTy::Char:
536 OS << "const char * {\"";
537 break;
538 case PrimTy::Char16:
539 OS << "const char16_t * {u\"";
540 break;
541 case PrimTy::Char32:
542 OS << "const char32_t * {U\"";
543 break;
544 default:
545 LLVM_BUILTIN_UNREACHABLE;
546 }
547 OS << TheString.Str << "\"";
548 if (TheString.IsLongStringLiteral)
549 OS << "...";
550 OS << "}";
551}
552
Zachary Turnera17721c2018-08-10 15:04:56 +0000553static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000554 NameResolver &Resolver);
555
556static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
557 NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000558 if (Params.IsEmptyParameterPack) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000559 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000560 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000561 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000562
563 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000564 const TemplateParams *Head = &Params;
565 while (Head) {
566 // Type can be null if this is a template template parameter,
567 // and Name can be null if this is a simple type.
568
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000569 if (Head->IsIntegerLiteral) {
570 if (Head->IntegerLiteralIsNegative)
571 OS << '-';
572 OS << Head->IntegralValue;
573 } else if (Head->PointerToSymbol || Head->ReferenceToSymbol) {
574 if (Head->PointerToSymbol)
575 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000576 Type::outputPre(OS, *Head->ParamType, Resolver);
Zachary Turnera17721c2018-08-10 15:04:56 +0000577 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turner172aea12018-08-02 17:08:03 +0000578 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000579 } else if (Head->ParamType) {
580 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000581 Type::outputPre(OS, *Head->ParamType, Resolver);
582 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000583 } else {
584 // Template alias.
Zachary Turnera17721c2018-08-10 15:04:56 +0000585 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000586 }
587
588 Head = Head->Next;
589
590 if (Head)
591 OS << ", ";
592 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000593 OS << ">";
594}
595
Zachary Turner172aea12018-08-02 17:08:03 +0000596static void outputNameComponent(OutputStream &OS, const Name &N,
597 NameResolver &Resolver) {
Zachary Turnera17721c2018-08-10 15:04:56 +0000598 if (N.IsConversionOperator) {
599 OS << " conv";
600 } else {
601 StringView S = N.Str;
Zachary Turner172aea12018-08-02 17:08:03 +0000602
Zachary Turnera17721c2018-08-10 15:04:56 +0000603 if (N.IsBackReference)
604 S = Resolver.resolve(N.Str);
605 OS << S;
606 }
Zachary Turner172aea12018-08-02 17:08:03 +0000607
Zachary Turnera17721c2018-08-10 15:04:56 +0000608 if (N.IsTemplateInstantiation && N.TParams)
Zachary Turner172aea12018-08-02 17:08:03 +0000609 outputParameterList(OS, *N.TParams, Resolver);
610}
611
Zachary Turnera17721c2018-08-10 15:04:56 +0000612static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000613 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000614 if (!TheName)
615 return;
616
617 outputSpaceIfNecessary(OS);
618
Zachary Turnera7dffb12018-07-28 22:10:42 +0000619 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000620 // Print out namespaces or outer class BackReferences.
621 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000622 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000623 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000624 OS << "::";
625 }
626
627 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000628 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000629 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000630 return;
631 }
632
633 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000634 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000635 OS << "~";
636
Zachary Turner44ebbc22018-08-01 18:32:47 +0000637 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turner172aea12018-08-02 17:08:03 +0000638 outputNameComponent(OS, *Previous, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000639 return;
640 }
641
Zachary Turnera17721c2018-08-10 15:04:56 +0000642 if (TheName->IsConversionOperator) {
643 OS << "operator";
644 if (TheName->IsTemplateInstantiation && TheName->TParams)
645 outputParameterList(OS, *TheName->TParams, Resolver);
646 OS << " ";
647 if (Ty) {
648 const FunctionType *FTy = static_cast<const FunctionType *>(Ty);
649 Type::outputPre(OS, *FTy->ReturnType, Resolver);
650 Type::outputPost(OS, *FTy->ReturnType, Resolver);
651 } else {
652 OS << "<conversion>";
653 }
654 } else {
655 // Print out an overloaded operator.
656 OS << "operator";
657 outputNameComponent(OS, *TheName, Resolver);
658 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000659}
660
661namespace {
662
663Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000664 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000665}
666
667// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000668void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000669 // Function types require custom handling of const and static so we
670 // handle them separately. All other types use the same decoration
671 // for these modifiers, so handle them here in common code.
672 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000673 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000674 return;
675 }
676
677 switch (Ty.Storage) {
678 case StorageClass::PrivateStatic:
679 case StorageClass::PublicStatic:
680 case StorageClass::ProtectedStatic:
681 OS << "static ";
682 default:
683 break;
684 }
Zachary Turner172aea12018-08-02 17:08:03 +0000685 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000686
687 if (Ty.Quals & Q_Const) {
688 outputSpaceIfNecessary(OS);
689 OS << "const";
690 }
691
692 if (Ty.Quals & Q_Volatile) {
693 outputSpaceIfNecessary(OS);
694 OS << "volatile";
695 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000696
697 if (Ty.Quals & Q_Restrict) {
698 outputSpaceIfNecessary(OS);
699 OS << "__restrict";
700 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000701}
702
703// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000704void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
705 Ty.outputPost(OS, Resolver);
706}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000707
Zachary Turner172aea12018-08-02 17:08:03 +0000708void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000709 switch (Prim) {
710 case PrimTy::Void:
711 OS << "void";
712 break;
713 case PrimTy::Bool:
714 OS << "bool";
715 break;
716 case PrimTy::Char:
717 OS << "char";
718 break;
719 case PrimTy::Schar:
720 OS << "signed char";
721 break;
722 case PrimTy::Uchar:
723 OS << "unsigned char";
724 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000725 case PrimTy::Char16:
726 OS << "char16_t";
727 break;
728 case PrimTy::Char32:
729 OS << "char32_t";
730 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000731 case PrimTy::Short:
732 OS << "short";
733 break;
734 case PrimTy::Ushort:
735 OS << "unsigned short";
736 break;
737 case PrimTy::Int:
738 OS << "int";
739 break;
740 case PrimTy::Uint:
741 OS << "unsigned int";
742 break;
743 case PrimTy::Long:
744 OS << "long";
745 break;
746 case PrimTy::Ulong:
747 OS << "unsigned long";
748 break;
749 case PrimTy::Int64:
750 OS << "__int64";
751 break;
752 case PrimTy::Uint64:
753 OS << "unsigned __int64";
754 break;
755 case PrimTy::Wchar:
756 OS << "wchar_t";
757 break;
758 case PrimTy::Float:
759 OS << "float";
760 break;
761 case PrimTy::Double:
762 OS << "double";
763 break;
764 case PrimTy::Ldouble:
765 OS << "long double";
766 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000767 case PrimTy::Nullptr:
768 OS << "std::nullptr_t";
769 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000770 default:
771 assert(false && "Invalid primitive type!");
772 }
773}
Zachary Turner172aea12018-08-02 17:08:03 +0000774void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000775
776Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000777 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000778}
779
Zachary Turner024e1762018-07-26 20:33:48 +0000780static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +0000781 const Name *MemberName, const Type *Pointee,
782 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +0000783 // "[]" and "()" (for function parameters) take precedence over "*",
784 // so "int *x(int)" means "x is a function returning int *". We need
785 // parentheses to supercede the default precedence. (e.g. we want to
786 // emit something like "int (*x)(int)".)
787 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
788 OS << "(";
789 if (Pointee->Prim == PrimTy::Function) {
790 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
791 assert(FTy->IsFunctionPointer);
792 outputCallingConvention(OS, FTy->CallConvention);
793 OS << " ";
794 }
795 }
796
797 if (MemberName) {
Zachary Turnera17721c2018-08-10 15:04:56 +0000798 outputName(OS, MemberName, Pointee, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +0000799 OS << "::";
800 }
801
802 if (Affinity == PointerAffinity::Pointer)
803 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000804 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000805 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000806 else
807 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000808}
809
Zachary Turner172aea12018-08-02 17:08:03 +0000810void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
811 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000812
813 outputSpaceIfNecessary(OS);
814
815 if (Quals & Q_Unaligned)
816 OS << "__unaligned ";
817
Zachary Turner172aea12018-08-02 17:08:03 +0000818 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000819
Zachary Turner91ecedd2018-07-20 18:07:33 +0000820 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000821 // if (Ty.Quals & Q_Pointer64)
822 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000823}
824
Zachary Turner172aea12018-08-02 17:08:03 +0000825void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000826 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
827 OS << ")";
828
Zachary Turner172aea12018-08-02 17:08:03 +0000829 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000830}
831
Zachary Turnerd742d642018-07-26 19:56:09 +0000832Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
833 return Arena.alloc<MemberPointerType>(*this);
834}
835
Zachary Turner172aea12018-08-02 17:08:03 +0000836void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
837 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000838
839 outputSpaceIfNecessary(OS);
840
Zachary Turner172aea12018-08-02 17:08:03 +0000841 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
842 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000843
844 // FIXME: We should output this, but it requires updating lots of tests.
845 // if (Ty.Quals & Q_Pointer64)
846 // OS << " __ptr64";
Zachary Turnerd742d642018-07-26 19:56:09 +0000847}
848
Zachary Turner172aea12018-08-02 17:08:03 +0000849void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +0000850 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
851 OS << ")";
852
Zachary Turner172aea12018-08-02 17:08:03 +0000853 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +0000854}
855
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000856Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000857 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000858}
859
Zachary Turner172aea12018-08-02 17:08:03 +0000860void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000861 if (!(FunctionClass & Global)) {
862 if (FunctionClass & Static)
863 OS << "static ";
864 }
Zachary Turner29ec67b2018-08-10 21:09:05 +0000865 if (FunctionClass & ExternC) {
866 OS << "extern \"C\" ";
867 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000868
Zachary Turner38b78a72018-07-26 20:20:10 +0000869 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +0000870 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +0000871 OS << " ";
872 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000873
Zachary Turner024e1762018-07-26 20:33:48 +0000874 // Function pointers print the calling convention as void (__cdecl *)(params)
875 // rather than void __cdecl (*)(params). So we need to let the PointerType
876 // class handle this.
877 if (!IsFunctionPointer)
878 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000879}
880
Zachary Turner172aea12018-08-02 17:08:03 +0000881void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turner29ec67b2018-08-10 21:09:05 +0000882 // extern "C" functions don't have a prototype.
883 if (FunctionClass & NoPrototype)
884 return;
885
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000886 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +0000887 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000888 OS << ")";
889 if (Quals & Q_Const)
890 OS << " const";
891 if (Quals & Q_Volatile)
892 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000893 if (Quals & Q_Restrict)
894 OS << " __restrict";
895 if (Quals & Q_Unaligned)
896 OS << " __unaligned";
897
898 if (RefKind == ReferenceKind::LValueRef)
899 OS << " &";
900 else if (RefKind == ReferenceKind::RValueRef)
901 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000902
903 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +0000904 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000905 return;
906}
907
908Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000909 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000910}
911
Zachary Turner172aea12018-08-02 17:08:03 +0000912void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000913 switch (Prim) {
914 case PrimTy::Class:
915 OS << "class ";
916 break;
917 case PrimTy::Struct:
918 OS << "struct ";
919 break;
920 case PrimTy::Union:
921 OS << "union ";
922 break;
923 case PrimTy::Enum:
924 OS << "enum ";
925 break;
926 default:
927 assert(false && "Not a udt type!");
928 }
929
Zachary Turnera17721c2018-08-10 15:04:56 +0000930 outputName(OS, UdtName, this, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000931}
932
933Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000934 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000935}
936
Zachary Turner172aea12018-08-02 17:08:03 +0000937void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
938 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000939}
940
Zachary Turner172aea12018-08-02 17:08:03 +0000941void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000942 ArrayDimension *D = Dims;
943 while (D) {
944 OS << "[";
945 if (D->Dim > 0)
946 OS << D->Dim;
947 OS << "]";
948 D = D->Next;
949 }
950
951 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000952}
953
Zachary Turner316109b2018-07-29 16:38:02 +0000954struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000955 SymbolCategory Category;
956
Zachary Turner316109b2018-07-29 16:38:02 +0000957 Name *SymbolName = nullptr;
958 Type *SymbolType = nullptr;
959};
960
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000961} // namespace
962
963namespace {
964
Zachary Turnerd346cba2018-08-08 17:17:04 +0000965struct BackrefContext {
966 static constexpr size_t Max = 10;
967
968 Type *FunctionParams[Max];
969 size_t FunctionParamCount = 0;
970
971 // The first 10 BackReferences in a mangled name can be back-referenced by
972 // special name @[0-9]. This is a storage for the first 10 BackReferences.
973 StringView Names[Max];
974 size_t NamesCount = 0;
975};
976
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000977// Demangler class takes the main role in demangling symbols.
978// It has a set of functions to parse mangled symbols into Type instances.
979// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +0000980class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000981public:
Zachary Turner316109b2018-07-29 16:38:02 +0000982 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +0000983 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000984
985 // You are supposed to call parse() first and then check if error is true. If
986 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000987 Symbol *parse(StringView &MangledName);
988 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000989
Zachary Turner172aea12018-08-02 17:08:03 +0000990 StringView resolve(StringView N) override;
991
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000992 // True if an error occurred.
993 bool Error = false;
994
Zachary Turner3a758e22018-08-01 18:33:04 +0000995 void dumpBackReferences();
996
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000997private:
Zachary Turner316109b2018-07-29 16:38:02 +0000998 Type *demangleVariableEncoding(StringView &MangledName);
999 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001000
Zachary Turner316109b2018-07-29 16:38:02 +00001001 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001002
1003 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +00001004 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
1005 Type *demangleBasicType(StringView &MangledName);
1006 UdtType *demangleClassType(StringView &MangledName);
1007 PointerType *demanglePointerType(StringView &MangledName);
1008 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
1009 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
1010 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001011
Zachary Turner316109b2018-07-29 16:38:02 +00001012 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001013
Zachary Turnerd30700f2018-07-31 17:16:44 +00001014 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
1015 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001016
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001017 std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001018
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001019 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +00001020
1021 /// Allocate a copy of \p Borrowed into memory that we own.
1022 StringView copyString(StringView Borrowed);
1023
Zachary Turner316109b2018-07-29 16:38:02 +00001024 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
1025 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001026
Zachary Turner44ebbc22018-08-01 18:32:47 +00001027 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001028 Name *demangleUnqualifiedSymbolName(StringView &MangledName,
1029 NameBackrefBehavior NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001030
Zachary Turner316109b2018-07-29 16:38:02 +00001031 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
1032 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001033
Zachary Turner316109b2018-07-29 16:38:02 +00001034 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001035 Name *demangleTemplateInstantiationName(StringView &MangledName,
1036 NameBackrefBehavior NBB);
Zachary Turner316109b2018-07-29 16:38:02 +00001037 Name *demangleOperatorName(StringView &MangledName);
1038 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
1039 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001040 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001041 Name *demangleStringLiteral(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001042
Zachary Turner931e8792018-07-30 23:02:10 +00001043 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
1044
Zachary Turner316109b2018-07-29 16:38:02 +00001045 FuncClass demangleFunctionClass(StringView &MangledName);
1046 CallingConv demangleCallingConvention(StringView &MangledName);
1047 StorageClass demangleVariableStorageClass(StringView &MangledName);
1048 ReferenceKind demangleReferenceKind(StringView &MangledName);
1049 void demangleThrowSpecification(StringView &MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001050 wchar_t demangleWcharLiteral(StringView &MangledName);
1051 uint8_t demangleCharLiteral(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001052
Zachary Turner316109b2018-07-29 16:38:02 +00001053 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001054
1055 // Memory allocator.
1056 ArenaAllocator Arena;
1057
Zachary Turner23df1312018-07-26 22:13:39 +00001058 // A single type uses one global back-ref table for all function params.
1059 // This means back-refs can even go "into" other types. Examples:
1060 //
1061 // // Second int* is a back-ref to first.
1062 // void foo(int *, int*);
1063 //
1064 // // Second int* is not a back-ref to first (first is not a function param).
1065 // int* foo(int*);
1066 //
1067 // // Second int* is a back-ref to first (ALL function types share the same
1068 // // back-ref map.
1069 // using F = void(*)(int*);
1070 // F G(int *);
Zachary Turnerd346cba2018-08-08 17:17:04 +00001071 BackrefContext Backrefs;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001072};
1073} // namespace
1074
Zachary Turner71c91f92018-07-30 03:12:34 +00001075StringView Demangler::copyString(StringView Borrowed) {
1076 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
1077 std::strcpy(Stable, Borrowed.begin());
1078
1079 return {Stable, Borrowed.size()};
1080}
1081
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001082// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +00001083Symbol *Demangler::parse(StringView &MangledName) {
1084 Symbol *S = Arena.alloc<Symbol>();
1085
Zachary Turner83313f82018-08-16 16:17:17 +00001086 // We can't demangle MD5 names, just output them as-is.
1087 if (MangledName.startsWith("??@")) {
1088 S->Category = SymbolCategory::Unknown;
1089 S->SymbolName = Arena.alloc<Name>();
1090 S->SymbolName->Str = MangledName;
Zachary Turner970fdc32018-08-16 16:17:36 +00001091 S->SymbolType = nullptr;
Zachary Turner83313f82018-08-16 16:17:17 +00001092 MangledName = StringView();
1093 return S;
1094 }
1095
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001096 // MSVC-style mangled symbols must start with '?'.
1097 if (!MangledName.consumeFront("?")) {
Zachary Turner970fdc32018-08-16 16:17:36 +00001098 S->Category = SymbolCategory::Unknown;
Zachary Turner316109b2018-07-29 16:38:02 +00001099 S->SymbolName = Arena.alloc<Name>();
1100 S->SymbolName->Str = MangledName;
Zachary Turner970fdc32018-08-16 16:17:36 +00001101 S->SymbolType = nullptr;
1102 return S;
1103 }
1104
1105 if (MangledName.consumeFront("?_C@_")) {
1106 // This is a string literal. Just demangle it and return.
1107 S->Category = SymbolCategory::StringLiteral;
1108 S->SymbolName = demangleStringLiteral(MangledName);
1109 S->SymbolType = nullptr;
Zachary Turner316109b2018-07-29 16:38:02 +00001110 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001111 }
1112
1113 // What follows is a main symbol name. This may include
1114 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +00001115 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001116 if (Error)
1117 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001118 // Read a variable.
Zachary Turner29ec67b2018-08-10 21:09:05 +00001119 if (startsWithDigit(MangledName) && !MangledName.startsWith('9')) {
1120 // 9 is a special marker for an extern "C" function with
1121 // no prototype.
Zachary Turner44ebbc22018-08-01 18:32:47 +00001122 S->Category = SymbolCategory::Variable;
1123 S->SymbolType = demangleVariableEncoding(MangledName);
1124 } else {
1125 S->Category = SymbolCategory::Function;
1126 S->SymbolType = demangleFunctionEncoding(MangledName);
1127 }
1128
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001129 if (Error)
1130 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001131
Zachary Turner316109b2018-07-29 16:38:02 +00001132 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001133}
1134
1135// <type-encoding> ::= <storage-class> <variable-type>
1136// <storage-class> ::= 0 # private static member
1137// ::= 1 # protected static member
1138// ::= 2 # public static member
1139// ::= 3 # global
1140// ::= 4 # static local
1141
Zachary Turner316109b2018-07-29 16:38:02 +00001142Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1143 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001144
Zachary Turner316109b2018-07-29 16:38:02 +00001145 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001146
1147 Ty->Storage = SC;
1148
1149 // <variable-type> ::= <type> <cvr-qualifiers>
1150 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1151 switch (Ty->Prim) {
1152 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001153 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001154 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001155 Ty->Quals =
1156 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001157
Zachary Turnerd742d642018-07-26 19:56:09 +00001158 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001159 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001160
Zachary Turnerd742d642018-07-26 19:56:09 +00001161 if (Ty->Prim == PrimTy::MemberPtr) {
1162 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001163 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001164 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001165 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1166 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1167 } else {
1168 PointerType *PTy = static_cast<PointerType *>(Ty);
1169 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001170 }
1171
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001172 break;
1173 }
1174 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001175 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001176 break;
1177 }
1178
1179 return Ty;
1180}
1181
1182// Sometimes numbers are encoded in mangled symbols. For example,
1183// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1184// length 20), so we need some way to embed numbers as part of symbols.
1185// This function parses it.
1186//
1187// <number> ::= [?] <non-negative integer>
1188//
1189// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1190// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1191//
1192// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001193std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
1194 bool IsNegative = MangledName.consumeFront('?');
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001195
1196 if (startsWithDigit(MangledName)) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001197 uint64_t Ret = MangledName[0] - '0' + 1;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001198 MangledName = MangledName.dropFront(1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001199 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001200 }
1201
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001202 uint64_t Ret = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001203 for (size_t i = 0; i < MangledName.size(); ++i) {
1204 char C = MangledName[i];
1205 if (C == '@') {
1206 MangledName = MangledName.dropFront(i + 1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001207 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001208 }
1209 if ('A' <= C && C <= 'P') {
1210 Ret = (Ret << 4) + (C - 'A');
1211 continue;
1212 }
1213 break;
1214 }
1215
1216 Error = true;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001217 return {0ULL, false};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001218}
1219
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001220// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1221// Memorize it.
1222void Demangler::memorizeString(StringView S) {
Zachary Turnerd346cba2018-08-08 17:17:04 +00001223 if (Backrefs.NamesCount >= BackrefContext::Max)
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001224 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001225 for (size_t i = 0; i < Backrefs.NamesCount; ++i)
1226 if (S == Backrefs.Names[i])
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001227 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001228 Backrefs.Names[Backrefs.NamesCount++] = S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001229}
1230
Zachary Turner316109b2018-07-29 16:38:02 +00001231Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001232 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001233 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001234 Node->IsBackReference = true;
1235 Node->Str = {MangledName.begin(), 1};
1236 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001237 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001238}
1239
Zachary Turner58d29cf2018-08-08 00:43:31 +00001240Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName,
1241 NameBackrefBehavior NBB) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001242 assert(MangledName.startsWith("?$"));
1243 MangledName.consumeFront("?$");
1244
Zachary Turnerd346cba2018-08-08 17:17:04 +00001245 BackrefContext OuterContext;
1246 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001247
Zachary Turnerd346cba2018-08-08 17:17:04 +00001248 Name *Node = demangleUnqualifiedSymbolName(MangledName, NBB_None);
1249 if (!Error)
1250 Node->TParams = demangleTemplateParameterList(MangledName);
1251
1252 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001253 if (Error)
1254 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001255
Zachary Turner44ebbc22018-08-01 18:32:47 +00001256 Node->IsTemplateInstantiation = true;
1257
Zachary Turner58d29cf2018-08-08 00:43:31 +00001258 if (NBB & NBB_Template) {
1259 // Render this class template name into a string buffer so that we can
1260 // memorize it for the purpose of back-referencing.
1261 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turnera17721c2018-08-10 15:04:56 +00001262 outputName(OS, Node, nullptr, *this);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001263 OS << '\0';
1264 char *Name = OS.getBuffer();
Zachary Turner71c91f92018-07-30 03:12:34 +00001265
Zachary Turner58d29cf2018-08-08 00:43:31 +00001266 StringView Owned = copyString(Name);
1267 memorizeString(Owned);
1268 std::free(Name);
1269 }
Zachary Turner71c91f92018-07-30 03:12:34 +00001270
Zachary Turnera7dffb12018-07-28 22:10:42 +00001271 return Node;
1272}
1273
Zachary Turner316109b2018-07-29 16:38:02 +00001274Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001275 assert(MangledName.startsWith('?'));
1276 MangledName.consumeFront('?');
1277
Zachary Turner316109b2018-07-29 16:38:02 +00001278 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001279 switch (MangledName.popFront()) {
1280 case '0':
1281 return "ctor";
1282 case '1':
1283 return "dtor";
1284 case '2':
1285 return " new";
1286 case '3':
1287 return " delete";
1288 case '4':
1289 return "=";
1290 case '5':
1291 return ">>";
1292 case '6':
1293 return "<<";
1294 case '7':
1295 return "!";
1296 case '8':
1297 return "==";
1298 case '9':
1299 return "!=";
1300 case 'A':
1301 return "[]";
1302 case 'C':
1303 return "->";
1304 case 'D':
1305 return "*";
1306 case 'E':
1307 return "++";
1308 case 'F':
1309 return "--";
1310 case 'G':
1311 return "-";
1312 case 'H':
1313 return "+";
1314 case 'I':
1315 return "&";
1316 case 'J':
1317 return "->*";
1318 case 'K':
1319 return "/";
1320 case 'L':
1321 return "%";
1322 case 'M':
1323 return "<";
1324 case 'N':
1325 return "<=";
1326 case 'O':
1327 return ">";
1328 case 'P':
1329 return ">=";
1330 case 'Q':
1331 return ",";
1332 case 'R':
1333 return "()";
1334 case 'S':
1335 return "~";
1336 case 'T':
1337 return "^";
1338 case 'U':
1339 return "|";
1340 case 'V':
1341 return "&&";
1342 case 'W':
1343 return "||";
1344 case 'X':
1345 return "*=";
1346 case 'Y':
1347 return "+=";
1348 case 'Z':
1349 return "-=";
1350 case '_': {
1351 if (MangledName.empty())
1352 break;
1353
1354 switch (MangledName.popFront()) {
1355 case '0':
1356 return "/=";
1357 case '1':
1358 return "%=";
1359 case '2':
1360 return ">>=";
1361 case '3':
1362 return "<<=";
1363 case '4':
1364 return "&=";
1365 case '5':
1366 return "|=";
1367 case '6':
1368 return "^=";
Zachary Turner970fdc32018-08-16 16:17:36 +00001369 // case '7': # vftable
1370 // case '8': # vbtable
1371 // case '9': # vcall
1372 // case 'A': # typeof
1373 // case 'B': # local static guard
1374 // case 'D': # vbase destructor
1375 // case 'E': # vector deleting destructor
1376 // case 'F': # default constructor closure
1377 // case 'G': # scalar deleting destructor
1378 // case 'H': # vector constructor iterator
1379 // case 'I': # vector destructor iterator
1380 // case 'J': # vector vbase constructor iterator
1381 // case 'K': # virtual displacement map
1382 // case 'L': # eh vector constructor iterator
1383 // case 'M': # eh vector destructor iterator
1384 // case 'N': # eh vector vbase constructor iterator
1385 // case 'O': # copy constructor closure
1386 // case 'P<name>': # udt returning <name>
1387 // case 'Q': # <unknown>
1388 // case 'R0': # RTTI Type Descriptor
1389 // case 'R1': # RTTI Base Class Descriptor at (a,b,c,d)
1390 // case 'R2': # RTTI Base Class Array
1391 // case 'R3': # RTTI Class Hierarchy Descriptor
1392 // case 'R4': # RTTI Complete Object Locator
1393 // case 'S': # local vftable
1394 // case 'T': # local vftable constructor closure
Zachary Turnera7dffb12018-07-28 22:10:42 +00001395 case 'U':
1396 return " new[]";
1397 case 'V':
1398 return " delete[]";
1399 case '_':
1400 if (MangledName.consumeFront("L"))
1401 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001402 if (MangledName.consumeFront("K")) {
1403 size_t EndPos = MangledName.find('@');
1404 if (EndPos == StringView::npos)
1405 break;
1406 StringView OpName = demangleSimpleString(MangledName, false);
1407 size_t FullSize = OpName.size() + 3; // <space>""OpName
1408 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1409 Buffer[0] = ' ';
1410 Buffer[1] = '"';
1411 Buffer[2] = '"';
1412 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1413 return {Buffer, FullSize};
1414 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001415 }
1416 }
1417 }
1418 Error = true;
1419 return "";
1420 };
1421
1422 Name *Node = Arena.alloc<Name>();
Zachary Turnera17721c2018-08-10 15:04:56 +00001423 if (MangledName.consumeFront('B')) {
1424 // Handle conversion operator specially.
1425 Node->IsConversionOperator = true;
1426 } else {
1427 Node->Str = NameString();
1428 }
Zachary Turner970fdc32018-08-16 16:17:36 +00001429 if (Error)
1430 return nullptr;
1431
Zachary Turner44ebbc22018-08-01 18:32:47 +00001432 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001433 return Node;
1434}
1435
Zachary Turner316109b2018-07-29 16:38:02 +00001436Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001437 StringView S = demangleSimpleString(MangledName, Memorize);
1438 if (Error)
1439 return nullptr;
1440
Zachary Turnera7dffb12018-07-28 22:10:42 +00001441 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001442 Node->Str = S;
1443 return Node;
1444}
1445
Zachary Turner970fdc32018-08-16 16:17:36 +00001446static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); }
1447
1448static uint8_t rebasedHexDigitToNumber(char C) {
1449 assert(isRebasedHexDigit(C));
1450 return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
1451}
1452
1453uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
1454 if (!MangledName.startsWith('?'))
1455 return MangledName.popFront();
1456
1457 MangledName = MangledName.dropFront();
1458 if (MangledName.empty())
1459 goto CharLiteralError;
1460
1461 if (MangledName.consumeFront('$')) {
1462 // Two hex digits
1463 if (MangledName.size() < 2)
1464 goto CharLiteralError;
1465 StringView Nibbles = MangledName.substr(0, 2);
1466 if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
1467 goto CharLiteralError;
1468 // Don't append the null terminator.
1469 uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
1470 uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
1471 MangledName = MangledName.dropFront(2);
1472 return (C1 << 4) | C2;
1473 }
1474
1475 if (startsWithDigit(MangledName)) {
1476 const char *Lookup = ",/\\:. \n\t'-";
1477 char C = Lookup[MangledName[0] - '0'];
1478 MangledName = MangledName.dropFront();
1479 return C;
1480 }
1481
1482 if (MangledName[0] >= 'a' && MangledName[0] <= 'z') {
1483 char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
1484 '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE',
1485 '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
1486 '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
1487 char C = Lookup[MangledName[0] - 'a'];
1488 MangledName = MangledName.dropFront();
1489 return C;
1490 }
1491
1492 if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') {
1493 char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
1494 '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE',
1495 '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
1496 '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
1497 char C = Lookup[MangledName[0] - 'A'];
1498 MangledName = MangledName.dropFront();
1499 return C;
1500 }
1501
1502CharLiteralError:
1503 Error = true;
1504 return '\0';
1505}
1506
1507wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
1508 uint8_t C1 = demangleCharLiteral(MangledName);
1509 if (Error)
1510 goto WCharLiteralError;
1511 uint8_t C2 = demangleCharLiteral(MangledName);
1512 if (Error)
1513 goto WCharLiteralError;
1514
1515 return ((wchar_t)C1 << 8) | (wchar_t)C2;
1516
1517WCharLiteralError:
1518 Error = true;
1519 return L'\0';
1520}
1521
1522static void writeHexDigit(char *Buffer, uint8_t Digit) {
1523 assert(Digit <= 15);
1524 *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
1525}
1526
1527static void outputHex(OutputStream &OS, unsigned C) {
1528 if (C == 0) {
1529 OS << "\\x00";
1530 return;
1531 }
1532 // It's easier to do the math if we can work from right to left, but we need
1533 // to print the numbers from left to right. So render this into a temporary
1534 // buffer first, then output the temporary buffer. Each byte is of the form
1535 // \xAB, which means that each byte needs 4 characters. Since there are at
1536 // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
1537 char TempBuffer[17];
1538
1539 ::memset(TempBuffer, 0, sizeof(TempBuffer));
1540 constexpr int MaxPos = 15;
1541
1542 int Pos = MaxPos - 1;
1543 while (C != 0) {
1544 for (int I = 0; I < 2; ++I) {
1545 writeHexDigit(&TempBuffer[Pos--], C % 16);
1546 C /= 16;
1547 }
1548 TempBuffer[Pos--] = 'x';
1549 TempBuffer[Pos--] = '\\';
1550 assert(Pos >= 0);
1551 }
1552 OS << StringView(&TempBuffer[Pos + 1]);
1553}
1554
1555static void outputEscapedChar(OutputStream &OS, unsigned C) {
1556 switch (C) {
1557 case '\'': // single quote
1558 OS << "\\\'";
1559 return;
1560 case '\"': // double quote
1561 OS << "\\\"";
1562 return;
1563 case '\\': // backslash
1564 OS << "\\\\";
1565 return;
1566 case '\a': // bell
1567 OS << "\\a";
1568 return;
1569 case '\b': // backspace
1570 OS << "\\b";
1571 return;
1572 case '\f': // form feed
1573 OS << "\\f";
1574 return;
1575 case '\n': // new line
1576 OS << "\\n";
1577 return;
1578 case '\r': // carriage return
1579 OS << "\\r";
1580 return;
1581 case '\t': // tab
1582 OS << "\\t";
1583 return;
1584 case '\v': // vertical tab
1585 OS << "\\v";
1586 return;
1587 default:
1588 break;
1589 }
1590
1591 if (C > 0x1F && C < 0x7F) {
1592 // Standard ascii char.
1593 OS << (char)C;
1594 return;
1595 }
1596
1597 outputHex(OS, C);
1598}
1599
1600unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
1601 const uint8_t *End = StringBytes + Length - 1;
1602 while (Length > 0 && *End == 0) {
1603 --Length;
1604 --End;
1605 }
1606 return End - StringBytes + 1;
1607}
1608
1609unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length) {
1610 unsigned Result = 0;
1611 for (unsigned I = 0; I < Length; ++I) {
1612 if (*StringBytes++ == 0)
1613 ++Result;
1614 }
1615 return Result;
1616}
1617
1618unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
1619 unsigned NumBytes) {
1620 assert(NumBytes > 0);
1621
1622 // If the number of bytes is odd, this is guaranteed to be a char string.
1623 if (NumBytes % 2 == 1)
1624 return 1;
1625
1626 // All strings can encode at most 32 bytes of data. If it's less than that,
1627 // then we encoded the entire string. In this case we check for a 1-byte,
1628 // 2-byte, or 4-byte null terminator.
1629 if (NumBytes < 32) {
1630 unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
1631 if (TrailingNulls >= 4)
1632 return 4;
1633 if (TrailingNulls >= 2)
1634 return 2;
1635 return 1;
1636 }
1637
1638 // The whole string was not able to be encoded. Try to look at embedded null
1639 // terminators to guess. The heuristic is that we count all embedded null
1640 // terminators. If more than 2/3 are null, it's a char32. If more than 1/3
1641 // are null, it's a char16. Otherwise it's a char8. This obviously isn't
1642 // perfect and is biased towards languages that have ascii alphabets, but this
1643 // was always going to be best effort since the encoding is lossy.
1644 unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
1645 if (Nulls >= 2 * NumChars / 3)
1646 return 4;
1647 if (Nulls >= NumChars / 3)
1648 return 2;
1649 return 1;
1650}
1651
1652static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
1653 unsigned CharIndex, unsigned CharBytes) {
1654 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1655 unsigned Offset = CharIndex * CharBytes;
1656 unsigned Result = 0;
1657 StringBytes = StringBytes + Offset;
1658 for (unsigned I = 0; I < CharBytes; ++I) {
1659 unsigned C = static_cast<unsigned>(StringBytes[I]);
1660 Result |= C << (8 * I);
1661 }
1662 return Result;
1663}
1664
1665Name *Demangler::demangleStringLiteral(StringView &MangledName) {
1666 OutputStream OS;
1667 StringView CRC;
1668 Name *Result = Arena.alloc<Name>();
1669 Result->IsStringLiteral = true;
1670
1671 // Prefix indicating the beginning of a string literal
1672 if (MangledName.empty())
1673 goto StringLiteralError;
1674
1675 // Char Type (regular or wchar_t)
1676 bool IsWcharT = false;
1677 switch (MangledName.popFront()) {
1678 case '1':
1679 IsWcharT = true;
1680 LLVM_FALLTHROUGH;
1681 case '0':
1682 break;
1683 default:
1684 goto StringLiteralError;
1685 }
1686
1687 // Encoded Length
1688 uint64_t StringByteSize;
1689 bool IsNegative;
1690 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1691 if (Error || IsNegative)
1692 goto StringLiteralError;
1693
1694 // CRC 32 (always 8 characters plus a terminator)
1695 size_t CrcEndPos = MangledName.find('@');
1696 if (CrcEndPos == StringView::npos)
1697 goto StringLiteralError;
1698 CRC = MangledName.substr(0, CrcEndPos);
1699 MangledName = MangledName.dropFront(CrcEndPos + 1);
1700 if (MangledName.empty())
1701 goto StringLiteralError;
1702
1703 OS = OutputStream::create(nullptr, nullptr, 1024);
1704 if (IsWcharT) {
1705 Result->StringLiteralType = PrimTy::Wchar;
1706 if (StringByteSize > 64)
1707 Result->IsLongStringLiteral = true;
1708
1709 while (!MangledName.consumeFront('@')) {
1710 assert(StringByteSize >= 2);
1711 wchar_t W = demangleWcharLiteral(MangledName);
1712 if (StringByteSize != 2 || Result->IsLongStringLiteral)
1713 outputEscapedChar(OS, W);
1714 StringByteSize -= 2;
1715 if (Error)
1716 goto StringLiteralError;
1717 }
1718 } else {
1719 if (StringByteSize > 32)
1720 Result->IsLongStringLiteral = true;
1721
1722 constexpr unsigned MaxStringByteLength = 32;
1723 uint8_t StringBytes[MaxStringByteLength];
1724
1725 unsigned BytesDecoded = 0;
1726 while (!MangledName.consumeFront('@')) {
1727 assert(StringByteSize >= 1);
1728 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1729 }
1730
1731 unsigned CharBytes =
1732 guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
1733 assert(StringByteSize % CharBytes == 0);
1734 switch (CharBytes) {
1735 case 1:
1736 Result->StringLiteralType = PrimTy::Char;
1737 break;
1738 case 2:
1739 Result->StringLiteralType = PrimTy::Char16;
1740 break;
1741 case 4:
1742 Result->StringLiteralType = PrimTy::Char32;
1743 break;
1744 default:
1745 LLVM_BUILTIN_UNREACHABLE;
1746 }
1747 const unsigned NumChars = BytesDecoded / CharBytes;
1748 for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1749 unsigned NextChar =
1750 decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
1751 if (CharIndex + 1 < NumChars || Result->IsLongStringLiteral)
1752 outputEscapedChar(OS, NextChar);
1753 }
1754 }
1755
1756 OS << '\0';
1757 char *ResultBuffer = OS.getBuffer();
1758 Result->Str = copyString(ResultBuffer);
1759 return Result;
1760
1761StringLiteralError:
1762 Error = true;
1763 return nullptr;
1764}
1765
Zachary Turner931e8792018-07-30 23:02:10 +00001766StringView Demangler::demangleSimpleString(StringView &MangledName,
1767 bool Memorize) {
1768 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001769 for (size_t i = 0; i < MangledName.size(); ++i) {
1770 if (MangledName[i] != '@')
1771 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001772 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001773 MangledName = MangledName.dropFront(i + 1);
1774
1775 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001776 memorizeString(S);
1777 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001778 }
1779
1780 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001781 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001782}
1783
Zachary Turner316109b2018-07-29 16:38:02 +00001784Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001785 assert(MangledName.startsWith("?A"));
1786 MangledName.consumeFront("?A");
1787
1788 Name *Node = Arena.alloc<Name>();
1789 Node->Str = "`anonymous namespace'";
1790 if (MangledName.consumeFront('@'))
1791 return Node;
1792
1793 Error = true;
1794 return nullptr;
1795}
1796
Zachary Turner71c91f92018-07-30 03:12:34 +00001797Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1798 assert(startsWithLocalScopePattern(MangledName));
1799
1800 Name *Node = Arena.alloc<Name>();
1801 MangledName.consumeFront('?');
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001802 auto Number = demangleNumber(MangledName);
1803 assert(!Number.second);
Zachary Turner71c91f92018-07-30 03:12:34 +00001804
1805 // One ? to terminate the number
1806 MangledName.consumeFront('?');
1807
1808 assert(!Error);
1809 Symbol *Scope = parse(MangledName);
1810 if (Error)
1811 return nullptr;
1812
1813 // Render the parent symbol's name into a buffer.
1814 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1815 OS << '`';
1816 output(Scope, OS);
1817 OS << '\'';
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001818 OS << "::`" << Number.first << "'";
Zachary Turner71c91f92018-07-30 03:12:34 +00001819 OS << '\0';
1820 char *Result = OS.getBuffer();
1821 Node->Str = copyString(Result);
1822 std::free(Result);
1823 return Node;
1824}
1825
Zachary Turnera7dffb12018-07-28 22:10:42 +00001826// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001827Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001828 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001829 if (Error)
1830 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001831 assert(TypeName);
1832
Zachary Turner316109b2018-07-29 16:38:02 +00001833 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001834 if (Error)
1835 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001836 assert(QualName);
1837 return QualName;
1838}
1839
1840// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1841// Symbol names have slightly different rules regarding what can appear
1842// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001843Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00001844 // This is the final component of a symbol name (i.e. the leftmost component
1845 // of a mangled name. Since the only possible template instantiation that
1846 // can appear in this context is a function template, and since those are
1847 // not saved for the purposes of name backreferences, only backref simple
1848 // names.
1849 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001850 if (Error)
1851 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001852 assert(SymbolName);
1853
Zachary Turner316109b2018-07-29 16:38:02 +00001854 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001855 if (Error)
1856 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001857 assert(QualName);
1858 return QualName;
1859}
1860
Zachary Turner44ebbc22018-08-01 18:32:47 +00001861Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1862 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001863 // An inner-most name can be a back-reference, because a fully-qualified name
1864 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1865 // them (for example template parameters), and these nested parameters can
1866 // refer to previously mangled types.
1867 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001868 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001869
1870 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001871 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001872
Zachary Turner44ebbc22018-08-01 18:32:47 +00001873 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001874}
1875
Zachary Turner44ebbc22018-08-01 18:32:47 +00001876Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00001877 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001878 if (startsWithDigit(MangledName))
1879 return demangleBackRefName(MangledName);
1880 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001881 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001882 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001883 return demangleOperatorName(MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001884 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001885}
1886
Zachary Turner316109b2018-07-29 16:38:02 +00001887Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001888 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001889 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001890
1891 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001892 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001893
1894 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001895 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001896
Zachary Turner71c91f92018-07-30 03:12:34 +00001897 if (startsWithLocalScopePattern(MangledName))
1898 return demangleLocallyScopedNamePiece(MangledName);
1899
Zachary Turner316109b2018-07-29 16:38:02 +00001900 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001901}
1902
Zachary Turner316109b2018-07-29 16:38:02 +00001903Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1904 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001905 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001906
1907 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001908 if (MangledName.empty()) {
1909 Error = true;
1910 return nullptr;
1911 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001912
1913 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001914 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001915 if (Error)
1916 return nullptr;
1917
1918 Elem->Next = Head;
1919 Head = Elem;
1920 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001921 return Head;
1922}
1923
Zachary Turner316109b2018-07-29 16:38:02 +00001924FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001925 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1926 RestoreOnError.shouldRestore(false);
1927
Zachary Turner29ec67b2018-08-10 21:09:05 +00001928 FuncClass TempFlags = FuncClass(0);
1929 if (MangledName.consumeFront("$$J0"))
1930 TempFlags = ExternC;
1931
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001932 switch (MangledName.popFront()) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00001933 case '9':
1934 return FuncClass(TempFlags | ExternC | NoPrototype);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001935 case 'A':
1936 return Private;
1937 case 'B':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001938 return FuncClass(TempFlags | Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001939 case 'C':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001940 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001941 case 'D':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001942 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001943 case 'E':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001944 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001945 case 'F':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001946 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001947 case 'I':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001948 return FuncClass(TempFlags | Protected);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001949 case 'J':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001950 return FuncClass(TempFlags | Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001951 case 'K':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001952 return FuncClass(TempFlags | Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001953 case 'L':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001954 return FuncClass(TempFlags | Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001955 case 'M':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001956 return FuncClass(TempFlags | Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001957 case 'N':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001958 return FuncClass(TempFlags | Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001959 case 'Q':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001960 return FuncClass(TempFlags | Public);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001961 case 'R':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001962 return FuncClass(TempFlags | Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001963 case 'S':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001964 return FuncClass(TempFlags | Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001965 case 'T':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001966 return FuncClass(TempFlags | Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001967 case 'U':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001968 return FuncClass(TempFlags | Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001969 case 'V':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001970 return FuncClass(TempFlags | Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001971 case 'Y':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001972 return FuncClass(TempFlags | Global);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001973 case 'Z':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001974 return FuncClass(TempFlags | Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001975 }
1976
1977 Error = true;
1978 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001979 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001980}
1981
Zachary Turner316109b2018-07-29 16:38:02 +00001982CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001983 switch (MangledName.popFront()) {
1984 case 'A':
1985 case 'B':
1986 return CallingConv::Cdecl;
1987 case 'C':
1988 case 'D':
1989 return CallingConv::Pascal;
1990 case 'E':
1991 case 'F':
1992 return CallingConv::Thiscall;
1993 case 'G':
1994 case 'H':
1995 return CallingConv::Stdcall;
1996 case 'I':
1997 case 'J':
1998 return CallingConv::Fastcall;
1999 case 'M':
2000 case 'N':
2001 return CallingConv::Clrcall;
2002 case 'O':
2003 case 'P':
2004 return CallingConv::Eabi;
2005 case 'Q':
2006 return CallingConv::Vectorcall;
2007 }
2008
2009 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00002010}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002011
Zachary Turner316109b2018-07-29 16:38:02 +00002012StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002013 assert(std::isdigit(MangledName.front()));
2014
2015 switch (MangledName.popFront()) {
2016 case '0':
2017 return StorageClass::PrivateStatic;
2018 case '1':
2019 return StorageClass::ProtectedStatic;
2020 case '2':
2021 return StorageClass::PublicStatic;
2022 case '3':
2023 return StorageClass::Global;
2024 case '4':
2025 return StorageClass::FunctionLocalStatic;
2026 }
2027 Error = true;
2028 return StorageClass::None;
2029}
2030
Zachary Turner316109b2018-07-29 16:38:02 +00002031std::pair<Qualifiers, bool>
2032Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002033
2034 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002035 // Member qualifiers
2036 case 'Q':
2037 return std::make_pair(Q_None, true);
2038 case 'R':
2039 return std::make_pair(Q_Const, true);
2040 case 'S':
2041 return std::make_pair(Q_Volatile, true);
2042 case 'T':
2043 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
2044 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002045 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00002046 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002047 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00002048 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002049 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00002050 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002051 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00002052 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002053 }
2054 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00002055 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002056}
2057
Zachary Turner931e8792018-07-30 23:02:10 +00002058static bool isTagType(StringView S) {
2059 switch (S.front()) {
2060 case 'T': // union
2061 case 'U': // struct
2062 case 'V': // class
2063 case 'W': // enum
2064 return true;
2065 }
2066 return false;
2067}
2068
2069static bool isPointerType(StringView S) {
2070 if (S.startsWith("$$Q")) // foo &&
2071 return true;
2072
2073 switch (S.front()) {
2074 case 'A': // foo &
2075 case 'P': // foo *
2076 case 'Q': // foo *const
2077 case 'R': // foo *volatile
2078 case 'S': // foo *const volatile
2079 return true;
2080 }
2081 return false;
2082}
2083
2084static bool isArrayType(StringView S) { return S[0] == 'Y'; }
2085
2086static bool isFunctionType(StringView S) {
2087 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
2088}
2089
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002090// <variable-type> ::= <type> <cvr-qualifiers>
2091// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00002092Type *Demangler::demangleType(StringView &MangledName,
2093 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002094 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00002095 bool IsMember = false;
2096 bool IsMemberKnown = false;
2097 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00002098 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002099 IsMemberKnown = true;
2100 } else if (QMM == QualifierMangleMode::Result) {
2101 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00002102 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002103 IsMemberKnown = true;
2104 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002105 }
2106
2107 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00002108 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002109 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002110 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002111 if (!IsMemberKnown)
2112 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002113
Zachary Turnerd742d642018-07-26 19:56:09 +00002114 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00002115 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002116 else
Zachary Turner316109b2018-07-29 16:38:02 +00002117 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002118 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002119 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002120 else if (isFunctionType(MangledName)) {
2121 if (MangledName.consumeFront("$$A8@@"))
2122 Ty = demangleFunctionType(MangledName, true, false);
2123 else {
2124 assert(MangledName.startsWith("$$A6"));
2125 MangledName.consumeFront("$$A6");
2126 Ty = demangleFunctionType(MangledName, false, false);
2127 }
2128 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00002129 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002130 assert(Ty && !Error);
2131 if (!Ty || Error)
2132 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002133 }
Zachary Turner931e8792018-07-30 23:02:10 +00002134
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002135 Ty->Quals = Qualifiers(Ty->Quals | Quals);
2136 return Ty;
2137}
2138
Zachary Turner316109b2018-07-29 16:38:02 +00002139ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002140 if (MangledName.consumeFront('G'))
2141 return ReferenceKind::LValueRef;
2142 else if (MangledName.consumeFront('H'))
2143 return ReferenceKind::RValueRef;
2144 return ReferenceKind::None;
2145}
2146
Zachary Turner316109b2018-07-29 16:38:02 +00002147void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002148 if (MangledName.consumeFront('Z'))
2149 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002150
Zachary Turner38b78a72018-07-26 20:20:10 +00002151 Error = true;
2152}
2153
Zachary Turner316109b2018-07-29 16:38:02 +00002154FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
2155 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00002156 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002157 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002158 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00002159 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00002160
2161 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00002162 FTy->Quals = demanglePointerExtQualifiers(MangledName);
2163 FTy->RefKind = demangleReferenceKind(MangledName);
2164 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002165 }
2166
2167 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00002168 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002169
2170 // <return-type> ::= <type>
2171 // ::= @ # structors (they have no declared return type)
2172 bool IsStructor = MangledName.consumeFront('@');
2173 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00002174 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002175
Zachary Turner316109b2018-07-29 16:38:02 +00002176 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002177
Zachary Turner316109b2018-07-29 16:38:02 +00002178 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002179
2180 return FTy;
2181}
2182
Zachary Turner316109b2018-07-29 16:38:02 +00002183Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
2184 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner29ec67b2018-08-10 21:09:05 +00002185 FunctionType *FTy = nullptr;
2186 if (FC & NoPrototype) {
2187 // This is an extern "C" function whose full signature hasn't been mangled.
2188 // This happens when we need to mangle a local symbol inside of an extern
2189 // "C" function.
2190 FTy = Arena.alloc<FunctionType>();
2191 } else {
2192 bool HasThisQuals = !(FC & (Global | Static));
2193 FTy = demangleFunctionType(MangledName, HasThisQuals, false);
2194 }
Zachary Turner38b78a72018-07-26 20:20:10 +00002195 FTy->FunctionClass = FC;
2196
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002197 return FTy;
2198}
2199
2200// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00002201Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002202 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002203
Zachary Turner931e8792018-07-30 23:02:10 +00002204 if (MangledName.consumeFront("$$T")) {
2205 Ty->Prim = PrimTy::Nullptr;
2206 return Ty;
2207 }
2208
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002209 switch (MangledName.popFront()) {
2210 case 'X':
2211 Ty->Prim = PrimTy::Void;
2212 break;
2213 case 'D':
2214 Ty->Prim = PrimTy::Char;
2215 break;
2216 case 'C':
2217 Ty->Prim = PrimTy::Schar;
2218 break;
2219 case 'E':
2220 Ty->Prim = PrimTy::Uchar;
2221 break;
2222 case 'F':
2223 Ty->Prim = PrimTy::Short;
2224 break;
2225 case 'G':
2226 Ty->Prim = PrimTy::Ushort;
2227 break;
2228 case 'H':
2229 Ty->Prim = PrimTy::Int;
2230 break;
2231 case 'I':
2232 Ty->Prim = PrimTy::Uint;
2233 break;
2234 case 'J':
2235 Ty->Prim = PrimTy::Long;
2236 break;
2237 case 'K':
2238 Ty->Prim = PrimTy::Ulong;
2239 break;
2240 case 'M':
2241 Ty->Prim = PrimTy::Float;
2242 break;
2243 case 'N':
2244 Ty->Prim = PrimTy::Double;
2245 break;
2246 case 'O':
2247 Ty->Prim = PrimTy::Ldouble;
2248 break;
2249 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00002250 if (MangledName.empty()) {
2251 Error = true;
2252 return nullptr;
2253 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002254 switch (MangledName.popFront()) {
2255 case 'N':
2256 Ty->Prim = PrimTy::Bool;
2257 break;
2258 case 'J':
2259 Ty->Prim = PrimTy::Int64;
2260 break;
2261 case 'K':
2262 Ty->Prim = PrimTy::Uint64;
2263 break;
2264 case 'W':
2265 Ty->Prim = PrimTy::Wchar;
2266 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002267 case 'S':
2268 Ty->Prim = PrimTy::Char16;
2269 break;
2270 case 'U':
2271 Ty->Prim = PrimTy::Char32;
2272 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00002273 default:
Zachary Turner931e8792018-07-30 23:02:10 +00002274 Error = true;
2275 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002276 }
2277 break;
2278 }
Zachary Turner931e8792018-07-30 23:02:10 +00002279 default:
2280 Error = true;
2281 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002282 }
2283 return Ty;
2284}
2285
Zachary Turner316109b2018-07-29 16:38:02 +00002286UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002287 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002288
2289 switch (MangledName.popFront()) {
2290 case 'T':
2291 UTy->Prim = PrimTy::Union;
2292 break;
2293 case 'U':
2294 UTy->Prim = PrimTy::Struct;
2295 break;
2296 case 'V':
2297 UTy->Prim = PrimTy::Class;
2298 break;
2299 case 'W':
2300 if (MangledName.popFront() != '4') {
2301 Error = true;
2302 return nullptr;
2303 }
2304 UTy->Prim = PrimTy::Enum;
2305 break;
2306 default:
2307 assert(false);
2308 }
2309
Zachary Turner316109b2018-07-29 16:38:02 +00002310 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002311 return UTy;
2312}
2313
Zachary Turnerd742d642018-07-26 19:56:09 +00002314static std::pair<Qualifiers, PointerAffinity>
2315demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00002316 if (MangledName.consumeFront("$$Q"))
2317 return std::make_pair(Q_None, PointerAffinity::RValueReference);
2318
Zachary Turnerd742d642018-07-26 19:56:09 +00002319 switch (MangledName.popFront()) {
2320 case 'A':
2321 return std::make_pair(Q_None, PointerAffinity::Reference);
2322 case 'P':
2323 return std::make_pair(Q_None, PointerAffinity::Pointer);
2324 case 'Q':
2325 return std::make_pair(Q_Const, PointerAffinity::Pointer);
2326 case 'R':
2327 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
2328 case 'S':
2329 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
2330 PointerAffinity::Pointer);
2331 default:
2332 assert(false && "Ty is not a pointer type!");
2333 }
2334 return std::make_pair(Q_None, PointerAffinity::Pointer);
2335}
2336
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002337// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
2338// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00002339PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002340 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002341
Zachary Turner931e8792018-07-30 23:02:10 +00002342 std::tie(Pointer->Quals, Pointer->Affinity) =
2343 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002344
Zachary Turner931e8792018-07-30 23:02:10 +00002345 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002346 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002347 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002348 return Pointer;
2349 }
2350
Zachary Turner316109b2018-07-29 16:38:02 +00002351 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002352 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2353
Zachary Turner316109b2018-07-29 16:38:02 +00002354 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002355 return Pointer;
2356}
2357
Zachary Turner316109b2018-07-29 16:38:02 +00002358MemberPointerType *
2359Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002360 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
2361 Pointer->Prim = PrimTy::MemberPtr;
2362
2363 PointerAffinity Affinity;
2364 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
2365 assert(Affinity == PointerAffinity::Pointer);
2366
Zachary Turner316109b2018-07-29 16:38:02 +00002367 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002368 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2369
Zachary Turner38b78a72018-07-26 20:20:10 +00002370 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002371 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
2372 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002373 } else {
2374 Qualifiers PointeeQuals = Q_None;
2375 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00002376 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002377 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00002378 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002379
Zachary Turner316109b2018-07-29 16:38:02 +00002380 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00002381 Pointer->Pointee->Quals = PointeeQuals;
2382 }
2383
Zachary Turnerd742d642018-07-26 19:56:09 +00002384 return Pointer;
2385}
2386
Zachary Turner316109b2018-07-29 16:38:02 +00002387Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002388 Qualifiers Quals = Q_None;
2389 if (MangledName.consumeFront('E'))
2390 Quals = Qualifiers(Quals | Q_Pointer64);
2391 if (MangledName.consumeFront('I'))
2392 Quals = Qualifiers(Quals | Q_Restrict);
2393 if (MangledName.consumeFront('F'))
2394 Quals = Qualifiers(Quals | Q_Unaligned);
2395
2396 return Quals;
2397}
2398
Zachary Turner316109b2018-07-29 16:38:02 +00002399ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002400 assert(MangledName.front() == 'Y');
2401 MangledName.popFront();
2402
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002403 uint64_t Rank = 0;
2404 bool IsNegative = false;
2405 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2406 if (IsNegative || Rank == 0) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002407 Error = true;
2408 return nullptr;
2409 }
2410
Zachary Turner9d72aa92018-07-20 18:35:06 +00002411 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002412 ATy->Prim = PrimTy::Array;
2413 ATy->Dims = Arena.alloc<ArrayDimension>();
2414 ArrayDimension *Dim = ATy->Dims;
2415 for (uint64_t I = 0; I < Rank; ++I) {
2416 std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
2417 if (IsNegative) {
2418 Error = true;
2419 return nullptr;
2420 }
2421 if (I + 1 < Rank) {
2422 Dim->Next = Arena.alloc<ArrayDimension>();
2423 Dim = Dim->Next;
2424 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002425 }
2426
2427 if (MangledName.consumeFront("$$C")) {
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002428 bool IsMember = false;
2429 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2430 if (IsMember) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002431 Error = true;
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002432 return nullptr;
2433 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002434 }
2435
Zachary Turner316109b2018-07-29 16:38:02 +00002436 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002437 return ATy;
2438}
2439
2440// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002441FunctionParams
2442Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002443 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00002444 if (MangledName.consumeFront('X'))
2445 return {};
2446
Zachary Turnerd30700f2018-07-31 17:16:44 +00002447 FunctionParams *Head;
2448 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002449 while (!Error && !MangledName.startsWith('@') &&
2450 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002451
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002452 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00002453 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002454 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002455 Error = true;
2456 return {};
2457 }
2458 MangledName = MangledName.dropFront();
2459
Zachary Turnerd30700f2018-07-31 17:16:44 +00002460 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00002461 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002462 Current = &(*Current)->Next;
2463 continue;
2464 }
2465
Zachary Turner23df1312018-07-26 22:13:39 +00002466 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002467
Zachary Turnerd30700f2018-07-31 17:16:44 +00002468 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00002469 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002470
Zachary Turner23df1312018-07-26 22:13:39 +00002471 size_t CharsConsumed = OldSize - MangledName.size();
2472 assert(CharsConsumed != 0);
2473
2474 // Single-letter types are ignored for backreferences because memorizing
2475 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002476 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2477 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2478 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002479
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002480 Current = &(*Current)->Next;
2481 }
2482
Zachary Turner38b78a72018-07-26 20:20:10 +00002483 if (Error)
2484 return {};
2485
2486 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2487 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2488 // the following Z could be a throw specifier.
2489 if (MangledName.consumeFront('@'))
2490 return *Head;
2491
2492 if (MangledName.consumeFront('Z')) {
2493 Head->IsVariadic = true;
2494 return *Head;
2495 }
2496
2497 Error = true;
2498 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002499}
2500
Zachary Turnerd30700f2018-07-31 17:16:44 +00002501TemplateParams *
2502Demangler::demangleTemplateParameterList(StringView &MangledName) {
2503 TemplateParams *Head;
2504 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002505 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002506 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002507 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002508
2509 // Empty parameter pack.
2510 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2511 MangledName.consumeFront("$$$V")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002512 (*Current)->IsEmptyParameterPack = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002513 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002514 }
2515
Zachary Turnerd30700f2018-07-31 17:16:44 +00002516 if (MangledName.consumeFront("$$Y")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002517 // Template alias
Zachary Turnerd30700f2018-07-31 17:16:44 +00002518 (*Current)->IsTemplateTemplate = true;
2519 (*Current)->IsAliasTemplate = true;
2520 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002521 } else if (MangledName.consumeFront("$$B")) {
2522 // Array
2523 (*Current)->ParamType =
2524 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner073620b2018-08-10 19:57:36 +00002525 } else if (MangledName.consumeFront("$$C")) {
2526 // Type has qualifiers.
2527 (*Current)->ParamType =
2528 demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002529 } else if (MangledName.startsWith("$1?")) {
2530 MangledName.consumeFront("$1");
2531 // Pointer to symbol
2532 Symbol *S = parse(MangledName);
2533 (*Current)->ParamName = S->SymbolName;
2534 (*Current)->ParamType = S->SymbolType;
2535 (*Current)->PointerToSymbol = true;
2536 } else if (MangledName.startsWith("$E?")) {
2537 MangledName.consumeFront("$E");
2538 // Reference to symbol
2539 Symbol *S = parse(MangledName);
2540 (*Current)->ParamName = S->SymbolName;
2541 (*Current)->ParamType = S->SymbolType;
2542 (*Current)->ReferenceToSymbol = true;
2543 } else if (MangledName.consumeFront("$0")) {
2544 // Integral non-type template parameter
2545 bool IsNegative = false;
2546 uint64_t Value = 0;
2547 std::tie(Value, IsNegative) = demangleNumber(MangledName);
2548
2549 (*Current)->IsIntegerLiteral = true;
2550 (*Current)->IntegerLiteralIsNegative = IsNegative;
2551 (*Current)->IntegralValue = Value;
Zachary Turnerd30700f2018-07-31 17:16:44 +00002552 } else {
2553 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002554 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002555 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002556 if (Error)
2557 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002558
2559 Current = &(*Current)->Next;
2560 }
2561
2562 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002563 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002564
2565 // Template parameter lists cannot be variadic, so it can only be terminated
2566 // by @.
2567 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002568 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002569 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002570 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002571}
2572
Zachary Turner172aea12018-08-02 17:08:03 +00002573StringView Demangler::resolve(StringView N) {
2574 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002575 size_t Digit = N[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002576 if (Digit >= Backrefs.NamesCount)
Zachary Turner172aea12018-08-02 17:08:03 +00002577 return N;
Zachary Turnerd346cba2018-08-08 17:17:04 +00002578 return Backrefs.Names[Digit];
Zachary Turner172aea12018-08-02 17:08:03 +00002579}
2580
Zachary Turner316109b2018-07-29 16:38:02 +00002581void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turner83313f82018-08-16 16:17:17 +00002582 if (S->Category == SymbolCategory::Unknown) {
2583 outputName(OS, S->SymbolName, S->SymbolType, *this);
2584 return;
2585 }
Zachary Turner970fdc32018-08-16 16:17:36 +00002586 if (S->Category == SymbolCategory::StringLiteral) {
2587 outputStringLiteral(OS, *S->SymbolName);
2588 return;
2589 }
2590
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002591 // Converts an AST to a string.
2592 //
2593 // Converting an AST representing a C++ type to a string is tricky due
2594 // to the bad grammar of the C++ declaration inherited from C. You have
2595 // to construct a string from inside to outside. For example, if a type
2596 // X is a pointer to a function returning int, the order you create a
2597 // string becomes something like this:
2598 //
2599 // (1) X is a pointer: *X
2600 // (2) (1) is a function returning int: int (*X)()
2601 //
2602 // So you cannot construct a result just by appending strings to a result.
2603 //
2604 // To deal with this, we split the function into two. outputPre() writes
2605 // the "first half" of type declaration, and outputPost() writes the
2606 // "second half". For example, outputPre() writes a return type for a
2607 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002608 Type::outputPre(OS, *S->SymbolType, *this);
Zachary Turnera17721c2018-08-10 15:04:56 +00002609 outputName(OS, S->SymbolName, S->SymbolType, *this);
Zachary Turner172aea12018-08-02 17:08:03 +00002610 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002611}
2612
Zachary Turner3a758e22018-08-01 18:33:04 +00002613void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002614 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00002615 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002616
2617 // Create an output stream so we can render each type.
2618 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00002619 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00002620 OS.setCurrentPosition(0);
2621
Zachary Turnerd346cba2018-08-08 17:17:04 +00002622 Type *T = Backrefs.FunctionParams[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002623 Type::outputPre(OS, *T, *this);
2624 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002625
Zachary Turner7563ebe2018-08-02 17:08:24 +00002626 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002627 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002628 }
2629 std::free(OS.getBuffer());
2630
Zachary Turnerd346cba2018-08-08 17:17:04 +00002631 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002632 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00002633 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
2634 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
2635 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
2636 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002637 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00002638 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002639 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002640}
2641
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002642char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002643 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002644 Demangler D;
2645 StringView Name{MangledName};
2646 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002647
Zachary Turner3a758e22018-08-01 18:33:04 +00002648 if (Flags & MSDF_DumpBackrefs)
2649 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002650 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002651 if (D.Error) {
2652 OS << MangledName;
2653 *Status = llvm::demangle_invalid_mangled_name;
2654 } else {
2655 D.output(S, OS);
2656 *Status = llvm::demangle_success;
2657 }
2658
Zachary Turner71c91f92018-07-30 03:12:34 +00002659 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002660 return OS.getBuffer();
2661}