blob: 4793ca8ad238c75c37645140c89221b318bee416 [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) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001508 uint8_t C1, C2;
1509
1510 C1 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001511 if (Error)
1512 goto WCharLiteralError;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001513 C2 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001514 if (Error)
1515 goto WCharLiteralError;
1516
1517 return ((wchar_t)C1 << 8) | (wchar_t)C2;
1518
1519WCharLiteralError:
1520 Error = true;
1521 return L'\0';
1522}
1523
1524static void writeHexDigit(char *Buffer, uint8_t Digit) {
1525 assert(Digit <= 15);
1526 *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
1527}
1528
1529static void outputHex(OutputStream &OS, unsigned C) {
1530 if (C == 0) {
1531 OS << "\\x00";
1532 return;
1533 }
1534 // It's easier to do the math if we can work from right to left, but we need
1535 // to print the numbers from left to right. So render this into a temporary
1536 // buffer first, then output the temporary buffer. Each byte is of the form
1537 // \xAB, which means that each byte needs 4 characters. Since there are at
1538 // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
1539 char TempBuffer[17];
1540
1541 ::memset(TempBuffer, 0, sizeof(TempBuffer));
1542 constexpr int MaxPos = 15;
1543
1544 int Pos = MaxPos - 1;
1545 while (C != 0) {
1546 for (int I = 0; I < 2; ++I) {
1547 writeHexDigit(&TempBuffer[Pos--], C % 16);
1548 C /= 16;
1549 }
1550 TempBuffer[Pos--] = 'x';
1551 TempBuffer[Pos--] = '\\';
1552 assert(Pos >= 0);
1553 }
1554 OS << StringView(&TempBuffer[Pos + 1]);
1555}
1556
1557static void outputEscapedChar(OutputStream &OS, unsigned C) {
1558 switch (C) {
1559 case '\'': // single quote
1560 OS << "\\\'";
1561 return;
1562 case '\"': // double quote
1563 OS << "\\\"";
1564 return;
1565 case '\\': // backslash
1566 OS << "\\\\";
1567 return;
1568 case '\a': // bell
1569 OS << "\\a";
1570 return;
1571 case '\b': // backspace
1572 OS << "\\b";
1573 return;
1574 case '\f': // form feed
1575 OS << "\\f";
1576 return;
1577 case '\n': // new line
1578 OS << "\\n";
1579 return;
1580 case '\r': // carriage return
1581 OS << "\\r";
1582 return;
1583 case '\t': // tab
1584 OS << "\\t";
1585 return;
1586 case '\v': // vertical tab
1587 OS << "\\v";
1588 return;
1589 default:
1590 break;
1591 }
1592
1593 if (C > 0x1F && C < 0x7F) {
1594 // Standard ascii char.
1595 OS << (char)C;
1596 return;
1597 }
1598
1599 outputHex(OS, C);
1600}
1601
1602unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
1603 const uint8_t *End = StringBytes + Length - 1;
1604 while (Length > 0 && *End == 0) {
1605 --Length;
1606 --End;
1607 }
1608 return End - StringBytes + 1;
1609}
1610
1611unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length) {
1612 unsigned Result = 0;
1613 for (unsigned I = 0; I < Length; ++I) {
1614 if (*StringBytes++ == 0)
1615 ++Result;
1616 }
1617 return Result;
1618}
1619
1620unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
1621 unsigned NumBytes) {
1622 assert(NumBytes > 0);
1623
1624 // If the number of bytes is odd, this is guaranteed to be a char string.
1625 if (NumBytes % 2 == 1)
1626 return 1;
1627
1628 // All strings can encode at most 32 bytes of data. If it's less than that,
1629 // then we encoded the entire string. In this case we check for a 1-byte,
1630 // 2-byte, or 4-byte null terminator.
1631 if (NumBytes < 32) {
1632 unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
1633 if (TrailingNulls >= 4)
1634 return 4;
1635 if (TrailingNulls >= 2)
1636 return 2;
1637 return 1;
1638 }
1639
1640 // The whole string was not able to be encoded. Try to look at embedded null
1641 // terminators to guess. The heuristic is that we count all embedded null
1642 // terminators. If more than 2/3 are null, it's a char32. If more than 1/3
1643 // are null, it's a char16. Otherwise it's a char8. This obviously isn't
1644 // perfect and is biased towards languages that have ascii alphabets, but this
1645 // was always going to be best effort since the encoding is lossy.
1646 unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
1647 if (Nulls >= 2 * NumChars / 3)
1648 return 4;
1649 if (Nulls >= NumChars / 3)
1650 return 2;
1651 return 1;
1652}
1653
1654static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
1655 unsigned CharIndex, unsigned CharBytes) {
1656 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1657 unsigned Offset = CharIndex * CharBytes;
1658 unsigned Result = 0;
1659 StringBytes = StringBytes + Offset;
1660 for (unsigned I = 0; I < CharBytes; ++I) {
1661 unsigned C = static_cast<unsigned>(StringBytes[I]);
1662 Result |= C << (8 * I);
1663 }
1664 return Result;
1665}
1666
1667Name *Demangler::demangleStringLiteral(StringView &MangledName) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001668 // This function uses goto, so declare all variables up front.
Zachary Turner970fdc32018-08-16 16:17:36 +00001669 OutputStream OS;
1670 StringView CRC;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001671 uint64_t StringByteSize;
1672 bool IsWcharT = false;
1673 bool IsNegative = false;
1674 size_t CrcEndPos = 0;
1675 char *ResultBuffer = nullptr;
1676
Zachary Turner970fdc32018-08-16 16:17:36 +00001677 Name *Result = Arena.alloc<Name>();
1678 Result->IsStringLiteral = true;
1679
1680 // Prefix indicating the beginning of a string literal
1681 if (MangledName.empty())
1682 goto StringLiteralError;
1683
1684 // Char Type (regular or wchar_t)
Zachary Turner970fdc32018-08-16 16:17:36 +00001685 switch (MangledName.popFront()) {
1686 case '1':
1687 IsWcharT = true;
1688 LLVM_FALLTHROUGH;
1689 case '0':
1690 break;
1691 default:
1692 goto StringLiteralError;
1693 }
1694
1695 // Encoded Length
Zachary Turner970fdc32018-08-16 16:17:36 +00001696 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1697 if (Error || IsNegative)
1698 goto StringLiteralError;
1699
1700 // CRC 32 (always 8 characters plus a terminator)
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001701 CrcEndPos = MangledName.find('@');
Zachary Turner970fdc32018-08-16 16:17:36 +00001702 if (CrcEndPos == StringView::npos)
1703 goto StringLiteralError;
1704 CRC = MangledName.substr(0, CrcEndPos);
1705 MangledName = MangledName.dropFront(CrcEndPos + 1);
1706 if (MangledName.empty())
1707 goto StringLiteralError;
1708
1709 OS = OutputStream::create(nullptr, nullptr, 1024);
1710 if (IsWcharT) {
1711 Result->StringLiteralType = PrimTy::Wchar;
1712 if (StringByteSize > 64)
1713 Result->IsLongStringLiteral = true;
1714
1715 while (!MangledName.consumeFront('@')) {
1716 assert(StringByteSize >= 2);
1717 wchar_t W = demangleWcharLiteral(MangledName);
1718 if (StringByteSize != 2 || Result->IsLongStringLiteral)
1719 outputEscapedChar(OS, W);
1720 StringByteSize -= 2;
1721 if (Error)
1722 goto StringLiteralError;
1723 }
1724 } else {
1725 if (StringByteSize > 32)
1726 Result->IsLongStringLiteral = true;
1727
1728 constexpr unsigned MaxStringByteLength = 32;
1729 uint8_t StringBytes[MaxStringByteLength];
1730
1731 unsigned BytesDecoded = 0;
1732 while (!MangledName.consumeFront('@')) {
1733 assert(StringByteSize >= 1);
1734 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1735 }
1736
1737 unsigned CharBytes =
1738 guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
1739 assert(StringByteSize % CharBytes == 0);
1740 switch (CharBytes) {
1741 case 1:
1742 Result->StringLiteralType = PrimTy::Char;
1743 break;
1744 case 2:
1745 Result->StringLiteralType = PrimTy::Char16;
1746 break;
1747 case 4:
1748 Result->StringLiteralType = PrimTy::Char32;
1749 break;
1750 default:
1751 LLVM_BUILTIN_UNREACHABLE;
1752 }
1753 const unsigned NumChars = BytesDecoded / CharBytes;
1754 for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1755 unsigned NextChar =
1756 decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
1757 if (CharIndex + 1 < NumChars || Result->IsLongStringLiteral)
1758 outputEscapedChar(OS, NextChar);
1759 }
1760 }
1761
1762 OS << '\0';
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001763 ResultBuffer = OS.getBuffer();
Zachary Turner970fdc32018-08-16 16:17:36 +00001764 Result->Str = copyString(ResultBuffer);
Zachary Turneraf738f72018-08-16 17:48:32 +00001765 std::free(ResultBuffer);
Zachary Turner970fdc32018-08-16 16:17:36 +00001766 return Result;
1767
1768StringLiteralError:
1769 Error = true;
1770 return nullptr;
1771}
1772
Zachary Turner931e8792018-07-30 23:02:10 +00001773StringView Demangler::demangleSimpleString(StringView &MangledName,
1774 bool Memorize) {
1775 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001776 for (size_t i = 0; i < MangledName.size(); ++i) {
1777 if (MangledName[i] != '@')
1778 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001779 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001780 MangledName = MangledName.dropFront(i + 1);
1781
1782 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001783 memorizeString(S);
1784 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001785 }
1786
1787 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001788 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001789}
1790
Zachary Turner316109b2018-07-29 16:38:02 +00001791Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001792 assert(MangledName.startsWith("?A"));
1793 MangledName.consumeFront("?A");
1794
1795 Name *Node = Arena.alloc<Name>();
1796 Node->Str = "`anonymous namespace'";
1797 if (MangledName.consumeFront('@'))
1798 return Node;
1799
1800 Error = true;
1801 return nullptr;
1802}
1803
Zachary Turner71c91f92018-07-30 03:12:34 +00001804Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1805 assert(startsWithLocalScopePattern(MangledName));
1806
1807 Name *Node = Arena.alloc<Name>();
1808 MangledName.consumeFront('?');
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001809 auto Number = demangleNumber(MangledName);
1810 assert(!Number.second);
Zachary Turner71c91f92018-07-30 03:12:34 +00001811
1812 // One ? to terminate the number
1813 MangledName.consumeFront('?');
1814
1815 assert(!Error);
1816 Symbol *Scope = parse(MangledName);
1817 if (Error)
1818 return nullptr;
1819
1820 // Render the parent symbol's name into a buffer.
1821 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1822 OS << '`';
1823 output(Scope, OS);
1824 OS << '\'';
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001825 OS << "::`" << Number.first << "'";
Zachary Turner71c91f92018-07-30 03:12:34 +00001826 OS << '\0';
1827 char *Result = OS.getBuffer();
1828 Node->Str = copyString(Result);
1829 std::free(Result);
1830 return Node;
1831}
1832
Zachary Turnera7dffb12018-07-28 22:10:42 +00001833// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001834Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001835 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001836 if (Error)
1837 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001838 assert(TypeName);
1839
Zachary Turner316109b2018-07-29 16:38:02 +00001840 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001841 if (Error)
1842 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001843 assert(QualName);
1844 return QualName;
1845}
1846
1847// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1848// Symbol names have slightly different rules regarding what can appear
1849// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001850Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00001851 // This is the final component of a symbol name (i.e. the leftmost component
1852 // of a mangled name. Since the only possible template instantiation that
1853 // can appear in this context is a function template, and since those are
1854 // not saved for the purposes of name backreferences, only backref simple
1855 // names.
1856 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001857 if (Error)
1858 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001859 assert(SymbolName);
1860
Zachary Turner316109b2018-07-29 16:38:02 +00001861 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001862 if (Error)
1863 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001864 assert(QualName);
1865 return QualName;
1866}
1867
Zachary Turner44ebbc22018-08-01 18:32:47 +00001868Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1869 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001870 // An inner-most name can be a back-reference, because a fully-qualified name
1871 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1872 // them (for example template parameters), and these nested parameters can
1873 // refer to previously mangled types.
1874 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001875 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001876
1877 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001878 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001879
Zachary Turner44ebbc22018-08-01 18:32:47 +00001880 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001881}
1882
Zachary Turner44ebbc22018-08-01 18:32:47 +00001883Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00001884 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001885 if (startsWithDigit(MangledName))
1886 return demangleBackRefName(MangledName);
1887 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001888 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001889 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001890 return demangleOperatorName(MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001891 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001892}
1893
Zachary Turner316109b2018-07-29 16:38:02 +00001894Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001895 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001896 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001897
1898 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00001899 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001900
1901 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001902 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001903
Zachary Turner71c91f92018-07-30 03:12:34 +00001904 if (startsWithLocalScopePattern(MangledName))
1905 return demangleLocallyScopedNamePiece(MangledName);
1906
Zachary Turner316109b2018-07-29 16:38:02 +00001907 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001908}
1909
Zachary Turner316109b2018-07-29 16:38:02 +00001910Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1911 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001912 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001913
1914 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001915 if (MangledName.empty()) {
1916 Error = true;
1917 return nullptr;
1918 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001919
1920 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001921 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001922 if (Error)
1923 return nullptr;
1924
1925 Elem->Next = Head;
1926 Head = Elem;
1927 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001928 return Head;
1929}
1930
Zachary Turner316109b2018-07-29 16:38:02 +00001931FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001932 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1933 RestoreOnError.shouldRestore(false);
1934
Zachary Turner29ec67b2018-08-10 21:09:05 +00001935 FuncClass TempFlags = FuncClass(0);
1936 if (MangledName.consumeFront("$$J0"))
1937 TempFlags = ExternC;
1938
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001939 switch (MangledName.popFront()) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00001940 case '9':
1941 return FuncClass(TempFlags | ExternC | NoPrototype);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001942 case 'A':
1943 return Private;
1944 case 'B':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001945 return FuncClass(TempFlags | Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001946 case 'C':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001947 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001948 case 'D':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001949 return FuncClass(TempFlags | Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001950 case 'E':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001951 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001952 case 'F':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001953 return FuncClass(TempFlags | Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001954 case 'I':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001955 return FuncClass(TempFlags | Protected);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001956 case 'J':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001957 return FuncClass(TempFlags | Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001958 case 'K':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001959 return FuncClass(TempFlags | Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001960 case 'L':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001961 return FuncClass(TempFlags | Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001962 case 'M':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001963 return FuncClass(TempFlags | Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001964 case 'N':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001965 return FuncClass(TempFlags | Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001966 case 'Q':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001967 return FuncClass(TempFlags | Public);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001968 case 'R':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001969 return FuncClass(TempFlags | Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001970 case 'S':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001971 return FuncClass(TempFlags | Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001972 case 'T':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001973 return FuncClass(TempFlags | Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001974 case 'U':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001975 return FuncClass(TempFlags | Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001976 case 'V':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001977 return FuncClass(TempFlags | Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001978 case 'Y':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001979 return FuncClass(TempFlags | Global);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001980 case 'Z':
Zachary Turner29ec67b2018-08-10 21:09:05 +00001981 return FuncClass(TempFlags | Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001982 }
1983
1984 Error = true;
1985 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001986 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001987}
1988
Zachary Turner316109b2018-07-29 16:38:02 +00001989CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001990 switch (MangledName.popFront()) {
1991 case 'A':
1992 case 'B':
1993 return CallingConv::Cdecl;
1994 case 'C':
1995 case 'D':
1996 return CallingConv::Pascal;
1997 case 'E':
1998 case 'F':
1999 return CallingConv::Thiscall;
2000 case 'G':
2001 case 'H':
2002 return CallingConv::Stdcall;
2003 case 'I':
2004 case 'J':
2005 return CallingConv::Fastcall;
2006 case 'M':
2007 case 'N':
2008 return CallingConv::Clrcall;
2009 case 'O':
2010 case 'P':
2011 return CallingConv::Eabi;
2012 case 'Q':
2013 return CallingConv::Vectorcall;
2014 }
2015
2016 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00002017}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002018
Zachary Turner316109b2018-07-29 16:38:02 +00002019StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002020 assert(std::isdigit(MangledName.front()));
2021
2022 switch (MangledName.popFront()) {
2023 case '0':
2024 return StorageClass::PrivateStatic;
2025 case '1':
2026 return StorageClass::ProtectedStatic;
2027 case '2':
2028 return StorageClass::PublicStatic;
2029 case '3':
2030 return StorageClass::Global;
2031 case '4':
2032 return StorageClass::FunctionLocalStatic;
2033 }
2034 Error = true;
2035 return StorageClass::None;
2036}
2037
Zachary Turner316109b2018-07-29 16:38:02 +00002038std::pair<Qualifiers, bool>
2039Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002040
2041 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002042 // Member qualifiers
2043 case 'Q':
2044 return std::make_pair(Q_None, true);
2045 case 'R':
2046 return std::make_pair(Q_Const, true);
2047 case 'S':
2048 return std::make_pair(Q_Volatile, true);
2049 case 'T':
2050 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
2051 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002052 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00002053 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002054 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00002055 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002056 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00002057 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002058 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00002059 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002060 }
2061 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00002062 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002063}
2064
Zachary Turner931e8792018-07-30 23:02:10 +00002065static bool isTagType(StringView S) {
2066 switch (S.front()) {
2067 case 'T': // union
2068 case 'U': // struct
2069 case 'V': // class
2070 case 'W': // enum
2071 return true;
2072 }
2073 return false;
2074}
2075
2076static bool isPointerType(StringView S) {
2077 if (S.startsWith("$$Q")) // foo &&
2078 return true;
2079
2080 switch (S.front()) {
2081 case 'A': // foo &
2082 case 'P': // foo *
2083 case 'Q': // foo *const
2084 case 'R': // foo *volatile
2085 case 'S': // foo *const volatile
2086 return true;
2087 }
2088 return false;
2089}
2090
2091static bool isArrayType(StringView S) { return S[0] == 'Y'; }
2092
2093static bool isFunctionType(StringView S) {
2094 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
2095}
2096
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002097// <variable-type> ::= <type> <cvr-qualifiers>
2098// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00002099Type *Demangler::demangleType(StringView &MangledName,
2100 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002101 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00002102 bool IsMember = false;
2103 bool IsMemberKnown = false;
2104 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00002105 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002106 IsMemberKnown = true;
2107 } else if (QMM == QualifierMangleMode::Result) {
2108 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00002109 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002110 IsMemberKnown = true;
2111 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002112 }
2113
2114 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00002115 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002116 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002117 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002118 if (!IsMemberKnown)
2119 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002120
Zachary Turnerd742d642018-07-26 19:56:09 +00002121 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00002122 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002123 else
Zachary Turner316109b2018-07-29 16:38:02 +00002124 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002125 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002126 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002127 else if (isFunctionType(MangledName)) {
2128 if (MangledName.consumeFront("$$A8@@"))
2129 Ty = demangleFunctionType(MangledName, true, false);
2130 else {
2131 assert(MangledName.startsWith("$$A6"));
2132 MangledName.consumeFront("$$A6");
2133 Ty = demangleFunctionType(MangledName, false, false);
2134 }
2135 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00002136 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002137 assert(Ty && !Error);
2138 if (!Ty || Error)
2139 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002140 }
Zachary Turner931e8792018-07-30 23:02:10 +00002141
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002142 Ty->Quals = Qualifiers(Ty->Quals | Quals);
2143 return Ty;
2144}
2145
Zachary Turner316109b2018-07-29 16:38:02 +00002146ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002147 if (MangledName.consumeFront('G'))
2148 return ReferenceKind::LValueRef;
2149 else if (MangledName.consumeFront('H'))
2150 return ReferenceKind::RValueRef;
2151 return ReferenceKind::None;
2152}
2153
Zachary Turner316109b2018-07-29 16:38:02 +00002154void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002155 if (MangledName.consumeFront('Z'))
2156 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002157
Zachary Turner38b78a72018-07-26 20:20:10 +00002158 Error = true;
2159}
2160
Zachary Turner316109b2018-07-29 16:38:02 +00002161FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
2162 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00002163 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002164 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002165 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00002166 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00002167
2168 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00002169 FTy->Quals = demanglePointerExtQualifiers(MangledName);
2170 FTy->RefKind = demangleReferenceKind(MangledName);
2171 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002172 }
2173
2174 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00002175 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002176
2177 // <return-type> ::= <type>
2178 // ::= @ # structors (they have no declared return type)
2179 bool IsStructor = MangledName.consumeFront('@');
2180 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00002181 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002182
Zachary Turner316109b2018-07-29 16:38:02 +00002183 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002184
Zachary Turner316109b2018-07-29 16:38:02 +00002185 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002186
2187 return FTy;
2188}
2189
Zachary Turner316109b2018-07-29 16:38:02 +00002190Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
2191 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner29ec67b2018-08-10 21:09:05 +00002192 FunctionType *FTy = nullptr;
2193 if (FC & NoPrototype) {
2194 // This is an extern "C" function whose full signature hasn't been mangled.
2195 // This happens when we need to mangle a local symbol inside of an extern
2196 // "C" function.
2197 FTy = Arena.alloc<FunctionType>();
2198 } else {
2199 bool HasThisQuals = !(FC & (Global | Static));
2200 FTy = demangleFunctionType(MangledName, HasThisQuals, false);
2201 }
Zachary Turner38b78a72018-07-26 20:20:10 +00002202 FTy->FunctionClass = FC;
2203
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002204 return FTy;
2205}
2206
2207// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00002208Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002209 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002210
Zachary Turner931e8792018-07-30 23:02:10 +00002211 if (MangledName.consumeFront("$$T")) {
2212 Ty->Prim = PrimTy::Nullptr;
2213 return Ty;
2214 }
2215
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002216 switch (MangledName.popFront()) {
2217 case 'X':
2218 Ty->Prim = PrimTy::Void;
2219 break;
2220 case 'D':
2221 Ty->Prim = PrimTy::Char;
2222 break;
2223 case 'C':
2224 Ty->Prim = PrimTy::Schar;
2225 break;
2226 case 'E':
2227 Ty->Prim = PrimTy::Uchar;
2228 break;
2229 case 'F':
2230 Ty->Prim = PrimTy::Short;
2231 break;
2232 case 'G':
2233 Ty->Prim = PrimTy::Ushort;
2234 break;
2235 case 'H':
2236 Ty->Prim = PrimTy::Int;
2237 break;
2238 case 'I':
2239 Ty->Prim = PrimTy::Uint;
2240 break;
2241 case 'J':
2242 Ty->Prim = PrimTy::Long;
2243 break;
2244 case 'K':
2245 Ty->Prim = PrimTy::Ulong;
2246 break;
2247 case 'M':
2248 Ty->Prim = PrimTy::Float;
2249 break;
2250 case 'N':
2251 Ty->Prim = PrimTy::Double;
2252 break;
2253 case 'O':
2254 Ty->Prim = PrimTy::Ldouble;
2255 break;
2256 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00002257 if (MangledName.empty()) {
2258 Error = true;
2259 return nullptr;
2260 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002261 switch (MangledName.popFront()) {
2262 case 'N':
2263 Ty->Prim = PrimTy::Bool;
2264 break;
2265 case 'J':
2266 Ty->Prim = PrimTy::Int64;
2267 break;
2268 case 'K':
2269 Ty->Prim = PrimTy::Uint64;
2270 break;
2271 case 'W':
2272 Ty->Prim = PrimTy::Wchar;
2273 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002274 case 'S':
2275 Ty->Prim = PrimTy::Char16;
2276 break;
2277 case 'U':
2278 Ty->Prim = PrimTy::Char32;
2279 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00002280 default:
Zachary Turner931e8792018-07-30 23:02:10 +00002281 Error = true;
2282 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002283 }
2284 break;
2285 }
Zachary Turner931e8792018-07-30 23:02:10 +00002286 default:
2287 Error = true;
2288 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002289 }
2290 return Ty;
2291}
2292
Zachary Turner316109b2018-07-29 16:38:02 +00002293UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002294 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002295
2296 switch (MangledName.popFront()) {
2297 case 'T':
2298 UTy->Prim = PrimTy::Union;
2299 break;
2300 case 'U':
2301 UTy->Prim = PrimTy::Struct;
2302 break;
2303 case 'V':
2304 UTy->Prim = PrimTy::Class;
2305 break;
2306 case 'W':
2307 if (MangledName.popFront() != '4') {
2308 Error = true;
2309 return nullptr;
2310 }
2311 UTy->Prim = PrimTy::Enum;
2312 break;
2313 default:
2314 assert(false);
2315 }
2316
Zachary Turner316109b2018-07-29 16:38:02 +00002317 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002318 return UTy;
2319}
2320
Zachary Turnerd742d642018-07-26 19:56:09 +00002321static std::pair<Qualifiers, PointerAffinity>
2322demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00002323 if (MangledName.consumeFront("$$Q"))
2324 return std::make_pair(Q_None, PointerAffinity::RValueReference);
2325
Zachary Turnerd742d642018-07-26 19:56:09 +00002326 switch (MangledName.popFront()) {
2327 case 'A':
2328 return std::make_pair(Q_None, PointerAffinity::Reference);
2329 case 'P':
2330 return std::make_pair(Q_None, PointerAffinity::Pointer);
2331 case 'Q':
2332 return std::make_pair(Q_Const, PointerAffinity::Pointer);
2333 case 'R':
2334 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
2335 case 'S':
2336 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
2337 PointerAffinity::Pointer);
2338 default:
2339 assert(false && "Ty is not a pointer type!");
2340 }
2341 return std::make_pair(Q_None, PointerAffinity::Pointer);
2342}
2343
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002344// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
2345// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00002346PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002347 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002348
Zachary Turner931e8792018-07-30 23:02:10 +00002349 std::tie(Pointer->Quals, Pointer->Affinity) =
2350 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002351
Zachary Turner931e8792018-07-30 23:02:10 +00002352 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002353 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002354 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002355 return Pointer;
2356 }
2357
Zachary Turner316109b2018-07-29 16:38:02 +00002358 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002359 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2360
Zachary Turner316109b2018-07-29 16:38:02 +00002361 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002362 return Pointer;
2363}
2364
Zachary Turner316109b2018-07-29 16:38:02 +00002365MemberPointerType *
2366Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002367 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
2368 Pointer->Prim = PrimTy::MemberPtr;
2369
2370 PointerAffinity Affinity;
2371 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
2372 assert(Affinity == PointerAffinity::Pointer);
2373
Zachary Turner316109b2018-07-29 16:38:02 +00002374 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002375 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2376
Zachary Turner38b78a72018-07-26 20:20:10 +00002377 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002378 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
2379 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002380 } else {
2381 Qualifiers PointeeQuals = Q_None;
2382 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00002383 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002384 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00002385 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002386
Zachary Turner316109b2018-07-29 16:38:02 +00002387 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00002388 Pointer->Pointee->Quals = PointeeQuals;
2389 }
2390
Zachary Turnerd742d642018-07-26 19:56:09 +00002391 return Pointer;
2392}
2393
Zachary Turner316109b2018-07-29 16:38:02 +00002394Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002395 Qualifiers Quals = Q_None;
2396 if (MangledName.consumeFront('E'))
2397 Quals = Qualifiers(Quals | Q_Pointer64);
2398 if (MangledName.consumeFront('I'))
2399 Quals = Qualifiers(Quals | Q_Restrict);
2400 if (MangledName.consumeFront('F'))
2401 Quals = Qualifiers(Quals | Q_Unaligned);
2402
2403 return Quals;
2404}
2405
Zachary Turner316109b2018-07-29 16:38:02 +00002406ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002407 assert(MangledName.front() == 'Y');
2408 MangledName.popFront();
2409
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002410 uint64_t Rank = 0;
2411 bool IsNegative = false;
2412 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2413 if (IsNegative || Rank == 0) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002414 Error = true;
2415 return nullptr;
2416 }
2417
Zachary Turner9d72aa92018-07-20 18:35:06 +00002418 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002419 ATy->Prim = PrimTy::Array;
2420 ATy->Dims = Arena.alloc<ArrayDimension>();
2421 ArrayDimension *Dim = ATy->Dims;
2422 for (uint64_t I = 0; I < Rank; ++I) {
2423 std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
2424 if (IsNegative) {
2425 Error = true;
2426 return nullptr;
2427 }
2428 if (I + 1 < Rank) {
2429 Dim->Next = Arena.alloc<ArrayDimension>();
2430 Dim = Dim->Next;
2431 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002432 }
2433
2434 if (MangledName.consumeFront("$$C")) {
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002435 bool IsMember = false;
2436 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2437 if (IsMember) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002438 Error = true;
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002439 return nullptr;
2440 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002441 }
2442
Zachary Turner316109b2018-07-29 16:38:02 +00002443 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002444 return ATy;
2445}
2446
2447// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002448FunctionParams
2449Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002450 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00002451 if (MangledName.consumeFront('X'))
2452 return {};
2453
Zachary Turnerd30700f2018-07-31 17:16:44 +00002454 FunctionParams *Head;
2455 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002456 while (!Error && !MangledName.startsWith('@') &&
2457 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002458
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002459 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00002460 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002461 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002462 Error = true;
2463 return {};
2464 }
2465 MangledName = MangledName.dropFront();
2466
Zachary Turnerd30700f2018-07-31 17:16:44 +00002467 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00002468 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002469 Current = &(*Current)->Next;
2470 continue;
2471 }
2472
Zachary Turner23df1312018-07-26 22:13:39 +00002473 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002474
Zachary Turnerd30700f2018-07-31 17:16:44 +00002475 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00002476 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002477
Zachary Turner23df1312018-07-26 22:13:39 +00002478 size_t CharsConsumed = OldSize - MangledName.size();
2479 assert(CharsConsumed != 0);
2480
2481 // Single-letter types are ignored for backreferences because memorizing
2482 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002483 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2484 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2485 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002486
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002487 Current = &(*Current)->Next;
2488 }
2489
Zachary Turner38b78a72018-07-26 20:20:10 +00002490 if (Error)
2491 return {};
2492
2493 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2494 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2495 // the following Z could be a throw specifier.
2496 if (MangledName.consumeFront('@'))
2497 return *Head;
2498
2499 if (MangledName.consumeFront('Z')) {
2500 Head->IsVariadic = true;
2501 return *Head;
2502 }
2503
2504 Error = true;
2505 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002506}
2507
Zachary Turnerd30700f2018-07-31 17:16:44 +00002508TemplateParams *
2509Demangler::demangleTemplateParameterList(StringView &MangledName) {
2510 TemplateParams *Head;
2511 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002512 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002513 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002514 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002515
2516 // Empty parameter pack.
2517 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2518 MangledName.consumeFront("$$$V")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002519 (*Current)->IsEmptyParameterPack = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002520 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002521 }
2522
Zachary Turnerd30700f2018-07-31 17:16:44 +00002523 if (MangledName.consumeFront("$$Y")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002524 // Template alias
Zachary Turnerd30700f2018-07-31 17:16:44 +00002525 (*Current)->IsTemplateTemplate = true;
2526 (*Current)->IsAliasTemplate = true;
2527 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002528 } else if (MangledName.consumeFront("$$B")) {
2529 // Array
2530 (*Current)->ParamType =
2531 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner073620b2018-08-10 19:57:36 +00002532 } else if (MangledName.consumeFront("$$C")) {
2533 // Type has qualifiers.
2534 (*Current)->ParamType =
2535 demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002536 } else if (MangledName.startsWith("$1?")) {
2537 MangledName.consumeFront("$1");
2538 // Pointer to symbol
2539 Symbol *S = parse(MangledName);
2540 (*Current)->ParamName = S->SymbolName;
2541 (*Current)->ParamType = S->SymbolType;
2542 (*Current)->PointerToSymbol = true;
2543 } else if (MangledName.startsWith("$E?")) {
2544 MangledName.consumeFront("$E");
2545 // Reference to symbol
2546 Symbol *S = parse(MangledName);
2547 (*Current)->ParamName = S->SymbolName;
2548 (*Current)->ParamType = S->SymbolType;
2549 (*Current)->ReferenceToSymbol = true;
2550 } else if (MangledName.consumeFront("$0")) {
2551 // Integral non-type template parameter
2552 bool IsNegative = false;
2553 uint64_t Value = 0;
2554 std::tie(Value, IsNegative) = demangleNumber(MangledName);
2555
2556 (*Current)->IsIntegerLiteral = true;
2557 (*Current)->IntegerLiteralIsNegative = IsNegative;
2558 (*Current)->IntegralValue = Value;
Zachary Turnerd30700f2018-07-31 17:16:44 +00002559 } else {
2560 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002561 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002562 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002563 if (Error)
2564 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002565
2566 Current = &(*Current)->Next;
2567 }
2568
2569 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002570 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002571
2572 // Template parameter lists cannot be variadic, so it can only be terminated
2573 // by @.
2574 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002575 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002576 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002577 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002578}
2579
Zachary Turner172aea12018-08-02 17:08:03 +00002580StringView Demangler::resolve(StringView N) {
2581 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002582 size_t Digit = N[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002583 if (Digit >= Backrefs.NamesCount)
Zachary Turner172aea12018-08-02 17:08:03 +00002584 return N;
Zachary Turnerd346cba2018-08-08 17:17:04 +00002585 return Backrefs.Names[Digit];
Zachary Turner172aea12018-08-02 17:08:03 +00002586}
2587
Zachary Turner316109b2018-07-29 16:38:02 +00002588void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turner83313f82018-08-16 16:17:17 +00002589 if (S->Category == SymbolCategory::Unknown) {
2590 outputName(OS, S->SymbolName, S->SymbolType, *this);
2591 return;
2592 }
Zachary Turner970fdc32018-08-16 16:17:36 +00002593 if (S->Category == SymbolCategory::StringLiteral) {
2594 outputStringLiteral(OS, *S->SymbolName);
2595 return;
2596 }
2597
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002598 // Converts an AST to a string.
2599 //
2600 // Converting an AST representing a C++ type to a string is tricky due
2601 // to the bad grammar of the C++ declaration inherited from C. You have
2602 // to construct a string from inside to outside. For example, if a type
2603 // X is a pointer to a function returning int, the order you create a
2604 // string becomes something like this:
2605 //
2606 // (1) X is a pointer: *X
2607 // (2) (1) is a function returning int: int (*X)()
2608 //
2609 // So you cannot construct a result just by appending strings to a result.
2610 //
2611 // To deal with this, we split the function into two. outputPre() writes
2612 // the "first half" of type declaration, and outputPost() writes the
2613 // "second half". For example, outputPre() writes a return type for a
2614 // function and outputPost() writes an parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +00002615 Type::outputPre(OS, *S->SymbolType, *this);
Zachary Turnera17721c2018-08-10 15:04:56 +00002616 outputName(OS, S->SymbolName, S->SymbolType, *this);
Zachary Turner172aea12018-08-02 17:08:03 +00002617 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002618}
2619
Zachary Turner3a758e22018-08-01 18:33:04 +00002620void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002621 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00002622 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002623
2624 // Create an output stream so we can render each type.
2625 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00002626 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00002627 OS.setCurrentPosition(0);
2628
Zachary Turnerd346cba2018-08-08 17:17:04 +00002629 Type *T = Backrefs.FunctionParams[I];
Zachary Turner172aea12018-08-02 17:08:03 +00002630 Type::outputPre(OS, *T, *this);
2631 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00002632
Zachary Turner7563ebe2018-08-02 17:08:24 +00002633 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00002634 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002635 }
2636 std::free(OS.getBuffer());
2637
Zachary Turnerd346cba2018-08-08 17:17:04 +00002638 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002639 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00002640 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
2641 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
2642 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
2643 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002644 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00002645 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002646 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002647}
2648
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002649char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002650 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002651 Demangler D;
2652 StringView Name{MangledName};
2653 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002654
Zachary Turner3a758e22018-08-01 18:33:04 +00002655 if (Flags & MSDF_DumpBackrefs)
2656 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002657 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002658 if (D.Error) {
2659 OS << MangledName;
2660 *Status = llvm::demangle_invalid_mangled_name;
2661 } else {
2662 D.output(S, OS);
2663 *Status = llvm::demangle_success;
2664 }
2665
Zachary Turner71c91f92018-07-30 03:12:34 +00002666 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002667 return OS.getBuffer();
2668}