blob: 9cf7c4bb1272d0ca279f588ee3b677fa280f57bb [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
Zachary Turner44ebbc22018-08-01 18:32:47 +0000207enum class SymbolCategory { Function, Variable };
208
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000209namespace {
210
211struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000212struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000213
Zachary Turnerd30700f2018-07-31 17:16:44 +0000214struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000215 bool IsVariadic = false;
216
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000217 Type *Current = nullptr;
218
Zachary Turnerd30700f2018-07-31 17:16:44 +0000219 FunctionParams *Next = nullptr;
220};
Zachary Turner931e8792018-07-30 23:02:10 +0000221
Zachary Turnerd30700f2018-07-31 17:16:44 +0000222struct TemplateParams {
223 bool IsTemplateTemplate = false;
224 bool IsAliasTemplate = false;
225
226 // Type can be null if this is a template template parameter. In that case
227 // only Name will be valid.
228 Type *ParamType = nullptr;
229
230 // Name can be valid if this is a template template parameter (see above) or
231 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
232 // Name contains the name of the function and Type contains the signature.
233 Name *ParamName = nullptr;
234
235 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000236};
237
238// The type class. Mangled symbols are first parsed and converted to
239// this type and then converted to string.
240struct Type {
241 virtual ~Type() {}
242
243 virtual Type *clone(ArenaAllocator &Arena) const;
244
245 // Write the "first half" of a given type. This is a static functions to
246 // give the code a chance to do processing that is common to a subset of
247 // subclasses
248 static void outputPre(OutputStream &OS, Type &Ty);
249
250 // Write the "second half" of a given type. This is a static functions to
251 // give the code a chance to do processing that is common to a subset of
252 // subclasses
253 static void outputPost(OutputStream &OS, Type &Ty);
254
255 virtual void outputPre(OutputStream &OS);
256 virtual void outputPost(OutputStream &OS);
257
258 // Primitive type such as Int.
259 PrimTy Prim = PrimTy::Unknown;
260
261 Qualifiers Quals = Q_None;
262 StorageClass Storage = StorageClass::None; // storage class
263};
264
265// Represents an identifier which may be a template.
266struct Name {
267 // Name read from an MangledName string.
268 StringView Str;
269
Zachary Turner44ebbc22018-08-01 18:32:47 +0000270 bool IsTemplateInstantiation = false;
271 bool IsOperator = false;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000272
Zachary Turner44ebbc22018-08-01 18:32:47 +0000273 // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
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 Turner44ebbc22018-08-01 18:32:47 +0000544 if (TheName->IsTemplateInstantiation)
Zachary Turnerd30700f2018-07-31 17:16:44 +0000545 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000546 OS << "::";
547 }
548
549 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000550 if (!TheName->IsOperator) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000551 OS << TheName->Str;
Zachary Turner44ebbc22018-08-01 18:32:47 +0000552 if (TheName->IsTemplateInstantiation)
Zachary Turnerd30700f2018-07-31 17:16:44 +0000553 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000554 return;
555 }
556
557 // Print out ctor or dtor.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000558 if (TheName->Str == "dtor")
Zachary Turnera7dffb12018-07-28 22:10:42 +0000559 OS << "~";
560
Zachary Turner44ebbc22018-08-01 18:32:47 +0000561 if (TheName->Str == "ctor" || TheName->Str == "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.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000569 OS << "operator" << TheName->Str;
570 if (TheName->IsTemplateInstantiation)
571 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000572}
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 {
Zachary Turner44ebbc22018-08-01 18:32:47 +0000856 SymbolCategory Category;
857
Zachary Turner316109b2018-07-29 16:38:02 +0000858 Name *SymbolName = nullptr;
859 Type *SymbolType = nullptr;
860};
861
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000862} // namespace
863
864namespace {
865
866// Demangler class takes the main role in demangling symbols.
867// It has a set of functions to parse mangled symbols into Type instances.
868// It also has a set of functions to cnovert Type instances to strings.
869class Demangler {
870public:
Zachary Turner316109b2018-07-29 16:38:02 +0000871 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000872
873 // You are supposed to call parse() first and then check if error is true. If
874 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000875 Symbol *parse(StringView &MangledName);
876 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000877
878 // True if an error occurred.
879 bool Error = false;
880
Zachary Turner3a758e22018-08-01 18:33:04 +0000881 void dumpBackReferences();
882
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000883private:
Zachary Turner316109b2018-07-29 16:38:02 +0000884 Type *demangleVariableEncoding(StringView &MangledName);
885 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000886
Zachary Turner316109b2018-07-29 16:38:02 +0000887 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000888
889 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000890 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
891 Type *demangleBasicType(StringView &MangledName);
892 UdtType *demangleClassType(StringView &MangledName);
893 PointerType *demanglePointerType(StringView &MangledName);
894 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
895 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
896 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000897
Zachary Turner316109b2018-07-29 16:38:02 +0000898 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000899
Zachary Turnerd30700f2018-07-31 17:16:44 +0000900 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
901 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000902
Zachary Turner316109b2018-07-29 16:38:02 +0000903 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000904
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000905 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000906
907 /// Allocate a copy of \p Borrowed into memory that we own.
908 StringView copyString(StringView Borrowed);
909
Zachary Turner316109b2018-07-29 16:38:02 +0000910 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
911 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000912
Zachary Turner44ebbc22018-08-01 18:32:47 +0000913 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
914 Name *demangleUnqualifiedSymbolName(StringView &MangledName, bool Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000915
Zachary Turner316109b2018-07-29 16:38:02 +0000916 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
917 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000918
Zachary Turner316109b2018-07-29 16:38:02 +0000919 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +0000920 Name *demangleTemplateInstantiationName(StringView &MangledName);
Zachary Turner316109b2018-07-29 16:38:02 +0000921 Name *demangleOperatorName(StringView &MangledName);
922 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
923 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000924 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000925
Zachary Turner931e8792018-07-30 23:02:10 +0000926 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
927
Zachary Turner316109b2018-07-29 16:38:02 +0000928 FuncClass demangleFunctionClass(StringView &MangledName);
929 CallingConv demangleCallingConvention(StringView &MangledName);
930 StorageClass demangleVariableStorageClass(StringView &MangledName);
931 ReferenceKind demangleReferenceKind(StringView &MangledName);
932 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000933
Zachary Turner316109b2018-07-29 16:38:02 +0000934 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000935
936 // Memory allocator.
937 ArenaAllocator Arena;
938
Zachary Turner23df1312018-07-26 22:13:39 +0000939 // A single type uses one global back-ref table for all function params.
940 // This means back-refs can even go "into" other types. Examples:
941 //
942 // // Second int* is a back-ref to first.
943 // void foo(int *, int*);
944 //
945 // // Second int* is not a back-ref to first (first is not a function param).
946 // int* foo(int*);
947 //
948 // // Second int* is a back-ref to first (ALL function types share the same
949 // // back-ref map.
950 // using F = void(*)(int*);
951 // F G(int *);
952 Type *FunctionParamBackRefs[10];
953 size_t FunctionParamBackRefCount = 0;
954
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000955 // The first 10 BackReferences in a mangled name can be back-referenced by
956 // special name @[0-9]. This is a storage for the first 10 BackReferences.
957 StringView BackReferences[10];
958 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000959};
960} // namespace
961
Zachary Turner71c91f92018-07-30 03:12:34 +0000962StringView Demangler::copyString(StringView Borrowed) {
963 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
964 std::strcpy(Stable, Borrowed.begin());
965
966 return {Stable, Borrowed.size()};
967}
968
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000969// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000970Symbol *Demangler::parse(StringView &MangledName) {
971 Symbol *S = Arena.alloc<Symbol>();
972
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000973 // MSVC-style mangled symbols must start with '?'.
974 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000975 S->SymbolName = Arena.alloc<Name>();
976 S->SymbolName->Str = MangledName;
977 S->SymbolType = Arena.alloc<Type>();
978 S->SymbolType->Prim = PrimTy::Unknown;
979 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000980 }
981
982 // What follows is a main symbol name. This may include
983 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000984 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000985 if (Error)
986 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000987 // Read a variable.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000988 if (startsWithDigit(MangledName)) {
989 S->Category = SymbolCategory::Variable;
990 S->SymbolType = demangleVariableEncoding(MangledName);
991 } else {
992 S->Category = SymbolCategory::Function;
993 S->SymbolType = demangleFunctionEncoding(MangledName);
994 }
995
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000996 if (Error)
997 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000998
Zachary Turner316109b2018-07-29 16:38:02 +0000999 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001000}
1001
1002// <type-encoding> ::= <storage-class> <variable-type>
1003// <storage-class> ::= 0 # private static member
1004// ::= 1 # protected static member
1005// ::= 2 # public static member
1006// ::= 3 # global
1007// ::= 4 # static local
1008
Zachary Turner316109b2018-07-29 16:38:02 +00001009Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1010 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001011
Zachary Turner316109b2018-07-29 16:38:02 +00001012 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001013
1014 Ty->Storage = SC;
1015
1016 // <variable-type> ::= <type> <cvr-qualifiers>
1017 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1018 switch (Ty->Prim) {
1019 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001020 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001021 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001022 Ty->Quals =
1023 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001024
Zachary Turnerd742d642018-07-26 19:56:09 +00001025 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001026 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001027
Zachary Turnerd742d642018-07-26 19:56:09 +00001028 if (Ty->Prim == PrimTy::MemberPtr) {
1029 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001030 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001031 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001032 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1033 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1034 } else {
1035 PointerType *PTy = static_cast<PointerType *>(Ty);
1036 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001037 }
1038
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001039 break;
1040 }
1041 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001042 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001043 break;
1044 }
1045
1046 return Ty;
1047}
1048
1049// Sometimes numbers are encoded in mangled symbols. For example,
1050// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1051// length 20), so we need some way to embed numbers as part of symbols.
1052// This function parses it.
1053//
1054// <number> ::= [?] <non-negative integer>
1055//
1056// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1057// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1058//
1059// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001060int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001061 bool neg = MangledName.consumeFront("?");
1062
1063 if (startsWithDigit(MangledName)) {
1064 int32_t Ret = MangledName[0] - '0' + 1;
1065 MangledName = MangledName.dropFront(1);
1066 return neg ? -Ret : Ret;
1067 }
1068
1069 int Ret = 0;
1070 for (size_t i = 0; i < MangledName.size(); ++i) {
1071 char C = MangledName[i];
1072 if (C == '@') {
1073 MangledName = MangledName.dropFront(i + 1);
1074 return neg ? -Ret : Ret;
1075 }
1076 if ('A' <= C && C <= 'P') {
1077 Ret = (Ret << 4) + (C - 'A');
1078 continue;
1079 }
1080 break;
1081 }
1082
1083 Error = true;
1084 return 0;
1085}
1086
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001087// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1088// Memorize it.
1089void Demangler::memorizeString(StringView S) {
1090 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1091 return;
1092 for (size_t i = 0; i < BackRefCount; ++i)
1093 if (S == BackReferences[i])
1094 return;
1095 BackReferences[BackRefCount++] = S;
1096}
1097
Zachary Turner316109b2018-07-29 16:38:02 +00001098Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001099 assert(startsWithDigit(MangledName));
1100
1101 size_t I = MangledName[0] - '0';
1102 if (I >= BackRefCount) {
1103 Error = true;
1104 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001106
1107 MangledName = MangledName.dropFront();
1108 Name *Node = Arena.alloc<Name>();
1109 Node->Str = BackReferences[I];
1110 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001111}
1112
Zachary Turner44ebbc22018-08-01 18:32:47 +00001113Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001114 assert(MangledName.startsWith("?$"));
1115 MangledName.consumeFront("?$");
1116
Zachary Turner44ebbc22018-08-01 18:32:47 +00001117 Name *Node = demangleUnqualifiedSymbolName(MangledName, false);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001118 if (Error)
1119 return nullptr;
1120
Zachary Turnerd30700f2018-07-31 17:16:44 +00001121 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001122 if (Error)
1123 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001124
Zachary Turner44ebbc22018-08-01 18:32:47 +00001125 Node->IsTemplateInstantiation = true;
1126
Zachary Turner71c91f92018-07-30 03:12:34 +00001127 // Render this class template name into a string buffer so that we can
1128 // memorize it for the purpose of back-referencing.
1129 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1130 outputName(OS, Node);
1131 OS << '\0';
1132 char *Name = OS.getBuffer();
1133
1134 StringView Owned = copyString(Name);
1135 memorizeString(Owned);
1136 std::free(Name);
1137
Zachary Turnera7dffb12018-07-28 22:10:42 +00001138 return Node;
1139}
1140
Zachary Turner316109b2018-07-29 16:38:02 +00001141Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001142 assert(MangledName.startsWith('?'));
1143 MangledName.consumeFront('?');
1144
Zachary Turner316109b2018-07-29 16:38:02 +00001145 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001146 switch (MangledName.popFront()) {
1147 case '0':
1148 return "ctor";
1149 case '1':
1150 return "dtor";
1151 case '2':
1152 return " new";
1153 case '3':
1154 return " delete";
1155 case '4':
1156 return "=";
1157 case '5':
1158 return ">>";
1159 case '6':
1160 return "<<";
1161 case '7':
1162 return "!";
1163 case '8':
1164 return "==";
1165 case '9':
1166 return "!=";
1167 case 'A':
1168 return "[]";
1169 case 'C':
1170 return "->";
1171 case 'D':
1172 return "*";
1173 case 'E':
1174 return "++";
1175 case 'F':
1176 return "--";
1177 case 'G':
1178 return "-";
1179 case 'H':
1180 return "+";
1181 case 'I':
1182 return "&";
1183 case 'J':
1184 return "->*";
1185 case 'K':
1186 return "/";
1187 case 'L':
1188 return "%";
1189 case 'M':
1190 return "<";
1191 case 'N':
1192 return "<=";
1193 case 'O':
1194 return ">";
1195 case 'P':
1196 return ">=";
1197 case 'Q':
1198 return ",";
1199 case 'R':
1200 return "()";
1201 case 'S':
1202 return "~";
1203 case 'T':
1204 return "^";
1205 case 'U':
1206 return "|";
1207 case 'V':
1208 return "&&";
1209 case 'W':
1210 return "||";
1211 case 'X':
1212 return "*=";
1213 case 'Y':
1214 return "+=";
1215 case 'Z':
1216 return "-=";
1217 case '_': {
1218 if (MangledName.empty())
1219 break;
1220
1221 switch (MangledName.popFront()) {
1222 case '0':
1223 return "/=";
1224 case '1':
1225 return "%=";
1226 case '2':
1227 return ">>=";
1228 case '3':
1229 return "<<=";
1230 case '4':
1231 return "&=";
1232 case '5':
1233 return "|=";
1234 case '6':
1235 return "^=";
1236 case 'U':
1237 return " new[]";
1238 case 'V':
1239 return " delete[]";
1240 case '_':
1241 if (MangledName.consumeFront("L"))
1242 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001243 if (MangledName.consumeFront("K")) {
1244 size_t EndPos = MangledName.find('@');
1245 if (EndPos == StringView::npos)
1246 break;
1247 StringView OpName = demangleSimpleString(MangledName, false);
1248 size_t FullSize = OpName.size() + 3; // <space>""OpName
1249 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1250 Buffer[0] = ' ';
1251 Buffer[1] = '"';
1252 Buffer[2] = '"';
1253 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1254 return {Buffer, FullSize};
1255 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001256 }
1257 }
1258 }
1259 Error = true;
1260 return "";
1261 };
1262
1263 Name *Node = Arena.alloc<Name>();
Zachary Turner44ebbc22018-08-01 18:32:47 +00001264 Node->Str = NameString();
1265 Node->IsOperator = true;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001266 return Node;
1267}
1268
Zachary Turner316109b2018-07-29 16:38:02 +00001269Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001270 StringView S = demangleSimpleString(MangledName, Memorize);
1271 if (Error)
1272 return nullptr;
1273
Zachary Turnera7dffb12018-07-28 22:10:42 +00001274 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001275 Node->Str = S;
1276 return Node;
1277}
1278
1279StringView Demangler::demangleSimpleString(StringView &MangledName,
1280 bool Memorize) {
1281 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001282 for (size_t i = 0; i < MangledName.size(); ++i) {
1283 if (MangledName[i] != '@')
1284 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001285 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001286 MangledName = MangledName.dropFront(i + 1);
1287
1288 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001289 memorizeString(S);
1290 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001291 }
1292
1293 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001294 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001295}
1296
Zachary Turner316109b2018-07-29 16:38:02 +00001297Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001298 assert(MangledName.startsWith("?A"));
1299 MangledName.consumeFront("?A");
1300
1301 Name *Node = Arena.alloc<Name>();
1302 Node->Str = "`anonymous namespace'";
1303 if (MangledName.consumeFront('@'))
1304 return Node;
1305
1306 Error = true;
1307 return nullptr;
1308}
1309
Zachary Turner71c91f92018-07-30 03:12:34 +00001310Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1311 assert(startsWithLocalScopePattern(MangledName));
1312
1313 Name *Node = Arena.alloc<Name>();
1314 MangledName.consumeFront('?');
1315 int ScopeIdentifier = demangleNumber(MangledName);
1316
1317 // One ? to terminate the number
1318 MangledName.consumeFront('?');
1319
1320 assert(!Error);
1321 Symbol *Scope = parse(MangledName);
1322 if (Error)
1323 return nullptr;
1324
1325 // Render the parent symbol's name into a buffer.
1326 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1327 OS << '`';
1328 output(Scope, OS);
1329 OS << '\'';
1330 OS << "::`" << ScopeIdentifier << "'";
1331 OS << '\0';
1332 char *Result = OS.getBuffer();
1333 Node->Str = copyString(Result);
1334 std::free(Result);
1335 return Node;
1336}
1337
Zachary Turnera7dffb12018-07-28 22:10:42 +00001338// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001339Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001340 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001341 if (Error)
1342 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001343 assert(TypeName);
1344
Zachary Turner316109b2018-07-29 16:38:02 +00001345 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001346 if (Error)
1347 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001348 assert(QualName);
1349 return QualName;
1350}
1351
1352// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1353// Symbol names have slightly different rules regarding what can appear
1354// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001355Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001356 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001357 if (Error)
1358 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001359 assert(SymbolName);
1360
Zachary Turner316109b2018-07-29 16:38:02 +00001361 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001362 if (Error)
1363 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001364 assert(QualName);
1365 return QualName;
1366}
1367
Zachary Turner44ebbc22018-08-01 18:32:47 +00001368Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1369 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001370 // An inner-most name can be a back-reference, because a fully-qualified name
1371 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1372 // them (for example template parameters), and these nested parameters can
1373 // refer to previously mangled types.
1374 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001375 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001376
1377 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001378 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001379
Zachary Turner44ebbc22018-08-01 18:32:47 +00001380 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001381}
1382
Zachary Turner44ebbc22018-08-01 18:32:47 +00001383Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
1384 bool Memorize) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001385 if (startsWithDigit(MangledName))
1386 return demangleBackRefName(MangledName);
1387 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001388 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001389 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001390 return demangleOperatorName(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001391 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001392}
1393
Zachary Turner316109b2018-07-29 16:38:02 +00001394Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001395 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001396 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001397
1398 if (MangledName.startsWith("?$"))
Zachary Turner44ebbc22018-08-01 18:32:47 +00001399 return demangleTemplateInstantiationName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001400
1401 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001402 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001403
Zachary Turner71c91f92018-07-30 03:12:34 +00001404 if (startsWithLocalScopePattern(MangledName))
1405 return demangleLocallyScopedNamePiece(MangledName);
1406
Zachary Turner316109b2018-07-29 16:38:02 +00001407 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001408}
1409
Zachary Turner316109b2018-07-29 16:38:02 +00001410Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1411 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001412 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001413
1414 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001415 if (MangledName.empty()) {
1416 Error = true;
1417 return nullptr;
1418 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001419
1420 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001421 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001422 if (Error)
1423 return nullptr;
1424
1425 Elem->Next = Head;
1426 Head = Elem;
1427 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001428 return Head;
1429}
1430
Zachary Turner316109b2018-07-29 16:38:02 +00001431FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001432 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1433 RestoreOnError.shouldRestore(false);
1434
1435 switch (MangledName.popFront()) {
1436 case 'A':
1437 return Private;
1438 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001439 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001440 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001441 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001442 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001443 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001444 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001445 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001446 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001447 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001448 case 'I':
1449 return Protected;
1450 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001451 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001452 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001453 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001455 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001456 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001457 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001458 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001459 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001460 case 'Q':
1461 return Public;
1462 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001463 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001464 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001465 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001466 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001467 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001468 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001469 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001470 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001471 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001472 case 'Y':
1473 return Global;
1474 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001475 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001476 }
1477
1478 Error = true;
1479 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001480 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001481}
1482
Zachary Turner316109b2018-07-29 16:38:02 +00001483CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001484 switch (MangledName.popFront()) {
1485 case 'A':
1486 case 'B':
1487 return CallingConv::Cdecl;
1488 case 'C':
1489 case 'D':
1490 return CallingConv::Pascal;
1491 case 'E':
1492 case 'F':
1493 return CallingConv::Thiscall;
1494 case 'G':
1495 case 'H':
1496 return CallingConv::Stdcall;
1497 case 'I':
1498 case 'J':
1499 return CallingConv::Fastcall;
1500 case 'M':
1501 case 'N':
1502 return CallingConv::Clrcall;
1503 case 'O':
1504 case 'P':
1505 return CallingConv::Eabi;
1506 case 'Q':
1507 return CallingConv::Vectorcall;
1508 }
1509
1510 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001511}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001512
Zachary Turner316109b2018-07-29 16:38:02 +00001513StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001514 assert(std::isdigit(MangledName.front()));
1515
1516 switch (MangledName.popFront()) {
1517 case '0':
1518 return StorageClass::PrivateStatic;
1519 case '1':
1520 return StorageClass::ProtectedStatic;
1521 case '2':
1522 return StorageClass::PublicStatic;
1523 case '3':
1524 return StorageClass::Global;
1525 case '4':
1526 return StorageClass::FunctionLocalStatic;
1527 }
1528 Error = true;
1529 return StorageClass::None;
1530}
1531
Zachary Turner316109b2018-07-29 16:38:02 +00001532std::pair<Qualifiers, bool>
1533Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001534
1535 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001536 // Member qualifiers
1537 case 'Q':
1538 return std::make_pair(Q_None, true);
1539 case 'R':
1540 return std::make_pair(Q_Const, true);
1541 case 'S':
1542 return std::make_pair(Q_Volatile, true);
1543 case 'T':
1544 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1545 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001546 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001547 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001548 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001549 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001550 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001551 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001552 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001553 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001554 }
1555 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001556 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001557}
1558
Zachary Turner931e8792018-07-30 23:02:10 +00001559static bool isTagType(StringView S) {
1560 switch (S.front()) {
1561 case 'T': // union
1562 case 'U': // struct
1563 case 'V': // class
1564 case 'W': // enum
1565 return true;
1566 }
1567 return false;
1568}
1569
1570static bool isPointerType(StringView S) {
1571 if (S.startsWith("$$Q")) // foo &&
1572 return true;
1573
1574 switch (S.front()) {
1575 case 'A': // foo &
1576 case 'P': // foo *
1577 case 'Q': // foo *const
1578 case 'R': // foo *volatile
1579 case 'S': // foo *const volatile
1580 return true;
1581 }
1582 return false;
1583}
1584
1585static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1586
1587static bool isFunctionType(StringView S) {
1588 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1589}
1590
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001591// <variable-type> ::= <type> <cvr-qualifiers>
1592// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001593Type *Demangler::demangleType(StringView &MangledName,
1594 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001595 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001596 bool IsMember = false;
1597 bool IsMemberKnown = false;
1598 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001599 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001600 IsMemberKnown = true;
1601 } else if (QMM == QualifierMangleMode::Result) {
1602 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001603 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001604 IsMemberKnown = true;
1605 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001606 }
1607
1608 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001609 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001610 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001611 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001612 if (!IsMemberKnown)
1613 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001614
Zachary Turnerd742d642018-07-26 19:56:09 +00001615 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001616 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001617 else
Zachary Turner316109b2018-07-29 16:38:02 +00001618 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001619 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001620 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001621 else if (isFunctionType(MangledName)) {
1622 if (MangledName.consumeFront("$$A8@@"))
1623 Ty = demangleFunctionType(MangledName, true, false);
1624 else {
1625 assert(MangledName.startsWith("$$A6"));
1626 MangledName.consumeFront("$$A6");
1627 Ty = demangleFunctionType(MangledName, false, false);
1628 }
1629 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001630 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001631 assert(Ty && !Error);
1632 if (!Ty || Error)
1633 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001634 }
Zachary Turner931e8792018-07-30 23:02:10 +00001635
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001636 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1637 return Ty;
1638}
1639
Zachary Turner316109b2018-07-29 16:38:02 +00001640ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001641 if (MangledName.consumeFront('G'))
1642 return ReferenceKind::LValueRef;
1643 else if (MangledName.consumeFront('H'))
1644 return ReferenceKind::RValueRef;
1645 return ReferenceKind::None;
1646}
1647
Zachary Turner316109b2018-07-29 16:38:02 +00001648void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001649 if (MangledName.consumeFront('Z'))
1650 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001651
Zachary Turner38b78a72018-07-26 20:20:10 +00001652 Error = true;
1653}
1654
Zachary Turner316109b2018-07-29 16:38:02 +00001655FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1656 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001657 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001658 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001659 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001660 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001661
1662 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001663 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1664 FTy->RefKind = demangleReferenceKind(MangledName);
1665 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001666 }
1667
1668 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001669 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001670
1671 // <return-type> ::= <type>
1672 // ::= @ # structors (they have no declared return type)
1673 bool IsStructor = MangledName.consumeFront('@');
1674 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001675 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001676
Zachary Turner316109b2018-07-29 16:38:02 +00001677 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001678
Zachary Turner316109b2018-07-29 16:38:02 +00001679 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001680
1681 return FTy;
1682}
1683
Zachary Turner316109b2018-07-29 16:38:02 +00001684Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1685 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001686
1687 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001688 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001689 FTy->FunctionClass = FC;
1690
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001691 return FTy;
1692}
1693
1694// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001695Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001696 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001697
Zachary Turner931e8792018-07-30 23:02:10 +00001698 if (MangledName.consumeFront("$$T")) {
1699 Ty->Prim = PrimTy::Nullptr;
1700 return Ty;
1701 }
1702
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001703 switch (MangledName.popFront()) {
1704 case 'X':
1705 Ty->Prim = PrimTy::Void;
1706 break;
1707 case 'D':
1708 Ty->Prim = PrimTy::Char;
1709 break;
1710 case 'C':
1711 Ty->Prim = PrimTy::Schar;
1712 break;
1713 case 'E':
1714 Ty->Prim = PrimTy::Uchar;
1715 break;
1716 case 'F':
1717 Ty->Prim = PrimTy::Short;
1718 break;
1719 case 'G':
1720 Ty->Prim = PrimTy::Ushort;
1721 break;
1722 case 'H':
1723 Ty->Prim = PrimTy::Int;
1724 break;
1725 case 'I':
1726 Ty->Prim = PrimTy::Uint;
1727 break;
1728 case 'J':
1729 Ty->Prim = PrimTy::Long;
1730 break;
1731 case 'K':
1732 Ty->Prim = PrimTy::Ulong;
1733 break;
1734 case 'M':
1735 Ty->Prim = PrimTy::Float;
1736 break;
1737 case 'N':
1738 Ty->Prim = PrimTy::Double;
1739 break;
1740 case 'O':
1741 Ty->Prim = PrimTy::Ldouble;
1742 break;
1743 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001744 if (MangledName.empty()) {
1745 Error = true;
1746 return nullptr;
1747 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001748 switch (MangledName.popFront()) {
1749 case 'N':
1750 Ty->Prim = PrimTy::Bool;
1751 break;
1752 case 'J':
1753 Ty->Prim = PrimTy::Int64;
1754 break;
1755 case 'K':
1756 Ty->Prim = PrimTy::Uint64;
1757 break;
1758 case 'W':
1759 Ty->Prim = PrimTy::Wchar;
1760 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001761 case 'S':
1762 Ty->Prim = PrimTy::Char16;
1763 break;
1764 case 'U':
1765 Ty->Prim = PrimTy::Char32;
1766 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001767 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001768 Error = true;
1769 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001770 }
1771 break;
1772 }
Zachary Turner931e8792018-07-30 23:02:10 +00001773 default:
1774 Error = true;
1775 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001776 }
1777 return Ty;
1778}
1779
Zachary Turner316109b2018-07-29 16:38:02 +00001780UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001781 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001782
1783 switch (MangledName.popFront()) {
1784 case 'T':
1785 UTy->Prim = PrimTy::Union;
1786 break;
1787 case 'U':
1788 UTy->Prim = PrimTy::Struct;
1789 break;
1790 case 'V':
1791 UTy->Prim = PrimTy::Class;
1792 break;
1793 case 'W':
1794 if (MangledName.popFront() != '4') {
1795 Error = true;
1796 return nullptr;
1797 }
1798 UTy->Prim = PrimTy::Enum;
1799 break;
1800 default:
1801 assert(false);
1802 }
1803
Zachary Turner316109b2018-07-29 16:38:02 +00001804 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001805 return UTy;
1806}
1807
Zachary Turnerd742d642018-07-26 19:56:09 +00001808static std::pair<Qualifiers, PointerAffinity>
1809demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001810 if (MangledName.consumeFront("$$Q"))
1811 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1812
Zachary Turnerd742d642018-07-26 19:56:09 +00001813 switch (MangledName.popFront()) {
1814 case 'A':
1815 return std::make_pair(Q_None, PointerAffinity::Reference);
1816 case 'P':
1817 return std::make_pair(Q_None, PointerAffinity::Pointer);
1818 case 'Q':
1819 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1820 case 'R':
1821 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1822 case 'S':
1823 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1824 PointerAffinity::Pointer);
1825 default:
1826 assert(false && "Ty is not a pointer type!");
1827 }
1828 return std::make_pair(Q_None, PointerAffinity::Pointer);
1829}
1830
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001831// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1832// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001833PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001834 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001835
Zachary Turner931e8792018-07-30 23:02:10 +00001836 std::tie(Pointer->Quals, Pointer->Affinity) =
1837 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001838
Zachary Turner931e8792018-07-30 23:02:10 +00001839 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001840 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001841 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001842 return Pointer;
1843 }
1844
Zachary Turner316109b2018-07-29 16:38:02 +00001845 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001846 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1847
Zachary Turner316109b2018-07-29 16:38:02 +00001848 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001849 return Pointer;
1850}
1851
Zachary Turner316109b2018-07-29 16:38:02 +00001852MemberPointerType *
1853Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001854 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1855 Pointer->Prim = PrimTy::MemberPtr;
1856
1857 PointerAffinity Affinity;
1858 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1859 assert(Affinity == PointerAffinity::Pointer);
1860
Zachary Turner316109b2018-07-29 16:38:02 +00001861 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001862 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1863
Zachary Turner38b78a72018-07-26 20:20:10 +00001864 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001865 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1866 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001867 } else {
1868 Qualifiers PointeeQuals = Q_None;
1869 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001870 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001871 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001872 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001873
Zachary Turner316109b2018-07-29 16:38:02 +00001874 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001875 Pointer->Pointee->Quals = PointeeQuals;
1876 }
1877
Zachary Turnerd742d642018-07-26 19:56:09 +00001878 return Pointer;
1879}
1880
Zachary Turner316109b2018-07-29 16:38:02 +00001881Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001882 Qualifiers Quals = Q_None;
1883 if (MangledName.consumeFront('E'))
1884 Quals = Qualifiers(Quals | Q_Pointer64);
1885 if (MangledName.consumeFront('I'))
1886 Quals = Qualifiers(Quals | Q_Restrict);
1887 if (MangledName.consumeFront('F'))
1888 Quals = Qualifiers(Quals | Q_Unaligned);
1889
1890 return Quals;
1891}
1892
Zachary Turner316109b2018-07-29 16:38:02 +00001893ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001894 assert(MangledName.front() == 'Y');
1895 MangledName.popFront();
1896
Zachary Turner316109b2018-07-29 16:38:02 +00001897 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001898 if (Dimension <= 0) {
1899 Error = true;
1900 return nullptr;
1901 }
1902
Zachary Turner9d72aa92018-07-20 18:35:06 +00001903 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001904 ArrayType *Dim = ATy;
1905 for (int I = 0; I < Dimension; ++I) {
1906 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001907 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001908 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001909 Dim = Dim->NextDimension;
1910 }
1911
1912 if (MangledName.consumeFront("$$C")) {
1913 if (MangledName.consumeFront("B"))
1914 ATy->Quals = Q_Const;
1915 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1916 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1917 else if (!MangledName.consumeFront("A"))
1918 Error = true;
1919 }
1920
Zachary Turner316109b2018-07-29 16:38:02 +00001921 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001922 Dim->ElementType = ATy->ElementType;
1923 return ATy;
1924}
1925
1926// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001927FunctionParams
1928Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001929 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001930 if (MangledName.consumeFront('X'))
1931 return {};
1932
Zachary Turnerd30700f2018-07-31 17:16:44 +00001933 FunctionParams *Head;
1934 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001935 while (!Error && !MangledName.startsWith('@') &&
1936 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001937
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001938 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001939 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001940 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001941 Error = true;
1942 return {};
1943 }
1944 MangledName = MangledName.dropFront();
1945
Zachary Turnerd30700f2018-07-31 17:16:44 +00001946 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001947 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001948 Current = &(*Current)->Next;
1949 continue;
1950 }
1951
Zachary Turner23df1312018-07-26 22:13:39 +00001952 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001953
Zachary Turnerd30700f2018-07-31 17:16:44 +00001954 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001955 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001956
Zachary Turner23df1312018-07-26 22:13:39 +00001957 size_t CharsConsumed = OldSize - MangledName.size();
1958 assert(CharsConsumed != 0);
1959
1960 // Single-letter types are ignored for backreferences because memorizing
1961 // them doesn't save anything.
1962 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1963 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1964
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001965 Current = &(*Current)->Next;
1966 }
1967
Zachary Turner38b78a72018-07-26 20:20:10 +00001968 if (Error)
1969 return {};
1970
1971 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1972 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1973 // the following Z could be a throw specifier.
1974 if (MangledName.consumeFront('@'))
1975 return *Head;
1976
1977 if (MangledName.consumeFront('Z')) {
1978 Head->IsVariadic = true;
1979 return *Head;
1980 }
1981
1982 Error = true;
1983 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001984}
1985
Zachary Turnerd30700f2018-07-31 17:16:44 +00001986TemplateParams *
1987Demangler::demangleTemplateParameterList(StringView &MangledName) {
1988 TemplateParams *Head;
1989 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00001990 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001991 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001992 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00001993
1994 // Empty parameter pack.
1995 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
1996 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001997 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001998 }
1999
Zachary Turnerd30700f2018-07-31 17:16:44 +00002000 if (MangledName.consumeFront("$$Y")) {
2001 (*Current)->IsTemplateTemplate = true;
2002 (*Current)->IsAliasTemplate = true;
2003 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
2004 } else if (MangledName.consumeFront("$1?")) {
2005 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
2006 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
2007 } else {
2008 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002009 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002010 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002011 if (Error)
2012 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002013
2014 Current = &(*Current)->Next;
2015 }
2016
2017 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002018 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002019
2020 // Template parameter lists cannot be variadic, so it can only be terminated
2021 // by @.
2022 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002023 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002024 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002025 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002026}
2027
Zachary Turner316109b2018-07-29 16:38:02 +00002028void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002029 // Converts an AST to a string.
2030 //
2031 // Converting an AST representing a C++ type to a string is tricky due
2032 // to the bad grammar of the C++ declaration inherited from C. You have
2033 // to construct a string from inside to outside. For example, if a type
2034 // X is a pointer to a function returning int, the order you create a
2035 // string becomes something like this:
2036 //
2037 // (1) X is a pointer: *X
2038 // (2) (1) is a function returning int: int (*X)()
2039 //
2040 // So you cannot construct a result just by appending strings to a result.
2041 //
2042 // To deal with this, we split the function into two. outputPre() writes
2043 // the "first half" of type declaration, and outputPost() writes the
2044 // "second half". For example, outputPre() writes a return type for a
2045 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00002046 Type::outputPre(OS, *S->SymbolType);
2047 outputName(OS, S->SymbolName);
2048 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002049}
2050
Zachary Turner3a758e22018-08-01 18:33:04 +00002051void Demangler::dumpBackReferences() {
2052 printf("%d function parameter backreferences\n",
2053 (int)FunctionParamBackRefCount);
2054
2055 // Create an output stream so we can render each type.
2056 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
2057 for (size_t I = 0; I < FunctionParamBackRefCount; ++I) {
2058 OS.setCurrentPosition(0);
2059
2060 Type *T = FunctionParamBackRefs[I];
2061 Type::outputPre(OS, *T);
2062 Type::outputPost(OS, *T);
2063
2064 printf(" [%d] - %*s\n", (int)I, (int)OS.getCurrentPosition(),
2065 OS.getBuffer());
2066 }
2067 std::free(OS.getBuffer());
2068
2069 if (FunctionParamBackRefCount > 0)
2070 printf("\n");
2071 printf("%d name backreferences\n", (int)BackRefCount);
2072 for (size_t I = 0; I < BackRefCount; ++I) {
2073 printf(" [%d] - %*s\n", (int)I, (int)BackReferences[I].size(),
2074 BackReferences[I].begin());
2075 }
2076 if (BackRefCount > 0)
2077 printf("\n");
2078}
2079
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002080char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00002081 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00002082 Demangler D;
2083 StringView Name{MangledName};
2084 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002085
Zachary Turner3a758e22018-08-01 18:33:04 +00002086 if (Flags & MSDF_DumpBackrefs)
2087 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00002088 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002089 if (D.Error) {
2090 OS << MangledName;
2091 *Status = llvm::demangle_invalid_mangled_name;
2092 } else {
2093 D.output(S, OS);
2094 *Status = llvm::demangle_success;
2095 }
2096
Zachary Turner71c91f92018-07-30 03:12:34 +00002097 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002098 return OS.getBuffer();
2099}