blob: 29f561f22e9a328d93ef6b9837c2304f8017f1e7 [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
Zachary Turnerd742d642018-07-26 19:56:09 +000024#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000025
26// This memory allocator is extremely fast, but it doesn't call dtors
27// for allocated objects. That means you can't use STL containers
28// (such as std::vector) with this allocator. But it pays off --
29// the demangler is 3x faster with this allocator compared to one with
30// STL containers.
31namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000032 constexpr size_t AllocUnit = 4096;
33
Zachary Turnerf435a7e2018-07-20 17:27:48 +000034class ArenaAllocator {
35 struct AllocatorNode {
36 uint8_t *Buf = nullptr;
37 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000038 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000039 AllocatorNode *Next = nullptr;
40 };
41
Zachary Turner71c91f92018-07-30 03:12:34 +000042 void addNode(size_t Capacity) {
43 AllocatorNode *NewHead = new AllocatorNode;
44 NewHead->Buf = new uint8_t[Capacity];
45 NewHead->Next = Head;
46 NewHead->Capacity = Capacity;
47 Head = NewHead;
48 NewHead->Used = 0;
49 }
50
Zachary Turnerf435a7e2018-07-20 17:27:48 +000051public:
Zachary Turnera6869512018-07-30 03:25:27 +000052 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000053
54 ~ArenaAllocator() {
55 while (Head) {
56 assert(Head->Buf);
57 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000058 AllocatorNode *Next = Head->Next;
59 delete Head;
60 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000061 }
62 }
63
Zachary Turner71c91f92018-07-30 03:12:34 +000064 char *allocUnalignedBuffer(size_t Length) {
65 uint8_t *Buf = Head->Buf + Head->Used;
66
67 Head->Used += Length;
68 if (Head->Used > Head->Capacity) {
69 // It's possible we need a buffer which is larger than our default unit
70 // size, so we need to be careful to add a node with capacity that is at
71 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000072 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000073 Head->Used = Length;
74 Buf = Head->Buf;
75 }
76
77 return reinterpret_cast<char *>(Buf);
78 }
79
Zachary Turner9d72aa92018-07-20 18:35:06 +000080 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
81
82 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000083 assert(Head && Head->Buf);
84
Zachary Turner9d72aa92018-07-20 18:35:06 +000085 size_t P = (size_t)Head->Buf + Head->Used;
86 uintptr_t AlignedP =
87 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
88 uint8_t *PP = (uint8_t *)AlignedP;
89 size_t Adjustment = AlignedP - P;
90
91 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000092 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000093 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000094
Zachary Turnera6869512018-07-30 03:25:27 +000095 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000096 Head->Used = Size;
97 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000098 }
99
100private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000101 AllocatorNode *Head = nullptr;
102};
103} // namespace
104
105static bool startsWithDigit(StringView S) {
106 return !S.empty() && std::isdigit(S.front());
107}
108
109// Writes a space if the last token does not end with a punctuation.
110static void outputSpaceIfNecessary(OutputStream &OS) {
111 if (OS.empty())
112 return;
113
114 char C = OS.back();
115 if (isalnum(C) || C == '>')
116 OS << " ";
117}
118
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000119// Storage classes
120enum Qualifiers : uint8_t {
121 Q_None = 0,
122 Q_Const = 1 << 0,
123 Q_Volatile = 1 << 1,
124 Q_Far = 1 << 2,
125 Q_Huge = 1 << 3,
126 Q_Unaligned = 1 << 4,
127 Q_Restrict = 1 << 5,
128 Q_Pointer64 = 1 << 6
129};
130
131enum class StorageClass : uint8_t {
132 None,
133 PrivateStatic,
134 ProtectedStatic,
135 PublicStatic,
136 Global,
137 FunctionLocalStatic
138};
139
140enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000141
Zachary Turner931e8792018-07-30 23:02:10 +0000142enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000143
144// Calling conventions
145enum class CallingConv : uint8_t {
146 None,
147 Cdecl,
148 Pascal,
149 Thiscall,
150 Stdcall,
151 Fastcall,
152 Clrcall,
153 Eabi,
154 Vectorcall,
155 Regcall,
156};
157
158enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
159
160// Types
161enum class PrimTy : uint8_t {
162 Unknown,
163 None,
164 Function,
165 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000166 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000167 Array,
168
169 Struct,
170 Union,
171 Class,
172 Enum,
173
174 Void,
175 Bool,
176 Char,
177 Schar,
178 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000179 Char16,
180 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000181 Short,
182 Ushort,
183 Int,
184 Uint,
185 Long,
186 Ulong,
187 Int64,
188 Uint64,
189 Wchar,
190 Float,
191 Double,
192 Ldouble,
Zachary Turner931e8792018-07-30 23:02:10 +0000193 Nullptr
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000194};
195
196// Function classes
197enum FuncClass : uint8_t {
198 Public = 1 << 0,
199 Protected = 1 << 1,
200 Private = 1 << 2,
201 Global = 1 << 3,
202 Static = 1 << 4,
203 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000204 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000205};
206
207namespace {
208
209struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000210struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000211
Zachary Turnerd30700f2018-07-31 17:16:44 +0000212struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000213 bool IsVariadic = false;
214
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000215 Type *Current = nullptr;
216
Zachary Turnerd30700f2018-07-31 17:16:44 +0000217 FunctionParams *Next = nullptr;
218};
Zachary Turner931e8792018-07-30 23:02:10 +0000219
Zachary Turnerd30700f2018-07-31 17:16:44 +0000220struct TemplateParams {
221 bool IsTemplateTemplate = false;
222 bool IsAliasTemplate = false;
223
224 // Type can be null if this is a template template parameter. In that case
225 // only Name will be valid.
226 Type *ParamType = nullptr;
227
228 // Name can be valid if this is a template template parameter (see above) or
229 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
230 // Name contains the name of the function and Type contains the signature.
231 Name *ParamName = nullptr;
232
233 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000234};
235
236// The type class. Mangled symbols are first parsed and converted to
237// this type and then converted to string.
238struct Type {
239 virtual ~Type() {}
240
241 virtual Type *clone(ArenaAllocator &Arena) const;
242
243 // Write the "first half" of a given type. This is a static functions to
244 // give the code a chance to do processing that is common to a subset of
245 // subclasses
246 static void outputPre(OutputStream &OS, Type &Ty);
247
248 // Write the "second half" of a given type. This is a static functions to
249 // give the code a chance to do processing that is common to a subset of
250 // subclasses
251 static void outputPost(OutputStream &OS, Type &Ty);
252
253 virtual void outputPre(OutputStream &OS);
254 virtual void outputPost(OutputStream &OS);
255
256 // Primitive type such as Int.
257 PrimTy Prim = PrimTy::Unknown;
258
259 Qualifiers Quals = Q_None;
260 StorageClass Storage = StorageClass::None; // storage class
261};
262
263// Represents an identifier which may be a template.
264struct Name {
265 // Name read from an MangledName string.
266 StringView Str;
267
268 // Overloaded operators are represented as special BackReferences in mangled
269 // symbols. If this is an operator name, "op" has an operator name (e.g.
270 // ">>"). Otherwise, empty.
271 StringView Operator;
272
273 // Template parameters. Null if not a template.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000274 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000275
276 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
277 Name *Next = nullptr;
278};
279
280struct PointerType : public Type {
281 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000282 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000283 void outputPost(OutputStream &OS) override;
284
Zachary Turner931e8792018-07-30 23:02:10 +0000285 PointerAffinity Affinity;
286
Zachary Turnerd742d642018-07-26 19:56:09 +0000287 // Represents a type X in "a pointer to X", "a reference to X",
288 // "an array of X", or "a function returning X".
289 Type *Pointee = nullptr;
290};
291
292struct MemberPointerType : public Type {
293 Type *clone(ArenaAllocator &Arena) const override;
294 void outputPre(OutputStream &OS) override;
295 void outputPost(OutputStream &OS) override;
296
297 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000298
299 // Represents a type X in "a pointer to X", "a reference to X",
300 // "an array of X", or "a function returning X".
301 Type *Pointee = nullptr;
302};
303
304struct FunctionType : public Type {
305 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000306 void outputPre(OutputStream &OS) override;
307 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000308
Zachary Turner024e1762018-07-26 20:33:48 +0000309 // True if this FunctionType instance is the Pointee of a PointerType or
310 // MemberPointerType.
311 bool IsFunctionPointer = false;
312
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000313 Type *ReturnType = nullptr;
314 // If this is a reference, the type of reference.
315 ReferenceKind RefKind;
316
317 CallingConv CallConvention;
318 FuncClass FunctionClass;
319
Zachary Turnerd30700f2018-07-31 17:16:44 +0000320 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000321};
322
323struct UdtType : public Type {
324 Type *clone(ArenaAllocator &Arena) const override;
325 void outputPre(OutputStream &OS) override;
326
327 Name *UdtName = nullptr;
328};
329
330struct ArrayType : public Type {
331 Type *clone(ArenaAllocator &Arena) const override;
332 void outputPre(OutputStream &OS) override;
333 void outputPost(OutputStream &OS) override;
334
335 // Either NextDimension or ElementType will be valid.
336 ArrayType *NextDimension = nullptr;
337 uint32_t ArrayDimension = 0;
338
339 Type *ElementType = nullptr;
340};
341
342} // namespace
343
Zachary Turnerd742d642018-07-26 19:56:09 +0000344static bool isMemberPointer(StringView MangledName) {
345 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000346 case '$':
347 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
348 // rvalue reference to a member.
349 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000350 case 'A':
351 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000352 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000353 return false;
354 case 'P':
355 case 'Q':
356 case 'R':
357 case 'S':
358 // These 4 values indicate some kind of pointer, but we still don't know
359 // what.
360 break;
361 default:
362 assert(false && "Ty is not a pointer type!");
363 }
364
365 // If it starts with a number, then 6 indicates a non-member function
366 // pointer, and 8 indicates a member function pointer.
367 if (startsWithDigit(MangledName)) {
368 assert(MangledName[0] == '6' || MangledName[0] == '8');
369 return (MangledName[0] == '8');
370 }
371
372 // Remove ext qualifiers since those can appear on either type and are
373 // therefore not indicative.
374 MangledName.consumeFront('E'); // 64-bit
375 MangledName.consumeFront('I'); // restrict
376 MangledName.consumeFront('F'); // unaligned
377
378 assert(!MangledName.empty());
379
380 // The next value should be either ABCD (non-member) or QRST (member).
381 switch (MangledName.front()) {
382 case 'A':
383 case 'B':
384 case 'C':
385 case 'D':
386 return false;
387 case 'Q':
388 case 'R':
389 case 'S':
390 case 'T':
391 return true;
392 default:
393 assert(false);
394 }
395 return false;
396}
397
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000398static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
399 outputSpaceIfNecessary(OS);
400
401 switch (CC) {
402 case CallingConv::Cdecl:
403 OS << "__cdecl";
404 break;
405 case CallingConv::Fastcall:
406 OS << "__fastcall";
407 break;
408 case CallingConv::Pascal:
409 OS << "__pascal";
410 break;
411 case CallingConv::Regcall:
412 OS << "__regcall";
413 break;
414 case CallingConv::Stdcall:
415 OS << "__stdcall";
416 break;
417 case CallingConv::Thiscall:
418 OS << "__thiscall";
419 break;
420 case CallingConv::Eabi:
421 OS << "__eabi";
422 break;
423 case CallingConv::Vectorcall:
424 OS << "__vectorcall";
425 break;
426 case CallingConv::Clrcall:
427 OS << "__clrcall";
428 break;
429 default:
430 break;
431 }
432}
433
Zachary Turner71c91f92018-07-30 03:12:34 +0000434static bool startsWithLocalScopePattern(StringView S) {
435 if (!S.consumeFront('?'))
436 return false;
437 if (S.size() < 2)
438 return false;
439
440 size_t End = S.find('?');
441 if (End == StringView::npos)
442 return false;
443 StringView Candidate = S.substr(0, End);
444 if (Candidate.empty())
445 return false;
446
447 // \?[0-9]\?
448 // ?@? is the discriminator 0.
449 if (Candidate.size() == 1)
450 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
451
452 // If it's not 0-9, then it's an encoded number terminated with an @
453 if (Candidate.back() != '@')
454 return false;
455 Candidate = Candidate.dropBack();
456
457 // An encoded number starts with B-P and all subsequent digits are in A-P.
458 // Note that the reason the first digit cannot be A is two fold. First, it
459 // would create an ambiguity with ?A which delimits the beginning of an
460 // anonymous namespace. Second, A represents 0, and you don't start a multi
461 // digit number with a leading 0. Presumably the anonymous namespace
462 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
463 if (Candidate[0] < 'B' || Candidate[0] > 'P')
464 return false;
465 Candidate = Candidate.dropFront();
466 while (!Candidate.empty()) {
467 if (Candidate[0] < 'A' || Candidate[0] > 'P')
468 return false;
469 Candidate = Candidate.dropFront();
470 }
471
472 return true;
473}
474
Zachary Turner931e8792018-07-30 23:02:10 +0000475static void outputName(OutputStream &OS, const Name *TheName);
476
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000477// Write a function or template parameter list.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000478static void outputParameterList(OutputStream &OS,
479 const FunctionParams &Params) {
480 if (!Params.Current) {
481 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000482 return;
483 }
484
Zachary Turnerd30700f2018-07-31 17:16:44 +0000485 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000486 while (Head) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000487 Type::outputPre(OS, *Head->Current);
488 Type::outputPost(OS, *Head->Current);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000489
490 Head = Head->Next;
491
492 if (Head)
493 OS << ", ";
494 }
495}
496
Zachary Turnerd30700f2018-07-31 17:16:44 +0000497static void outputParameterList(OutputStream &OS,
498 const TemplateParams &Params) {
499 if (!Params.ParamType && !Params.ParamName) {
500 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000501 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000502 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000503
504 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000505 const TemplateParams *Head = &Params;
506 while (Head) {
507 // Type can be null if this is a template template parameter,
508 // and Name can be null if this is a simple type.
509
510 if (Head->ParamType && Head->ParamName) {
511 // Function pointer.
512 OS << "&";
513 Type::outputPre(OS, *Head->ParamType);
514 outputName(OS, Head->ParamName);
515 Type::outputPost(OS, *Head->ParamType);
516 } else if (Head->ParamType) {
517 // simple type.
518 Type::outputPre(OS, *Head->ParamType);
519 Type::outputPost(OS, *Head->ParamType);
520 } else {
521 // Template alias.
522 outputName(OS, Head->ParamName);
523 }
524
525 Head = Head->Next;
526
527 if (Head)
528 OS << ", ";
529 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000530 OS << ">";
531}
532
533static void outputName(OutputStream &OS, const Name *TheName) {
534 if (!TheName)
535 return;
536
537 outputSpaceIfNecessary(OS);
538
Zachary Turnera7dffb12018-07-28 22:10:42 +0000539 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000540 // Print out namespaces or outer class BackReferences.
541 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000542 Previous = TheName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000543 OS << TheName->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000544 if (TheName->TParams)
545 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000546 OS << "::";
547 }
548
549 // Print out a regular name.
550 if (TheName->Operator.empty()) {
551 OS << TheName->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000552 if (TheName->TParams)
553 outputParameterList(OS, *TheName->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000554 return;
555 }
556
557 // Print out ctor or dtor.
Zachary Turnera7dffb12018-07-28 22:10:42 +0000558 if (TheName->Operator == "dtor")
559 OS << "~";
560
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000562 OS << Previous->Str;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000563 if (Previous->TParams)
564 outputParameterList(OS, *Previous->TParams);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000565 return;
566 }
567
568 // Print out an overloaded operator.
569 if (!TheName->Str.empty())
570 OS << TheName->Str << "::";
571 OS << "operator" << TheName->Operator;
572}
573
574namespace {
575
576Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000577 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000578}
579
580// Write the "first half" of a given type.
581void Type::outputPre(OutputStream &OS, Type &Ty) {
582 // Function types require custom handling of const and static so we
583 // handle them separately. All other types use the same decoration
584 // for these modifiers, so handle them here in common code.
585 if (Ty.Prim == PrimTy::Function) {
586 Ty.outputPre(OS);
587 return;
588 }
589
590 switch (Ty.Storage) {
591 case StorageClass::PrivateStatic:
592 case StorageClass::PublicStatic:
593 case StorageClass::ProtectedStatic:
594 OS << "static ";
595 default:
596 break;
597 }
598 Ty.outputPre(OS);
599
600 if (Ty.Quals & Q_Const) {
601 outputSpaceIfNecessary(OS);
602 OS << "const";
603 }
604
605 if (Ty.Quals & Q_Volatile) {
606 outputSpaceIfNecessary(OS);
607 OS << "volatile";
608 }
Zachary Turnerca7aef12018-07-26 20:25:35 +0000609
610 if (Ty.Quals & Q_Restrict) {
611 outputSpaceIfNecessary(OS);
612 OS << "__restrict";
613 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000614}
615
616// Write the "second half" of a given type.
617void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
618
619void Type::outputPre(OutputStream &OS) {
620 switch (Prim) {
621 case PrimTy::Void:
622 OS << "void";
623 break;
624 case PrimTy::Bool:
625 OS << "bool";
626 break;
627 case PrimTy::Char:
628 OS << "char";
629 break;
630 case PrimTy::Schar:
631 OS << "signed char";
632 break;
633 case PrimTy::Uchar:
634 OS << "unsigned char";
635 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000636 case PrimTy::Char16:
637 OS << "char16_t";
638 break;
639 case PrimTy::Char32:
640 OS << "char32_t";
641 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000642 case PrimTy::Short:
643 OS << "short";
644 break;
645 case PrimTy::Ushort:
646 OS << "unsigned short";
647 break;
648 case PrimTy::Int:
649 OS << "int";
650 break;
651 case PrimTy::Uint:
652 OS << "unsigned int";
653 break;
654 case PrimTy::Long:
655 OS << "long";
656 break;
657 case PrimTy::Ulong:
658 OS << "unsigned long";
659 break;
660 case PrimTy::Int64:
661 OS << "__int64";
662 break;
663 case PrimTy::Uint64:
664 OS << "unsigned __int64";
665 break;
666 case PrimTy::Wchar:
667 OS << "wchar_t";
668 break;
669 case PrimTy::Float:
670 OS << "float";
671 break;
672 case PrimTy::Double:
673 OS << "double";
674 break;
675 case PrimTy::Ldouble:
676 OS << "long double";
677 break;
Zachary Turner931e8792018-07-30 23:02:10 +0000678 case PrimTy::Nullptr:
679 OS << "std::nullptr_t";
680 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000681 default:
682 assert(false && "Invalid primitive type!");
683 }
684}
685void Type::outputPost(OutputStream &OS) {}
686
687Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000688 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000689}
690
Zachary Turner024e1762018-07-26 20:33:48 +0000691static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
692 const Name *MemberName,
693 const Type *Pointee) {
694 // "[]" and "()" (for function parameters) take precedence over "*",
695 // so "int *x(int)" means "x is a function returning int *". We need
696 // parentheses to supercede the default precedence. (e.g. we want to
697 // emit something like "int (*x)(int)".)
698 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
699 OS << "(";
700 if (Pointee->Prim == PrimTy::Function) {
701 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
702 assert(FTy->IsFunctionPointer);
703 outputCallingConvention(OS, FTy->CallConvention);
704 OS << " ";
705 }
706 }
707
708 if (MemberName) {
709 outputName(OS, MemberName);
710 OS << "::";
711 }
712
713 if (Affinity == PointerAffinity::Pointer)
714 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +0000715 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +0000716 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +0000717 else
718 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +0000719}
720
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000721void PointerType::outputPre(OutputStream &OS) {
722 Type::outputPre(OS, *Pointee);
723
724 outputSpaceIfNecessary(OS);
725
726 if (Quals & Q_Unaligned)
727 OS << "__unaligned ";
728
Zachary Turner024e1762018-07-26 20:33:48 +0000729 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000730
Zachary Turner91ecedd2018-07-20 18:07:33 +0000731 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000732 // if (Ty.Quals & Q_Pointer64)
733 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000734}
735
736void PointerType::outputPost(OutputStream &OS) {
737 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
738 OS << ")";
739
740 Type::outputPost(OS, *Pointee);
741}
742
Zachary Turnerd742d642018-07-26 19:56:09 +0000743Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
744 return Arena.alloc<MemberPointerType>(*this);
745}
746
747void MemberPointerType::outputPre(OutputStream &OS) {
748 Type::outputPre(OS, *Pointee);
749
750 outputSpaceIfNecessary(OS);
751
Zachary Turner024e1762018-07-26 20:33:48 +0000752 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +0000753
754 // FIXME: We should output this, but it requires updating lots of tests.
755 // if (Ty.Quals & Q_Pointer64)
756 // OS << " __ptr64";
757 if (Quals & Q_Restrict)
758 OS << " __restrict";
759}
760
761void MemberPointerType::outputPost(OutputStream &OS) {
762 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
763 OS << ")";
764
765 Type::outputPost(OS, *Pointee);
766}
767
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000768Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000769 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000770}
771
772void FunctionType::outputPre(OutputStream &OS) {
773 if (!(FunctionClass & Global)) {
774 if (FunctionClass & Static)
775 OS << "static ";
776 }
777
Zachary Turner38b78a72018-07-26 20:20:10 +0000778 if (ReturnType) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000779 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +0000780 OS << " ";
781 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000782
Zachary Turner024e1762018-07-26 20:33:48 +0000783 // Function pointers print the calling convention as void (__cdecl *)(params)
784 // rather than void __cdecl (*)(params). So we need to let the PointerType
785 // class handle this.
786 if (!IsFunctionPointer)
787 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000788}
789
790void FunctionType::outputPost(OutputStream &OS) {
791 OS << "(";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000792 outputParameterList(OS, Params);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000793 OS << ")";
794 if (Quals & Q_Const)
795 OS << " const";
796 if (Quals & Q_Volatile)
797 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +0000798 if (Quals & Q_Restrict)
799 OS << " __restrict";
800 if (Quals & Q_Unaligned)
801 OS << " __unaligned";
802
803 if (RefKind == ReferenceKind::LValueRef)
804 OS << " &";
805 else if (RefKind == ReferenceKind::RValueRef)
806 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +0000807
808 if (ReturnType)
809 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000810 return;
811}
812
813Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000814 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000815}
816
817void UdtType::outputPre(OutputStream &OS) {
818 switch (Prim) {
819 case PrimTy::Class:
820 OS << "class ";
821 break;
822 case PrimTy::Struct:
823 OS << "struct ";
824 break;
825 case PrimTy::Union:
826 OS << "union ";
827 break;
828 case PrimTy::Enum:
829 OS << "enum ";
830 break;
831 default:
832 assert(false && "Not a udt type!");
833 }
834
835 outputName(OS, UdtName);
836}
837
838Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000839 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000840}
841
842void ArrayType::outputPre(OutputStream &OS) {
843 Type::outputPre(OS, *ElementType);
844}
845
846void ArrayType::outputPost(OutputStream &OS) {
847 if (ArrayDimension > 0)
848 OS << "[" << ArrayDimension << "]";
849 if (NextDimension)
850 Type::outputPost(OS, *NextDimension);
851 else if (ElementType)
852 Type::outputPost(OS, *ElementType);
853}
854
Zachary Turner316109b2018-07-29 16:38:02 +0000855struct Symbol {
856 Name *SymbolName = nullptr;
857 Type *SymbolType = nullptr;
858};
859
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000860} // namespace
861
862namespace {
863
864// Demangler class takes the main role in demangling symbols.
865// It has a set of functions to parse mangled symbols into Type instances.
866// It also has a set of functions to cnovert Type instances to strings.
867class Demangler {
868public:
Zachary Turner316109b2018-07-29 16:38:02 +0000869 Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000870
871 // You are supposed to call parse() first and then check if error is true. If
872 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +0000873 Symbol *parse(StringView &MangledName);
874 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000875
876 // True if an error occurred.
877 bool Error = false;
878
879private:
Zachary Turner316109b2018-07-29 16:38:02 +0000880 Type *demangleVariableEncoding(StringView &MangledName);
881 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000882
Zachary Turner316109b2018-07-29 16:38:02 +0000883 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000884
885 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +0000886 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
887 Type *demangleBasicType(StringView &MangledName);
888 UdtType *demangleClassType(StringView &MangledName);
889 PointerType *demanglePointerType(StringView &MangledName);
890 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
891 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
892 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000893
Zachary Turner316109b2018-07-29 16:38:02 +0000894 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000895
Zachary Turnerd30700f2018-07-31 17:16:44 +0000896 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
897 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000898
Zachary Turner316109b2018-07-29 16:38:02 +0000899 int demangleNumber(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000900
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000901 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +0000902
903 /// Allocate a copy of \p Borrowed into memory that we own.
904 StringView copyString(StringView Borrowed);
905
Zachary Turner316109b2018-07-29 16:38:02 +0000906 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
907 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000908
Zachary Turner316109b2018-07-29 16:38:02 +0000909 Name *demangleUnqualifiedTypeName(StringView &MangledName);
910 Name *demangleUnqualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000911
Zachary Turner316109b2018-07-29 16:38:02 +0000912 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
913 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000914
Zachary Turner316109b2018-07-29 16:38:02 +0000915 Name *demangleBackRefName(StringView &MangledName);
916 Name *demangleClassTemplateName(StringView &MangledName);
917 Name *demangleOperatorName(StringView &MangledName);
918 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
919 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +0000920 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +0000921
Zachary Turner931e8792018-07-30 23:02:10 +0000922 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
923
Zachary Turner316109b2018-07-29 16:38:02 +0000924 FuncClass demangleFunctionClass(StringView &MangledName);
925 CallingConv demangleCallingConvention(StringView &MangledName);
926 StorageClass demangleVariableStorageClass(StringView &MangledName);
927 ReferenceKind demangleReferenceKind(StringView &MangledName);
928 void demangleThrowSpecification(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000929
Zachary Turner316109b2018-07-29 16:38:02 +0000930 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000931
932 // Memory allocator.
933 ArenaAllocator Arena;
934
Zachary Turner23df1312018-07-26 22:13:39 +0000935 // A single type uses one global back-ref table for all function params.
936 // This means back-refs can even go "into" other types. Examples:
937 //
938 // // Second int* is a back-ref to first.
939 // void foo(int *, int*);
940 //
941 // // Second int* is not a back-ref to first (first is not a function param).
942 // int* foo(int*);
943 //
944 // // Second int* is a back-ref to first (ALL function types share the same
945 // // back-ref map.
946 // using F = void(*)(int*);
947 // F G(int *);
948 Type *FunctionParamBackRefs[10];
949 size_t FunctionParamBackRefCount = 0;
950
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000951 // The first 10 BackReferences in a mangled name can be back-referenced by
952 // special name @[0-9]. This is a storage for the first 10 BackReferences.
953 StringView BackReferences[10];
954 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000955};
956} // namespace
957
Zachary Turner71c91f92018-07-30 03:12:34 +0000958StringView Demangler::copyString(StringView Borrowed) {
959 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
960 std::strcpy(Stable, Borrowed.begin());
961
962 return {Stable, Borrowed.size()};
963}
964
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000965// Parser entry point.
Zachary Turner316109b2018-07-29 16:38:02 +0000966Symbol *Demangler::parse(StringView &MangledName) {
967 Symbol *S = Arena.alloc<Symbol>();
968
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000969 // MSVC-style mangled symbols must start with '?'.
970 if (!MangledName.consumeFront("?")) {
Zachary Turner316109b2018-07-29 16:38:02 +0000971 S->SymbolName = Arena.alloc<Name>();
972 S->SymbolName->Str = MangledName;
973 S->SymbolType = Arena.alloc<Type>();
974 S->SymbolType->Prim = PrimTy::Unknown;
975 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000976 }
977
978 // What follows is a main symbol name. This may include
979 // namespaces or class BackReferences.
Zachary Turner316109b2018-07-29 16:38:02 +0000980 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000981 if (Error)
982 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000983 // Read a variable.
Zachary Turner316109b2018-07-29 16:38:02 +0000984 S->SymbolType = startsWithDigit(MangledName)
985 ? demangleVariableEncoding(MangledName)
986 : demangleFunctionEncoding(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +0000987 if (Error)
988 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000989
Zachary Turner316109b2018-07-29 16:38:02 +0000990 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000991}
992
993// <type-encoding> ::= <storage-class> <variable-type>
994// <storage-class> ::= 0 # private static member
995// ::= 1 # protected static member
996// ::= 2 # public static member
997// ::= 3 # global
998// ::= 4 # static local
999
Zachary Turner316109b2018-07-29 16:38:02 +00001000Type *Demangler::demangleVariableEncoding(StringView &MangledName) {
1001 StorageClass SC = demangleVariableStorageClass(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001002
Zachary Turner316109b2018-07-29 16:38:02 +00001003 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001004
1005 Ty->Storage = SC;
1006
1007 // <variable-type> ::= <type> <cvr-qualifiers>
1008 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1009 switch (Ty->Prim) {
1010 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001011 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001012 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001013 Ty->Quals =
1014 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001015
Zachary Turnerd742d642018-07-26 19:56:09 +00001016 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001017 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001018
Zachary Turnerd742d642018-07-26 19:56:09 +00001019 if (Ty->Prim == PrimTy::MemberPtr) {
1020 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001021 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001022 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001023 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1024 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1025 } else {
1026 PointerType *PTy = static_cast<PointerType *>(Ty);
1027 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001028 }
1029
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001030 break;
1031 }
1032 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001033 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001034 break;
1035 }
1036
1037 return Ty;
1038}
1039
1040// Sometimes numbers are encoded in mangled symbols. For example,
1041// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1042// length 20), so we need some way to embed numbers as part of symbols.
1043// This function parses it.
1044//
1045// <number> ::= [?] <non-negative integer>
1046//
1047// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1048// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1049//
1050// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turner316109b2018-07-29 16:38:02 +00001051int Demangler::demangleNumber(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001052 bool neg = MangledName.consumeFront("?");
1053
1054 if (startsWithDigit(MangledName)) {
1055 int32_t Ret = MangledName[0] - '0' + 1;
1056 MangledName = MangledName.dropFront(1);
1057 return neg ? -Ret : Ret;
1058 }
1059
1060 int Ret = 0;
1061 for (size_t i = 0; i < MangledName.size(); ++i) {
1062 char C = MangledName[i];
1063 if (C == '@') {
1064 MangledName = MangledName.dropFront(i + 1);
1065 return neg ? -Ret : Ret;
1066 }
1067 if ('A' <= C && C <= 'P') {
1068 Ret = (Ret << 4) + (C - 'A');
1069 continue;
1070 }
1071 break;
1072 }
1073
1074 Error = true;
1075 return 0;
1076}
1077
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001078// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1079// Memorize it.
1080void Demangler::memorizeString(StringView S) {
1081 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
1082 return;
1083 for (size_t i = 0; i < BackRefCount; ++i)
1084 if (S == BackReferences[i])
1085 return;
1086 BackReferences[BackRefCount++] = S;
1087}
1088
Zachary Turner316109b2018-07-29 16:38:02 +00001089Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001090 assert(startsWithDigit(MangledName));
1091
1092 size_t I = MangledName[0] - '0';
1093 if (I >= BackRefCount) {
1094 Error = true;
1095 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001096 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001097
1098 MangledName = MangledName.dropFront();
1099 Name *Node = Arena.alloc<Name>();
1100 Node->Str = BackReferences[I];
1101 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001102}
1103
Zachary Turner316109b2018-07-29 16:38:02 +00001104Name *Demangler::demangleClassTemplateName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001105 assert(MangledName.startsWith("?$"));
1106 MangledName.consumeFront("?$");
1107
Zachary Turner316109b2018-07-29 16:38:02 +00001108 Name *Node = demangleSimpleName(MangledName, false);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001109 if (Error)
1110 return nullptr;
1111
Zachary Turnerd30700f2018-07-31 17:16:44 +00001112 Node->TParams = demangleTemplateParameterList(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001113 if (Error)
1114 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001115
1116 // Render this class template name into a string buffer so that we can
1117 // memorize it for the purpose of back-referencing.
1118 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1119 outputName(OS, Node);
1120 OS << '\0';
1121 char *Name = OS.getBuffer();
1122
1123 StringView Owned = copyString(Name);
1124 memorizeString(Owned);
1125 std::free(Name);
1126
Zachary Turnera7dffb12018-07-28 22:10:42 +00001127 return Node;
1128}
1129
Zachary Turner316109b2018-07-29 16:38:02 +00001130Name *Demangler::demangleOperatorName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001131 assert(MangledName.startsWith('?'));
1132 MangledName.consumeFront('?');
1133
Zachary Turner316109b2018-07-29 16:38:02 +00001134 auto NameString = [this, &MangledName]() -> StringView {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001135 switch (MangledName.popFront()) {
1136 case '0':
1137 return "ctor";
1138 case '1':
1139 return "dtor";
1140 case '2':
1141 return " new";
1142 case '3':
1143 return " delete";
1144 case '4':
1145 return "=";
1146 case '5':
1147 return ">>";
1148 case '6':
1149 return "<<";
1150 case '7':
1151 return "!";
1152 case '8':
1153 return "==";
1154 case '9':
1155 return "!=";
1156 case 'A':
1157 return "[]";
1158 case 'C':
1159 return "->";
1160 case 'D':
1161 return "*";
1162 case 'E':
1163 return "++";
1164 case 'F':
1165 return "--";
1166 case 'G':
1167 return "-";
1168 case 'H':
1169 return "+";
1170 case 'I':
1171 return "&";
1172 case 'J':
1173 return "->*";
1174 case 'K':
1175 return "/";
1176 case 'L':
1177 return "%";
1178 case 'M':
1179 return "<";
1180 case 'N':
1181 return "<=";
1182 case 'O':
1183 return ">";
1184 case 'P':
1185 return ">=";
1186 case 'Q':
1187 return ",";
1188 case 'R':
1189 return "()";
1190 case 'S':
1191 return "~";
1192 case 'T':
1193 return "^";
1194 case 'U':
1195 return "|";
1196 case 'V':
1197 return "&&";
1198 case 'W':
1199 return "||";
1200 case 'X':
1201 return "*=";
1202 case 'Y':
1203 return "+=";
1204 case 'Z':
1205 return "-=";
1206 case '_': {
1207 if (MangledName.empty())
1208 break;
1209
1210 switch (MangledName.popFront()) {
1211 case '0':
1212 return "/=";
1213 case '1':
1214 return "%=";
1215 case '2':
1216 return ">>=";
1217 case '3':
1218 return "<<=";
1219 case '4':
1220 return "&=";
1221 case '5':
1222 return "|=";
1223 case '6':
1224 return "^=";
1225 case 'U':
1226 return " new[]";
1227 case 'V':
1228 return " delete[]";
1229 case '_':
1230 if (MangledName.consumeFront("L"))
1231 return " co_await";
Zachary Turner931e8792018-07-30 23:02:10 +00001232 if (MangledName.consumeFront("K")) {
1233 size_t EndPos = MangledName.find('@');
1234 if (EndPos == StringView::npos)
1235 break;
1236 StringView OpName = demangleSimpleString(MangledName, false);
1237 size_t FullSize = OpName.size() + 3; // <space>""OpName
1238 char *Buffer = Arena.allocUnalignedBuffer(FullSize);
1239 Buffer[0] = ' ';
1240 Buffer[1] = '"';
1241 Buffer[2] = '"';
1242 std::memcpy(Buffer + 3, OpName.begin(), OpName.size());
1243 return {Buffer, FullSize};
1244 }
Zachary Turnera7dffb12018-07-28 22:10:42 +00001245 }
1246 }
1247 }
1248 Error = true;
1249 return "";
1250 };
1251
1252 Name *Node = Arena.alloc<Name>();
1253 Node->Operator = NameString();
1254 return Node;
1255}
1256
Zachary Turner316109b2018-07-29 16:38:02 +00001257Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001258 StringView S = demangleSimpleString(MangledName, Memorize);
1259 if (Error)
1260 return nullptr;
1261
Zachary Turnera7dffb12018-07-28 22:10:42 +00001262 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001263 Node->Str = S;
1264 return Node;
1265}
1266
1267StringView Demangler::demangleSimpleString(StringView &MangledName,
1268 bool Memorize) {
1269 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001270 for (size_t i = 0; i < MangledName.size(); ++i) {
1271 if (MangledName[i] != '@')
1272 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00001273 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001274 MangledName = MangledName.dropFront(i + 1);
1275
1276 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00001277 memorizeString(S);
1278 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001279 }
1280
1281 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00001282 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00001283}
1284
Zachary Turner316109b2018-07-29 16:38:02 +00001285Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001286 assert(MangledName.startsWith("?A"));
1287 MangledName.consumeFront("?A");
1288
1289 Name *Node = Arena.alloc<Name>();
1290 Node->Str = "`anonymous namespace'";
1291 if (MangledName.consumeFront('@'))
1292 return Node;
1293
1294 Error = true;
1295 return nullptr;
1296}
1297
Zachary Turner71c91f92018-07-30 03:12:34 +00001298Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1299 assert(startsWithLocalScopePattern(MangledName));
1300
1301 Name *Node = Arena.alloc<Name>();
1302 MangledName.consumeFront('?');
1303 int ScopeIdentifier = demangleNumber(MangledName);
1304
1305 // One ? to terminate the number
1306 MangledName.consumeFront('?');
1307
1308 assert(!Error);
1309 Symbol *Scope = parse(MangledName);
1310 if (Error)
1311 return nullptr;
1312
1313 // Render the parent symbol's name into a buffer.
1314 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
1315 OS << '`';
1316 output(Scope, OS);
1317 OS << '\'';
1318 OS << "::`" << ScopeIdentifier << "'";
1319 OS << '\0';
1320 char *Result = OS.getBuffer();
1321 Node->Str = copyString(Result);
1322 std::free(Result);
1323 return Node;
1324}
1325
Zachary Turnera7dffb12018-07-28 22:10:42 +00001326// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00001327Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
1328 Name *TypeName = demangleUnqualifiedTypeName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001329 if (Error)
1330 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001331 assert(TypeName);
1332
Zachary Turner316109b2018-07-29 16:38:02 +00001333 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001334 if (Error)
1335 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001336 assert(QualName);
1337 return QualName;
1338}
1339
1340// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1341// Symbol names have slightly different rules regarding what can appear
1342// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00001343Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
1344 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001345 if (Error)
1346 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001347 assert(SymbolName);
1348
Zachary Turner316109b2018-07-29 16:38:02 +00001349 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001350 if (Error)
1351 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00001352 assert(QualName);
1353 return QualName;
1354}
1355
Zachary Turner316109b2018-07-29 16:38:02 +00001356Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001357 // An inner-most name can be a back-reference, because a fully-qualified name
1358 // (e.g. Scope + Inner) can contain other fully qualified names inside of
1359 // them (for example template parameters), and these nested parameters can
1360 // refer to previously mangled types.
1361 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001362 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001363
1364 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001365 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001366
Zachary Turner316109b2018-07-29 16:38:02 +00001367 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001368}
1369
Zachary Turner316109b2018-07-29 16:38:02 +00001370Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName) {
Zachary Turner71c91f92018-07-30 03:12:34 +00001371 if (startsWithDigit(MangledName))
1372 return demangleBackRefName(MangledName);
1373 if (MangledName.startsWith("?$"))
1374 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001375 if (MangledName.startsWith('?'))
Zachary Turner316109b2018-07-29 16:38:02 +00001376 return demangleOperatorName(MangledName);
1377 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001378}
1379
Zachary Turner316109b2018-07-29 16:38:02 +00001380Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001381 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001382 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001383
1384 if (MangledName.startsWith("?$"))
Zachary Turner316109b2018-07-29 16:38:02 +00001385 return demangleClassTemplateName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001386
1387 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00001388 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001389
Zachary Turner71c91f92018-07-30 03:12:34 +00001390 if (startsWithLocalScopePattern(MangledName))
1391 return demangleLocallyScopedNamePiece(MangledName);
1392
Zachary Turner316109b2018-07-29 16:38:02 +00001393 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001394}
1395
Zachary Turner316109b2018-07-29 16:38:02 +00001396Name *Demangler::demangleNameScopeChain(StringView &MangledName,
1397 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001398 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001399
1400 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001401 if (MangledName.empty()) {
1402 Error = true;
1403 return nullptr;
1404 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001405
1406 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00001407 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001408 if (Error)
1409 return nullptr;
1410
1411 Elem->Next = Head;
1412 Head = Elem;
1413 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001414 return Head;
1415}
1416
Zachary Turner316109b2018-07-29 16:38:02 +00001417FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001418 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1419 RestoreOnError.shouldRestore(false);
1420
1421 switch (MangledName.popFront()) {
1422 case 'A':
1423 return Private;
1424 case 'B':
Zachary Turner38b78a72018-07-26 20:20:10 +00001425 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001426 case 'C':
Zachary Turner38b78a72018-07-26 20:20:10 +00001427 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001428 case 'D':
Zachary Turner38b78a72018-07-26 20:20:10 +00001429 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001430 case 'E':
Zachary Turner38b78a72018-07-26 20:20:10 +00001431 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001432 case 'F':
Zachary Turner38b78a72018-07-26 20:20:10 +00001433 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001434 case 'I':
1435 return Protected;
1436 case 'J':
Zachary Turner38b78a72018-07-26 20:20:10 +00001437 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001438 case 'K':
Zachary Turner38b78a72018-07-26 20:20:10 +00001439 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001440 case 'L':
Zachary Turner38b78a72018-07-26 20:20:10 +00001441 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001442 case 'M':
Zachary Turner38b78a72018-07-26 20:20:10 +00001443 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001444 case 'N':
Zachary Turner38b78a72018-07-26 20:20:10 +00001445 return FuncClass(Protected | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001446 case 'Q':
1447 return Public;
1448 case 'R':
Zachary Turner38b78a72018-07-26 20:20:10 +00001449 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001450 case 'S':
Zachary Turner38b78a72018-07-26 20:20:10 +00001451 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001452 case 'T':
Zachary Turner38b78a72018-07-26 20:20:10 +00001453 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001454 case 'U':
Zachary Turner38b78a72018-07-26 20:20:10 +00001455 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001456 case 'V':
Zachary Turner38b78a72018-07-26 20:20:10 +00001457 return FuncClass(Public | Virtual | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001458 case 'Y':
1459 return Global;
1460 case 'Z':
Zachary Turner38b78a72018-07-26 20:20:10 +00001461 return FuncClass(Global | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001462 }
1463
1464 Error = true;
1465 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001466 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001467}
1468
Zachary Turner316109b2018-07-29 16:38:02 +00001469CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001470 switch (MangledName.popFront()) {
1471 case 'A':
1472 case 'B':
1473 return CallingConv::Cdecl;
1474 case 'C':
1475 case 'D':
1476 return CallingConv::Pascal;
1477 case 'E':
1478 case 'F':
1479 return CallingConv::Thiscall;
1480 case 'G':
1481 case 'H':
1482 return CallingConv::Stdcall;
1483 case 'I':
1484 case 'J':
1485 return CallingConv::Fastcall;
1486 case 'M':
1487 case 'N':
1488 return CallingConv::Clrcall;
1489 case 'O':
1490 case 'P':
1491 return CallingConv::Eabi;
1492 case 'Q':
1493 return CallingConv::Vectorcall;
1494 }
1495
1496 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001497}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001498
Zachary Turner316109b2018-07-29 16:38:02 +00001499StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001500 assert(std::isdigit(MangledName.front()));
1501
1502 switch (MangledName.popFront()) {
1503 case '0':
1504 return StorageClass::PrivateStatic;
1505 case '1':
1506 return StorageClass::ProtectedStatic;
1507 case '2':
1508 return StorageClass::PublicStatic;
1509 case '3':
1510 return StorageClass::Global;
1511 case '4':
1512 return StorageClass::FunctionLocalStatic;
1513 }
1514 Error = true;
1515 return StorageClass::None;
1516}
1517
Zachary Turner316109b2018-07-29 16:38:02 +00001518std::pair<Qualifiers, bool>
1519Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001520
1521 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001522 // Member qualifiers
1523 case 'Q':
1524 return std::make_pair(Q_None, true);
1525 case 'R':
1526 return std::make_pair(Q_Const, true);
1527 case 'S':
1528 return std::make_pair(Q_Volatile, true);
1529 case 'T':
1530 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1531 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001532 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00001533 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001534 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00001535 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001536 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00001537 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001538 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00001539 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001540 }
1541 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00001542 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001543}
1544
Zachary Turner931e8792018-07-30 23:02:10 +00001545static bool isTagType(StringView S) {
1546 switch (S.front()) {
1547 case 'T': // union
1548 case 'U': // struct
1549 case 'V': // class
1550 case 'W': // enum
1551 return true;
1552 }
1553 return false;
1554}
1555
1556static bool isPointerType(StringView S) {
1557 if (S.startsWith("$$Q")) // foo &&
1558 return true;
1559
1560 switch (S.front()) {
1561 case 'A': // foo &
1562 case 'P': // foo *
1563 case 'Q': // foo *const
1564 case 'R': // foo *volatile
1565 case 'S': // foo *const volatile
1566 return true;
1567 }
1568 return false;
1569}
1570
1571static bool isArrayType(StringView S) { return S[0] == 'Y'; }
1572
1573static bool isFunctionType(StringView S) {
1574 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
1575}
1576
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001577// <variable-type> ::= <type> <cvr-qualifiers>
1578// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00001579Type *Demangler::demangleType(StringView &MangledName,
1580 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001581 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00001582 bool IsMember = false;
1583 bool IsMemberKnown = false;
1584 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00001585 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001586 IsMemberKnown = true;
1587 } else if (QMM == QualifierMangleMode::Result) {
1588 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00001589 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001590 IsMemberKnown = true;
1591 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001592 }
1593
1594 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00001595 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001596 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001597 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001598 if (!IsMemberKnown)
1599 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001600
Zachary Turnerd742d642018-07-26 19:56:09 +00001601 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00001602 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001603 else
Zachary Turner316109b2018-07-29 16:38:02 +00001604 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001605 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00001606 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001607 else if (isFunctionType(MangledName)) {
1608 if (MangledName.consumeFront("$$A8@@"))
1609 Ty = demangleFunctionType(MangledName, true, false);
1610 else {
1611 assert(MangledName.startsWith("$$A6"));
1612 MangledName.consumeFront("$$A6");
1613 Ty = demangleFunctionType(MangledName, false, false);
1614 }
1615 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00001616 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00001617 assert(Ty && !Error);
1618 if (!Ty || Error)
1619 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001620 }
Zachary Turner931e8792018-07-30 23:02:10 +00001621
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001622 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1623 return Ty;
1624}
1625
Zachary Turner316109b2018-07-29 16:38:02 +00001626ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001627 if (MangledName.consumeFront('G'))
1628 return ReferenceKind::LValueRef;
1629 else if (MangledName.consumeFront('H'))
1630 return ReferenceKind::RValueRef;
1631 return ReferenceKind::None;
1632}
1633
Zachary Turner316109b2018-07-29 16:38:02 +00001634void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001635 if (MangledName.consumeFront('Z'))
1636 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001637
Zachary Turner38b78a72018-07-26 20:20:10 +00001638 Error = true;
1639}
1640
Zachary Turner316109b2018-07-29 16:38:02 +00001641FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
1642 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00001643 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001644 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001645 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00001646 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00001647
1648 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00001649 FTy->Quals = demanglePointerExtQualifiers(MangledName);
1650 FTy->RefKind = demangleReferenceKind(MangledName);
1651 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001652 }
1653
1654 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00001655 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001656
1657 // <return-type> ::= <type>
1658 // ::= @ # structors (they have no declared return type)
1659 bool IsStructor = MangledName.consumeFront('@');
1660 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00001661 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001662
Zachary Turner316109b2018-07-29 16:38:02 +00001663 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001664
Zachary Turner316109b2018-07-29 16:38:02 +00001665 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001666
1667 return FTy;
1668}
1669
Zachary Turner316109b2018-07-29 16:38:02 +00001670Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
1671 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001672
1673 bool HasThisQuals = !(FC & (Global | Static));
Zachary Turner316109b2018-07-29 16:38:02 +00001674 FunctionType *FTy = demangleFunctionType(MangledName, HasThisQuals, false);
Zachary Turner38b78a72018-07-26 20:20:10 +00001675 FTy->FunctionClass = FC;
1676
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001677 return FTy;
1678}
1679
1680// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00001681Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001682 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001683
Zachary Turner931e8792018-07-30 23:02:10 +00001684 if (MangledName.consumeFront("$$T")) {
1685 Ty->Prim = PrimTy::Nullptr;
1686 return Ty;
1687 }
1688
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001689 switch (MangledName.popFront()) {
1690 case 'X':
1691 Ty->Prim = PrimTy::Void;
1692 break;
1693 case 'D':
1694 Ty->Prim = PrimTy::Char;
1695 break;
1696 case 'C':
1697 Ty->Prim = PrimTy::Schar;
1698 break;
1699 case 'E':
1700 Ty->Prim = PrimTy::Uchar;
1701 break;
1702 case 'F':
1703 Ty->Prim = PrimTy::Short;
1704 break;
1705 case 'G':
1706 Ty->Prim = PrimTy::Ushort;
1707 break;
1708 case 'H':
1709 Ty->Prim = PrimTy::Int;
1710 break;
1711 case 'I':
1712 Ty->Prim = PrimTy::Uint;
1713 break;
1714 case 'J':
1715 Ty->Prim = PrimTy::Long;
1716 break;
1717 case 'K':
1718 Ty->Prim = PrimTy::Ulong;
1719 break;
1720 case 'M':
1721 Ty->Prim = PrimTy::Float;
1722 break;
1723 case 'N':
1724 Ty->Prim = PrimTy::Double;
1725 break;
1726 case 'O':
1727 Ty->Prim = PrimTy::Ldouble;
1728 break;
1729 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001730 if (MangledName.empty()) {
1731 Error = true;
1732 return nullptr;
1733 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001734 switch (MangledName.popFront()) {
1735 case 'N':
1736 Ty->Prim = PrimTy::Bool;
1737 break;
1738 case 'J':
1739 Ty->Prim = PrimTy::Int64;
1740 break;
1741 case 'K':
1742 Ty->Prim = PrimTy::Uint64;
1743 break;
1744 case 'W':
1745 Ty->Prim = PrimTy::Wchar;
1746 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001747 case 'S':
1748 Ty->Prim = PrimTy::Char16;
1749 break;
1750 case 'U':
1751 Ty->Prim = PrimTy::Char32;
1752 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001753 default:
Zachary Turner931e8792018-07-30 23:02:10 +00001754 Error = true;
1755 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001756 }
1757 break;
1758 }
Zachary Turner931e8792018-07-30 23:02:10 +00001759 default:
1760 Error = true;
1761 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001762 }
1763 return Ty;
1764}
1765
Zachary Turner316109b2018-07-29 16:38:02 +00001766UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001767 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001768
1769 switch (MangledName.popFront()) {
1770 case 'T':
1771 UTy->Prim = PrimTy::Union;
1772 break;
1773 case 'U':
1774 UTy->Prim = PrimTy::Struct;
1775 break;
1776 case 'V':
1777 UTy->Prim = PrimTy::Class;
1778 break;
1779 case 'W':
1780 if (MangledName.popFront() != '4') {
1781 Error = true;
1782 return nullptr;
1783 }
1784 UTy->Prim = PrimTy::Enum;
1785 break;
1786 default:
1787 assert(false);
1788 }
1789
Zachary Turner316109b2018-07-29 16:38:02 +00001790 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001791 return UTy;
1792}
1793
Zachary Turnerd742d642018-07-26 19:56:09 +00001794static std::pair<Qualifiers, PointerAffinity>
1795demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00001796 if (MangledName.consumeFront("$$Q"))
1797 return std::make_pair(Q_None, PointerAffinity::RValueReference);
1798
Zachary Turnerd742d642018-07-26 19:56:09 +00001799 switch (MangledName.popFront()) {
1800 case 'A':
1801 return std::make_pair(Q_None, PointerAffinity::Reference);
1802 case 'P':
1803 return std::make_pair(Q_None, PointerAffinity::Pointer);
1804 case 'Q':
1805 return std::make_pair(Q_Const, PointerAffinity::Pointer);
1806 case 'R':
1807 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
1808 case 'S':
1809 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
1810 PointerAffinity::Pointer);
1811 default:
1812 assert(false && "Ty is not a pointer type!");
1813 }
1814 return std::make_pair(Q_None, PointerAffinity::Pointer);
1815}
1816
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001817// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1818// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00001819PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001820 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001821
Zachary Turner931e8792018-07-30 23:02:10 +00001822 std::tie(Pointer->Quals, Pointer->Affinity) =
1823 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001824
Zachary Turner931e8792018-07-30 23:02:10 +00001825 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001826 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001827 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001828 return Pointer;
1829 }
1830
Zachary Turner316109b2018-07-29 16:38:02 +00001831 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001832 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1833
Zachary Turner316109b2018-07-29 16:38:02 +00001834 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001835 return Pointer;
1836}
1837
Zachary Turner316109b2018-07-29 16:38:02 +00001838MemberPointerType *
1839Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001840 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
1841 Pointer->Prim = PrimTy::MemberPtr;
1842
1843 PointerAffinity Affinity;
1844 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
1845 assert(Affinity == PointerAffinity::Pointer);
1846
Zachary Turner316109b2018-07-29 16:38:02 +00001847 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001848 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1849
Zachary Turner38b78a72018-07-26 20:20:10 +00001850 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00001851 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
1852 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00001853 } else {
1854 Qualifiers PointeeQuals = Q_None;
1855 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001856 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00001857 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001858 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00001859
Zachary Turner316109b2018-07-29 16:38:02 +00001860 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00001861 Pointer->Pointee->Quals = PointeeQuals;
1862 }
1863
Zachary Turnerd742d642018-07-26 19:56:09 +00001864 return Pointer;
1865}
1866
Zachary Turner316109b2018-07-29 16:38:02 +00001867Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001868 Qualifiers Quals = Q_None;
1869 if (MangledName.consumeFront('E'))
1870 Quals = Qualifiers(Quals | Q_Pointer64);
1871 if (MangledName.consumeFront('I'))
1872 Quals = Qualifiers(Quals | Q_Restrict);
1873 if (MangledName.consumeFront('F'))
1874 Quals = Qualifiers(Quals | Q_Unaligned);
1875
1876 return Quals;
1877}
1878
Zachary Turner316109b2018-07-29 16:38:02 +00001879ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001880 assert(MangledName.front() == 'Y');
1881 MangledName.popFront();
1882
Zachary Turner316109b2018-07-29 16:38:02 +00001883 int Dimension = demangleNumber(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001884 if (Dimension <= 0) {
1885 Error = true;
1886 return nullptr;
1887 }
1888
Zachary Turner9d72aa92018-07-20 18:35:06 +00001889 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001890 ArrayType *Dim = ATy;
1891 for (int I = 0; I < Dimension; ++I) {
1892 Dim->Prim = PrimTy::Array;
Zachary Turner316109b2018-07-29 16:38:02 +00001893 Dim->ArrayDimension = demangleNumber(MangledName);
Zachary Turner9d72aa92018-07-20 18:35:06 +00001894 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001895 Dim = Dim->NextDimension;
1896 }
1897
1898 if (MangledName.consumeFront("$$C")) {
1899 if (MangledName.consumeFront("B"))
1900 ATy->Quals = Q_Const;
1901 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1902 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1903 else if (!MangledName.consumeFront("A"))
1904 Error = true;
1905 }
1906
Zachary Turner316109b2018-07-29 16:38:02 +00001907 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001908 Dim->ElementType = ATy->ElementType;
1909 return ATy;
1910}
1911
1912// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001913FunctionParams
1914Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00001915 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00001916 if (MangledName.consumeFront('X'))
1917 return {};
1918
Zachary Turnerd30700f2018-07-31 17:16:44 +00001919 FunctionParams *Head;
1920 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001921 while (!Error && !MangledName.startsWith('@') &&
1922 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001923
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001924 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00001925 size_t N = MangledName[0] - '0';
Zachary Turner23df1312018-07-26 22:13:39 +00001926 if (N >= FunctionParamBackRefCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001927 Error = true;
1928 return {};
1929 }
1930 MangledName = MangledName.dropFront();
1931
Zachary Turnerd30700f2018-07-31 17:16:44 +00001932 *Current = Arena.alloc<FunctionParams>();
Zachary Turner23df1312018-07-26 22:13:39 +00001933 (*Current)->Current = FunctionParamBackRefs[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001934 Current = &(*Current)->Next;
1935 continue;
1936 }
1937
Zachary Turner23df1312018-07-26 22:13:39 +00001938 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001939
Zachary Turnerd30700f2018-07-31 17:16:44 +00001940 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00001941 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001942
Zachary Turner23df1312018-07-26 22:13:39 +00001943 size_t CharsConsumed = OldSize - MangledName.size();
1944 assert(CharsConsumed != 0);
1945
1946 // Single-letter types are ignored for backreferences because memorizing
1947 // them doesn't save anything.
1948 if (FunctionParamBackRefCount <= 9 && CharsConsumed > 1)
1949 FunctionParamBackRefs[FunctionParamBackRefCount++] = (*Current)->Current;
1950
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001951 Current = &(*Current)->Next;
1952 }
1953
Zachary Turner38b78a72018-07-26 20:20:10 +00001954 if (Error)
1955 return {};
1956
1957 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
1958 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
1959 // the following Z could be a throw specifier.
1960 if (MangledName.consumeFront('@'))
1961 return *Head;
1962
1963 if (MangledName.consumeFront('Z')) {
1964 Head->IsVariadic = true;
1965 return *Head;
1966 }
1967
1968 Error = true;
1969 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001970}
1971
Zachary Turnerd30700f2018-07-31 17:16:44 +00001972TemplateParams *
1973Demangler::demangleTemplateParameterList(StringView &MangledName) {
1974 TemplateParams *Head;
1975 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00001976 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00001977 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00001978 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00001979
1980 // Empty parameter pack.
1981 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
1982 MangledName.consumeFront("$$$V")) {
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001983 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001984 }
1985
Zachary Turnerd30700f2018-07-31 17:16:44 +00001986 if (MangledName.consumeFront("$$Y")) {
1987 (*Current)->IsTemplateTemplate = true;
1988 (*Current)->IsAliasTemplate = true;
1989 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
1990 } else if (MangledName.consumeFront("$1?")) {
1991 (*Current)->ParamName = demangleFullyQualifiedSymbolName(MangledName);
1992 (*Current)->ParamType = demangleFunctionEncoding(MangledName);
1993 } else {
1994 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00001995 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00001996 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001997 if (Error)
1998 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00001999
2000 Current = &(*Current)->Next;
2001 }
2002
2003 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002004 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002005
2006 // Template parameter lists cannot be variadic, so it can only be terminated
2007 // by @.
2008 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002009 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002010 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002011 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002012}
2013
Zachary Turner316109b2018-07-29 16:38:02 +00002014void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002015 // Converts an AST to a string.
2016 //
2017 // Converting an AST representing a C++ type to a string is tricky due
2018 // to the bad grammar of the C++ declaration inherited from C. You have
2019 // to construct a string from inside to outside. For example, if a type
2020 // X is a pointer to a function returning int, the order you create a
2021 // string becomes something like this:
2022 //
2023 // (1) X is a pointer: *X
2024 // (2) (1) is a function returning int: int (*X)()
2025 //
2026 // So you cannot construct a result just by appending strings to a result.
2027 //
2028 // To deal with this, we split the function into two. outputPre() writes
2029 // the "first half" of type declaration, and outputPost() writes the
2030 // "second half". For example, outputPre() writes a return type for a
2031 // function and outputPost() writes an parameter list.
Zachary Turner316109b2018-07-29 16:38:02 +00002032 Type::outputPre(OS, *S->SymbolType);
2033 outputName(OS, S->SymbolName);
2034 Type::outputPost(OS, *S->SymbolType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002035}
2036
2037char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
2038 int *Status) {
Zachary Turner316109b2018-07-29 16:38:02 +00002039 Demangler D;
2040 StringView Name{MangledName};
2041 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002042
Zachary Turner316109b2018-07-29 16:38:02 +00002043 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002044 if (D.Error) {
2045 OS << MangledName;
2046 *Status = llvm::demangle_invalid_mangled_name;
2047 } else {
2048 D.output(S, OS);
2049 *Status = llvm::demangle_success;
2050 }
2051
Zachary Turner71c91f92018-07-30 03:12:34 +00002052 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002053 return OS.getBuffer();
2054}