blob: 8b19d77acbfd173d643b62cad3e1744af6c873cc [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
Zachary Turner5ae08b82018-08-01 18:44:12 +000024#include <cstdio>
Zachary Turnerd742d642018-07-26 19:56:09 +000025#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000026
27// This memory allocator is extremely fast, but it doesn't call dtors
28// for allocated objects. That means you can't use STL containers
29// (such as std::vector) with this allocator. But it pays off --
30// the demangler is 3x faster with this allocator compared to one with
31// STL containers.
32namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000033 constexpr size_t AllocUnit = 4096;
34
Zachary Turnerf435a7e2018-07-20 17:27:48 +000035class ArenaAllocator {
36 struct AllocatorNode {
37 uint8_t *Buf = nullptr;
38 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000039 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000040 AllocatorNode *Next = nullptr;
41 };
42
Zachary Turner71c91f92018-07-30 03:12:34 +000043 void addNode(size_t Capacity) {
44 AllocatorNode *NewHead = new AllocatorNode;
45 NewHead->Buf = new uint8_t[Capacity];
46 NewHead->Next = Head;
47 NewHead->Capacity = Capacity;
48 Head = NewHead;
49 NewHead->Used = 0;
50 }
51
Zachary Turnerf435a7e2018-07-20 17:27:48 +000052public:
Zachary Turnera6869512018-07-30 03:25:27 +000053 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000054
55 ~ArenaAllocator() {
56 while (Head) {
57 assert(Head->Buf);
58 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000059 AllocatorNode *Next = Head->Next;
60 delete Head;
61 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000062 }
63 }
64
Zachary Turner71c91f92018-07-30 03:12:34 +000065 char *allocUnalignedBuffer(size_t Length) {
66 uint8_t *Buf = Head->Buf + Head->Used;
67
68 Head->Used += Length;
69 if (Head->Used > Head->Capacity) {
70 // It's possible we need a buffer which is larger than our default unit
71 // size, so we need to be careful to add a node with capacity that is at
72 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000073 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000074 Head->Used = Length;
75 Buf = Head->Buf;
76 }
77
78 return reinterpret_cast<char *>(Buf);
79 }
80
Zachary Turner9d72aa92018-07-20 18:35:06 +000081 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
82
83 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000084 assert(Head && Head->Buf);
85
Zachary Turner9d72aa92018-07-20 18:35:06 +000086 size_t P = (size_t)Head->Buf + Head->Used;
87 uintptr_t AlignedP =
88 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
89 uint8_t *PP = (uint8_t *)AlignedP;
90 size_t Adjustment = AlignedP - P;
91
92 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000093 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000094 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000095
Zachary Turnera6869512018-07-30 03:25:27 +000096 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000097 Head->Used = Size;
98 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000099 }
100
101private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000102 AllocatorNode *Head = nullptr;
103};
104} // namespace
105
106static bool startsWithDigit(StringView S) {
107 return !S.empty() && std::isdigit(S.front());
108}
109
110// Writes a space if the last token does not end with a punctuation.
111static void outputSpaceIfNecessary(OutputStream &OS) {
112 if (OS.empty())
113 return;
114
115 char C = OS.back();
116 if (isalnum(C) || C == '>')
117 OS << " ";
118}
119
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000120// Storage classes
121enum Qualifiers : uint8_t {
122 Q_None = 0,
123 Q_Const = 1 << 0,
124 Q_Volatile = 1 << 1,
125 Q_Far = 1 << 2,
126 Q_Huge = 1 << 3,
127 Q_Unaligned = 1 << 4,
128 Q_Restrict = 1 << 5,
129 Q_Pointer64 = 1 << 6
130};
131
132enum class StorageClass : uint8_t {
133 None,
134 PrivateStatic,
135 ProtectedStatic,
136 PublicStatic,
137 Global,
138 FunctionLocalStatic
139};
140
141enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000142
Zachary Turner931e8792018-07-30 23:02:10 +0000143enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000144
145// Calling conventions
146enum class CallingConv : uint8_t {
147 None,
148 Cdecl,
149 Pascal,
150 Thiscall,
151 Stdcall,
152 Fastcall,
153 Clrcall,
154 Eabi,
155 Vectorcall,
156 Regcall,
157};
158
159enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
160
161// Types
162enum class PrimTy : uint8_t {
163 Unknown,
164 None,
165 Function,
166 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000167 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000168 Array,
169
170 Struct,
171 Union,
172 Class,
173 Enum,
174
175 Void,
176 Bool,
177 Char,
178 Schar,
179 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000180 Char16,
181 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000182 Short,
183 Ushort,
184 Int,
185 Uint,
186 Long,
187 Ulong,
188 Int64,
189 Uint64,
190 Wchar,
191 Float,
192 Double,
193 Ldouble,
Zachary Turner931e8792018-07-30 23:02:10 +0000194 Nullptr
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000195};
196
197// Function classes
198enum FuncClass : uint8_t {
199 Public = 1 << 0,
200 Protected = 1 << 1,
201 Private = 1 << 2,
202 Global = 1 << 3,
203 Static = 1 << 4,
204 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000205 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000206};
207
Zachary Turner44ebbc22018-08-01 18:32:47 +0000208enum class SymbolCategory { Function, Variable };
209
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000210namespace {
211
212struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000213struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000214
Zachary Turnerd30700f2018-07-31 17:16:44 +0000215struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000216 bool IsVariadic = false;
217
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000218 Type *Current = nullptr;
219
Zachary Turnerd30700f2018-07-31 17:16:44 +0000220 FunctionParams *Next = nullptr;
221};
Zachary Turner931e8792018-07-30 23:02:10 +0000222
Zachary Turnerd30700f2018-07-31 17:16:44 +0000223struct TemplateParams {
224 bool IsTemplateTemplate = false;
225 bool IsAliasTemplate = false;
226
227 // Type can be null if this is a template template parameter. In that case
228 // only Name will be valid.
229 Type *ParamType = nullptr;
230
231 // Name can be valid if this is a template template parameter (see above) or
232 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
233 // Name contains the name of the function and Type contains the signature.
234 Name *ParamName = nullptr;
235
236 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000237};
238
239// The type class. Mangled symbols are first parsed and converted to
240// this type and then converted to string.
241struct Type {
242 virtual ~Type() {}
243
244 virtual Type *clone(ArenaAllocator &Arena) const;
245
246 // Write the "first half" of a given type. This is a static functions to
247 // give the code a chance to do processing that is common to a subset of
248 // subclasses
249 static void outputPre(OutputStream &OS, Type &Ty);
250
251 // Write the "second half" of a given type. This is a static functions to
252 // give the code a chance to do processing that is common to a subset of
253 // subclasses
254 static void outputPost(OutputStream &OS, Type &Ty);
255
256 virtual void outputPre(OutputStream &OS);
257 virtual void outputPost(OutputStream &OS);
258
259 // Primitive type such as Int.
260 PrimTy Prim = PrimTy::Unknown;
261
262 Qualifiers Quals = Q_None;
263 StorageClass Storage = StorageClass::None; // storage class
264};
265
266// Represents an identifier which may be a template.
267struct Name {
268 // Name read from an MangledName string.
269 StringView Str;
270
Zachary Turner44ebbc22018-08-01 18:32:47 +0000271 bool IsTemplateInstantiation = false;
272 bool IsOperator = false;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000273
Zachary Turner44ebbc22018-08-01 18:32:47 +0000274 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000275 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000276
277 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
278 Name *Next = nullptr;
279};
280
281struct PointerType : public Type {
282 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000283 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000284 void outputPost(OutputStream &OS) override;
285
Zachary Turner931e8792018-07-30 23:02:10 +0000286 PointerAffinity Affinity;
287
Zachary Turnerd742d642018-07-26 19:56:09 +0000288 // Represents a type X in "a pointer to X", "a reference to X",
289 // "an array of X", or "a function returning X".
290 Type *Pointee = nullptr;
291};
292
293struct MemberPointerType : public Type {
294 Type *clone(ArenaAllocator &Arena) const override;
295 void outputPre(OutputStream &OS) override;
296 void outputPost(OutputStream &OS) override;
297
298 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000299
300 // Represents a type X in "a pointer to X", "a reference to X",
301 // "an array of X", or "a function returning X".
302 Type *Pointee = nullptr;
303};
304
305struct FunctionType : public Type {
306 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000307 void outputPre(OutputStream &OS) override;
308 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000309
Zachary Turner024e1762018-07-26 20:33:48 +0000310 // True if this FunctionType instance is the Pointee of a PointerType or
311 // MemberPointerType.
312 bool IsFunctionPointer = false;
313
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000314 Type *ReturnType = nullptr;
315 // If this is a reference, the type of reference.
316 ReferenceKind RefKind;
317
318 CallingConv CallConvention;
319 FuncClass FunctionClass;
320
Zachary Turnerd30700f2018-07-31 17:16:44 +0000321 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000322};
323
324struct UdtType : public Type {
325 Type *clone(ArenaAllocator &Arena) const override;
326 void outputPre(OutputStream &OS) override;
327
328 Name *UdtName = nullptr;
329};
330
331struct ArrayType : public Type {
332 Type *clone(ArenaAllocator &Arena) const override;
333 void outputPre(OutputStream &OS) override;
334 void outputPost(OutputStream &OS) override;
335
336 // Either NextDimension or ElementType will be valid.
337 ArrayType *NextDimension = nullptr;
338 uint32_t ArrayDimension = 0;
339
340 Type *ElementType = nullptr;
341};
342
343} // namespace
344
Zachary Turnerd742d642018-07-26 19:56:09 +0000345static bool isMemberPointer(StringView MangledName) {
346 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000347 case '$':
348 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
349 // rvalue reference to a member.
350 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000351 case 'A':
352 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000353 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000354 return false;
355 case 'P':
356 case 'Q':
357 case 'R':
358 case 'S':
359 // These 4 values indicate some kind of pointer, but we still don't know
360 // what.
361 break;
362 default:
363 assert(false && "Ty is not a pointer type!");
364 }
365
366 // If it starts with a number, then 6 indicates a non-member function
367 // pointer, and 8 indicates a member function pointer.
368 if (startsWithDigit(MangledName)) {
369 assert(MangledName[0] == '6' || MangledName[0] == '8');
370 return (MangledName[0] == '8');
371 }
372
373 // Remove ext qualifiers since those can appear on either type and are
374 // therefore not indicative.
375 MangledName.consumeFront('E'); // 64-bit
376 MangledName.consumeFront('I'); // restrict
377 MangledName.consumeFront('F'); // unaligned
378
379 assert(!MangledName.empty());
380
381 // The next value should be either ABCD (non-member) or QRST (member).
382 switch (MangledName.front()) {
383 case 'A':
384 case 'B':
385 case 'C':
386 case 'D':
387 return false;
388 case 'Q':
389 case 'R':
390 case 'S':
391 case 'T':
392 return true;
393 default:
394 assert(false);
395 }
396 return false;
397}
398
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000399static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
400 outputSpaceIfNecessary(OS);
401
402 switch (CC) {
403 case CallingConv::Cdecl:
404 OS << "__cdecl";
405 break;
406 case CallingConv::Fastcall:
407 OS << "__fastcall";
408 break;
409 case CallingConv::Pascal:
410 OS << "__pascal";
411 break;
412 case CallingConv::Regcall:
413 OS << "__regcall";
414 break;
415 case CallingConv::Stdcall:
416 OS << "__stdcall";
417 break;
418 case CallingConv::Thiscall:
419 OS << "__thiscall";
420 break;
421 case CallingConv::Eabi:
422 OS << "__eabi";
423 break;
424 case CallingConv::Vectorcall:
425 OS << "__vectorcall";
426 break;
427 case CallingConv::Clrcall:
428 OS << "__clrcall";
429 break;
430 default:
431 break;
432 }
433}
434
Zachary Turner71c91f92018-07-30 03:12:34 +0000435static bool startsWithLocalScopePattern(StringView S) {
436 if (!S.consumeFront('?'))
437 return false;
438 if (S.size() < 2)
439 return false;
440
441 size_t End = S.find('?');
442 if (End == StringView::npos)
443 return false;
444 StringView Candidate = S.substr(0, End);
445 if (Candidate.empty())
446 return false;
447
448 // \?[0-9]\?
449 // ?@? is the discriminator 0.
450 if (Candidate.size() == 1)
451 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
452
453 // If it's not 0-9, then it's an encoded number terminated with an @
454 if (Candidate.back() != '@')
455 return false;
456 Candidate = Candidate.dropBack();
457
458 // An encoded number starts with B-P and all subsequent digits are in A-P.
459 // Note that the reason the first digit cannot be A is two fold. First, it
460 // would create an ambiguity with ?A which delimits the beginning of an
461 // anonymous namespace. Second, A represents 0, and you don't start a multi
462 // digit number with a leading 0. Presumably the anonymous namespace
463 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
464 if (Candidate[0] < 'B' || Candidate[0] > 'P')
465 return false;
466 Candidate = Candidate.dropFront();
467 while (!Candidate.empty()) {
468 if (Candidate[0] < 'A' || Candidate[0] > 'P')
469 return false;
470 Candidate = Candidate.dropFront();
471 }
472
473 return true;
474}
475
Zachary Turner931e8792018-07-30 23:02:10 +0000476static void outputName(OutputStream &OS, const Name *TheName);
477
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000478// Write a function or template parameter list.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000479static void outputParameterList(OutputStream &OS,
480 const FunctionParams &Params) {
481 if (!Params.Current) {
482 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000483 return;
484 }
485
Zachary Turnerd30700f2018-07-31 17:16:44 +0000486 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000487 while (Head) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000488 Type::outputPre(OS, *Head->Current);
489 Type::outputPost(OS, *Head->Current);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000490
491 Head = Head->Next;
492
493 if (Head)
494 OS << ", ";
495 }
496}
497
Zachary Turnerd30700f2018-07-31 17:16:44 +0000498static void outputParameterList(OutputStream &OS,
499 const TemplateParams &Params) {
500 if (!Params.ParamType && !Params.ParamName) {
501 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000502 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000503 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000504
505 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000506 const TemplateParams *Head = &Params;
507 while (Head) {
508 // Type can be null if this is a template template parameter,
509 // and Name can be null if this is a simple type.
510
511 if (Head->ParamType && Head->ParamName) {
512 // Function pointer.
513 OS << "&";
514 Type::outputPre(OS, *Head->ParamType);
515 outputName(OS, Head->ParamName);
516 Type::outputPost(OS, *Head->ParamType);
517 } else if (Head->ParamType) {
518 // simple type.
519 Type::outputPre(OS, *Head->ParamType);
520 Type::outputPost(OS, *Head->ParamType);
521 } else {
522 // Template alias.
523 outputName(OS, Head->ParamName);
524 }
525
526 Head = Head->Next;
527
528 if (Head)
529 OS << ", ";
530 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000531 OS << ">";
532}
533
534static void outputName(OutputStream &OS, const Name *TheName) {
535 if (!TheName)
536 return;
537
538 outputSpaceIfNecessary(OS);
539
Zachary Turnera7dffb12018-07-28 22:10:42 +0000540 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000541 // Print out namespaces or outer class BackReferences.
542 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000543 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000544 OS << TheName->Str;
Zachary Turner44ebbc22018-08-01 18:32:47 +0000545 if (TheName->IsTemplateInstantiation)
Zachary Turnerd30700f2018-07-31 17:16:44 +0000546 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000547 OS << "::";
548 }
549
550 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000551 if (!TheName->IsOperator) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000552 OS << TheName->Str;
Zachary Turner44ebbc22018-08-01 18:32:47 +0000553 if (TheName->IsTemplateInstantiation)
Zachary Turnerd30700f2018-07-31 17:16:44 +0000554 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000555 return;
556 }
557
558 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000559 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000560 OS << "~";
561
Zachary Turner44ebbc22018-08-01 18:32:47 +0000562 if (TheName->Str == "ctor" || TheName->Str == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000563 OS << Previous->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000564 if (Previous->TParams)
565 outputParameterList(OS, *Previous->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000566 return;
567 }
568
569 // Print out an overloaded operator.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000570 OS << "operator" << TheName->Str;
571 if (TheName->IsTemplateInstantiation)
572 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000573}
574
575namespace {
576
577Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000578 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000579}
580
581// Write the "first half" of a given type.
582void Type::outputPre(OutputStream &OS, Type &Ty) {
583 // Function types require custom handling of const and static so we
584 // handle them separately. All other types use the same decoration
585 // for these modifiers, so handle them here in common code.
586 if (Ty.Prim == PrimTy::Function) {
587 Ty.outputPre(OS);
588 return;
589 }
590
591 switch (Ty.Storage) {
592 case StorageClass::PrivateStatic:
593 case StorageClass::PublicStatic:
594 case StorageClass::ProtectedStatic:
595 OS << "static ";
596 default:
597 break;
598 }
599 Ty.outputPre(OS);
600
601 if (Ty.Quals & Q_Const) {
602 outputSpaceIfNecessary(OS);
603 OS << "const";
604 }
605
606 if (Ty.Quals & Q_Volatile) {
607 outputSpaceIfNecessary(OS);
608 OS << "volatile";
609 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000610
611 if (Ty.Quals & Q_Restrict) {
612 outputSpaceIfNecessary(OS);
613 OS << "__restrict";
614 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000615}
616
617// Write the "second half" of a given type.
618void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
619
620void Type::outputPre(OutputStream &OS) {
621 switch (Prim) {
622 case PrimTy::Void:
623 OS << "void";
624 break;
625 case PrimTy::Bool:
626 OS << "bool";
627 break;
628 case PrimTy::Char:
629 OS << "char";
630 break;
631 case PrimTy::Schar:
632 OS << "signed char";
633 break;
634 case PrimTy::Uchar:
635 OS << "unsigned char";
636 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000637 case PrimTy::Char16:
638 OS << "char16_t";
639 break;
640 case PrimTy::Char32:
641 OS << "char32_t";
642 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000643 case PrimTy::Short:
644 OS << "short";
645 break;
646 case PrimTy::Ushort:
647 OS << "unsigned short";
648 break;
649 case PrimTy::Int:
650 OS << "int";
651 break;
652 case PrimTy::Uint:
653 OS << "unsigned int";
654 break;
655 case PrimTy::Long:
656 OS << "long";
657 break;
658 case PrimTy::Ulong:
659 OS << "unsigned long";
660 break;
661 case PrimTy::Int64:
662 OS << "__int64";
663 break;
664 case PrimTy::Uint64:
665 OS << "unsigned __int64";
666 break;
667 case PrimTy::Wchar:
668 OS << "wchar_t";
669 break;
670 case PrimTy::Float:
671 OS << "float";
672 break;
673 case PrimTy::Double:
674 OS << "double";
675 break;
676 case PrimTy::Ldouble:
677 OS << "long double";
678 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000679 case PrimTy::Nullptr:
680 OS << "std::nullptr_t";
681 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000682 default:
683 assert(false && "Invalid primitive type!");
684 }
685}
686void Type::outputPost(OutputStream &OS) {}
687
688Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000689 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000690}
691
Zachary Turner024e1762018-07-26 20:33:48 +0000692static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
693 const Name *MemberName,
694 const Type *Pointee) {
695 // "[]" and "()" (for function parameters) take precedence over "*",
696 // so "int *x(int)" means "x is a function returning int *". We need
697 // parentheses to supercede the default precedence. (e.g. we want to
698 // emit something like "int (*x)(int)".)
699 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
700 OS << "(";
701 if (Pointee->Prim == PrimTy::Function) {
702 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
703 assert(FTy->IsFunctionPointer);
704 outputCallingConvention(OS, FTy->CallConvention);
705 OS << " ";
706 }
707 }
708
709 if (MemberName) {
710 outputName(OS, MemberName);
711 OS << "::";
712 }
713
714 if (Affinity == PointerAffinity::Pointer)
715 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000716 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000717 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000718 else
719 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000720}
721
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000722void PointerType::outputPre(OutputStream &OS) {
723 Type::outputPre(OS, *Pointee);
724
725 outputSpaceIfNecessary(OS);
726
727 if (Quals & Q_Unaligned)
728 OS << "__unaligned ";
729
Zachary Turner024e1762018-07-26 20:33:48 +0000730 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000731
Zachary Turner91ecedd2018-07-20 18:07:33 +0000732 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000733 // if (Ty.Quals & Q_Pointer64)
734 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000735}
736
737void PointerType::outputPost(OutputStream &OS) {
738 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
739 OS << ")";
740
741 Type::outputPost(OS, *Pointee);
742}
743
Zachary Turnerd742d642018-07-26 19:56:09 +0000744Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
745 return Arena.alloc<MemberPointerType>(*this);
746}
747
748void MemberPointerType::outputPre(OutputStream &OS) {
749 Type::outputPre(OS, *Pointee);
750
751 outputSpaceIfNecessary(OS);
752
Zachary Turner024e1762018-07-26 20:33:48 +0000753 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000754
755 // FIXME: We should output this, but it requires updating lots of tests.
756 // if (Ty.Quals & Q_Pointer64)
757 // OS << " __ptr64";
758 if (Quals & Q_Restrict)
759 OS << " __restrict";
760}
761
762void MemberPointerType::outputPost(OutputStream &OS) {
763 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
764 OS << ")";
765
766 Type::outputPost(OS, *Pointee);
767}
768
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000769Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000770 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000771}
772
773void FunctionType::outputPre(OutputStream &OS) {
774 if (!(FunctionClass & Global)) {
775 if (FunctionClass & Static)
776 OS << "static ";
777 }
778
Zachary Turner38b78a72018-07-26 20:20:10 +0000779 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000780 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000781 OS << " ";
782 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000783
Zachary Turner024e1762018-07-26 20:33:48 +0000784 // Function pointers print the calling convention as void (__cdecl *)(params)
785 // rather than void __cdecl (*)(params). So we need to let the PointerType
786 // class handle this.
787 if (!IsFunctionPointer)
788 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000789}
790
791void FunctionType::outputPost(OutputStream &OS) {
792 OS << "(";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000793 outputParameterList(OS, Params);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000794 OS << ")";
795 if (Quals & Q_Const)
796 OS << " const";
797 if (Quals & Q_Volatile)
798 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000799 if (Quals & Q_Restrict)
800 OS << " __restrict";
801 if (Quals & Q_Unaligned)
802 OS << " __unaligned";
803
804 if (RefKind == ReferenceKind::LValueRef)
805 OS << " &";
806 else if (RefKind == ReferenceKind::RValueRef)
807 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000808
809 if (ReturnType)
810 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000811 return;
812}
813
814Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000815 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000816}
817
818void UdtType::outputPre(OutputStream &OS) {
819 switch (Prim) {
820 case PrimTy::Class:
821 OS << "class ";
822 break;
823 case PrimTy::Struct:
824 OS << "struct ";
825 break;
826 case PrimTy::Union:
827 OS << "union ";
828 break;
829 case PrimTy::Enum:
830 OS << "enum ";
831 break;
832 default:
833 assert(false && "Not a udt type!");
834 }
835
836 outputName(OS, UdtName);
837}
838
839Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000840 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000841}
842
843void ArrayType::outputPre(OutputStream &OS) {
844 Type::outputPre(OS, *ElementType);
845}
846
847void ArrayType::outputPost(OutputStream &OS) {
848 if (ArrayDimension > 0)
849 OS << "[" << ArrayDimension << "]";
850 if (NextDimension)
851 Type::outputPost(OS, *NextDimension);
852 else if (ElementType)
853 Type::outputPost(OS, *ElementType);
854}
855
Zachary Turner316109b2018-07-29 16:38:02 +0000856struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000857 SymbolCategory Category;
858
Zachary Turner316109b2018-07-29 16:38:02 +0000859 Name *SymbolName = nullptr;
860 Type *SymbolType = nullptr;
861};
862
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000863} // namespace
864
865namespace {
866
867// Demangler class takes the main role in demangling symbols.
868// It has a set of functions to parse mangled symbols into Type instances.
869// It also has a set of functions to cnovert Type instances to strings.
870class Demangler {
871public:
Zachary Turner316109b2018-07-29 16:38:02 +0000872 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000873
874 // You are supposed to call parse() first and then check if error is true. If
875 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000876 Symbol *parse(StringView &MangledName);
877 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000878
879 // True if an error occurred.
880 bool Error = false;
881
Zachary Turner3a758e22018-08-01 18:33:04 +0000882 void dumpBackReferences();
883
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000884private:
Zachary Turner316109b2018-07-29 16:38:02 +0000885 Type *demangleVariableEncoding(StringView &MangledName);
886 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000887
Zachary Turner316109b2018-07-29 16:38:02 +0000888 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000889
890 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000891 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
892 Type *demangleBasicType(StringView &MangledName);
893 UdtType *demangleClassType(StringView &MangledName);
894 PointerType *demanglePointerType(StringView &MangledName);
895 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
896 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
897 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000898
Zachary Turner316109b2018-07-29 16:38:02 +0000899 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000900
Zachary Turnerd30700f2018-07-31 17:16:44 +0000901 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
902 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000903
Zachary Turner316109b2018-07-29 16:38:02 +0000904 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000905
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000906 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000907
908 /// Allocate a copy of \p Borrowed into memory that we own.
909 StringView copyString(StringView Borrowed);
910
Zachary Turner316109b2018-07-29 16:38:02 +0000911 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
912 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000913
Zachary Turner44ebbc22018-08-01 18:32:47 +0000914 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
915 Name *demangleUnqualifiedSymbolName(StringView &MangledName, bool Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000916
Zachary Turner316109b2018-07-29 16:38:02 +0000917 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
918 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000919
Zachary Turner316109b2018-07-29 16:38:02 +0000920 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +0000921 Name *demangleTemplateInstantiationName(StringView &MangledName);
Zachary Turner316109b2018-07-29 16:38:02 +0000922 Name *demangleOperatorName(StringView &MangledName);
923 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
924 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000925 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000926
Zachary Turner931e8792018-07-30 23:02:10 +0000927 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
928
Zachary Turner316109b2018-07-29 16:38:02 +0000929 FuncClass demangleFunctionClass(StringView &MangledName);
930 CallingConv demangleCallingConvention(StringView &MangledName);
931 StorageClass demangleVariableStorageClass(StringView &MangledName);
932 ReferenceKind demangleReferenceKind(StringView &MangledName);
933 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000934
Zachary Turner316109b2018-07-29 16:38:02 +0000935 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000936
937 // Memory allocator.
938 ArenaAllocator Arena;
939
Zachary Turner23df1312018-07-26 22:13:39 +0000940 // A single type uses one global back-ref table for all function params.
941 // This means back-refs can even go "into" other types. Examples:
942 //
943 // // Second int* is a back-ref to first.
944 // void foo(int *, int*);
945 //
946 // // Second int* is not a back-ref to first (first is not a function param).
947 // int* foo(int*);
948 //
949 // // Second int* is a back-ref to first (ALL function types share the same
950 // // back-ref map.
951 // using F = void(*)(int*);
952 // F G(int *);
953 Type *FunctionParamBackRefs[10];
954 size_t FunctionParamBackRefCount = 0;
955
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000956 // The first 10 BackReferences in a mangled name can be back-referenced by
957 // special name @[0-9]. This is a storage for the first 10 BackReferences.
958 StringView BackReferences[10];
959 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000960};
961} // namespace
962
Zachary Turner71c91f92018-07-30 03:12:34 +0000963StringView Demangler::copyString(StringView Borrowed) {
964 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
965 std::strcpy(Stable, Borrowed.begin());
966
967 return {Stable, Borrowed.size()};
968}
969
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000970// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000971Symbol *Demangler::parse(StringView &MangledName) {
972 Symbol *S = Arena.alloc<Symbol>();
973
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000974 // MSVC-style mangled symbols must start with '?'.
975 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000976 S->SymbolName = Arena.alloc<Name>();
977 S->SymbolName->Str = MangledName;
978 S->SymbolType = Arena.alloc<Type>();
979 S->SymbolType->Prim = PrimTy::Unknown;
980 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000981 }
982
983 // What follows is a main symbol name. This may include
984 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000985 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000986 if (Error)
987 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000988 // Read a variable.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000989 if (startsWithDigit(MangledName)) {
990 S->Category = SymbolCategory::Variable;
991 S->SymbolType = demangleVariableEncoding(MangledName);
992 } else {
993 S->Category = SymbolCategory::Function;
994 S->SymbolType = demangleFunctionEncoding(MangledName);
995 }
996
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000997 if (Error)
998 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000999
Zachary Turner316109b2018-07-29 16:38:02 +00001000 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001001}
1002
1003// <type-encoding> ::= <storage-class> <variable-type>
1004// <storage-class> ::= 0 # private static member
1005// ::= 1 # protected static member
1006// ::= 2 # public static member
1007// ::= 3 # global
1008// ::= 4 # static local
1009
Zachary Turner316109b2018-07-29 16:38:02 +00001010Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1011 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001012
Zachary Turner316109b2018-07-29 16:38:02 +00001013 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001014
1015 Ty->Storage = SC;
1016
1017 // <variable-type> ::= <type> <cvr-qualifiers>
1018 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1019 switch (Ty->Prim) {
1020 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001021 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001022 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001023 Ty->Quals =
1024 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001025
Zachary Turnerd742d642018-07-26 19:56:09 +00001026 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001027 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001028
Zachary Turnerd742d642018-07-26 19:56:09 +00001029 if (Ty->Prim == PrimTy::MemberPtr) {
1030 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001031 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001032 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001033 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1034 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1035 } else {
1036 PointerType *PTy = static_cast<PointerType *>(Ty);
1037 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001038 }
1039
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001040 break;
1041 }
1042 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001043 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001044 break;
1045 }
1046
1047 return Ty;
1048}
1049
1050// Sometimes numbers are encoded in mangled symbols. For example,
1051// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1052// length 20), so we need some way to embed numbers as part of symbols.
1053// This function parses it.
1054//
1055// <number> ::= [?] <non-negative integer>
1056//
1057// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1058// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1059//
1060// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001061int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001062 bool neg = MangledName.consumeFront("?");
1063
1064 if (startsWithDigit(MangledName)) {
1065 int32_t Ret = MangledName[0] - '0' + 1;
1066 MangledName = MangledName.dropFront(1);
1067 return neg ? -Ret : Ret;
1068 }
1069
1070 int Ret = 0;
1071 for (size_t i = 0; i < MangledName.size(); ++i) {
1072 char C = MangledName[i];
1073 if (C == '@') {
1074 MangledName = MangledName.dropFront(i + 1);
1075 return neg ? -Ret : Ret;
1076 }
1077 if ('A' <= C && C <= 'P') {
1078 Ret = (Ret << 4) + (C - 'A');
1079 continue;
1080 }
1081 break;
1082 }
1083
1084 Error = true;
1085 return 0;
1086}
1087
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001088// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1089// Memorize it.
1090void Demangler::memorizeString(StringView S) {
1091 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1092 return;
1093 for (size_t i = 0; i < BackRefCount; ++i)
1094 if (S == BackReferences[i])
1095 return;
1096 BackReferences[BackRefCount++] = S;
1097}
1098
Zachary Turner316109b2018-07-29 16:38:02 +00001099Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001100 assert(startsWithDigit(MangledName));
1101
1102 size_t I = MangledName[0] - '0';
1103 if (I >= BackRefCount) {
1104 Error = true;
1105 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001106 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001107
1108 MangledName = MangledName.dropFront();
1109 Name *Node = Arena.alloc<Name>();
1110 Node->Str = BackReferences[I];
1111 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001112}
1113
Zachary Turner44ebbc22018-08-01 18:32:47 +00001114Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001115 assert(MangledName.startsWith("?$"));
1116 MangledName.consumeFront("?$");
1117
Zachary Turner44ebbc22018-08-01 18:32:47 +00001118 Name *Node = demangleUnqualifiedSymbolName(MangledName, false);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001119 if (Error)
1120 return nullptr;
1121
Zachary Turnerd30700f2018-07-31 17:16:44 +00001122 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001123 if (Error)
1124 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001125
Zachary Turner44ebbc22018-08-01 18:32:47 +00001126 Node->IsTemplateInstantiation = true;
1127
Zachary Turner71c91f92018-07-30 03:12:34 +00001128 // Render this class template name into a string buffer so that we can
1129 // memorize it for the purpose of back-referencing.
1130 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1131 outputName(OS, Node);
1132 OS << '\0';
1133 char *Name = OS.getBuffer();
1134
1135 StringView Owned = copyString(Name);
1136 memorizeString(Owned);
1137 std::free(Name);
1138
Zachary Turnera7dffb12018-07-28 22:10:42 +00001139 return Node;
1140}
1141
Zachary Turner316109b2018-07-29 16:38:02 +00001142Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001143 assert(MangledName.startsWith('?'));
1144 MangledName.consumeFront('?');
1145
Zachary Turner316109b2018-07-29 16:38:02 +00001146 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001147 switch (MangledName.popFront()) {
1148 case '0':
1149 return "ctor";
1150 case '1':
1151 return "dtor";
1152 case '2':
1153 return " new";
1154 case '3':
1155 return " delete";
1156 case '4':
1157 return "=";
1158 case '5':
1159 return ">>";
1160 case '6':
1161 return "<<";
1162 case '7':
1163 return "!";
1164 case '8':
1165 return "==";
1166 case '9':
1167 return "!=";
1168 case 'A':
1169 return "[]";
1170 case 'C':
1171 return "->";
1172 case 'D':
1173 return "*";
1174 case 'E':
1175 return "++";
1176 case 'F':
1177 return "--";
1178 case 'G':
1179 return "-";
1180 case 'H':
1181 return "+";
1182 case 'I':
1183 return "&";
1184 case 'J':
1185 return "->*";
1186 case 'K':
1187 return "/";
1188 case 'L':
1189 return "%";
1190 case 'M':
1191 return "<";
1192 case 'N':
1193 return "<=";
1194 case 'O':
1195 return ">";
1196 case 'P':
1197 return ">=";
1198 case 'Q':
1199 return ",";
1200 case 'R':
1201 return "()";
1202 case 'S':
1203 return "~";
1204 case 'T':
1205 return "^";
1206 case 'U':
1207 return "|";
1208 case 'V':
1209 return "&&";
1210 case 'W':
1211 return "||";
1212 case 'X':
1213 return "*=";
1214 case 'Y':
1215 return "+=";
1216 case 'Z':
1217 return "-=";
1218 case '_': {
1219 if (MangledName.empty())
1220 break;
1221
1222 switch (MangledName.popFront()) {
1223 case '0':
1224 return "/=";
1225 case '1':
1226 return "%=";
1227 case '2':
1228 return ">>=";
1229 case '3':
1230 return "<<=";
1231 case '4':
1232 return "&=";
1233 case '5':
1234 return "|=";
1235 case '6':
1236 return "^=";
1237 case 'U':
1238 return " new[]";
1239 case 'V':
1240 return " delete[]";
1241 case '_':
1242 if (MangledName.consumeFront("L"))
1243 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001244 if (MangledName.consumeFront("K")) {
1245 size_t EndPos = MangledName.find('@');
1246 if (EndPos == StringView::npos)
1247 break;
1248 StringView OpName = demangleSimpleString(MangledName, false);
1249 size_t FullSize = OpName.size() + 3; // <space>""OpName
1250 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1251 Buffer[0] = ' ';
1252 Buffer[1] = '"';
1253 Buffer[2] = '"';
1254 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1255 return {Buffer, FullSize};
1256 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001257 }
1258 }
1259 }
1260 Error = true;
1261 return "";
1262 };
1263
1264 Name *Node = Arena.alloc<Name>();
Zachary Turner44ebbc22018-08-01 18:32:47 +00001265 Node->Str = NameString();
1266 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001267 return Node;
1268}
1269
Zachary Turner316109b2018-07-29 16:38:02 +00001270Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001271 StringView S = demangleSimpleString(MangledName, Memorize);
1272 if (Error)
1273 return nullptr;
1274
Zachary Turnera7dffb12018-07-28 22:10:42 +00001275 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001276 Node->Str = S;
1277 return Node;
1278}
1279
1280StringView Demangler::demangleSimpleString(StringView &MangledName,
1281 bool Memorize) {
1282 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001283 for (size_t i = 0; i < MangledName.size(); ++i) {
1284 if (MangledName[i] != '@')
1285 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001286 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001287 MangledName = MangledName.dropFront(i + 1);
1288
1289 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001290 memorizeString(S);
1291 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001292 }
1293
1294 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001295 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001296}
1297
Zachary Turner316109b2018-07-29 16:38:02 +00001298Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001299 assert(MangledName.startsWith("?A"));
1300 MangledName.consumeFront("?A");
1301
1302 Name *Node = Arena.alloc<Name>();
1303 Node->Str = "`anonymous namespace'";
1304 if (MangledName.consumeFront('@'))
1305 return Node;
1306
1307 Error = true;
1308 return nullptr;
1309}
1310
Zachary Turner71c91f92018-07-30 03:12:34 +00001311Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1312 assert(startsWithLocalScopePattern(MangledName));
1313
1314 Name *Node = Arena.alloc<Name>();
1315 MangledName.consumeFront('?');
1316 int ScopeIdentifier = demangleNumber(MangledName);
1317
1318 // One ? to terminate the number
1319 MangledName.consumeFront('?');
1320
1321 assert(!Error);
1322 Symbol *Scope = parse(MangledName);
1323 if (Error)
1324 return nullptr;
1325
1326 // Render the parent symbol's name into a buffer.
1327 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1328 OS << '`';
1329 output(Scope, OS);
1330 OS << '\'';
1331 OS << "::`" << ScopeIdentifier << "'";
1332 OS << '\0';
1333 char *Result = OS.getBuffer();
1334 Node->Str = copyString(Result);
1335 std::free(Result);
1336 return Node;
1337}
1338
Zachary Turnera7dffb12018-07-28 22:10:42 +00001339// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001340Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001341 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001342 if (Error)
1343 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001344 assert(TypeName);
1345
Zachary Turner316109b2018-07-29 16:38:02 +00001346 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001347 if (Error)
1348 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001349 assert(QualName);
1350 return QualName;
1351}
1352
1353// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1354// Symbol names have slightly different rules regarding what can appear
1355// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001356Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001357 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001358 if (Error)
1359 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001360 assert(SymbolName);
1361
Zachary Turner316109b2018-07-29 16:38:02 +00001362 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001363 if (Error)
1364 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001365 assert(QualName);
1366 return QualName;
1367}
1368
Zachary Turner44ebbc22018-08-01 18:32:47 +00001369Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1370 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001371 // An inner-most name can be a back-reference, because a fully-qualified name
1372 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1373 // them (for example template parameters), and these nested parameters can
1374 // refer to previously mangled types.
1375 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001376 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001377
1378 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001379 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001380
Zachary Turner44ebbc22018-08-01 18:32:47 +00001381 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001382}
1383
Zachary Turner44ebbc22018-08-01 18:32:47 +00001384Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
1385 bool Memorize) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001386 if (startsWithDigit(MangledName))
1387 return demangleBackRefName(MangledName);
1388 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001389 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001390 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001391 return demangleOperatorName(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001392 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001393}
1394
Zachary Turner316109b2018-07-29 16:38:02 +00001395Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001396 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001397 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001398
1399 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001400 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001401
1402 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001403 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001404
Zachary Turner71c91f92018-07-30 03:12:34 +00001405 if (startsWithLocalScopePattern(MangledName))
1406 return demangleLocallyScopedNamePiece(MangledName);
1407
Zachary Turner316109b2018-07-29 16:38:02 +00001408 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001409}
1410
Zachary Turner316109b2018-07-29 16:38:02 +00001411Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1412 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001413 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001414
1415 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001416 if (MangledName.empty()) {
1417 Error = true;
1418 return nullptr;
1419 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001420
1421 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001422 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001423 if (Error)
1424 return nullptr;
1425
1426 Elem->Next = Head;
1427 Head = Elem;
1428 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001429 return Head;
1430}
1431
Zachary Turner316109b2018-07-29 16:38:02 +00001432FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001433 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1434 RestoreOnError.shouldRestore(false);
1435
1436 switch (MangledName.popFront()) {
1437 case 'A':
1438 return Private;
1439 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001440 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001441 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001442 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001443 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001444 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001445 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001446 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001447 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001448 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001449 case 'I':
1450 return Protected;
1451 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001452 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001453 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001454 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001455 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001456 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001457 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001458 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001459 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001460 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001461 case 'Q':
1462 return Public;
1463 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001464 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001465 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001466 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001467 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001468 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001469 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001470 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001471 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001472 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001473 case 'Y':
1474 return Global;
1475 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001476 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001477 }
1478
1479 Error = true;
1480 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001481 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001482}
1483
Zachary Turner316109b2018-07-29 16:38:02 +00001484CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001485 switch (MangledName.popFront()) {
1486 case 'A':
1487 case 'B':
1488 return CallingConv::Cdecl;
1489 case 'C':
1490 case 'D':
1491 return CallingConv::Pascal;
1492 case 'E':
1493 case 'F':
1494 return CallingConv::Thiscall;
1495 case 'G':
1496 case 'H':
1497 return CallingConv::Stdcall;
1498 case 'I':
1499 case 'J':
1500 return CallingConv::Fastcall;
1501 case 'M':
1502 case 'N':
1503 return CallingConv::Clrcall;
1504 case 'O':
1505 case 'P':
1506 return CallingConv::Eabi;
1507 case 'Q':
1508 return CallingConv::Vectorcall;
1509 }
1510
1511 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001512}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001513
Zachary Turner316109b2018-07-29 16:38:02 +00001514StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001515 assert(std::isdigit(MangledName.front()));
1516
1517 switch (MangledName.popFront()) {
1518 case '0':
1519 return StorageClass::PrivateStatic;
1520 case '1':
1521 return StorageClass::ProtectedStatic;
1522 case '2':
1523 return StorageClass::PublicStatic;
1524 case '3':
1525 return StorageClass::Global;
1526 case '4':
1527 return StorageClass::FunctionLocalStatic;
1528 }
1529 Error = true;
1530 return StorageClass::None;
1531}
1532
Zachary Turner316109b2018-07-29 16:38:02 +00001533std::pair<Qualifiers, bool>
1534Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001535
1536 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001537 // Member qualifiers
1538 case 'Q':
1539 return std::make_pair(Q_None, true);
1540 case 'R':
1541 return std::make_pair(Q_Const, true);
1542 case 'S':
1543 return std::make_pair(Q_Volatile, true);
1544 case 'T':
1545 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1546 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001547 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001548 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001549 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001550 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001551 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001552 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001553 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001554 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001555 }
1556 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001557 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001558}
1559
Zachary Turner931e8792018-07-30 23:02:10 +00001560static bool isTagType(StringView S) {
1561 switch (S.front()) {
1562 case 'T': // union
1563 case 'U': // struct
1564 case 'V': // class
1565 case 'W': // enum
1566 return true;
1567 }
1568 return false;
1569}
1570
1571static bool isPointerType(StringView S) {
1572 if (S.startsWith("$$Q")) // foo &&
1573 return true;
1574
1575 switch (S.front()) {
1576 case 'A': // foo &
1577 case 'P': // foo *
1578 case 'Q': // foo *const
1579 case 'R': // foo *volatile
1580 case 'S': // foo *const volatile
1581 return true;
1582 }
1583 return false;
1584}
1585
1586static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1587
1588static bool isFunctionType(StringView S) {
1589 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1590}
1591
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001592// <variable-type> ::= <type> <cvr-qualifiers>
1593// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001594Type *Demangler::demangleType(StringView &MangledName,
1595 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001596 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001597 bool IsMember = false;
1598 bool IsMemberKnown = false;
1599 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001600 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001601 IsMemberKnown = true;
1602 } else if (QMM == QualifierMangleMode::Result) {
1603 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001604 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001605 IsMemberKnown = true;
1606 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001607 }
1608
1609 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001610 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001611 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001612 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001613 if (!IsMemberKnown)
1614 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001615
Zachary Turnerd742d642018-07-26 19:56:09 +00001616 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001617 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001618 else
Zachary Turner316109b2018-07-29 16:38:02 +00001619 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001620 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001621 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001622 else if (isFunctionType(MangledName)) {
1623 if (MangledName.consumeFront("$$A8@@"))
1624 Ty = demangleFunctionType(MangledName, true, false);
1625 else {
1626 assert(MangledName.startsWith("$$A6"));
1627 MangledName.consumeFront("$$A6");
1628 Ty = demangleFunctionType(MangledName, false, false);
1629 }
1630 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001631 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001632 assert(Ty && !Error);
1633 if (!Ty || Error)
1634 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001635 }
Zachary Turner931e8792018-07-30 23:02:10 +00001636
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001637 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1638 return Ty;
1639}
1640
Zachary Turner316109b2018-07-29 16:38:02 +00001641ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001642 if (MangledName.consumeFront('G'))
1643 return ReferenceKind::LValueRef;
1644 else if (MangledName.consumeFront('H'))
1645 return ReferenceKind::RValueRef;
1646 return ReferenceKind::None;
1647}
1648
Zachary Turner316109b2018-07-29 16:38:02 +00001649void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001650 if (MangledName.consumeFront('Z'))
1651 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001652
Zachary Turner38b78a72018-07-26 20:20:10 +00001653 Error = true;
1654}
1655
Zachary Turner316109b2018-07-29 16:38:02 +00001656FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1657 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001658 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001659 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001660 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001661 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001662
1663 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001664 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1665 FTy->RefKind = demangleReferenceKind(MangledName);
1666 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001667 }
1668
1669 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001670 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001671
1672 // <return-type> ::= <type>
1673 // ::= @ # structors (they have no declared return type)
1674 bool IsStructor = MangledName.consumeFront('@');
1675 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001676 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001677
Zachary Turner316109b2018-07-29 16:38:02 +00001678 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001679
Zachary Turner316109b2018-07-29 16:38:02 +00001680 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001681
1682 return FTy;
1683}
1684
Zachary Turner316109b2018-07-29 16:38:02 +00001685Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1686 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001687
1688 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001689 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001690 FTy->FunctionClass = FC;
1691
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001692 return FTy;
1693}
1694
1695// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001696Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001697 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001698
Zachary Turner931e8792018-07-30 23:02:10 +00001699 if (MangledName.consumeFront("$$T")) {
1700 Ty->Prim = PrimTy::Nullptr;
1701 return Ty;
1702 }
1703
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001704 switch (MangledName.popFront()) {
1705 case 'X':
1706 Ty->Prim = PrimTy::Void;
1707 break;
1708 case 'D':
1709 Ty->Prim = PrimTy::Char;
1710 break;
1711 case 'C':
1712 Ty->Prim = PrimTy::Schar;
1713 break;
1714 case 'E':
1715 Ty->Prim = PrimTy::Uchar;
1716 break;
1717 case 'F':
1718 Ty->Prim = PrimTy::Short;
1719 break;
1720 case 'G':
1721 Ty->Prim = PrimTy::Ushort;
1722 break;
1723 case 'H':
1724 Ty->Prim = PrimTy::Int;
1725 break;
1726 case 'I':
1727 Ty->Prim = PrimTy::Uint;
1728 break;
1729 case 'J':
1730 Ty->Prim = PrimTy::Long;
1731 break;
1732 case 'K':
1733 Ty->Prim = PrimTy::Ulong;
1734 break;
1735 case 'M':
1736 Ty->Prim = PrimTy::Float;
1737 break;
1738 case 'N':
1739 Ty->Prim = PrimTy::Double;
1740 break;
1741 case 'O':
1742 Ty->Prim = PrimTy::Ldouble;
1743 break;
1744 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001745 if (MangledName.empty()) {
1746 Error = true;
1747 return nullptr;
1748 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001749 switch (MangledName.popFront()) {
1750 case 'N':
1751 Ty->Prim = PrimTy::Bool;
1752 break;
1753 case 'J':
1754 Ty->Prim = PrimTy::Int64;
1755 break;
1756 case 'K':
1757 Ty->Prim = PrimTy::Uint64;
1758 break;
1759 case 'W':
1760 Ty->Prim = PrimTy::Wchar;
1761 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001762 case 'S':
1763 Ty->Prim = PrimTy::Char16;
1764 break;
1765 case 'U':
1766 Ty->Prim = PrimTy::Char32;
1767 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001768 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001769 Error = true;
1770 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001771 }
1772 break;
1773 }
Zachary Turner931e8792018-07-30 23:02:10 +00001774 default:
1775 Error = true;
1776 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001777 }
1778 return Ty;
1779}
1780
Zachary Turner316109b2018-07-29 16:38:02 +00001781UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001782 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001783
1784 switch (MangledName.popFront()) {
1785 case 'T':
1786 UTy->Prim = PrimTy::Union;
1787 break;
1788 case 'U':
1789 UTy->Prim = PrimTy::Struct;
1790 break;
1791 case 'V':
1792 UTy->Prim = PrimTy::Class;
1793 break;
1794 case 'W':
1795 if (MangledName.popFront() != '4') {
1796 Error = true;
1797 return nullptr;
1798 }
1799 UTy->Prim = PrimTy::Enum;
1800 break;
1801 default:
1802 assert(false);
1803 }
1804
Zachary Turner316109b2018-07-29 16:38:02 +00001805 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001806 return UTy;
1807}
1808
Zachary Turnerd742d642018-07-26 19:56:09 +00001809static std::pair<Qualifiers, PointerAffinity>
1810demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001811 if (MangledName.consumeFront("$$Q"))
1812 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1813
Zachary Turnerd742d642018-07-26 19:56:09 +00001814 switch (MangledName.popFront()) {
1815 case 'A':
1816 return std::make_pair(Q_None, PointerAffinity::Reference);
1817 case 'P':
1818 return std::make_pair(Q_None, PointerAffinity::Pointer);
1819 case 'Q':
1820 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1821 case 'R':
1822 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1823 case 'S':
1824 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1825 PointerAffinity::Pointer);
1826 default:
1827 assert(false && "Ty is not a pointer type!");
1828 }
1829 return std::make_pair(Q_None, PointerAffinity::Pointer);
1830}
1831
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001832// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1833// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001834PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001835 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001836
Zachary Turner931e8792018-07-30 23:02:10 +00001837 std::tie(Pointer->Quals, Pointer->Affinity) =
1838 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001839
Zachary Turner931e8792018-07-30 23:02:10 +00001840 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001841 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001842 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001843 return Pointer;
1844 }
1845
Zachary Turner316109b2018-07-29 16:38:02 +00001846 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001847 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1848
Zachary Turner316109b2018-07-29 16:38:02 +00001849 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001850 return Pointer;
1851}
1852
Zachary Turner316109b2018-07-29 16:38:02 +00001853MemberPointerType *
1854Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001855 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1856 Pointer->Prim = PrimTy::MemberPtr;
1857
1858 PointerAffinity Affinity;
1859 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1860 assert(Affinity == PointerAffinity::Pointer);
1861
Zachary Turner316109b2018-07-29 16:38:02 +00001862 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001863 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1864
Zachary Turner38b78a72018-07-26 20:20:10 +00001865 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001866 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1867 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001868 } else {
1869 Qualifiers PointeeQuals = Q_None;
1870 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001871 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001872 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001873 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001874
Zachary Turner316109b2018-07-29 16:38:02 +00001875 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001876 Pointer->Pointee->Quals = PointeeQuals;
1877 }
1878
Zachary Turnerd742d642018-07-26 19:56:09 +00001879 return Pointer;
1880}
1881
Zachary Turner316109b2018-07-29 16:38:02 +00001882Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001883 Qualifiers Quals = Q_None;
1884 if (MangledName.consumeFront('E'))
1885 Quals = Qualifiers(Quals | Q_Pointer64);
1886 if (MangledName.consumeFront('I'))
1887 Quals = Qualifiers(Quals | Q_Restrict);
1888 if (MangledName.consumeFront('F'))
1889 Quals = Qualifiers(Quals | Q_Unaligned);
1890
1891 return Quals;
1892}
1893
Zachary Turner316109b2018-07-29 16:38:02 +00001894ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001895 assert(MangledName.front() == 'Y');
1896 MangledName.popFront();
1897
Zachary Turner316109b2018-07-29 16:38:02 +00001898 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001899 if (Dimension <= 0) {
1900 Error = true;
1901 return nullptr;
1902 }
1903
Zachary Turner9d72aa92018-07-20 18:35:06 +00001904 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001905 ArrayType *Dim = ATy;
1906 for (int I = 0; I < Dimension; ++I) {
1907 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001908 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001909 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001910 Dim = Dim->NextDimension;
1911 }
1912
1913 if (MangledName.consumeFront("$$C")) {
1914 if (MangledName.consumeFront("B"))
1915 ATy->Quals = Q_Const;
1916 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1917 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1918 else if (!MangledName.consumeFront("A"))
1919 Error = true;
1920 }
1921
Zachary Turner316109b2018-07-29 16:38:02 +00001922 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001923 Dim->ElementType = ATy->ElementType;
1924 return ATy;
1925}
1926
1927// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001928FunctionParams
1929Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001930 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001931 if (MangledName.consumeFront('X'))
1932 return {};
1933
Zachary Turnerd30700f2018-07-31 17:16:44 +00001934 FunctionParams *Head;
1935 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001936 while (!Error && !MangledName.startsWith('@') &&
1937 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001938
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001939 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001940 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001941 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001942 Error = true;
1943 return {};
1944 }
1945 MangledName = MangledName.dropFront();
1946
Zachary Turnerd30700f2018-07-31 17:16:44 +00001947 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001948 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001949 Current = &(*Current)->Next;
1950 continue;
1951 }
1952
Zachary Turner23df1312018-07-26 22:13:39 +00001953 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001954
Zachary Turnerd30700f2018-07-31 17:16:44 +00001955 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001956 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001957
Zachary Turner23df1312018-07-26 22:13:39 +00001958 size_t CharsConsumed = OldSize - MangledName.size();
1959 assert(CharsConsumed != 0);
1960
1961 // Single-letter types are ignored for backreferences because memorizing
1962 // them doesn't save anything.
1963 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1964 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1965
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001966 Current = &(*Current)->Next;
1967 }
1968
Zachary Turner38b78a72018-07-26 20:20:10 +00001969 if (Error)
1970 return {};
1971
1972 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1973 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1974 // the following Z could be a throw specifier.
1975 if (MangledName.consumeFront('@'))
1976 return *Head;
1977
1978 if (MangledName.consumeFront('Z')) {
1979 Head->IsVariadic = true;
1980 return *Head;
1981 }
1982
1983 Error = true;
1984 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001985}
1986
Zachary Turnerd30700f2018-07-31 17:16:44 +00001987TemplateParams *
1988Demangler::demangleTemplateParameterList(StringView &MangledName) {
1989 TemplateParams *Head;
1990 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00001991 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001992 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001993 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00001994
1995 // Empty parameter pack.
1996 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
1997 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001998 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001999 }
2000
Zachary Turnerd30700f2018-07-31 17:16:44 +00002001 if (MangledName.consumeFront("$$Y")) {
2002 (*Current)->IsTemplateTemplate = true;
2003 (*Current)->IsAliasTemplate = true;
2004 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
2005 } else if (MangledName.consumeFront("$1?")) {
2006 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
2007 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
2008 } else {
2009 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002010 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002011 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002012 if (Error)
2013 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002014
2015 Current = &(*Current)->Next;
2016 }
2017
2018 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002019 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002020
2021 // Template parameter lists cannot be variadic, so it can only be terminated
2022 // by @.
2023 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002024 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002025 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002026 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002027}
2028
Zachary Turner316109b2018-07-29 16:38:02 +00002029void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002030 // Converts an AST to a string.
2031 //
2032 // Converting an AST representing a C++ type to a string is tricky due
2033 // to the bad grammar of the C++ declaration inherited from C. You have
2034 // to construct a string from inside to outside. For example, if a type
2035 // X is a pointer to a function returning int, the order you create a
2036 // string becomes something like this:
2037 //
2038 // (1) X is a pointer: *X
2039 // (2) (1) is a function returning int: int (*X)()
2040 //
2041 // So you cannot construct a result just by appending strings to a result.
2042 //
2043 // To deal with this, we split the function into two. outputPre() writes
2044 // the "first half" of type declaration, and outputPost() writes the
2045 // "second half". For example, outputPre() writes a return type for a
2046 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00002047 Type::outputPre(OS, *S->SymbolType);
2048 outputName(OS, S->SymbolName);
2049 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002050}
2051
Zachary Turner3a758e22018-08-01 18:33:04 +00002052void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002053 std::printf("%d function parameter backreferences\n",
2054 (int)FunctionParamBackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002055
2056 // Create an output stream so we can render each type.
2057 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
2058 for (size_t I = 0; I < FunctionParamBackRefCount; ++I) {
2059 OS.setCurrentPosition(0);
2060
2061 Type *T = FunctionParamBackRefs[I];
2062 Type::outputPre(OS, *T);
2063 Type::outputPost(OS, *T);
2064
Zachary Turner5ae08b82018-08-01 18:44:12 +00002065 std::printf(" [%d] - %*s\n", (int)I, (int)OS.getCurrentPosition(),
2066 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00002067 }
2068 std::free(OS.getBuffer());
2069
2070 if (FunctionParamBackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002071 std::printf("\n");
2072 std::printf("%d name backreferences\n", (int)BackRefCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00002073 for (size_t I = 0; I < BackRefCount; ++I) {
Zachary Turner5ae08b82018-08-01 18:44:12 +00002074 std::printf(" [%d] - %*s\n", (int)I, (int)BackReferences[I].size(),
2075 BackReferences[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00002076 }
2077 if (BackRefCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00002078 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00002079}
2080
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002081char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002082 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002083 Demangler D;
2084 StringView Name{MangledName};
2085 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002086
Zachary Turner3a758e22018-08-01 18:33:04 +00002087 if (Flags & MSDF_DumpBackrefs)
2088 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002089 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002090 if (D.Error) {
2091 OS << MangledName;
2092 *Status = llvm::demangle_invalid_mangled_name;
2093 } else {
2094 D.output(S, OS);
2095 *Status = llvm::demangle_success;
2096 }
2097
Zachary Turner71c91f92018-07-30 03:12:34 +00002098 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002099 return OS.getBuffer();
2100}