blob: 3eac87d610112405a5406aebc98532029f4ca929 [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 Turnerd742d642018-07-26 19:56:09 +000024#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000025
26// This memory allocator is extremely fast, but it doesn't call dtors
27// for allocated objects. That means you can't use STL containers
28// (such as std::vector) with this allocator. But it pays off --
29// the demangler is 3x faster with this allocator compared to one with
30// STL containers.
31namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000032 constexpr size_t AllocUnit = 4096;
33
Zachary Turnerf435a7e2018-07-20 17:27:48 +000034class ArenaAllocator {
35 struct AllocatorNode {
36 uint8_t *Buf = nullptr;
37 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000038 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000039 AllocatorNode *Next = nullptr;
40 };
41
Zachary Turner71c91f92018-07-30 03:12:34 +000042 void addNode(size_t Capacity) {
43 AllocatorNode *NewHead = new AllocatorNode;
44 NewHead->Buf = new uint8_t[Capacity];
45 NewHead->Next = Head;
46 NewHead->Capacity = Capacity;
47 Head = NewHead;
48 NewHead->Used = 0;
49 }
50
Zachary Turnerf435a7e2018-07-20 17:27:48 +000051public:
Zachary Turnera6869512018-07-30 03:25:27 +000052 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000053
54 ~ArenaAllocator() {
55 while (Head) {
56 assert(Head->Buf);
57 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000058 AllocatorNode *Next = Head->Next;
59 delete Head;
60 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000061 }
62 }
63
Zachary Turner71c91f92018-07-30 03:12:34 +000064 char *allocUnalignedBuffer(size_t Length) {
65 uint8_t *Buf = Head->Buf + Head->Used;
66
67 Head->Used += Length;
68 if (Head->Used > Head->Capacity) {
69 // It's possible we need a buffer which is larger than our default unit
70 // size, so we need to be careful to add a node with capacity that is at
71 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000072 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000073 Head->Used = Length;
74 Buf = Head->Buf;
75 }
76
77 return reinterpret_cast<char *>(Buf);
78 }
79
Zachary Turner9d72aa92018-07-20 18:35:06 +000080 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
81
82 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000083 assert(Head && Head->Buf);
84
Zachary Turner9d72aa92018-07-20 18:35:06 +000085 size_t P = (size_t)Head->Buf + Head->Used;
86 uintptr_t AlignedP =
87 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
88 uint8_t *PP = (uint8_t *)AlignedP;
89 size_t Adjustment = AlignedP - P;
90
91 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000092 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000093 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000094
Zachary Turnera6869512018-07-30 03:25:27 +000095 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000096 Head->Used = Size;
97 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000098 }
99
100private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000101 AllocatorNode *Head = nullptr;
102};
103} // namespace
104
105static bool startsWithDigit(StringView S) {
106 return !S.empty() && std::isdigit(S.front());
107}
108
109// Writes a space if the last token does not end with a punctuation.
110static void outputSpaceIfNecessary(OutputStream &OS) {
111 if (OS.empty())
112 return;
113
114 char C = OS.back();
115 if (isalnum(C) || C == '>')
116 OS << " ";
117}
118
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000119// Storage classes
120enum Qualifiers : uint8_t {
121 Q_None = 0,
122 Q_Const = 1 << 0,
123 Q_Volatile = 1 << 1,
124 Q_Far = 1 << 2,
125 Q_Huge = 1 << 3,
126 Q_Unaligned = 1 << 4,
127 Q_Restrict = 1 << 5,
128 Q_Pointer64 = 1 << 6
129};
130
131enum class StorageClass : uint8_t {
132 None,
133 PrivateStatic,
134 ProtectedStatic,
135 PublicStatic,
136 Global,
137 FunctionLocalStatic
138};
139
140enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000141
Zachary Turner931e8792018-07-30 23:02:10 +0000142enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000143
144// Calling conventions
145enum class CallingConv : uint8_t {
146 None,
147 Cdecl,
148 Pascal,
149 Thiscall,
150 Stdcall,
151 Fastcall,
152 Clrcall,
153 Eabi,
154 Vectorcall,
155 Regcall,
156};
157
158enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
159
160// Types
161enum class PrimTy : uint8_t {
162 Unknown,
163 None,
164 Function,
165 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000166 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000167 Array,
168
169 Struct,
170 Union,
171 Class,
172 Enum,
173
174 Void,
175 Bool,
176 Char,
177 Schar,
178 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000179 Char16,
180 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000181 Short,
182 Ushort,
183 Int,
184 Uint,
185 Long,
186 Ulong,
187 Int64,
188 Uint64,
189 Wchar,
190 Float,
191 Double,
192 Ldouble,
Zachary Turner931e8792018-07-30 23:02:10 +0000193 Nullptr
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000194};
195
196// Function classes
197enum FuncClass : uint8_t {
198 Public = 1 << 0,
199 Protected = 1 << 1,
200 Private = 1 << 2,
201 Global = 1 << 3,
202 Static = 1 << 4,
203 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000204 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000205};
206
207namespace {
208
209struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000210struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000211
Zachary Turnerd30700f2018-07-31 17:16:44 +0000212struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000213 bool IsVariadic = false;
214
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000215 Type *Current = nullptr;
216
Zachary Turnerd30700f2018-07-31 17:16:44 +0000217 FunctionParams *Next = nullptr;
218};
Zachary Turner931e8792018-07-30 23:02:10 +0000219
Zachary Turnerd30700f2018-07-31 17:16:44 +0000220struct TemplateParams {
221 bool IsTemplateTemplate = false;
222 bool IsAliasTemplate = false;
223
224 // Type can be null if this is a template template parameter. In that case
225 // only Name will be valid.
226 Type *ParamType = nullptr;
227
228 // Name can be valid if this is a template template parameter (see above) or
229 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
230 // Name contains the name of the function and Type contains the signature.
231 Name *ParamName = nullptr;
232
233 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000234};
235
236// The type class. Mangled symbols are first parsed and converted to
237// this type and then converted to string.
238struct Type {
239 virtual ~Type() {}
240
241 virtual Type *clone(ArenaAllocator &Arena) const;
242
243 // Write the "first half" of a given type. This is a static functions to
244 // give the code a chance to do processing that is common to a subset of
245 // subclasses
246 static void outputPre(OutputStream &OS, Type &Ty);
247
248 // Write the "second half" of a given type. This is a static functions to
249 // give the code a chance to do processing that is common to a subset of
250 // subclasses
251 static void outputPost(OutputStream &OS, Type &Ty);
252
253 virtual void outputPre(OutputStream &OS);
254 virtual void outputPost(OutputStream &OS);
255
256 // Primitive type such as Int.
257 PrimTy Prim = PrimTy::Unknown;
258
259 Qualifiers Quals = Q_None;
260 StorageClass Storage = StorageClass::None; // storage class
261};
262
263// Represents an identifier which may be a template.
264struct Name {
265 // Name read from an MangledName string.
266 StringView Str;
267
268 // Overloaded operators are represented as special BackReferences in mangled
269 // symbols. If this is an operator name, "op" has an operator name (e.g.
270 // ">>"). Otherwise, empty.
271 StringView Operator;
272
273 // Template parameters. Null if not a template.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000274 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000275
276 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
277 Name *Next = nullptr;
278};
279
280struct PointerType : public Type {
281 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000282 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000283 void outputPost(OutputStream &OS) override;
284
Zachary Turner931e8792018-07-30 23:02:10 +0000285 PointerAffinity Affinity;
286
Zachary Turnerd742d642018-07-26 19:56:09 +0000287 // Represents a type X in "a pointer to X", "a reference to X",
288 // "an array of X", or "a function returning X".
289 Type *Pointee = nullptr;
290};
291
292struct MemberPointerType : public Type {
293 Type *clone(ArenaAllocator &Arena) const override;
294 void outputPre(OutputStream &OS) override;
295 void outputPost(OutputStream &OS) override;
296
297 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000298
299 // Represents a type X in "a pointer to X", "a reference to X",
300 // "an array of X", or "a function returning X".
301 Type *Pointee = nullptr;
302};
303
304struct FunctionType : public Type {
305 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000306 void outputPre(OutputStream &OS) override;
307 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000308
Zachary Turner024e1762018-07-26 20:33:48 +0000309 // True if this FunctionType instance is the Pointee of a PointerType or
310 // MemberPointerType.
311 bool IsFunctionPointer = false;
312
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000313 Type *ReturnType = nullptr;
314 // If this is a reference, the type of reference.
315 ReferenceKind RefKind;
316
317 CallingConv CallConvention;
318 FuncClass FunctionClass;
319
Zachary Turnerd30700f2018-07-31 17:16:44 +0000320 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000321};
322
323struct UdtType : public Type {
324 Type *clone(ArenaAllocator &Arena) const override;
325 void outputPre(OutputStream &OS) override;
326
327 Name *UdtName = nullptr;
328};
329
330struct ArrayType : public Type {
331 Type *clone(ArenaAllocator &Arena) const override;
332 void outputPre(OutputStream &OS) override;
333 void outputPost(OutputStream &OS) override;
334
335 // Either NextDimension or ElementType will be valid.
336 ArrayType *NextDimension = nullptr;
337 uint32_t ArrayDimension = 0;
338
339 Type *ElementType = nullptr;
340};
341
342} // namespace
343
Zachary Turnerd742d642018-07-26 19:56:09 +0000344static bool isMemberPointer(StringView MangledName) {
345 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000346 case '$':
347 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
348 // rvalue reference to a member.
349 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000350 case 'A':
351 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000352 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000353 return false;
354 case 'P':
355 case 'Q':
356 case 'R':
357 case 'S':
358 // These 4 values indicate some kind of pointer, but we still don't know
359 // what.
360 break;
361 default:
362 assert(false && "Ty is not a pointer type!");
363 }
364
365 // If it starts with a number, then 6 indicates a non-member function
366 // pointer, and 8 indicates a member function pointer.
367 if (startsWithDigit(MangledName)) {
368 assert(MangledName[0] == '6' || MangledName[0] == '8');
369 return (MangledName[0] == '8');
370 }
371
372 // Remove ext qualifiers since those can appear on either type and are
373 // therefore not indicative.
374 MangledName.consumeFront('E'); // 64-bit
375 MangledName.consumeFront('I'); // restrict
376 MangledName.consumeFront('F'); // unaligned
377
378 assert(!MangledName.empty());
379
380 // The next value should be either ABCD (non-member) or QRST (member).
381 switch (MangledName.front()) {
382 case 'A':
383 case 'B':
384 case 'C':
385 case 'D':
386 return false;
387 case 'Q':
388 case 'R':
389 case 'S':
390 case 'T':
391 return true;
392 default:
393 assert(false);
394 }
395 return false;
396}
397
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000398static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
399 outputSpaceIfNecessary(OS);
400
401 switch (CC) {
402 case CallingConv::Cdecl:
403 OS << "__cdecl";
404 break;
405 case CallingConv::Fastcall:
406 OS << "__fastcall";
407 break;
408 case CallingConv::Pascal:
409 OS << "__pascal";
410 break;
411 case CallingConv::Regcall:
412 OS << "__regcall";
413 break;
414 case CallingConv::Stdcall:
415 OS << "__stdcall";
416 break;
417 case CallingConv::Thiscall:
418 OS << "__thiscall";
419 break;
420 case CallingConv::Eabi:
421 OS << "__eabi";
422 break;
423 case CallingConv::Vectorcall:
424 OS << "__vectorcall";
425 break;
426 case CallingConv::Clrcall:
427 OS << "__clrcall";
428 break;
429 default:
430 break;
431 }
432}
433
Zachary Turner71c91f92018-07-30 03:12:34 +0000434static bool startsWithLocalScopePattern(StringView S) {
435 if (!S.consumeFront('?'))
436 return false;
437 if (S.size() < 2)
438 return false;
439
440 size_t End = S.find('?');
441 if (End == StringView::npos)
442 return false;
443 StringView Candidate = S.substr(0, End);
444 if (Candidate.empty())
445 return false;
446
447 // \?[0-9]\?
448 // ?@? is the discriminator 0.
449 if (Candidate.size() == 1)
450 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
451
452 // If it's not 0-9, then it's an encoded number terminated with an @
453 if (Candidate.back() != '@')
454 return false;
455 Candidate = Candidate.dropBack();
456
457 // An encoded number starts with B-P and all subsequent digits are in A-P.
458 // Note that the reason the first digit cannot be A is two fold. First, it
459 // would create an ambiguity with ?A which delimits the beginning of an
460 // anonymous namespace. Second, A represents 0, and you don't start a multi
461 // digit number with a leading 0. Presumably the anonymous namespace
462 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
463 if (Candidate[0] < 'B' || Candidate[0] > 'P')
464 return false;
465 Candidate = Candidate.dropFront();
466 while (!Candidate.empty()) {
467 if (Candidate[0] < 'A' || Candidate[0] > 'P')
468 return false;
469 Candidate = Candidate.dropFront();
470 }
471
472 return true;
473}
474
Zachary Turner931e8792018-07-30 23:02:10 +0000475static void outputName(OutputStream &OS, const Name *TheName);
476
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000477// Write a function or template parameter list.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000478static void outputParameterList(OutputStream &OS,
479 const FunctionParams &Params) {
480 if (!Params.Current) {
481 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000482 return;
483 }
484
Zachary Turnerd30700f2018-07-31 17:16:44 +0000485 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000486 while (Head) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000487 Type::outputPre(OS, *Head->Current);
488 Type::outputPost(OS, *Head->Current);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000489
490 Head = Head->Next;
491
492 if (Head)
493 OS << ", ";
494 }
495}
496
Zachary Turnerd30700f2018-07-31 17:16:44 +0000497static void outputParameterList(OutputStream &OS,
498 const TemplateParams &Params) {
499 if (!Params.ParamType && !Params.ParamName) {
500 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000501 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000502 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000503
504 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000505 const TemplateParams *Head = &Params;
506 while (Head) {
507 // Type can be null if this is a template template parameter,
508 // and Name can be null if this is a simple type.
509
510 if (Head->ParamType && Head->ParamName) {
511 // Function pointer.
512 OS << "&";
513 Type::outputPre(OS, *Head->ParamType);
514 outputName(OS, Head->ParamName);
515 Type::outputPost(OS, *Head->ParamType);
516 } else if (Head->ParamType) {
517 // simple type.
518 Type::outputPre(OS, *Head->ParamType);
519 Type::outputPost(OS, *Head->ParamType);
520 } else {
521 // Template alias.
522 outputName(OS, Head->ParamName);
523 }
524
525 Head = Head->Next;
526
527 if (Head)
528 OS << ", ";
529 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000530 OS << ">";
531}
532
533static void outputName(OutputStream &OS, const Name *TheName) {
534 if (!TheName)
535 return;
536
537 outputSpaceIfNecessary(OS);
538
Zachary Turnera7dffb12018-07-28 22:10:42 +0000539 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000540 // Print out namespaces or outer class BackReferences.
541 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000542 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000543 OS << TheName->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000544 if (TheName->TParams)
545 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000546 OS << "::";
547 }
548
549 // Print out a regular name.
550 if (TheName->Operator.empty()) {
551 OS << TheName->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000552 if (TheName->TParams)
553 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000554 return;
555 }
556
557 // Print out ctor or dtor.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000558 if (TheName->Operator == "dtor")
559 OS << "~";
560
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000562 OS << Previous->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000563 if (Previous->TParams)
564 outputParameterList(OS, *Previous->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000565 return;
566 }
567
568 // Print out an overloaded operator.
569 if (!TheName->Str.empty())
570 OS << TheName->Str << "::";
571 OS << "operator" << TheName->Operator;
572}
573
574namespace {
575
576Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000577 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000578}
579
580// Write the "first half" of a given type.
581void Type::outputPre(OutputStream &OS, Type &Ty) {
582 // Function types require custom handling of const and static so we
583 // handle them separately. All other types use the same decoration
584 // for these modifiers, so handle them here in common code.
585 if (Ty.Prim == PrimTy::Function) {
586 Ty.outputPre(OS);
587 return;
588 }
589
590 switch (Ty.Storage) {
591 case StorageClass::PrivateStatic:
592 case StorageClass::PublicStatic:
593 case StorageClass::ProtectedStatic:
594 OS << "static ";
595 default:
596 break;
597 }
598 Ty.outputPre(OS);
599
600 if (Ty.Quals & Q_Const) {
601 outputSpaceIfNecessary(OS);
602 OS << "const";
603 }
604
605 if (Ty.Quals & Q_Volatile) {
606 outputSpaceIfNecessary(OS);
607 OS << "volatile";
608 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000609
610 if (Ty.Quals & Q_Restrict) {
611 outputSpaceIfNecessary(OS);
612 OS << "__restrict";
613 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000614}
615
616// Write the "second half" of a given type.
617void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
618
619void Type::outputPre(OutputStream &OS) {
620 switch (Prim) {
621 case PrimTy::Void:
622 OS << "void";
623 break;
624 case PrimTy::Bool:
625 OS << "bool";
626 break;
627 case PrimTy::Char:
628 OS << "char";
629 break;
630 case PrimTy::Schar:
631 OS << "signed char";
632 break;
633 case PrimTy::Uchar:
634 OS << "unsigned char";
635 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000636 case PrimTy::Char16:
637 OS << "char16_t";
638 break;
639 case PrimTy::Char32:
640 OS << "char32_t";
641 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000642 case PrimTy::Short:
643 OS << "short";
644 break;
645 case PrimTy::Ushort:
646 OS << "unsigned short";
647 break;
648 case PrimTy::Int:
649 OS << "int";
650 break;
651 case PrimTy::Uint:
652 OS << "unsigned int";
653 break;
654 case PrimTy::Long:
655 OS << "long";
656 break;
657 case PrimTy::Ulong:
658 OS << "unsigned long";
659 break;
660 case PrimTy::Int64:
661 OS << "__int64";
662 break;
663 case PrimTy::Uint64:
664 OS << "unsigned __int64";
665 break;
666 case PrimTy::Wchar:
667 OS << "wchar_t";
668 break;
669 case PrimTy::Float:
670 OS << "float";
671 break;
672 case PrimTy::Double:
673 OS << "double";
674 break;
675 case PrimTy::Ldouble:
676 OS << "long double";
677 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000678 case PrimTy::Nullptr:
679 OS << "std::nullptr_t";
680 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000681 default:
682 assert(false && "Invalid primitive type!");
683 }
684}
685void Type::outputPost(OutputStream &OS) {}
686
687Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000688 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000689}
690
Zachary Turner024e1762018-07-26 20:33:48 +0000691static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
692 const Name *MemberName,
693 const Type *Pointee) {
694 // "[]" and "()" (for function parameters) take precedence over "*",
695 // so "int *x(int)" means "x is a function returning int *". We need
696 // parentheses to supercede the default precedence. (e.g. we want to
697 // emit something like "int (*x)(int)".)
698 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
699 OS << "(";
700 if (Pointee->Prim == PrimTy::Function) {
701 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
702 assert(FTy->IsFunctionPointer);
703 outputCallingConvention(OS, FTy->CallConvention);
704 OS << " ";
705 }
706 }
707
708 if (MemberName) {
709 outputName(OS, MemberName);
710 OS << "::";
711 }
712
713 if (Affinity == PointerAffinity::Pointer)
714 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000715 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000716 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000717 else
718 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000719}
720
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000721void PointerType::outputPre(OutputStream &OS) {
722 Type::outputPre(OS, *Pointee);
723
724 outputSpaceIfNecessary(OS);
725
726 if (Quals & Q_Unaligned)
727 OS << "__unaligned ";
728
Zachary Turner024e1762018-07-26 20:33:48 +0000729 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000730
Zachary Turner91ecedd2018-07-20 18:07:33 +0000731 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000732 // if (Ty.Quals & Q_Pointer64)
733 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000734}
735
736void PointerType::outputPost(OutputStream &OS) {
737 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
738 OS << ")";
739
740 Type::outputPost(OS, *Pointee);
741}
742
Zachary Turnerd742d642018-07-26 19:56:09 +0000743Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
744 return Arena.alloc<MemberPointerType>(*this);
745}
746
747void MemberPointerType::outputPre(OutputStream &OS) {
748 Type::outputPre(OS, *Pointee);
749
750 outputSpaceIfNecessary(OS);
751
Zachary Turner024e1762018-07-26 20:33:48 +0000752 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000753
754 // FIXME: We should output this, but it requires updating lots of tests.
755 // if (Ty.Quals & Q_Pointer64)
756 // OS << " __ptr64";
757 if (Quals & Q_Restrict)
758 OS << " __restrict";
759}
760
761void MemberPointerType::outputPost(OutputStream &OS) {
762 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
763 OS << ")";
764
765 Type::outputPost(OS, *Pointee);
766}
767
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000768Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000769 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000770}
771
772void FunctionType::outputPre(OutputStream &OS) {
773 if (!(FunctionClass & Global)) {
774 if (FunctionClass & Static)
775 OS << "static ";
776 }
777
Zachary Turner38b78a72018-07-26 20:20:10 +0000778 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000779 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000780 OS << " ";
781 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000782
Zachary Turner024e1762018-07-26 20:33:48 +0000783 // Function pointers print the calling convention as void (__cdecl *)(params)
784 // rather than void __cdecl (*)(params). So we need to let the PointerType
785 // class handle this.
786 if (!IsFunctionPointer)
787 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000788}
789
790void FunctionType::outputPost(OutputStream &OS) {
791 OS << "(";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000792 outputParameterList(OS, Params);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000793 OS << ")";
794 if (Quals & Q_Const)
795 OS << " const";
796 if (Quals & Q_Volatile)
797 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000798 if (Quals & Q_Restrict)
799 OS << " __restrict";
800 if (Quals & Q_Unaligned)
801 OS << " __unaligned";
802
803 if (RefKind == ReferenceKind::LValueRef)
804 OS << " &";
805 else if (RefKind == ReferenceKind::RValueRef)
806 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000807
808 if (ReturnType)
809 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000810 return;
811}
812
813Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000814 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000815}
816
817void UdtType::outputPre(OutputStream &OS) {
818 switch (Prim) {
819 case PrimTy::Class:
820 OS << "class ";
821 break;
822 case PrimTy::Struct:
823 OS << "struct ";
824 break;
825 case PrimTy::Union:
826 OS << "union ";
827 break;
828 case PrimTy::Enum:
829 OS << "enum ";
830 break;
831 default:
832 assert(false && "Not a udt type!");
833 }
834
835 outputName(OS, UdtName);
836}
837
838Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000839 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000840}
841
842void ArrayType::outputPre(OutputStream &OS) {
843 Type::outputPre(OS, *ElementType);
844}
845
846void ArrayType::outputPost(OutputStream &OS) {
847 if (ArrayDimension > 0)
848 OS << "[" << ArrayDimension << "]";
849 if (NextDimension)
850 Type::outputPost(OS, *NextDimension);
851 else if (ElementType)
852 Type::outputPost(OS, *ElementType);
853}
854
Zachary Turner316109b2018-07-29 16:38:02 +0000855struct Symbol {
856 Name *SymbolName = nullptr;
857 Type *SymbolType = nullptr;
858};
859
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000860} // namespace
861
862namespace {
863
864// Demangler class takes the main role in demangling symbols.
865// It has a set of functions to parse mangled symbols into Type instances.
866// It also has a set of functions to cnovert Type instances to strings.
867class Demangler {
868public:
Zachary Turner316109b2018-07-29 16:38:02 +0000869 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000870
871 // You are supposed to call parse() first and then check if error is true. If
872 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000873 Symbol *parse(StringView &MangledName);
874 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000875
876 // True if an error occurred.
877 bool Error = false;
878
879private:
Zachary Turner316109b2018-07-29 16:38:02 +0000880 Type *demangleVariableEncoding(StringView &MangledName);
881 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000882
Zachary Turner316109b2018-07-29 16:38:02 +0000883 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000884
885 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000886 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
887 Type *demangleBasicType(StringView &MangledName);
888 UdtType *demangleClassType(StringView &MangledName);
889 PointerType *demanglePointerType(StringView &MangledName);
890 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
891 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
892 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000893
Zachary Turner316109b2018-07-29 16:38:02 +0000894 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000895
Zachary Turnerd30700f2018-07-31 17:16:44 +0000896 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
897 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000898
Zachary Turner316109b2018-07-29 16:38:02 +0000899 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000900
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000901 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000902
903 /// Allocate a copy of \p Borrowed into memory that we own.
904 StringView copyString(StringView Borrowed);
905
Zachary Turner316109b2018-07-29 16:38:02 +0000906 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
907 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000908
Zachary Turner316109b2018-07-29 16:38:02 +0000909 Name *demangleUnqualifiedTypeName(StringView &MangledName);
910 Name *demangleUnqualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000911
Zachary Turner316109b2018-07-29 16:38:02 +0000912 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
913 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000914
Zachary Turner316109b2018-07-29 16:38:02 +0000915 Name *demangleBackRefName(StringView &MangledName);
916 Name *demangleClassTemplateName(StringView &MangledName);
917 Name *demangleOperatorName(StringView &MangledName);
918 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
919 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000920 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000921
Zachary Turner931e8792018-07-30 23:02:10 +0000922 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
923
Zachary Turner316109b2018-07-29 16:38:02 +0000924 FuncClass demangleFunctionClass(StringView &MangledName);
925 CallingConv demangleCallingConvention(StringView &MangledName);
926 StorageClass demangleVariableStorageClass(StringView &MangledName);
927 ReferenceKind demangleReferenceKind(StringView &MangledName);
928 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000929
Zachary Turner316109b2018-07-29 16:38:02 +0000930 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000931
932 // Memory allocator.
933 ArenaAllocator Arena;
934
Zachary Turner23df1312018-07-26 22:13:39 +0000935 // A single type uses one global back-ref table for all function params.
936 // This means back-refs can even go "into" other types. Examples:
937 //
938 // // Second int* is a back-ref to first.
939 // void foo(int *, int*);
940 //
941 // // Second int* is not a back-ref to first (first is not a function param).
942 // int* foo(int*);
943 //
944 // // Second int* is a back-ref to first (ALL function types share the same
945 // // back-ref map.
946 // using F = void(*)(int*);
947 // F G(int *);
948 Type *FunctionParamBackRefs[10];
949 size_t FunctionParamBackRefCount = 0;
950
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000951 // The first 10 BackReferences in a mangled name can be back-referenced by
952 // special name @[0-9]. This is a storage for the first 10 BackReferences.
953 StringView BackReferences[10];
954 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000955};
956} // namespace
957
Zachary Turner71c91f92018-07-30 03:12:34 +0000958StringView Demangler::copyString(StringView Borrowed) {
959 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
960 std::strcpy(Stable, Borrowed.begin());
961
962 return {Stable, Borrowed.size()};
963}
964
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000965// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000966Symbol *Demangler::parse(StringView &MangledName) {
967 Symbol *S = Arena.alloc<Symbol>();
968
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000969 // MSVC-style mangled symbols must start with '?'.
970 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000971 S->SymbolName = Arena.alloc<Name>();
972 S->SymbolName->Str = MangledName;
973 S->SymbolType = Arena.alloc<Type>();
974 S->SymbolType->Prim = PrimTy::Unknown;
975 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000976 }
977
978 // What follows is a main symbol name. This may include
979 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000980 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000981
982 // Read a variable.
Zachary Turner316109b2018-07-29 16:38:02 +0000983 S->SymbolType = startsWithDigit(MangledName)
984 ? demangleVariableEncoding(MangledName)
985 : demangleFunctionEncoding(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000986
Zachary Turner316109b2018-07-29 16:38:02 +0000987 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000988}
989
990// <type-encoding> ::= <storage-class> <variable-type>
991// <storage-class> ::= 0 # private static member
992// ::= 1 # protected static member
993// ::= 2 # public static member
994// ::= 3 # global
995// ::= 4 # static local
996
Zachary Turner316109b2018-07-29 16:38:02 +0000997Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
998 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000999
Zachary Turner316109b2018-07-29 16:38:02 +00001000 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001001
1002 Ty->Storage = SC;
1003
1004 // <variable-type> ::= <type> <cvr-qualifiers>
1005 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1006 switch (Ty->Prim) {
1007 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001008 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001009 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001010 Ty->Quals =
1011 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001012
Zachary Turnerd742d642018-07-26 19:56:09 +00001013 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001014 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001015
Zachary Turnerd742d642018-07-26 19:56:09 +00001016 if (Ty->Prim == PrimTy::MemberPtr) {
1017 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001018 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001019 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001020 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1021 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1022 } else {
1023 PointerType *PTy = static_cast<PointerType *>(Ty);
1024 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001025 }
1026
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001027 break;
1028 }
1029 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001030 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001031 break;
1032 }
1033
1034 return Ty;
1035}
1036
1037// Sometimes numbers are encoded in mangled symbols. For example,
1038// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1039// length 20), so we need some way to embed numbers as part of symbols.
1040// This function parses it.
1041//
1042// <number> ::= [?] <non-negative integer>
1043//
1044// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1045// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1046//
1047// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001048int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001049 bool neg = MangledName.consumeFront("?");
1050
1051 if (startsWithDigit(MangledName)) {
1052 int32_t Ret = MangledName[0] - '0' + 1;
1053 MangledName = MangledName.dropFront(1);
1054 return neg ? -Ret : Ret;
1055 }
1056
1057 int Ret = 0;
1058 for (size_t i = 0; i < MangledName.size(); ++i) {
1059 char C = MangledName[i];
1060 if (C == '@') {
1061 MangledName = MangledName.dropFront(i + 1);
1062 return neg ? -Ret : Ret;
1063 }
1064 if ('A' <= C && C <= 'P') {
1065 Ret = (Ret << 4) + (C - 'A');
1066 continue;
1067 }
1068 break;
1069 }
1070
1071 Error = true;
1072 return 0;
1073}
1074
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001075// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1076// Memorize it.
1077void Demangler::memorizeString(StringView S) {
1078 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1079 return;
1080 for (size_t i = 0; i < BackRefCount; ++i)
1081 if (S == BackReferences[i])
1082 return;
1083 BackReferences[BackRefCount++] = S;
1084}
1085
Zachary Turner316109b2018-07-29 16:38:02 +00001086Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001087 assert(startsWithDigit(MangledName));
1088
1089 size_t I = MangledName[0] - '0';
1090 if (I >= BackRefCount) {
1091 Error = true;
1092 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001093 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001094
1095 MangledName = MangledName.dropFront();
1096 Name *Node = Arena.alloc<Name>();
1097 Node->Str = BackReferences[I];
1098 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001099}
1100
Zachary Turner316109b2018-07-29 16:38:02 +00001101Name *Demangler::demangleClassTemplateName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001102 assert(MangledName.startsWith("?$"));
1103 MangledName.consumeFront("?$");
1104
Zachary Turner316109b2018-07-29 16:38:02 +00001105 Name *Node = demangleSimpleName(MangledName, false);
Zachary Turnerd30700f2018-07-31 17:16:44 +00001106 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001107
1108 // Render this class template name into a string buffer so that we can
1109 // memorize it for the purpose of back-referencing.
1110 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1111 outputName(OS, Node);
1112 OS << '\0';
1113 char *Name = OS.getBuffer();
1114
1115 StringView Owned = copyString(Name);
1116 memorizeString(Owned);
1117 std::free(Name);
1118
Zachary Turnera7dffb12018-07-28 22:10:42 +00001119 return Node;
1120}
1121
Zachary Turner316109b2018-07-29 16:38:02 +00001122Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001123 assert(MangledName.startsWith('?'));
1124 MangledName.consumeFront('?');
1125
Zachary Turner316109b2018-07-29 16:38:02 +00001126 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001127 switch (MangledName.popFront()) {
1128 case '0':
1129 return "ctor";
1130 case '1':
1131 return "dtor";
1132 case '2':
1133 return " new";
1134 case '3':
1135 return " delete";
1136 case '4':
1137 return "=";
1138 case '5':
1139 return ">>";
1140 case '6':
1141 return "<<";
1142 case '7':
1143 return "!";
1144 case '8':
1145 return "==";
1146 case '9':
1147 return "!=";
1148 case 'A':
1149 return "[]";
1150 case 'C':
1151 return "->";
1152 case 'D':
1153 return "*";
1154 case 'E':
1155 return "++";
1156 case 'F':
1157 return "--";
1158 case 'G':
1159 return "-";
1160 case 'H':
1161 return "+";
1162 case 'I':
1163 return "&";
1164 case 'J':
1165 return "->*";
1166 case 'K':
1167 return "/";
1168 case 'L':
1169 return "%";
1170 case 'M':
1171 return "<";
1172 case 'N':
1173 return "<=";
1174 case 'O':
1175 return ">";
1176 case 'P':
1177 return ">=";
1178 case 'Q':
1179 return ",";
1180 case 'R':
1181 return "()";
1182 case 'S':
1183 return "~";
1184 case 'T':
1185 return "^";
1186 case 'U':
1187 return "|";
1188 case 'V':
1189 return "&&";
1190 case 'W':
1191 return "||";
1192 case 'X':
1193 return "*=";
1194 case 'Y':
1195 return "+=";
1196 case 'Z':
1197 return "-=";
1198 case '_': {
1199 if (MangledName.empty())
1200 break;
1201
1202 switch (MangledName.popFront()) {
1203 case '0':
1204 return "/=";
1205 case '1':
1206 return "%=";
1207 case '2':
1208 return ">>=";
1209 case '3':
1210 return "<<=";
1211 case '4':
1212 return "&=";
1213 case '5':
1214 return "|=";
1215 case '6':
1216 return "^=";
1217 case 'U':
1218 return " new[]";
1219 case 'V':
1220 return " delete[]";
1221 case '_':
1222 if (MangledName.consumeFront("L"))
1223 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001224 if (MangledName.consumeFront("K")) {
1225 size_t EndPos = MangledName.find('@');
1226 if (EndPos == StringView::npos)
1227 break;
1228 StringView OpName = demangleSimpleString(MangledName, false);
1229 size_t FullSize = OpName.size() + 3; // <space>""OpName
1230 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1231 Buffer[0] = ' ';
1232 Buffer[1] = '"';
1233 Buffer[2] = '"';
1234 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1235 return {Buffer, FullSize};
1236 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001237 }
1238 }
1239 }
1240 Error = true;
1241 return "";
1242 };
1243
1244 Name *Node = Arena.alloc<Name>();
1245 Node->Operator = NameString();
1246 return Node;
1247}
1248
Zachary Turner316109b2018-07-29 16:38:02 +00001249Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001250 StringView S = demangleSimpleString(MangledName, Memorize);
1251 if (Error)
1252 return nullptr;
1253
Zachary Turnera7dffb12018-07-28 22:10:42 +00001254 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001255 Node->Str = S;
1256 return Node;
1257}
1258
1259StringView Demangler::demangleSimpleString(StringView &MangledName,
1260 bool Memorize) {
1261 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001262 for (size_t i = 0; i < MangledName.size(); ++i) {
1263 if (MangledName[i] != '@')
1264 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001265 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001266 MangledName = MangledName.dropFront(i + 1);
1267
1268 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001269 memorizeString(S);
1270 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001271 }
1272
1273 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001274 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001275}
1276
Zachary Turner316109b2018-07-29 16:38:02 +00001277Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001278 assert(MangledName.startsWith("?A"));
1279 MangledName.consumeFront("?A");
1280
1281 Name *Node = Arena.alloc<Name>();
1282 Node->Str = "`anonymous namespace'";
1283 if (MangledName.consumeFront('@'))
1284 return Node;
1285
1286 Error = true;
1287 return nullptr;
1288}
1289
Zachary Turner71c91f92018-07-30 03:12:34 +00001290Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1291 assert(startsWithLocalScopePattern(MangledName));
1292
1293 Name *Node = Arena.alloc<Name>();
1294 MangledName.consumeFront('?');
1295 int ScopeIdentifier = demangleNumber(MangledName);
1296
1297 // One ? to terminate the number
1298 MangledName.consumeFront('?');
1299
1300 assert(!Error);
1301 Symbol *Scope = parse(MangledName);
1302 if (Error)
1303 return nullptr;
1304
1305 // Render the parent symbol's name into a buffer.
1306 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1307 OS << '`';
1308 output(Scope, OS);
1309 OS << '\'';
1310 OS << "::`" << ScopeIdentifier << "'";
1311 OS << '\0';
1312 char *Result = OS.getBuffer();
1313 Node->Str = copyString(Result);
1314 std::free(Result);
1315 return Node;
1316}
1317
Zachary Turnera7dffb12018-07-28 22:10:42 +00001318// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001319Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
1320 Name *TypeName = demangleUnqualifiedTypeName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001321 assert(TypeName);
1322
Zachary Turner316109b2018-07-29 16:38:02 +00001323 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001324 assert(QualName);
1325 return QualName;
1326}
1327
1328// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1329// Symbol names have slightly different rules regarding what can appear
1330// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001331Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
1332 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001333 assert(SymbolName);
1334
Zachary Turner316109b2018-07-29 16:38:02 +00001335 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001336 assert(QualName);
1337 return QualName;
1338}
1339
Zachary Turner316109b2018-07-29 16:38:02 +00001340Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001341 // An inner-most name can be a back-reference, because a fully-qualified name
1342 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1343 // them (for example template parameters), and these nested parameters can
1344 // refer to previously mangled types.
1345 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001346 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001347
1348 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001349 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001350
Zachary Turner316109b2018-07-29 16:38:02 +00001351 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001352}
1353
Zachary Turner316109b2018-07-29 16:38:02 +00001354Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001355 if (startsWithDigit(MangledName))
1356 return demangleBackRefName(MangledName);
1357 if (MangledName.startsWith("?$"))
1358 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001359 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001360 return demangleOperatorName(MangledName);
1361 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001362}
1363
Zachary Turner316109b2018-07-29 16:38:02 +00001364Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001365 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001366 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001367
1368 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001369 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001370
1371 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001372 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001373
Zachary Turner71c91f92018-07-30 03:12:34 +00001374 if (startsWithLocalScopePattern(MangledName))
1375 return demangleLocallyScopedNamePiece(MangledName);
1376
Zachary Turner316109b2018-07-29 16:38:02 +00001377 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001378}
1379
Zachary Turner316109b2018-07-29 16:38:02 +00001380Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1381 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001382 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001383
1384 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001385 if (MangledName.empty()) {
1386 Error = true;
1387 return nullptr;
1388 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001389
1390 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001391 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001392 if (Error)
1393 return nullptr;
1394
1395 Elem->Next = Head;
1396 Head = Elem;
1397 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001398 return Head;
1399}
1400
Zachary Turner316109b2018-07-29 16:38:02 +00001401FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001402 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1403 RestoreOnError.shouldRestore(false);
1404
1405 switch (MangledName.popFront()) {
1406 case 'A':
1407 return Private;
1408 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001409 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001410 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001411 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001412 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001413 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001414 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001415 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001416 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001417 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001418 case 'I':
1419 return Protected;
1420 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001421 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001422 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001423 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001424 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001425 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001426 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001427 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001428 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001429 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001430 case 'Q':
1431 return Public;
1432 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001433 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001434 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001435 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001436 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001437 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001438 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001439 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001440 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001441 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001442 case 'Y':
1443 return Global;
1444 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001445 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001446 }
1447
1448 Error = true;
1449 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001450 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001451}
1452
Zachary Turner316109b2018-07-29 16:38:02 +00001453CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454 switch (MangledName.popFront()) {
1455 case 'A':
1456 case 'B':
1457 return CallingConv::Cdecl;
1458 case 'C':
1459 case 'D':
1460 return CallingConv::Pascal;
1461 case 'E':
1462 case 'F':
1463 return CallingConv::Thiscall;
1464 case 'G':
1465 case 'H':
1466 return CallingConv::Stdcall;
1467 case 'I':
1468 case 'J':
1469 return CallingConv::Fastcall;
1470 case 'M':
1471 case 'N':
1472 return CallingConv::Clrcall;
1473 case 'O':
1474 case 'P':
1475 return CallingConv::Eabi;
1476 case 'Q':
1477 return CallingConv::Vectorcall;
1478 }
1479
1480 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001481}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001482
Zachary Turner316109b2018-07-29 16:38:02 +00001483StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001484 assert(std::isdigit(MangledName.front()));
1485
1486 switch (MangledName.popFront()) {
1487 case '0':
1488 return StorageClass::PrivateStatic;
1489 case '1':
1490 return StorageClass::ProtectedStatic;
1491 case '2':
1492 return StorageClass::PublicStatic;
1493 case '3':
1494 return StorageClass::Global;
1495 case '4':
1496 return StorageClass::FunctionLocalStatic;
1497 }
1498 Error = true;
1499 return StorageClass::None;
1500}
1501
Zachary Turner316109b2018-07-29 16:38:02 +00001502std::pair<Qualifiers, bool>
1503Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001504
1505 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001506 // Member qualifiers
1507 case 'Q':
1508 return std::make_pair(Q_None, true);
1509 case 'R':
1510 return std::make_pair(Q_Const, true);
1511 case 'S':
1512 return std::make_pair(Q_Volatile, true);
1513 case 'T':
1514 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1515 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001516 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001517 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001518 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001519 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001520 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001521 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001522 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001523 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001524 }
1525 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001526 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001527}
1528
Zachary Turner931e8792018-07-30 23:02:10 +00001529static bool isTagType(StringView S) {
1530 switch (S.front()) {
1531 case 'T': // union
1532 case 'U': // struct
1533 case 'V': // class
1534 case 'W': // enum
1535 return true;
1536 }
1537 return false;
1538}
1539
1540static bool isPointerType(StringView S) {
1541 if (S.startsWith("$$Q")) // foo &&
1542 return true;
1543
1544 switch (S.front()) {
1545 case 'A': // foo &
1546 case 'P': // foo *
1547 case 'Q': // foo *const
1548 case 'R': // foo *volatile
1549 case 'S': // foo *const volatile
1550 return true;
1551 }
1552 return false;
1553}
1554
1555static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1556
1557static bool isFunctionType(StringView S) {
1558 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1559}
1560
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001561// <variable-type> ::= <type> <cvr-qualifiers>
1562// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001563Type *Demangler::demangleType(StringView &MangledName,
1564 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001565 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001566 bool IsMember = false;
1567 bool IsMemberKnown = false;
1568 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001569 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001570 IsMemberKnown = true;
1571 } else if (QMM == QualifierMangleMode::Result) {
1572 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001573 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001574 IsMemberKnown = true;
1575 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001576 }
1577
1578 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001579 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001580 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001581 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001582 if (!IsMemberKnown)
1583 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001584
Zachary Turnerd742d642018-07-26 19:56:09 +00001585 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001586 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001587 else
Zachary Turner316109b2018-07-29 16:38:02 +00001588 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001589 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001590 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001591 else if (isFunctionType(MangledName)) {
1592 if (MangledName.consumeFront("$$A8@@"))
1593 Ty = demangleFunctionType(MangledName, true, false);
1594 else {
1595 assert(MangledName.startsWith("$$A6"));
1596 MangledName.consumeFront("$$A6");
1597 Ty = demangleFunctionType(MangledName, false, false);
1598 }
1599 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001600 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001601 assert(Ty && !Error);
1602 if (!Ty || Error)
1603 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001604 }
Zachary Turner931e8792018-07-30 23:02:10 +00001605
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001606 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1607 return Ty;
1608}
1609
Zachary Turner316109b2018-07-29 16:38:02 +00001610ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001611 if (MangledName.consumeFront('G'))
1612 return ReferenceKind::LValueRef;
1613 else if (MangledName.consumeFront('H'))
1614 return ReferenceKind::RValueRef;
1615 return ReferenceKind::None;
1616}
1617
Zachary Turner316109b2018-07-29 16:38:02 +00001618void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001619 if (MangledName.consumeFront('Z'))
1620 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001621
Zachary Turner38b78a72018-07-26 20:20:10 +00001622 Error = true;
1623}
1624
Zachary Turner316109b2018-07-29 16:38:02 +00001625FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1626 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001627 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001628 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001629 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001630 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001631
1632 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001633 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1634 FTy->RefKind = demangleReferenceKind(MangledName);
1635 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001636 }
1637
1638 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001639 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001640
1641 // <return-type> ::= <type>
1642 // ::= @ # structors (they have no declared return type)
1643 bool IsStructor = MangledName.consumeFront('@');
1644 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001645 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001646
Zachary Turner316109b2018-07-29 16:38:02 +00001647 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001648
Zachary Turner316109b2018-07-29 16:38:02 +00001649 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001650
1651 return FTy;
1652}
1653
Zachary Turner316109b2018-07-29 16:38:02 +00001654Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1655 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001656
1657 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001658 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001659 FTy->FunctionClass = FC;
1660
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001661 return FTy;
1662}
1663
1664// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001665Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001666 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001667
Zachary Turner931e8792018-07-30 23:02:10 +00001668 if (MangledName.consumeFront("$$T")) {
1669 Ty->Prim = PrimTy::Nullptr;
1670 return Ty;
1671 }
1672
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001673 switch (MangledName.popFront()) {
1674 case 'X':
1675 Ty->Prim = PrimTy::Void;
1676 break;
1677 case 'D':
1678 Ty->Prim = PrimTy::Char;
1679 break;
1680 case 'C':
1681 Ty->Prim = PrimTy::Schar;
1682 break;
1683 case 'E':
1684 Ty->Prim = PrimTy::Uchar;
1685 break;
1686 case 'F':
1687 Ty->Prim = PrimTy::Short;
1688 break;
1689 case 'G':
1690 Ty->Prim = PrimTy::Ushort;
1691 break;
1692 case 'H':
1693 Ty->Prim = PrimTy::Int;
1694 break;
1695 case 'I':
1696 Ty->Prim = PrimTy::Uint;
1697 break;
1698 case 'J':
1699 Ty->Prim = PrimTy::Long;
1700 break;
1701 case 'K':
1702 Ty->Prim = PrimTy::Ulong;
1703 break;
1704 case 'M':
1705 Ty->Prim = PrimTy::Float;
1706 break;
1707 case 'N':
1708 Ty->Prim = PrimTy::Double;
1709 break;
1710 case 'O':
1711 Ty->Prim = PrimTy::Ldouble;
1712 break;
1713 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001714 if (MangledName.empty()) {
1715 Error = true;
1716 return nullptr;
1717 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001718 switch (MangledName.popFront()) {
1719 case 'N':
1720 Ty->Prim = PrimTy::Bool;
1721 break;
1722 case 'J':
1723 Ty->Prim = PrimTy::Int64;
1724 break;
1725 case 'K':
1726 Ty->Prim = PrimTy::Uint64;
1727 break;
1728 case 'W':
1729 Ty->Prim = PrimTy::Wchar;
1730 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001731 case 'S':
1732 Ty->Prim = PrimTy::Char16;
1733 break;
1734 case 'U':
1735 Ty->Prim = PrimTy::Char32;
1736 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001737 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001738 Error = true;
1739 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001740 }
1741 break;
1742 }
Zachary Turner931e8792018-07-30 23:02:10 +00001743 default:
1744 Error = true;
1745 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001746 }
1747 return Ty;
1748}
1749
Zachary Turner316109b2018-07-29 16:38:02 +00001750UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001751 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001752
1753 switch (MangledName.popFront()) {
1754 case 'T':
1755 UTy->Prim = PrimTy::Union;
1756 break;
1757 case 'U':
1758 UTy->Prim = PrimTy::Struct;
1759 break;
1760 case 'V':
1761 UTy->Prim = PrimTy::Class;
1762 break;
1763 case 'W':
1764 if (MangledName.popFront() != '4') {
1765 Error = true;
1766 return nullptr;
1767 }
1768 UTy->Prim = PrimTy::Enum;
1769 break;
1770 default:
1771 assert(false);
1772 }
1773
Zachary Turner316109b2018-07-29 16:38:02 +00001774 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001775 return UTy;
1776}
1777
Zachary Turnerd742d642018-07-26 19:56:09 +00001778static std::pair<Qualifiers, PointerAffinity>
1779demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001780 if (MangledName.consumeFront("$$Q"))
1781 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1782
Zachary Turnerd742d642018-07-26 19:56:09 +00001783 switch (MangledName.popFront()) {
1784 case 'A':
1785 return std::make_pair(Q_None, PointerAffinity::Reference);
1786 case 'P':
1787 return std::make_pair(Q_None, PointerAffinity::Pointer);
1788 case 'Q':
1789 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1790 case 'R':
1791 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1792 case 'S':
1793 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1794 PointerAffinity::Pointer);
1795 default:
1796 assert(false && "Ty is not a pointer type!");
1797 }
1798 return std::make_pair(Q_None, PointerAffinity::Pointer);
1799}
1800
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001801// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1802// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001803PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001804 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001805
Zachary Turner931e8792018-07-30 23:02:10 +00001806 std::tie(Pointer->Quals, Pointer->Affinity) =
1807 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001808
Zachary Turner931e8792018-07-30 23:02:10 +00001809 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001810 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001811 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001812 return Pointer;
1813 }
1814
Zachary Turner316109b2018-07-29 16:38:02 +00001815 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001816 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1817
Zachary Turner316109b2018-07-29 16:38:02 +00001818 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001819 return Pointer;
1820}
1821
Zachary Turner316109b2018-07-29 16:38:02 +00001822MemberPointerType *
1823Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001824 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1825 Pointer->Prim = PrimTy::MemberPtr;
1826
1827 PointerAffinity Affinity;
1828 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1829 assert(Affinity == PointerAffinity::Pointer);
1830
Zachary Turner316109b2018-07-29 16:38:02 +00001831 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001832 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1833
Zachary Turner38b78a72018-07-26 20:20:10 +00001834 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001835 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1836 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001837 } else {
1838 Qualifiers PointeeQuals = Q_None;
1839 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001840 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001841 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001842 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001843
Zachary Turner316109b2018-07-29 16:38:02 +00001844 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001845 Pointer->Pointee->Quals = PointeeQuals;
1846 }
1847
Zachary Turnerd742d642018-07-26 19:56:09 +00001848 return Pointer;
1849}
1850
Zachary Turner316109b2018-07-29 16:38:02 +00001851Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001852 Qualifiers Quals = Q_None;
1853 if (MangledName.consumeFront('E'))
1854 Quals = Qualifiers(Quals | Q_Pointer64);
1855 if (MangledName.consumeFront('I'))
1856 Quals = Qualifiers(Quals | Q_Restrict);
1857 if (MangledName.consumeFront('F'))
1858 Quals = Qualifiers(Quals | Q_Unaligned);
1859
1860 return Quals;
1861}
1862
Zachary Turner316109b2018-07-29 16:38:02 +00001863ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001864 assert(MangledName.front() == 'Y');
1865 MangledName.popFront();
1866
Zachary Turner316109b2018-07-29 16:38:02 +00001867 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001868 if (Dimension <= 0) {
1869 Error = true;
1870 return nullptr;
1871 }
1872
Zachary Turner9d72aa92018-07-20 18:35:06 +00001873 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001874 ArrayType *Dim = ATy;
1875 for (int I = 0; I < Dimension; ++I) {
1876 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001877 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001878 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001879 Dim = Dim->NextDimension;
1880 }
1881
1882 if (MangledName.consumeFront("$$C")) {
1883 if (MangledName.consumeFront("B"))
1884 ATy->Quals = Q_Const;
1885 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1886 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1887 else if (!MangledName.consumeFront("A"))
1888 Error = true;
1889 }
1890
Zachary Turner316109b2018-07-29 16:38:02 +00001891 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001892 Dim->ElementType = ATy->ElementType;
1893 return ATy;
1894}
1895
1896// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001897FunctionParams
1898Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001899 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001900 if (MangledName.consumeFront('X'))
1901 return {};
1902
Zachary Turnerd30700f2018-07-31 17:16:44 +00001903 FunctionParams *Head;
1904 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001905 while (!Error && !MangledName.startsWith('@') &&
1906 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001907
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001908 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001909 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001910 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001911 Error = true;
1912 return {};
1913 }
1914 MangledName = MangledName.dropFront();
1915
Zachary Turnerd30700f2018-07-31 17:16:44 +00001916 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001917 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001918 Current = &(*Current)->Next;
1919 continue;
1920 }
1921
Zachary Turner23df1312018-07-26 22:13:39 +00001922 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001923
Zachary Turnerd30700f2018-07-31 17:16:44 +00001924 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001925 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001926
Zachary Turner23df1312018-07-26 22:13:39 +00001927 size_t CharsConsumed = OldSize - MangledName.size();
1928 assert(CharsConsumed != 0);
1929
1930 // Single-letter types are ignored for backreferences because memorizing
1931 // them doesn't save anything.
1932 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1933 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1934
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001935 Current = &(*Current)->Next;
1936 }
1937
Zachary Turner38b78a72018-07-26 20:20:10 +00001938 if (Error)
1939 return {};
1940
1941 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1942 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1943 // the following Z could be a throw specifier.
1944 if (MangledName.consumeFront('@'))
1945 return *Head;
1946
1947 if (MangledName.consumeFront('Z')) {
1948 Head->IsVariadic = true;
1949 return *Head;
1950 }
1951
1952 Error = true;
1953 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001954}
1955
Zachary Turnerd30700f2018-07-31 17:16:44 +00001956TemplateParams *
1957Demangler::demangleTemplateParameterList(StringView &MangledName) {
1958 TemplateParams *Head;
1959 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00001960 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001961 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001962 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00001963
1964 // Empty parameter pack.
1965 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
1966 MangledName.consumeFront("$$$V")) {
1967 if (!MangledName.startsWith('@'))
1968 Error = true;
1969 continue;
1970 }
1971
Zachary Turnerd30700f2018-07-31 17:16:44 +00001972 if (MangledName.consumeFront("$$Y")) {
1973 (*Current)->IsTemplateTemplate = true;
1974 (*Current)->IsAliasTemplate = true;
1975 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
1976 } else if (MangledName.consumeFront("$1?")) {
1977 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
1978 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
1979 } else {
1980 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00001981 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00001982 }
Zachary Turner23df1312018-07-26 22:13:39 +00001983
1984 Current = &(*Current)->Next;
1985 }
1986
1987 if (Error)
1988 return {};
1989
1990 // Template parameter lists cannot be variadic, so it can only be terminated
1991 // by @.
1992 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00001993 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00001994 Error = true;
1995 return {};
1996}
1997
Zachary Turner316109b2018-07-29 16:38:02 +00001998void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001999 // Converts an AST to a string.
2000 //
2001 // Converting an AST representing a C++ type to a string is tricky due
2002 // to the bad grammar of the C++ declaration inherited from C. You have
2003 // to construct a string from inside to outside. For example, if a type
2004 // X is a pointer to a function returning int, the order you create a
2005 // string becomes something like this:
2006 //
2007 // (1) X is a pointer: *X
2008 // (2) (1) is a function returning int: int (*X)()
2009 //
2010 // So you cannot construct a result just by appending strings to a result.
2011 //
2012 // To deal with this, we split the function into two. outputPre() writes
2013 // the "first half" of type declaration, and outputPost() writes the
2014 // "second half". For example, outputPre() writes a return type for a
2015 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00002016 Type::outputPre(OS, *S->SymbolType);
2017 outputName(OS, S->SymbolName);
2018 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002019}
2020
2021char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
2022 int *Status) {
Zachary Turner316109b2018-07-29 16:38:02 +00002023 Demangler D;
2024 StringView Name{MangledName};
2025 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002026
2027 if (D.Error)
2028 *Status = llvm::demangle_invalid_mangled_name;
2029 else
2030 *Status = llvm::demangle_success;
2031
Zachary Turner316109b2018-07-29 16:38:02 +00002032 OutputStream OS = OutputStream::create(Buf, N, 1024);
2033 D.output(S, OS);
Zachary Turner71c91f92018-07-30 03:12:34 +00002034 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002035 return OS.getBuffer();
2036}