blob: a89ced25baaa29c3c1a9280e971f83a391d56c7a [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>
24
25// This memory allocator is extremely fast, but it doesn't call dtors
26// for allocated objects. That means you can't use STL containers
27// (such as std::vector) with this allocator. But it pays off --
28// the demangler is 3x faster with this allocator compared to one with
29// STL containers.
30namespace {
31class ArenaAllocator {
32 struct AllocatorNode {
33 uint8_t *Buf = nullptr;
34 size_t Used = 0;
35 AllocatorNode *Next = nullptr;
36 };
37
38public:
39 ArenaAllocator() : Head(new AllocatorNode) { Head->Buf = new uint8_t[Unit]; }
40
41 ~ArenaAllocator() {
42 while (Head) {
43 assert(Head->Buf);
44 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000045 AllocatorNode *Next = Head->Next;
46 delete Head;
47 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000048 }
49 }
50
Zachary Turner9d72aa92018-07-20 18:35:06 +000051 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
52
53 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000054 assert(Size < Unit);
55 assert(Head && Head->Buf);
56
Zachary Turner9d72aa92018-07-20 18:35:06 +000057 size_t P = (size_t)Head->Buf + Head->Used;
58 uintptr_t AlignedP =
59 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
60 uint8_t *PP = (uint8_t *)AlignedP;
61 size_t Adjustment = AlignedP - P;
62
63 Head->Used += Size + Adjustment;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000064 if (Head->Used < Unit)
Zachary Turner9d72aa92018-07-20 18:35:06 +000065 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000066
67 AllocatorNode *NewHead = new AllocatorNode;
68 NewHead->Buf = new uint8_t[ArenaAllocator::Unit];
69 NewHead->Next = Head;
70 Head = NewHead;
71 NewHead->Used = Size;
Zachary Turner9d72aa92018-07-20 18:35:06 +000072 return new (NewHead->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000073 }
74
75private:
76 static constexpr size_t Unit = 4096;
77
78 AllocatorNode *Head = nullptr;
79};
80} // namespace
81
82static bool startsWithDigit(StringView S) {
83 return !S.empty() && std::isdigit(S.front());
84}
85
86// Writes a space if the last token does not end with a punctuation.
87static void outputSpaceIfNecessary(OutputStream &OS) {
88 if (OS.empty())
89 return;
90
91 char C = OS.back();
92 if (isalnum(C) || C == '>')
93 OS << " ";
94}
95
Zachary Turnerf435a7e2018-07-20 17:27:48 +000096// Storage classes
97enum Qualifiers : uint8_t {
98 Q_None = 0,
99 Q_Const = 1 << 0,
100 Q_Volatile = 1 << 1,
101 Q_Far = 1 << 2,
102 Q_Huge = 1 << 3,
103 Q_Unaligned = 1 << 4,
104 Q_Restrict = 1 << 5,
105 Q_Pointer64 = 1 << 6
106};
107
108enum class StorageClass : uint8_t {
109 None,
110 PrivateStatic,
111 ProtectedStatic,
112 PublicStatic,
113 Global,
114 FunctionLocalStatic
115};
116
117enum class QualifierMangleMode { Drop, Mangle, Result };
118enum class QualifierMangleLocation { Member, NonMember, Detect };
119
120// Calling conventions
121enum class CallingConv : uint8_t {
122 None,
123 Cdecl,
124 Pascal,
125 Thiscall,
126 Stdcall,
127 Fastcall,
128 Clrcall,
129 Eabi,
130 Vectorcall,
131 Regcall,
132};
133
134enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
135
136// Types
137enum class PrimTy : uint8_t {
138 Unknown,
139 None,
140 Function,
141 Ptr,
142 Ref,
143 Array,
144
145 Struct,
146 Union,
147 Class,
148 Enum,
149
150 Void,
151 Bool,
152 Char,
153 Schar,
154 Uchar,
155 Short,
156 Ushort,
157 Int,
158 Uint,
159 Long,
160 Ulong,
161 Int64,
162 Uint64,
163 Wchar,
164 Float,
165 Double,
166 Ldouble,
167};
168
169// Function classes
170enum FuncClass : uint8_t {
171 Public = 1 << 0,
172 Protected = 1 << 1,
173 Private = 1 << 2,
174 Global = 1 << 3,
175 Static = 1 << 4,
176 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000177 Far = 1 << 6,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000178};
179
180namespace {
181
182struct Type;
183
184// Represents a list of parameters (template params or function arguments.
185// It's represented as a linked list.
186struct ParamList {
187 Type *Current = nullptr;
188
189 ParamList *Next = nullptr;
190};
191
192// The type class. Mangled symbols are first parsed and converted to
193// this type and then converted to string.
194struct Type {
195 virtual ~Type() {}
196
197 virtual Type *clone(ArenaAllocator &Arena) const;
198
199 // Write the "first half" of a given type. This is a static functions to
200 // give the code a chance to do processing that is common to a subset of
201 // subclasses
202 static void outputPre(OutputStream &OS, Type &Ty);
203
204 // Write the "second half" of a given type. This is a static functions to
205 // give the code a chance to do processing that is common to a subset of
206 // subclasses
207 static void outputPost(OutputStream &OS, Type &Ty);
208
209 virtual void outputPre(OutputStream &OS);
210 virtual void outputPost(OutputStream &OS);
211
212 // Primitive type such as Int.
213 PrimTy Prim = PrimTy::Unknown;
214
215 Qualifiers Quals = Q_None;
216 StorageClass Storage = StorageClass::None; // storage class
217};
218
219// Represents an identifier which may be a template.
220struct Name {
221 // Name read from an MangledName string.
222 StringView Str;
223
224 // Overloaded operators are represented as special BackReferences in mangled
225 // symbols. If this is an operator name, "op" has an operator name (e.g.
226 // ">>"). Otherwise, empty.
227 StringView Operator;
228
229 // Template parameters. Null if not a template.
230 ParamList TemplateParams;
231
232 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
233 Name *Next = nullptr;
234};
235
236struct PointerType : public Type {
237 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000238 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000239 void outputPost(OutputStream &OS) override;
240
241 bool isMemberPointer() const { return false; }
242
243 // Represents a type X in "a pointer to X", "a reference to X",
244 // "an array of X", or "a function returning X".
245 Type *Pointee = nullptr;
246};
247
248struct FunctionType : public Type {
249 Type *clone(ArenaAllocator &Arena) const override;
Benjamin Kramera2e18bb2018-07-20 18:22:12 +0000250 void outputPre(OutputStream &OS) override;
251 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000252
253 Type *ReturnType = nullptr;
254 // If this is a reference, the type of reference.
255 ReferenceKind RefKind;
256
257 CallingConv CallConvention;
258 FuncClass FunctionClass;
259
260 ParamList Params;
261};
262
263struct UdtType : public Type {
264 Type *clone(ArenaAllocator &Arena) const override;
265 void outputPre(OutputStream &OS) override;
266
267 Name *UdtName = nullptr;
268};
269
270struct ArrayType : public Type {
271 Type *clone(ArenaAllocator &Arena) const override;
272 void outputPre(OutputStream &OS) override;
273 void outputPost(OutputStream &OS) override;
274
275 // Either NextDimension or ElementType will be valid.
276 ArrayType *NextDimension = nullptr;
277 uint32_t ArrayDimension = 0;
278
279 Type *ElementType = nullptr;
280};
281
282} // namespace
283
284static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
285 outputSpaceIfNecessary(OS);
286
287 switch (CC) {
288 case CallingConv::Cdecl:
289 OS << "__cdecl";
290 break;
291 case CallingConv::Fastcall:
292 OS << "__fastcall";
293 break;
294 case CallingConv::Pascal:
295 OS << "__pascal";
296 break;
297 case CallingConv::Regcall:
298 OS << "__regcall";
299 break;
300 case CallingConv::Stdcall:
301 OS << "__stdcall";
302 break;
303 case CallingConv::Thiscall:
304 OS << "__thiscall";
305 break;
306 case CallingConv::Eabi:
307 OS << "__eabi";
308 break;
309 case CallingConv::Vectorcall:
310 OS << "__vectorcall";
311 break;
312 case CallingConv::Clrcall:
313 OS << "__clrcall";
314 break;
315 default:
316 break;
317 }
318}
319
320// Write a function or template parameter list.
321static void outputParameterList(OutputStream &OS, const ParamList &Params) {
322 const ParamList *Head = &Params;
323 while (Head) {
324 Type::outputPre(OS, *Head->Current);
325 Type::outputPost(OS, *Head->Current);
326
327 Head = Head->Next;
328
329 if (Head)
330 OS << ", ";
331 }
332}
333
334static void outputTemplateParams(OutputStream &OS, const Name &TheName) {
335 if (!TheName.TemplateParams.Current)
336 return;
337
338 OS << "<";
339 outputParameterList(OS, TheName.TemplateParams);
340 OS << ">";
341}
342
343static void outputName(OutputStream &OS, const Name *TheName) {
344 if (!TheName)
345 return;
346
347 outputSpaceIfNecessary(OS);
348
349 // Print out namespaces or outer class BackReferences.
350 for (; TheName->Next; TheName = TheName->Next) {
351 OS << TheName->Str;
352 outputTemplateParams(OS, *TheName);
353 OS << "::";
354 }
355
356 // Print out a regular name.
357 if (TheName->Operator.empty()) {
358 OS << TheName->Str;
359 outputTemplateParams(OS, *TheName);
360 return;
361 }
362
363 // Print out ctor or dtor.
364 if (TheName->Operator == "ctor" || TheName->Operator == "dtor") {
365 OS << TheName->Str;
366 outputTemplateParams(OS, *TheName);
367 OS << "::";
368 if (TheName->Operator == "dtor")
369 OS << "~";
370 OS << TheName->Str;
371 outputTemplateParams(OS, *TheName);
372 return;
373 }
374
375 // Print out an overloaded operator.
376 if (!TheName->Str.empty())
377 OS << TheName->Str << "::";
378 OS << "operator" << TheName->Operator;
379}
380
381namespace {
382
383Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000384 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000385}
386
387// Write the "first half" of a given type.
388void Type::outputPre(OutputStream &OS, Type &Ty) {
389 // Function types require custom handling of const and static so we
390 // handle them separately. All other types use the same decoration
391 // for these modifiers, so handle them here in common code.
392 if (Ty.Prim == PrimTy::Function) {
393 Ty.outputPre(OS);
394 return;
395 }
396
397 switch (Ty.Storage) {
398 case StorageClass::PrivateStatic:
399 case StorageClass::PublicStatic:
400 case StorageClass::ProtectedStatic:
401 OS << "static ";
402 default:
403 break;
404 }
405 Ty.outputPre(OS);
406
407 if (Ty.Quals & Q_Const) {
408 outputSpaceIfNecessary(OS);
409 OS << "const";
410 }
411
412 if (Ty.Quals & Q_Volatile) {
413 outputSpaceIfNecessary(OS);
414 OS << "volatile";
415 }
416}
417
418// Write the "second half" of a given type.
419void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
420
421void Type::outputPre(OutputStream &OS) {
422 switch (Prim) {
423 case PrimTy::Void:
424 OS << "void";
425 break;
426 case PrimTy::Bool:
427 OS << "bool";
428 break;
429 case PrimTy::Char:
430 OS << "char";
431 break;
432 case PrimTy::Schar:
433 OS << "signed char";
434 break;
435 case PrimTy::Uchar:
436 OS << "unsigned char";
437 break;
438 case PrimTy::Short:
439 OS << "short";
440 break;
441 case PrimTy::Ushort:
442 OS << "unsigned short";
443 break;
444 case PrimTy::Int:
445 OS << "int";
446 break;
447 case PrimTy::Uint:
448 OS << "unsigned int";
449 break;
450 case PrimTy::Long:
451 OS << "long";
452 break;
453 case PrimTy::Ulong:
454 OS << "unsigned long";
455 break;
456 case PrimTy::Int64:
457 OS << "__int64";
458 break;
459 case PrimTy::Uint64:
460 OS << "unsigned __int64";
461 break;
462 case PrimTy::Wchar:
463 OS << "wchar_t";
464 break;
465 case PrimTy::Float:
466 OS << "float";
467 break;
468 case PrimTy::Double:
469 OS << "double";
470 break;
471 case PrimTy::Ldouble:
472 OS << "long double";
473 break;
474 default:
475 assert(false && "Invalid primitive type!");
476 }
477}
478void Type::outputPost(OutputStream &OS) {}
479
480Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000481 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000482}
483
484void PointerType::outputPre(OutputStream &OS) {
485 Type::outputPre(OS, *Pointee);
486
487 outputSpaceIfNecessary(OS);
488
489 if (Quals & Q_Unaligned)
490 OS << "__unaligned ";
491
492 // "[]" and "()" (for function parameters) take precedence over "*",
493 // so "int *x(int)" means "x is a function returning int *". We need
494 // parentheses to supercede the default precedence. (e.g. we want to
495 // emit something like "int (*x)(int)".)
496 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
497 OS << "(";
498
499 if (Prim == PrimTy::Ptr)
500 OS << "*";
501 else
502 OS << "&";
503
Zachary Turner91ecedd2018-07-20 18:07:33 +0000504 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000505 // if (Ty.Quals & Q_Pointer64)
506 // OS << " __ptr64";
507 if (Quals & Q_Restrict)
508 OS << " __restrict";
509}
510
511void PointerType::outputPost(OutputStream &OS) {
512 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
513 OS << ")";
514
515 Type::outputPost(OS, *Pointee);
516}
517
518Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000519 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000520}
521
522void FunctionType::outputPre(OutputStream &OS) {
523 if (!(FunctionClass & Global)) {
524 if (FunctionClass & Static)
525 OS << "static ";
526 }
527
528 if (ReturnType)
529 Type::outputPre(OS, *ReturnType);
530
531 outputCallingConvention(OS, CallConvention);
532}
533
534void FunctionType::outputPost(OutputStream &OS) {
535 OS << "(";
536 outputParameterList(OS, Params);
537 OS << ")";
538 if (Quals & Q_Const)
539 OS << " const";
540 if (Quals & Q_Volatile)
541 OS << " volatile";
542 return;
543}
544
545Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000546 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000547}
548
549void UdtType::outputPre(OutputStream &OS) {
550 switch (Prim) {
551 case PrimTy::Class:
552 OS << "class ";
553 break;
554 case PrimTy::Struct:
555 OS << "struct ";
556 break;
557 case PrimTy::Union:
558 OS << "union ";
559 break;
560 case PrimTy::Enum:
561 OS << "enum ";
562 break;
563 default:
564 assert(false && "Not a udt type!");
565 }
566
567 outputName(OS, UdtName);
568}
569
570Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000571 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000572}
573
574void ArrayType::outputPre(OutputStream &OS) {
575 Type::outputPre(OS, *ElementType);
576}
577
578void ArrayType::outputPost(OutputStream &OS) {
579 if (ArrayDimension > 0)
580 OS << "[" << ArrayDimension << "]";
581 if (NextDimension)
582 Type::outputPost(OS, *NextDimension);
583 else if (ElementType)
584 Type::outputPost(OS, *ElementType);
585}
586
587} // namespace
588
589namespace {
590
591// Demangler class takes the main role in demangling symbols.
592// It has a set of functions to parse mangled symbols into Type instances.
593// It also has a set of functions to cnovert Type instances to strings.
594class Demangler {
595public:
596 Demangler(OutputStream &OS, StringView s) : OS(OS), MangledName(s) {}
597
598 // You are supposed to call parse() first and then check if error is true. If
599 // it is false, call output() to write the formatted name to the given stream.
600 void parse();
601 void output();
602
603 // True if an error occurred.
604 bool Error = false;
605
606private:
607 Type *demangleVariableEncoding();
608 Type *demangleFunctionEncoding();
609
610 Qualifiers demanglePointerExtQualifiers();
611
612 // Parser functions. This is a recursive-descent parser.
613 Type *demangleType(QualifierMangleMode QMM);
614 Type *demangleBasicType();
615 UdtType *demangleClassType();
616 PointerType *demanglePointerType();
617
618 ArrayType *demangleArrayType();
619
620 ParamList demangleParameterList();
621
622 int demangleNumber();
623 void demangleNamePiece(Name &Node, bool IsHead);
624
625 StringView demangleString(bool memorize);
626 void memorizeString(StringView s);
627 Name *demangleName();
628 void demangleOperator(Name *);
629 StringView demangleOperatorName();
630 int demangleFunctionClass();
631 CallingConv demangleCallingConvention();
632 StorageClass demangleVariableStorageClass();
633 ReferenceKind demangleReferenceKind();
634
635 Qualifiers demangleFunctionQualifiers();
Zachary Turner91ecedd2018-07-20 18:07:33 +0000636 Qualifiers demangleVariablQualifiers();
637 Qualifiers demangleReturnTypQualifiers();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000638
639 Qualifiers demangleQualifiers(
640 QualifierMangleLocation Location = QualifierMangleLocation::Detect);
641
Zachary Turner91ecedd2018-07-20 18:07:33 +0000642 // The result is written to this stream.
643 OutputStream OS;
644
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000645 // Mangled symbol. demangle* functions shorten this string
646 // as they parse it.
647 StringView MangledName;
648
649 // A parsed mangled symbol.
Zachary Turner91ecedd2018-07-20 18:07:33 +0000650 Type *SymbolType = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000651
652 // The main symbol name. (e.g. "ns::foo" in "int ns::foo()".)
653 Name *SymbolName = nullptr;
654
655 // Memory allocator.
656 ArenaAllocator Arena;
657
658 // The first 10 BackReferences in a mangled name can be back-referenced by
659 // special name @[0-9]. This is a storage for the first 10 BackReferences.
660 StringView BackReferences[10];
661 size_t BackRefCount = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000662};
663} // namespace
664
665// Parser entry point.
666void Demangler::parse() {
667 // MSVC-style mangled symbols must start with '?'.
668 if (!MangledName.consumeFront("?")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000669 SymbolName = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000670 SymbolName->Str = MangledName;
Zachary Turner9d72aa92018-07-20 18:35:06 +0000671 SymbolType = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000672 SymbolType->Prim = PrimTy::Unknown;
673 }
674
675 // What follows is a main symbol name. This may include
676 // namespaces or class BackReferences.
677 SymbolName = demangleName();
678
679 // Read a variable.
680 if (startsWithDigit(MangledName)) {
681 SymbolType = demangleVariableEncoding();
682 return;
683 }
684
685 // Read a function.
686 SymbolType = demangleFunctionEncoding();
687}
688
689// <type-encoding> ::= <storage-class> <variable-type>
690// <storage-class> ::= 0 # private static member
691// ::= 1 # protected static member
692// ::= 2 # public static member
693// ::= 3 # global
694// ::= 4 # static local
695
696Type *Demangler::demangleVariableEncoding() {
697 StorageClass SC = demangleVariableStorageClass();
698
699 Type *Ty = demangleType(QualifierMangleMode::Drop);
700
701 Ty->Storage = SC;
702
703 // <variable-type> ::= <type> <cvr-qualifiers>
704 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
705 switch (Ty->Prim) {
706 case PrimTy::Ptr:
707 case PrimTy::Ref: {
708 Qualifiers ExtraChildQuals = Q_None;
709 Ty->Quals = Qualifiers(Ty->Quals | demanglePointerExtQualifiers());
710
711 PointerType *PTy = static_cast<PointerType *>(Ty);
712 QualifierMangleLocation Location = PTy->isMemberPointer()
713 ? QualifierMangleLocation::Member
714 : QualifierMangleLocation::NonMember;
715
716 ExtraChildQuals = demangleQualifiers(Location);
717
718 if (PTy->isMemberPointer()) {
719 Name *BackRefName = demangleName();
720 (void)BackRefName;
721 }
722
723 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
724 break;
725 }
726 default:
727 Ty->Quals = demangleQualifiers();
728 break;
729 }
730
731 return Ty;
732}
733
734// Sometimes numbers are encoded in mangled symbols. For example,
735// "int (*x)[20]" is a valid C type (x is a pointer to an array of
736// length 20), so we need some way to embed numbers as part of symbols.
737// This function parses it.
738//
739// <number> ::= [?] <non-negative integer>
740//
741// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
742// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
743//
744// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
745int Demangler::demangleNumber() {
746 bool neg = MangledName.consumeFront("?");
747
748 if (startsWithDigit(MangledName)) {
749 int32_t Ret = MangledName[0] - '0' + 1;
750 MangledName = MangledName.dropFront(1);
751 return neg ? -Ret : Ret;
752 }
753
754 int Ret = 0;
755 for (size_t i = 0; i < MangledName.size(); ++i) {
756 char C = MangledName[i];
757 if (C == '@') {
758 MangledName = MangledName.dropFront(i + 1);
759 return neg ? -Ret : Ret;
760 }
761 if ('A' <= C && C <= 'P') {
762 Ret = (Ret << 4) + (C - 'A');
763 continue;
764 }
765 break;
766 }
767
768 Error = true;
769 return 0;
770}
771
772// Read until the next '@'.
773StringView Demangler::demangleString(bool Memorize) {
774 for (size_t i = 0; i < MangledName.size(); ++i) {
775 if (MangledName[i] != '@')
776 continue;
777 StringView ret = MangledName.substr(0, i);
778 MangledName = MangledName.dropFront(i + 1);
779
780 if (Memorize)
781 memorizeString(ret);
782 return ret;
783 }
784
785 Error = true;
786 return "";
787}
788
789// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
790// Memorize it.
791void Demangler::memorizeString(StringView S) {
792 if (BackRefCount >= sizeof(BackReferences) / sizeof(*BackReferences))
793 return;
794 for (size_t i = 0; i < BackRefCount; ++i)
795 if (S == BackReferences[i])
796 return;
797 BackReferences[BackRefCount++] = S;
798}
799
800void Demangler::demangleNamePiece(Name &Node, bool IsHead) {
801 if (startsWithDigit(MangledName)) {
802 size_t I = MangledName[0] - '0';
803 if (I >= BackRefCount) {
804 Error = true;
805 return;
806 }
807 MangledName = MangledName.dropFront();
808 Node.Str = BackReferences[I];
809 } else if (MangledName.consumeFront("?$")) {
810 // Class template.
811 Node.Str = demangleString(false);
812 Node.TemplateParams = demangleParameterList();
813 if (!MangledName.consumeFront('@')) {
814 Error = true;
815 return;
816 }
817 } else if (!IsHead && MangledName.consumeFront("?A")) {
818 // Anonymous namespace starts with ?A. So does overloaded operator[],
819 // but the distinguishing factor is that namespace themselves are not
820 // mangled, only the variables and functions inside of them are. So
821 // an anonymous namespace will never occur as the first item in the
822 // name.
823 Node.Str = "`anonymous namespace'";
824 if (!MangledName.consumeFront('@')) {
825 Error = true;
826 return;
827 }
828 } else if (MangledName.consumeFront("?")) {
829 // Overloaded operator.
830 demangleOperator(&Node);
831 } else {
832 // Non-template functions or classes.
833 Node.Str = demangleString(true);
834 }
835}
836
837// Parses a name in the form of A@B@C@@ which represents C::B::A.
838Name *Demangler::demangleName() {
839 Name *Head = nullptr;
840
841 while (!MangledName.consumeFront("@")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000842 Name *Elem = Arena.alloc<Name>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000843
844 assert(!Error);
845 demangleNamePiece(*Elem, Head == nullptr);
846 if (Error)
847 return nullptr;
848
849 Elem->Next = Head;
850 Head = Elem;
851 }
852
853 return Head;
854}
855
856void Demangler::demangleOperator(Name *OpName) {
857 OpName->Operator = demangleOperatorName();
858 if (!Error && !MangledName.empty() && MangledName.front() != '@')
859 demangleNamePiece(*OpName, false);
860}
861
862StringView Demangler::demangleOperatorName() {
863 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
864 RestoreOnError.shouldRestore(false);
865
866 switch (MangledName.popFront()) {
867 case '0':
868 return "ctor";
869 case '1':
870 return "dtor";
871 case '2':
872 return " new";
873 case '3':
874 return " delete";
875 case '4':
876 return "=";
877 case '5':
878 return ">>";
879 case '6':
880 return "<<";
881 case '7':
882 return "!";
883 case '8':
884 return "==";
885 case '9':
886 return "!=";
887 case 'A':
888 return "[]";
889 case 'C':
890 return "->";
891 case 'D':
892 return "*";
893 case 'E':
894 return "++";
895 case 'F':
896 return "--";
897 case 'G':
898 return "-";
899 case 'H':
900 return "+";
901 case 'I':
902 return "&";
903 case 'J':
904 return "->*";
905 case 'K':
906 return "/";
907 case 'L':
908 return "%";
909 case 'M':
910 return "<";
911 case 'N':
912 return "<=";
913 case 'O':
914 return ">";
915 case 'P':
916 return ">=";
917 case 'Q':
918 return ",";
919 case 'R':
920 return "()";
921 case 'S':
922 return "~";
923 case 'T':
924 return "^";
925 case 'U':
926 return "|";
927 case 'V':
928 return "&&";
929 case 'W':
930 return "||";
931 case 'X':
932 return "*=";
933 case 'Y':
934 return "+=";
935 case 'Z':
936 return "-=";
937 case '_': {
938 if (MangledName.empty())
939 break;
940
941 switch (MangledName.popFront()) {
942 case '0':
943 return "/=";
944 case '1':
945 return "%=";
946 case '2':
947 return ">>=";
948 case '3':
949 return "<<=";
950 case '4':
951 return "&=";
952 case '5':
953 return "|=";
954 case '6':
955 return "^=";
956 case 'U':
957 return " new[]";
958 case 'V':
959 return " delete[]";
960 case '_':
961 if (MangledName.consumeFront("L"))
962 return " co_await";
963 }
964 }
965 }
966
967 Error = true;
968 RestoreOnError.shouldRestore(true);
969 return "";
970}
971
972int Demangler::demangleFunctionClass() {
973 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
974 RestoreOnError.shouldRestore(false);
975
976 switch (MangledName.popFront()) {
977 case 'A':
978 return Private;
979 case 'B':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000980 return Private | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000981 case 'C':
982 return Private | Static;
983 case 'D':
984 return Private | Static;
985 case 'E':
986 return Private | Virtual;
987 case 'F':
988 return Private | Virtual;
989 case 'I':
990 return Protected;
991 case 'J':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000992 return Protected | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000993 case 'K':
994 return Protected | Static;
995 case 'L':
Zachary Turner91ecedd2018-07-20 18:07:33 +0000996 return Protected | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000997 case 'M':
998 return Protected | Virtual;
999 case 'N':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001000 return Protected | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001001 case 'Q':
1002 return Public;
1003 case 'R':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001004 return Public | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001005 case 'S':
1006 return Public | Static;
1007 case 'T':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001008 return Public | Static | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001009 case 'U':
1010 return Public | Virtual;
1011 case 'V':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001012 return Public | Virtual | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001013 case 'Y':
1014 return Global;
1015 case 'Z':
Zachary Turner91ecedd2018-07-20 18:07:33 +00001016 return Global | Far;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001017 }
1018
1019 Error = true;
1020 RestoreOnError.shouldRestore(true);
1021 return 0;
1022}
1023
1024Qualifiers Demangler::demangleFunctionQualifiers() {
1025 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1026 RestoreOnError.shouldRestore(false);
1027
1028 switch (MangledName.popFront()) {
1029 case 'A':
1030 return Q_None;
1031 case 'B':
1032 return Q_Const;
1033 case 'C':
1034 return Q_Volatile;
1035 case 'D':
1036 return Qualifiers(Q_Const | Q_Volatile);
1037 }
1038
1039 Error = true;
1040 RestoreOnError.shouldRestore(true);
1041 return Q_None;
1042}
1043
1044CallingConv Demangler::demangleCallingConvention() {
1045 switch (MangledName.popFront()) {
1046 case 'A':
1047 case 'B':
1048 return CallingConv::Cdecl;
1049 case 'C':
1050 case 'D':
1051 return CallingConv::Pascal;
1052 case 'E':
1053 case 'F':
1054 return CallingConv::Thiscall;
1055 case 'G':
1056 case 'H':
1057 return CallingConv::Stdcall;
1058 case 'I':
1059 case 'J':
1060 return CallingConv::Fastcall;
1061 case 'M':
1062 case 'N':
1063 return CallingConv::Clrcall;
1064 case 'O':
1065 case 'P':
1066 return CallingConv::Eabi;
1067 case 'Q':
1068 return CallingConv::Vectorcall;
1069 }
1070
1071 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00001072}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001073
1074StorageClass Demangler::demangleVariableStorageClass() {
1075 assert(std::isdigit(MangledName.front()));
1076
1077 switch (MangledName.popFront()) {
1078 case '0':
1079 return StorageClass::PrivateStatic;
1080 case '1':
1081 return StorageClass::ProtectedStatic;
1082 case '2':
1083 return StorageClass::PublicStatic;
1084 case '3':
1085 return StorageClass::Global;
1086 case '4':
1087 return StorageClass::FunctionLocalStatic;
1088 }
1089 Error = true;
1090 return StorageClass::None;
1091}
1092
Zachary Turner91ecedd2018-07-20 18:07:33 +00001093Qualifiers Demangler::demangleVariablQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001094 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1095 RestoreOnError.shouldRestore(false);
1096
1097 switch (MangledName.popFront()) {
1098 case 'A':
1099 return Q_None;
1100 case 'B':
1101 return Q_Const;
1102 case 'C':
1103 return Q_Volatile;
1104 case 'D':
1105 return Qualifiers(Q_Const | Q_Volatile);
1106 case 'E':
1107 return Q_Far;
1108 case 'F':
1109 return Qualifiers(Q_Const | Q_Far);
1110 case 'G':
1111 return Qualifiers(Q_Volatile | Q_Far);
1112 case 'H':
1113 return Qualifiers(Q_Const | Q_Volatile | Q_Far);
1114 }
1115
1116 Error = true;
1117 RestoreOnError.shouldRestore(true);
1118 return Q_None;
1119}
1120
Zachary Turner91ecedd2018-07-20 18:07:33 +00001121Qualifiers Demangler::demangleReturnTypQualifiers() {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001122 if (!MangledName.consumeFront("?"))
1123 return Q_None;
1124
1125 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
1126 RestoreOnError.shouldRestore(false);
1127
1128 switch (MangledName.popFront()) {
1129 case 'A':
1130 return Q_None;
1131 case 'B':
1132 return Q_Const;
1133 case 'C':
1134 return Q_Volatile;
1135 case 'D':
1136 return Qualifiers(Q_Const | Q_Volatile);
1137 }
1138
1139 Error = true;
1140 RestoreOnError.shouldRestore(true);
1141 return Q_None;
1142}
1143
1144Qualifiers Demangler::demangleQualifiers(QualifierMangleLocation Location) {
1145 if (Location == QualifierMangleLocation::Detect) {
1146 switch (MangledName.front()) {
1147 case 'Q':
1148 case 'R':
1149 case 'S':
1150 case 'T':
1151 Location = QualifierMangleLocation::Member;
1152 break;
1153 case 'A':
1154 case 'B':
1155 case 'C':
1156 case 'D':
1157 Location = QualifierMangleLocation::NonMember;
1158 break;
1159 default:
1160 Error = true;
1161 return Q_None;
1162 }
1163 }
1164
1165 if (Location == QualifierMangleLocation::Member) {
1166 switch (MangledName.popFront()) {
1167 // Member qualifiers
1168 case 'Q':
1169 return Q_None;
1170 case 'R':
1171 return Q_Const;
1172 case 'S':
1173 return Q_Volatile;
1174 case 'T':
1175 return Qualifiers(Q_Const | Q_Volatile);
1176 }
1177 } else {
1178 switch (MangledName.popFront()) {
1179 // Non-Member qualifiers
1180 case 'A':
1181 return Q_None;
1182 case 'B':
1183 return Q_Const;
1184 case 'C':
1185 return Q_Volatile;
1186 case 'D':
1187 return Qualifiers(Q_Const | Q_Volatile);
1188 }
1189 }
1190 Error = true;
1191 return Q_None;
1192}
1193
1194// <variable-type> ::= <type> <cvr-qualifiers>
1195// ::= <type> <pointee-cvr-qualifiers> # pointers, references
1196Type *Demangler::demangleType(QualifierMangleMode QMM) {
1197 Qualifiers Quals = Q_None;
1198 if (QMM == QualifierMangleMode::Mangle)
1199 Quals = Qualifiers(Quals | demangleQualifiers());
1200 else if (QMM == QualifierMangleMode::Result) {
1201 if (MangledName.consumeFront('?'))
1202 Quals = Qualifiers(Quals | demangleQualifiers());
1203 }
1204
1205 Type *Ty = nullptr;
1206 switch (MangledName.front()) {
1207 case 'T': // union
1208 case 'U': // struct
1209 case 'V': // class
1210 case 'W': // enum
1211 Ty = demangleClassType();
1212 break;
1213 case 'A': // foo &
1214 case 'P': // foo *
1215 case 'Q': // foo *const
1216 case 'R': // foo *volatile
1217 case 'S': // foo *const volatile
1218 Ty = demanglePointerType();
1219 break;
1220 case 'Y':
1221 Ty = demangleArrayType();
1222 break;
1223 default:
1224 Ty = demangleBasicType();
1225 break;
1226 }
1227 Ty->Quals = Qualifiers(Ty->Quals | Quals);
1228 return Ty;
1229}
1230
1231static bool functionHasThisPtr(const FunctionType &Ty) {
1232 assert(Ty.Prim == PrimTy::Function);
1233 if (Ty.FunctionClass & Global)
1234 return false;
1235 if (Ty.FunctionClass & Static)
1236 return false;
1237 return true;
1238}
1239
1240ReferenceKind Demangler::demangleReferenceKind() {
1241 if (MangledName.consumeFront('G'))
1242 return ReferenceKind::LValueRef;
1243 else if (MangledName.consumeFront('H'))
1244 return ReferenceKind::RValueRef;
1245 return ReferenceKind::None;
1246}
1247
1248Type *Demangler::demangleFunctionEncoding() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001249 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001250
1251 FTy->Prim = PrimTy::Function;
1252 FTy->FunctionClass = (FuncClass)demangleFunctionClass();
1253 if (functionHasThisPtr(*FTy)) {
1254 FTy->Quals = demanglePointerExtQualifiers();
1255 FTy->RefKind = demangleReferenceKind();
1256 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers());
1257 }
1258
1259 // Fields that appear on both member and non-member functions.
1260 FTy->CallConvention = demangleCallingConvention();
1261
1262 // <return-type> ::= <type>
1263 // ::= @ # structors (they have no declared return type)
1264 bool IsStructor = MangledName.consumeFront('@');
1265 if (!IsStructor)
1266 FTy->ReturnType = demangleType(QualifierMangleMode::Result);
1267
1268 FTy->Params = demangleParameterList();
1269
1270 return FTy;
1271}
1272
1273// Reads a primitive type.
1274Type *Demangler::demangleBasicType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001275 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001276
1277 switch (MangledName.popFront()) {
1278 case 'X':
1279 Ty->Prim = PrimTy::Void;
1280 break;
1281 case 'D':
1282 Ty->Prim = PrimTy::Char;
1283 break;
1284 case 'C':
1285 Ty->Prim = PrimTy::Schar;
1286 break;
1287 case 'E':
1288 Ty->Prim = PrimTy::Uchar;
1289 break;
1290 case 'F':
1291 Ty->Prim = PrimTy::Short;
1292 break;
1293 case 'G':
1294 Ty->Prim = PrimTy::Ushort;
1295 break;
1296 case 'H':
1297 Ty->Prim = PrimTy::Int;
1298 break;
1299 case 'I':
1300 Ty->Prim = PrimTy::Uint;
1301 break;
1302 case 'J':
1303 Ty->Prim = PrimTy::Long;
1304 break;
1305 case 'K':
1306 Ty->Prim = PrimTy::Ulong;
1307 break;
1308 case 'M':
1309 Ty->Prim = PrimTy::Float;
1310 break;
1311 case 'N':
1312 Ty->Prim = PrimTy::Double;
1313 break;
1314 case 'O':
1315 Ty->Prim = PrimTy::Ldouble;
1316 break;
1317 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00001318 if (MangledName.empty()) {
1319 Error = true;
1320 return nullptr;
1321 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001322 switch (MangledName.popFront()) {
1323 case 'N':
1324 Ty->Prim = PrimTy::Bool;
1325 break;
1326 case 'J':
1327 Ty->Prim = PrimTy::Int64;
1328 break;
1329 case 'K':
1330 Ty->Prim = PrimTy::Uint64;
1331 break;
1332 case 'W':
1333 Ty->Prim = PrimTy::Wchar;
1334 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00001335 default:
1336 assert(false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001337 }
1338 break;
1339 }
1340 }
1341 return Ty;
1342}
1343
1344UdtType *Demangler::demangleClassType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001345 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001346
1347 switch (MangledName.popFront()) {
1348 case 'T':
1349 UTy->Prim = PrimTy::Union;
1350 break;
1351 case 'U':
1352 UTy->Prim = PrimTy::Struct;
1353 break;
1354 case 'V':
1355 UTy->Prim = PrimTy::Class;
1356 break;
1357 case 'W':
1358 if (MangledName.popFront() != '4') {
1359 Error = true;
1360 return nullptr;
1361 }
1362 UTy->Prim = PrimTy::Enum;
1363 break;
1364 default:
1365 assert(false);
1366 }
1367
1368 UTy->UdtName = demangleName();
1369 return UTy;
1370}
1371
1372// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
1373// # the E is required for 64-bit non-static pointers
1374PointerType *Demangler::demanglePointerType() {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001375 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001376
1377 Pointer->Quals = Q_None;
1378 switch (MangledName.popFront()) {
1379 case 'A':
1380 Pointer->Prim = PrimTy::Ref;
1381 break;
1382 case 'P':
1383 Pointer->Prim = PrimTy::Ptr;
1384 break;
1385 case 'Q':
1386 Pointer->Prim = PrimTy::Ptr;
1387 Pointer->Quals = Q_Const;
1388 break;
1389 case 'R':
1390 Pointer->Quals = Q_Volatile;
1391 Pointer->Prim = PrimTy::Ptr;
1392 break;
1393 case 'S':
1394 Pointer->Quals = Qualifiers(Q_Const | Q_Volatile);
1395 Pointer->Prim = PrimTy::Ptr;
1396 break;
1397 default:
1398 assert(false && "Ty is not a pointer type!");
1399 }
1400
1401 if (MangledName.consumeFront("6")) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001402 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001403 FTy->Prim = PrimTy::Function;
1404 FTy->CallConvention = demangleCallingConvention();
1405
1406 FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
1407 FTy->Params = demangleParameterList();
1408
1409 if (!MangledName.consumeFront("@Z"))
1410 MangledName.consumeFront("Z");
1411
1412 Pointer->Pointee = FTy;
1413 return Pointer;
1414 }
1415
1416 Qualifiers ExtQuals = demanglePointerExtQualifiers();
1417 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
1418
1419 Pointer->Pointee = demangleType(QualifierMangleMode::Mangle);
1420 return Pointer;
1421}
1422
1423Qualifiers Demangler::demanglePointerExtQualifiers() {
1424 Qualifiers Quals = Q_None;
1425 if (MangledName.consumeFront('E'))
1426 Quals = Qualifiers(Quals | Q_Pointer64);
1427 if (MangledName.consumeFront('I'))
1428 Quals = Qualifiers(Quals | Q_Restrict);
1429 if (MangledName.consumeFront('F'))
1430 Quals = Qualifiers(Quals | Q_Unaligned);
1431
1432 return Quals;
1433}
1434
1435ArrayType *Demangler::demangleArrayType() {
1436 assert(MangledName.front() == 'Y');
1437 MangledName.popFront();
1438
1439 int Dimension = demangleNumber();
1440 if (Dimension <= 0) {
1441 Error = true;
1442 return nullptr;
1443 }
1444
Zachary Turner9d72aa92018-07-20 18:35:06 +00001445 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001446 ArrayType *Dim = ATy;
1447 for (int I = 0; I < Dimension; ++I) {
1448 Dim->Prim = PrimTy::Array;
1449 Dim->ArrayDimension = demangleNumber();
Zachary Turner9d72aa92018-07-20 18:35:06 +00001450 Dim->NextDimension = Arena.alloc<ArrayType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001451 Dim = Dim->NextDimension;
1452 }
1453
1454 if (MangledName.consumeFront("$$C")) {
1455 if (MangledName.consumeFront("B"))
1456 ATy->Quals = Q_Const;
1457 else if (MangledName.consumeFront("C") || MangledName.consumeFront("D"))
1458 ATy->Quals = Qualifiers(Q_Const | Q_Volatile);
1459 else if (!MangledName.consumeFront("A"))
1460 Error = true;
1461 }
1462
1463 ATy->ElementType = demangleType(QualifierMangleMode::Drop);
1464 Dim->ElementType = ATy->ElementType;
1465 return ATy;
1466}
1467
1468// Reads a function or a template parameters.
1469ParamList Demangler::demangleParameterList() {
1470 // Within the same parameter list, you can backreference the first 10 types.
1471 Type *BackRef[10];
1472 int Idx = 0;
1473
1474 ParamList *Head;
1475 ParamList **Current = &Head;
1476 while (!Error && !MangledName.startsWith('@') &&
1477 !MangledName.startsWith('Z')) {
1478 if (startsWithDigit(MangledName)) {
1479 int N = MangledName[0] - '0';
1480 if (N >= Idx) {
1481 Error = true;
1482 return {};
1483 }
1484 MangledName = MangledName.dropFront();
1485
Zachary Turner9d72aa92018-07-20 18:35:06 +00001486 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001487 (*Current)->Current = BackRef[N]->clone(Arena);
1488 Current = &(*Current)->Next;
1489 continue;
1490 }
1491
1492 size_t ArrayDimension = MangledName.size();
1493
Zachary Turner9d72aa92018-07-20 18:35:06 +00001494 *Current = Arena.alloc<ParamList>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001495 (*Current)->Current = demangleType(QualifierMangleMode::Drop);
1496
1497 // Single-letter types are ignored for backreferences because
1498 // memorizing them doesn't save anything.
1499 if (Idx <= 9 && ArrayDimension - MangledName.size() > 1)
1500 BackRef[Idx++] = (*Current)->Current;
1501 Current = &(*Current)->Next;
1502 }
1503
1504 return *Head;
1505}
1506
1507void Demangler::output() {
1508 // Converts an AST to a string.
1509 //
1510 // Converting an AST representing a C++ type to a string is tricky due
1511 // to the bad grammar of the C++ declaration inherited from C. You have
1512 // to construct a string from inside to outside. For example, if a type
1513 // X is a pointer to a function returning int, the order you create a
1514 // string becomes something like this:
1515 //
1516 // (1) X is a pointer: *X
1517 // (2) (1) is a function returning int: int (*X)()
1518 //
1519 // So you cannot construct a result just by appending strings to a result.
1520 //
1521 // To deal with this, we split the function into two. outputPre() writes
1522 // the "first half" of type declaration, and outputPost() writes the
1523 // "second half". For example, outputPre() writes a return type for a
1524 // function and outputPost() writes an parameter list.
1525 Type::outputPre(OS, *SymbolType);
1526 outputName(OS, SymbolName);
1527 Type::outputPost(OS, *SymbolType);
1528
1529 // Null terminate the buffer.
1530 OS << '\0';
1531}
1532
1533char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
1534 int *Status) {
1535 OutputStream OS = OutputStream::create(Buf, N, 1024);
1536
1537 Demangler D(OS, StringView(MangledName));
1538 D.parse();
1539
1540 if (D.Error)
1541 *Status = llvm::demangle_invalid_mangled_name;
1542 else
1543 *Status = llvm::demangle_success;
1544
1545 D.output();
1546 return OS.getBuffer();
1547}