blob: 172ba0bca930c3f1f7945a6a308cf952870a966f [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===- MicrosoftDemangle.cpp ----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a demangler for MSVC-style mangled symbols.
11//
12// This file has no dependencies on the rest of LLVM so that it can be
13// easily reused in other programs such as libcxxabi.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Demangle/Demangle.h"
18
19#include "Compiler.h"
20#include "StringView.h"
21#include "Utility.h"
22
23#include <cctype>
Zachary Turner5ae08b82018-08-01 18:44:12 +000024#include <cstdio>
Zachary Turnerd742d642018-07-26 19:56:09 +000025#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000026
27// This memory allocator is extremely fast, but it doesn't call dtors
28// for allocated objects. That means you can't use STL containers
29// (such as std::vector) with this allocator. But it pays off --
30// the demangler is 3x faster with this allocator compared to one with
31// STL containers.
32namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000033 constexpr size_t AllocUnit = 4096;
34
Zachary Turnerf435a7e2018-07-20 17:27:48 +000035class ArenaAllocator {
36 struct AllocatorNode {
37 uint8_t *Buf = nullptr;
38 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000039 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000040 AllocatorNode *Next = nullptr;
41 };
42
Zachary Turner71c91f92018-07-30 03:12:34 +000043 void addNode(size_t Capacity) {
44 AllocatorNode *NewHead = new AllocatorNode;
45 NewHead->Buf = new uint8_t[Capacity];
46 NewHead->Next = Head;
47 NewHead->Capacity = Capacity;
48 Head = NewHead;
49 NewHead->Used = 0;
50 }
51
Zachary Turnerf435a7e2018-07-20 17:27:48 +000052public:
Zachary Turnera6869512018-07-30 03:25:27 +000053 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000054
55 ~ArenaAllocator() {
56 while (Head) {
57 assert(Head->Buf);
58 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000059 AllocatorNode *Next = Head->Next;
60 delete Head;
61 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000062 }
63 }
64
Zachary Turner71c91f92018-07-30 03:12:34 +000065 char *allocUnalignedBuffer(size_t Length) {
66 uint8_t *Buf = Head->Buf + Head->Used;
67
68 Head->Used += Length;
69 if (Head->Used > Head->Capacity) {
70 // It's possible we need a buffer which is larger than our default unit
71 // size, so we need to be careful to add a node with capacity that is at
72 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000073 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000074 Head->Used = Length;
75 Buf = Head->Buf;
76 }
77
78 return reinterpret_cast<char *>(Buf);
79 }
80
Zachary Turner9d72aa92018-07-20 18:35:06 +000081 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
82
83 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000084 assert(Head && Head->Buf);
85
Zachary Turner9d72aa92018-07-20 18:35:06 +000086 size_t P = (size_t)Head->Buf + Head->Used;
87 uintptr_t AlignedP =
88 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
89 uint8_t *PP = (uint8_t *)AlignedP;
90 size_t Adjustment = AlignedP - P;
91
92 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000093 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000094 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000095
Zachary Turnera6869512018-07-30 03:25:27 +000096 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000097 Head->Used = Size;
98 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000099 }
100
101private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000102 AllocatorNode *Head = nullptr;
103};
104} // namespace
105
106static bool startsWithDigit(StringView S) {
107 return !S.empty() && std::isdigit(S.front());
108}
109
110// Writes a space if the last token does not end with a punctuation.
111static void outputSpaceIfNecessary(OutputStream &OS) {
112 if (OS.empty())
113 return;
114
115 char C = OS.back();
116 if (isalnum(C) || C == '>')
117 OS << " ";
118}
119
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000120// Storage classes
121enum Qualifiers : uint8_t {
122 Q_None = 0,
123 Q_Const = 1 << 0,
124 Q_Volatile = 1 << 1,
125 Q_Far = 1 << 2,
126 Q_Huge = 1 << 3,
127 Q_Unaligned = 1 << 4,
128 Q_Restrict = 1 << 5,
129 Q_Pointer64 = 1 << 6
130};
131
132enum class StorageClass : uint8_t {
133 None,
134 PrivateStatic,
135 ProtectedStatic,
136 PublicStatic,
137 Global,
Zachary Turner3461bfa2018-08-17 16:14:05 +0000138 FunctionLocalStatic,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000139};
140
141enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000142
Zachary Turner931e8792018-07-30 23:02:10 +0000143enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000144
145// Calling conventions
146enum class CallingConv : uint8_t {
147 None,
148 Cdecl,
149 Pascal,
150 Thiscall,
151 Stdcall,
152 Fastcall,
153 Clrcall,
154 Eabi,
155 Vectorcall,
156 Regcall,
157};
158
159enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
160
161// Types
162enum class PrimTy : uint8_t {
163 Unknown,
164 None,
165 Function,
166 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000167 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000168 Array,
169
170 Struct,
171 Union,
172 Class,
173 Enum,
174
175 Void,
176 Bool,
177 Char,
178 Schar,
179 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000180 Char16,
181 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000182 Short,
183 Ushort,
184 Int,
185 Uint,
186 Long,
187 Ulong,
188 Int64,
189 Uint64,
190 Wchar,
191 Float,
192 Double,
193 Ldouble,
Zachary Turner3461bfa2018-08-17 16:14:05 +0000194 Nullptr,
195 Vftable,
196 Vbtable,
197 LocalStaticGuard
198};
199
200enum class OperatorTy : uint8_t {
201 Ctor, // ?0 # Foo::Foo()
202 Dtor, // ?1 # Foo::~Foo()
203 New, // ?2 # operator new
204 Delete, // ?3 # operator delete
205 Assign, // ?4 # operator=
206 RightShift, // ?5 # operator>>
207 LeftShift, // ?6 # operator<<
208 LogicalNot, // ?7 # operator!
209 Equals, // ?8 # operator==
210 NotEquals, // ?9 # operator!=
211 ArraySubscript, // ?A # operator[]
212 Conversion, // ?B # Foo::operator <type>()
213 Pointer, // ?C # operator->
214 Dereference, // ?D # operator*
215 Increment, // ?E # operator++
216 Decrement, // ?F # operator--
217 Minus, // ?G # operator-
218 Plus, // ?H # operator+
219 BitwiseAnd, // ?I # operator&
220 MemberPointer, // ?J # operator->*
221 Divide, // ?K # operator/
222 Modulus, // ?L # operator%
223 LessThan, // ?M operator<
224 LessThanEqual, // ?N operator<=
225 GreaterThan, // ?O operator>
226 GreaterThanEqual, // ?P operator>=
227 Comma, // ?Q operator,
228 Parens, // ?R operator()
229 BitwiseNot, // ?S operator~
230 BitwiseXor, // ?T operator^
231 BitwiseOr, // ?U operator|
232 LogicalAnd, // ?V operator&&
233 LogicalOr, // ?W operator||
234 TimesEqual, // ?X operator*=
235 PlusEqual, // ?Y operator+=
236 MinusEqual, // ?Z operator-=
237 DivEqual, // ?_0 operator/=
238 ModEqual, // ?_1 operator%=
239 RshEqual, // ?_2 operator>>=
240 LshEqual, // ?_3 operator<<=
241 BitwiseAndEqual, // ?_4 operator&=
242 BitwiseOrEqual, // ?_5 operator|=
243 BitwiseXorEqual, // ?_6 operator^=
244 Vftable, // ?_7 # vftable
245 Vbtable, // ?_8 # vbtable
246 Vcall, // ?_9 # vcall
247 Typeof, // ?_A # typeof
248 LocalStaticGuard, // ?_B # local static guard
249 StringLiteral, // ?_C # string literal
250 VbaseDtor, // ?_D # vbase destructor
251 VecDelDtor, // ?_E # vector deleting destructor
252 DefaultCtorClosure, // ?_F # default constructor closure
253 ScalarDelDtor, // ?_G # scalar deleting destructor
254 VecCtorIter, // ?_H # vector constructor iterator
255 VecDtorIter, // ?_I # vector destructor iterator
256 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
257 VdispMap, // ?_K # virtual displacement map
258 EHVecCtorIter, // ?_L # eh vector constructor iterator
259 EHVecDtorIter, // ?_M # eh vector destructor iterator
260 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
261 CopyCtorClosure, // ?_O # copy constructor closure
262 UdtReturning, // ?_P<name> # udt returning <name>
263 Unknown, // ?_Q # <unknown>
264 RttiTypeDescriptor, // ?_R0 # RTTI Type Descriptor
265 RttiBaseClassDescriptor, // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
266 RttiBaseClassArray, // ?_R2 # RTTI Base Class Array
267 RttiClassHierarchyDescriptor, // ?_R3 # RTTI Class Hierarchy Descriptor
268 RttiCompleteObjLocator, // ?_R4 # RTTI Complete Object Locator
269 LocalVftable, // ?_S # local vftable
270 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
271 ArrayNew, // ?_U operator new[]
272 ArrayDelete, // ?_V operator delete[]
273 LiteralOperator, // ?__K operator ""_name
274 CoAwait, // ?__L co_await
275 Spaceship, // operator<=>
276};
277
278// A map to translate from operator prefix to operator type.
279struct OperatorMapEntry {
280 StringView Prefix;
281 StringView Name;
282 OperatorTy Operator;
283};
284
Zachary Turner469f0762018-08-17 21:18:05 +0000285// The entries here must be in the same order as the enumeration so that it can
286// be indexed by enum value.
Zachary Turner3461bfa2018-08-17 16:14:05 +0000287OperatorMapEntry OperatorMap[] = {
288 {"0", " <ctor>", OperatorTy::Ctor},
289 {"1", " <dtor>", OperatorTy::Dtor},
290 {"2", "operator new", OperatorTy::New},
291 {"3", "operator delete", OperatorTy::Delete},
292 {"4", "operator=", OperatorTy::Assign},
293 {"5", "operator>>", OperatorTy::RightShift},
294 {"6", "operator<<", OperatorTy::LeftShift},
295 {"7", "operator!", OperatorTy::LogicalNot},
296 {"8", "operator==", OperatorTy::Equals},
297 {"9", "operator!=", OperatorTy::NotEquals},
298 {"A", "operator[]", OperatorTy::ArraySubscript},
299 {"B", "operator <conversion>", OperatorTy::Conversion},
300 {"C", "operator->", OperatorTy::Pointer},
301 {"D", "operator*", OperatorTy::Dereference},
302 {"E", "operator++", OperatorTy::Increment},
303 {"F", "operator--", OperatorTy::Decrement},
304 {"G", "operator-", OperatorTy::Minus},
305 {"H", "operator+", OperatorTy::Plus},
306 {"I", "operator&", OperatorTy::BitwiseAnd},
307 {"J", "operator->*", OperatorTy::MemberPointer},
308 {"K", "operator/", OperatorTy::Divide},
309 {"L", "operator%", OperatorTy::Modulus},
310 {"M", "operator<", OperatorTy::LessThan},
311 {"N", "operator<=", OperatorTy::LessThanEqual},
312 {"O", "operator>", OperatorTy::GreaterThan},
313 {"P", "operator>=", OperatorTy::GreaterThanEqual},
314 {"Q", "operator,", OperatorTy::Comma},
315 {"R", "operator()", OperatorTy::Parens},
316 {"S", "operator~", OperatorTy::BitwiseNot},
317 {"T", "operator^", OperatorTy::BitwiseXor},
318 {"U", "operator|", OperatorTy::BitwiseOr},
319 {"V", "operator&&", OperatorTy::LogicalAnd},
320 {"W", "operator||", OperatorTy::LogicalOr},
321 {"X", "operator*=", OperatorTy::TimesEqual},
322 {"Y", "operator+=", OperatorTy::PlusEqual},
323 {"Z", "operator-=", OperatorTy::MinusEqual},
324 {"_0", "operator/=", OperatorTy::DivEqual},
325 {"_1", "operator%=", OperatorTy::ModEqual},
326 {"_2", "operator>>=", OperatorTy::RshEqual},
327 {"_3", "operator<<=", OperatorTy::LshEqual},
328 {"_4", "operator&=", OperatorTy::BitwiseAndEqual},
329 {"_5", "operator|=", OperatorTy::BitwiseOrEqual},
330 {"_6", "operator^=", OperatorTy::BitwiseXorEqual},
331 {"_7", "`vftable'", OperatorTy::Vftable},
332 {"_8", "`vbtable'", OperatorTy::Vbtable},
333 {"_9", "`vcall'", OperatorTy::Vcall},
334 {"_A", "`typeof'", OperatorTy::Typeof},
335 {"_B", "`local static guard'", OperatorTy::LocalStaticGuard},
336 {"_C", "`string'", OperatorTy::StringLiteral},
337 {"_D", "`vbase dtor'", OperatorTy::VbaseDtor},
338 {"_E", "`vector deleting dtor'", OperatorTy::VecDelDtor},
339 {"_F", "`default ctor closure'", OperatorTy::DefaultCtorClosure},
340 {"_G", "`scalar deleting dtor'", OperatorTy::ScalarDelDtor},
341 {"_H", "`vector ctor iterator'", OperatorTy::VecCtorIter},
342 {"_I", "`vector dtor iterator'", OperatorTy::VecDtorIter},
343 {"_J", "`vector vbase ctor iterator'", OperatorTy::VecVbaseCtorIter},
344 {"_K", "`virtual displacement map'", OperatorTy::VdispMap},
345 {"_L", "`eh vector ctor iterator'", OperatorTy::EHVecCtorIter},
346 {"_M", "`eh vector dtor iterator'", OperatorTy::EHVecDtorIter},
347 {"_N", "`eh vector vbase ctor iterator'", OperatorTy::EHVecVbaseCtorIter},
348 {"_O", "`copy ctor closure'", OperatorTy::CopyCtorClosure},
349 {"_P", "`udt returning'", OperatorTy::UdtReturning},
350 {"_Q", "`unknown'", OperatorTy::Unknown},
351 {"_R0", "`RTTI Type Descriptor'", OperatorTy::RttiTypeDescriptor},
Zachary Turner469f0762018-08-17 21:18:05 +0000352 {"_R1", "RTTI Base Class Descriptor", OperatorTy::RttiBaseClassDescriptor},
Zachary Turner3461bfa2018-08-17 16:14:05 +0000353 {"_R2", "`RTTI Base Class Array'", OperatorTy::RttiBaseClassArray},
354 {"_R3", "`RTTI Class Hierarchy Descriptor'",
355 OperatorTy::RttiClassHierarchyDescriptor},
356 {"_R4", "`RTTI Complete Object Locator'",
357 OperatorTy::RttiCompleteObjLocator},
358 {"_S", "`local vftable'", OperatorTy::LocalVftable},
359 {"_T", "`local vftable ctor closure'", OperatorTy::LocalVftableCtorClosure},
360 {"_U", "operator new[]", OperatorTy::ArrayNew},
361 {"_V", "operator delete[]", OperatorTy::ArrayDelete},
362 {"__K", "operator \"\"", OperatorTy::LiteralOperator},
363 {"__L", "co_await", OperatorTy::CoAwait},
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000364};
365
366// Function classes
Zachary Turner29ec67b2018-08-10 21:09:05 +0000367enum FuncClass : uint16_t {
Zachary Turner469f0762018-08-17 21:18:05 +0000368 None = 0,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000369 Public = 1 << 0,
370 Protected = 1 << 1,
371 Private = 1 << 2,
372 Global = 1 << 3,
373 Static = 1 << 4,
374 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000375 Far = 1 << 6,
Zachary Turner29ec67b2018-08-10 21:09:05 +0000376 ExternC = 1 << 7,
377 NoPrototype = 1 << 8,
Zachary Turner469f0762018-08-17 21:18:05 +0000378 VirtualThisAdjust = 1 << 9,
379 VirtualThisAdjustEx = 1 << 10,
380 StaticThisAdjust = 1 << 11
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000381};
382
Zachary Turner58d29cf2018-08-08 00:43:31 +0000383enum NameBackrefBehavior : uint8_t {
384 NBB_None = 0, // don't save any names as backrefs.
385 NBB_Template = 1 << 0, // save template instanations.
386 NBB_Simple = 1 << 1, // save simple names.
387};
388
Zachary Turner469f0762018-08-17 21:18:05 +0000389enum class SymbolCategory {
390 Unknown,
391 NamedFunction,
392 NamedVariable,
393 UnnamedFunction,
394 UnnamedVariable,
395 SpecialOperator
396};
Zachary Turner44ebbc22018-08-01 18:32:47 +0000397
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000398namespace {
399
Zachary Turner172aea12018-08-02 17:08:03 +0000400struct NameResolver {
Zachary Turnerae672182018-08-02 17:33:33 +0000401 virtual ~NameResolver() = default;
Zachary Turner172aea12018-08-02 17:08:03 +0000402 virtual StringView resolve(StringView S) = 0;
403};
404
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000405struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000406struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000407
Zachary Turnerd30700f2018-07-31 17:16:44 +0000408struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000409 bool IsVariadic = false;
410
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000411 Type *Current = nullptr;
412
Zachary Turnerd30700f2018-07-31 17:16:44 +0000413 FunctionParams *Next = nullptr;
414};
Zachary Turner931e8792018-07-30 23:02:10 +0000415
Zachary Turnerd30700f2018-07-31 17:16:44 +0000416struct TemplateParams {
417 bool IsTemplateTemplate = false;
418 bool IsAliasTemplate = false;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000419 bool IsIntegerLiteral = false;
420 bool IntegerLiteralIsNegative = false;
421 bool IsEmptyParameterPack = false;
422 bool PointerToSymbol = false;
423 bool ReferenceToSymbol = false;
424
425 // If IsIntegerLiteral is true, this is a non-type template parameter
426 // whose value is contained in this field.
427 uint64_t IntegralValue = 0;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000428
429 // Type can be null if this is a template template parameter. In that case
430 // only Name will be valid.
431 Type *ParamType = nullptr;
432
433 // Name can be valid if this is a template template parameter (see above) or
434 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
435 // Name contains the name of the function and Type contains the signature.
436 Name *ParamName = nullptr;
437
438 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000439};
440
441// The type class. Mangled symbols are first parsed and converted to
442// this type and then converted to string.
443struct Type {
444 virtual ~Type() {}
445
446 virtual Type *clone(ArenaAllocator &Arena) const;
447
448 // Write the "first half" of a given type. This is a static functions to
449 // give the code a chance to do processing that is common to a subset of
450 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000451 static void outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000452
453 // Write the "second half" of a given type. This is a static functions to
454 // give the code a chance to do processing that is common to a subset of
455 // subclasses
Zachary Turner172aea12018-08-02 17:08:03 +0000456 static void outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000457
Zachary Turner172aea12018-08-02 17:08:03 +0000458 virtual void outputPre(OutputStream &OS, NameResolver &Resolver);
459 virtual void outputPost(OutputStream &OS, NameResolver &Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000460
461 // Primitive type such as Int.
462 PrimTy Prim = PrimTy::Unknown;
463
464 Qualifiers Quals = Q_None;
465 StorageClass Storage = StorageClass::None; // storage class
466};
467
468// Represents an identifier which may be a template.
469struct Name {
Zachary Turner3461bfa2018-08-17 16:14:05 +0000470 virtual ~Name() = default;
471
Zachary Turner44ebbc22018-08-01 18:32:47 +0000472 bool IsTemplateInstantiation = false;
473 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000474 bool IsBackReference = false;
Zachary Turner970fdc32018-08-16 16:17:36 +0000475
Zachary Turner3461bfa2018-08-17 16:14:05 +0000476 bool isStringLiteralOperatorInfo() const;
Zachary Turnera17721c2018-08-10 15:04:56 +0000477
478 // Name read from an MangledName string.
479 StringView Str;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000480
Zachary Turner3461bfa2018-08-17 16:14:05 +0000481 // Template parameters. Only valid if IsTemplateInstantiation is true.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000482 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000483
484 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
485 Name *Next = nullptr;
486};
487
Zachary Turner3461bfa2018-08-17 16:14:05 +0000488struct OperatorInfo : public Name {
Zachary Turner469f0762018-08-17 21:18:05 +0000489 explicit OperatorInfo(const OperatorMapEntry &Info) : Info(&Info) {
490 this->IsOperator = true;
491 }
492 explicit OperatorInfo(OperatorTy OpType)
493 : OperatorInfo(OperatorMap[(int)OpType]) {}
494
Zachary Turner3461bfa2018-08-17 16:14:05 +0000495 const OperatorMapEntry *Info = nullptr;
496};
497
498struct StringLiteral : public OperatorInfo {
Zachary Turner469f0762018-08-17 21:18:05 +0000499 StringLiteral() : OperatorInfo(OperatorTy::StringLiteral) {}
500
Zachary Turner3461bfa2018-08-17 16:14:05 +0000501 PrimTy CharType;
502 bool IsTruncated = false;
503};
504
Zachary Turner469f0762018-08-17 21:18:05 +0000505struct RttiBaseClassDescriptor : public OperatorInfo {
506 RttiBaseClassDescriptor()
507 : OperatorInfo(OperatorTy::RttiBaseClassDescriptor) {}
508
509 uint32_t NVOffset = 0;
510 int32_t VBPtrOffset = 0;
511 uint32_t VBTableOffset = 0;
512 uint32_t Flags = 0;
513};
514
515struct LocalStaticGuardVariable : public OperatorInfo {
516 LocalStaticGuardVariable() : OperatorInfo(OperatorTy::LocalStaticGuard) {}
517
518 uint32_t ScopeIndex = 0;
519 bool IsVisible = false;
520};
521
522struct VirtualMemberPtrThunk : public OperatorInfo {
523 VirtualMemberPtrThunk() : OperatorInfo(OperatorTy::Vcall) {}
524
525 uint64_t OffsetInVTable = 0;
526 CallingConv CC = CallingConv::Cdecl;
527};
528
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000529struct PointerType : public Type {
530 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000531 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
532 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000533
Zachary Turner931e8792018-07-30 23:02:10 +0000534 PointerAffinity Affinity;
535
Zachary Turnerd742d642018-07-26 19:56:09 +0000536 // Represents a type X in "a pointer to X", "a reference to X",
537 // "an array of X", or "a function returning X".
538 Type *Pointee = nullptr;
539};
540
541struct MemberPointerType : public Type {
542 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000543 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
544 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000545
546 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000547
548 // Represents a type X in "a pointer to X", "a reference to X",
549 // "an array of X", or "a function returning X".
550 Type *Pointee = nullptr;
551};
552
553struct FunctionType : public Type {
Zachary Turner469f0762018-08-17 21:18:05 +0000554 struct ThisAdjustor {
555 uint32_t StaticOffset = 0;
556 int32_t VBPtrOffset = 0;
557 int32_t VBOffsetOffset = 0;
558 int32_t VtordispOffset = 0;
559 };
560
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000561 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000562 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
563 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000564
Zachary Turner024e1762018-07-26 20:33:48 +0000565 // True if this FunctionType instance is the Pointee of a PointerType or
566 // MemberPointerType.
567 bool IsFunctionPointer = false;
Zachary Turner469f0762018-08-17 21:18:05 +0000568 bool IsThunk = false;
Zachary Turner024e1762018-07-26 20:33:48 +0000569
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000570 Type *ReturnType = nullptr;
571 // If this is a reference, the type of reference.
572 ReferenceKind RefKind;
573
574 CallingConv CallConvention;
575 FuncClass FunctionClass;
576
Zachary Turner469f0762018-08-17 21:18:05 +0000577 // Valid if IsThunk is true.
578 ThisAdjustor *ThisAdjust = nullptr;
579
Zachary Turnerd30700f2018-07-31 17:16:44 +0000580 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000581};
582
583struct UdtType : public Type {
584 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000585 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000586
587 Name *UdtName = nullptr;
588};
589
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000590struct ArrayDimension {
591 uint64_t Dim = 0;
592 ArrayDimension *Next = nullptr;
593};
594
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000595struct ArrayType : public Type {
596 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turner172aea12018-08-02 17:08:03 +0000597 void outputPre(OutputStream &OS, NameResolver &Resolver) override;
598 void outputPost(OutputStream &OS, NameResolver &Resolver) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000599
600 // Either NextDimension or ElementType will be valid.
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000601 ArrayDimension *Dims = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000602
603 Type *ElementType = nullptr;
604};
605
606} // namespace
607
Zachary Turnerd742d642018-07-26 19:56:09 +0000608static bool isMemberPointer(StringView MangledName) {
609 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000610 case '$':
611 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
612 // rvalue reference to a member.
613 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000614 case 'A':
615 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000616 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000617 return false;
618 case 'P':
619 case 'Q':
620 case 'R':
621 case 'S':
622 // These 4 values indicate some kind of pointer, but we still don't know
623 // what.
624 break;
625 default:
626 assert(false && "Ty is not a pointer type!");
627 }
628
629 // If it starts with a number, then 6 indicates a non-member function
630 // pointer, and 8 indicates a member function pointer.
631 if (startsWithDigit(MangledName)) {
632 assert(MangledName[0] == '6' || MangledName[0] == '8');
633 return (MangledName[0] == '8');
634 }
635
636 // Remove ext qualifiers since those can appear on either type and are
637 // therefore not indicative.
638 MangledName.consumeFront('E'); // 64-bit
639 MangledName.consumeFront('I'); // restrict
640 MangledName.consumeFront('F'); // unaligned
641
642 assert(!MangledName.empty());
643
644 // The next value should be either ABCD (non-member) or QRST (member).
645 switch (MangledName.front()) {
646 case 'A':
647 case 'B':
648 case 'C':
649 case 'D':
650 return false;
651 case 'Q':
652 case 'R':
653 case 'S':
654 case 'T':
655 return true;
656 default:
657 assert(false);
658 }
659 return false;
660}
661
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000662static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
663 outputSpaceIfNecessary(OS);
664
665 switch (CC) {
666 case CallingConv::Cdecl:
667 OS << "__cdecl";
668 break;
669 case CallingConv::Fastcall:
670 OS << "__fastcall";
671 break;
672 case CallingConv::Pascal:
673 OS << "__pascal";
674 break;
675 case CallingConv::Regcall:
676 OS << "__regcall";
677 break;
678 case CallingConv::Stdcall:
679 OS << "__stdcall";
680 break;
681 case CallingConv::Thiscall:
682 OS << "__thiscall";
683 break;
684 case CallingConv::Eabi:
685 OS << "__eabi";
686 break;
687 case CallingConv::Vectorcall:
688 OS << "__vectorcall";
689 break;
690 case CallingConv::Clrcall:
691 OS << "__clrcall";
692 break;
693 default:
694 break;
695 }
696}
697
Zachary Turner71c91f92018-07-30 03:12:34 +0000698static bool startsWithLocalScopePattern(StringView S) {
699 if (!S.consumeFront('?'))
700 return false;
701 if (S.size() < 2)
702 return false;
703
704 size_t End = S.find('?');
705 if (End == StringView::npos)
706 return false;
707 StringView Candidate = S.substr(0, End);
708 if (Candidate.empty())
709 return false;
710
711 // \?[0-9]\?
712 // ?@? is the discriminator 0.
713 if (Candidate.size() == 1)
714 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
715
716 // If it's not 0-9, then it's an encoded number terminated with an @
717 if (Candidate.back() != '@')
718 return false;
719 Candidate = Candidate.dropBack();
720
721 // An encoded number starts with B-P and all subsequent digits are in A-P.
722 // Note that the reason the first digit cannot be A is two fold. First, it
723 // would create an ambiguity with ?A which delimits the beginning of an
724 // anonymous namespace. Second, A represents 0, and you don't start a multi
725 // digit number with a leading 0. Presumably the anonymous namespace
726 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
727 if (Candidate[0] < 'B' || Candidate[0] > 'P')
728 return false;
729 Candidate = Candidate.dropFront();
730 while (!Candidate.empty()) {
731 if (Candidate[0] < 'A' || Candidate[0] > 'P')
732 return false;
733 Candidate = Candidate.dropFront();
734 }
735
736 return true;
737}
738
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000739// Write a function or template parameter list.
Zachary Turner172aea12018-08-02 17:08:03 +0000740static void outputParameterList(OutputStream &OS, const FunctionParams &Params,
741 NameResolver &Resolver) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000742 if (!Params.Current) {
743 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000744 return;
745 }
746
Zachary Turnerd30700f2018-07-31 17:16:44 +0000747 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000748 while (Head) {
Zachary Turner172aea12018-08-02 17:08:03 +0000749 Type::outputPre(OS, *Head->Current, Resolver);
750 Type::outputPost(OS, *Head->Current, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000751
752 Head = Head->Next;
753
754 if (Head)
755 OS << ", ";
756 }
757}
758
Zachary Turner3461bfa2018-08-17 16:14:05 +0000759static void outputStringLiteral(OutputStream &OS, const StringLiteral &Str) {
760 switch (Str.CharType) {
Zachary Turner970fdc32018-08-16 16:17:36 +0000761 case PrimTy::Wchar:
762 OS << "const wchar_t * {L\"";
763 break;
764 case PrimTy::Char:
765 OS << "const char * {\"";
766 break;
767 case PrimTy::Char16:
768 OS << "const char16_t * {u\"";
769 break;
770 case PrimTy::Char32:
771 OS << "const char32_t * {U\"";
772 break;
773 default:
774 LLVM_BUILTIN_UNREACHABLE;
775 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000776 OS << Str.Str << "\"";
777 if (Str.IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +0000778 OS << "...";
779 OS << "}";
780}
781
Zachary Turnera17721c2018-08-10 15:04:56 +0000782static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000783 NameResolver &Resolver);
784
785static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
786 NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000787 if (Params.IsEmptyParameterPack) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000788 OS << "<>";
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000789 return;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000790 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000791
792 OS << "<";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000793 const TemplateParams *Head = &Params;
794 while (Head) {
795 // Type can be null if this is a template template parameter,
796 // and Name can be null if this is a simple type.
797
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000798 if (Head->IsIntegerLiteral) {
799 if (Head->IntegerLiteralIsNegative)
800 OS << '-';
801 OS << Head->IntegralValue;
802 } else if (Head->PointerToSymbol || Head->ReferenceToSymbol) {
803 if (Head->PointerToSymbol)
804 OS << "&";
Zachary Turner172aea12018-08-02 17:08:03 +0000805 Type::outputPre(OS, *Head->ParamType, Resolver);
Zachary Turnera17721c2018-08-10 15:04:56 +0000806 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turner172aea12018-08-02 17:08:03 +0000807 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000808 } else if (Head->ParamType) {
809 // simple type.
Zachary Turner172aea12018-08-02 17:08:03 +0000810 Type::outputPre(OS, *Head->ParamType, Resolver);
811 Type::outputPost(OS, *Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000812 } else {
813 // Template alias.
Zachary Turnera17721c2018-08-10 15:04:56 +0000814 outputName(OS, Head->ParamName, Head->ParamType, Resolver);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000815 }
816
817 Head = Head->Next;
818
819 if (Head)
820 OS << ", ";
821 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000822 OS << ">";
823}
824
Zachary Turner469f0762018-08-17 21:18:05 +0000825static void outputQualifiers(OutputStream &OS, Qualifiers Q) {
826 if (Q & Q_Const) {
827 outputSpaceIfNecessary(OS);
828 OS << "const";
829 }
830
831 if (Q & Q_Volatile) {
832 outputSpaceIfNecessary(OS);
833 OS << "volatile";
834 }
835
836 if (Q & Q_Restrict) {
837 outputSpaceIfNecessary(OS);
838 OS << "__restrict";
839 }
840}
841
Zachary Turner3461bfa2018-08-17 16:14:05 +0000842static void outputNameComponent(OutputStream &OS, bool IsBackReference,
843 const TemplateParams *TParams, StringView Str,
844 NameResolver &Resolver) {
845 if (IsBackReference)
846 Str = Resolver.resolve(Str);
847 OS << Str;
848
849 if (TParams)
850 outputParameterList(OS, *TParams, Resolver);
851}
852
Zachary Turner172aea12018-08-02 17:08:03 +0000853static void outputNameComponent(OutputStream &OS, const Name &N,
854 NameResolver &Resolver) {
Zachary Turner3461bfa2018-08-17 16:14:05 +0000855 outputNameComponent(OS, N.IsBackReference, N.TParams, N.Str, Resolver);
Zachary Turner172aea12018-08-02 17:08:03 +0000856}
857
Zachary Turnera17721c2018-08-10 15:04:56 +0000858static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
Zachary Turner172aea12018-08-02 17:08:03 +0000859 NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000860 if (!TheName)
861 return;
862
863 outputSpaceIfNecessary(OS);
864
Zachary Turnera7dffb12018-07-28 22:10:42 +0000865 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000866 // Print out namespaces or outer class BackReferences.
867 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000868 Previous = TheName;
Zachary Turner172aea12018-08-02 17:08:03 +0000869 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000870 OS << "::";
871 }
872
873 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000874 if (!TheName->IsOperator) {
Zachary Turner172aea12018-08-02 17:08:03 +0000875 outputNameComponent(OS, *TheName, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000876 return;
877 }
878
Zachary Turner3461bfa2018-08-17 16:14:05 +0000879 const OperatorInfo &Operator = static_cast<const OperatorInfo &>(*TheName);
880
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000881 // Print out ctor or dtor.
Zachary Turner3461bfa2018-08-17 16:14:05 +0000882 switch (Operator.Info->Operator) {
883 case OperatorTy::Dtor:
Zachary Turnera7dffb12018-07-28 22:10:42 +0000884 OS << "~";
Zachary Turner3461bfa2018-08-17 16:14:05 +0000885 LLVM_FALLTHROUGH;
886 case OperatorTy::Ctor:
Zachary Turner172aea12018-08-02 17:08:03 +0000887 outputNameComponent(OS, *Previous, Resolver);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000888 break;
889 case OperatorTy::Conversion:
Zachary Turnera17721c2018-08-10 15:04:56 +0000890 OS << "operator";
891 if (TheName->IsTemplateInstantiation && TheName->TParams)
892 outputParameterList(OS, *TheName->TParams, Resolver);
893 OS << " ";
894 if (Ty) {
895 const FunctionType *FTy = static_cast<const FunctionType *>(Ty);
896 Type::outputPre(OS, *FTy->ReturnType, Resolver);
897 Type::outputPost(OS, *FTy->ReturnType, Resolver);
898 } else {
899 OS << "<conversion>";
900 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000901 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +0000902 case OperatorTy::LiteralOperator:
903 OS << Operator.Info->Name;
Zachary Turnera17721c2018-08-10 15:04:56 +0000904 outputNameComponent(OS, *TheName, Resolver);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000905 break;
Zachary Turner469f0762018-08-17 21:18:05 +0000906 case OperatorTy::RttiBaseClassDescriptor: {
907 const RttiBaseClassDescriptor &BCD =
908 static_cast<const RttiBaseClassDescriptor &>(Operator);
909 OS << "`" << Operator.Info->Name << " at (";
910 OS << BCD.NVOffset << ", " << BCD.VBPtrOffset << ", " << BCD.VBTableOffset
911 << ", " << BCD.Flags;
912 OS << ")'";
913 break;
914 }
915 case OperatorTy::LocalStaticGuard: {
916 const LocalStaticGuardVariable &LSG =
917 static_cast<const LocalStaticGuardVariable &>(Operator);
918 OS << Operator.Info->Name;
919 if (LSG.ScopeIndex > 0)
920 OS << "{" << LSG.ScopeIndex << "}";
921 break;
922 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000923 default:
924 OS << Operator.Info->Name;
925 if (Operator.IsTemplateInstantiation)
926 outputParameterList(OS, *Operator.TParams, Resolver);
927 break;
Zachary Turnera17721c2018-08-10 15:04:56 +0000928 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000929}
930
Zachary Turner469f0762018-08-17 21:18:05 +0000931static void outputSpecialOperator(OutputStream &OS, const Name *OuterName,
932 NameResolver &Resolver) {
933 assert(OuterName);
934 // The last component should be an operator.
935 const Name *LastComponent = OuterName;
936 while (LastComponent->Next)
937 LastComponent = LastComponent->Next;
938
939 assert(LastComponent->IsOperator);
940 const OperatorInfo &Oper = static_cast<const OperatorInfo &>(*LastComponent);
941 switch (Oper.Info->Operator) {
942 case OperatorTy::StringLiteral: {
943 const StringLiteral &SL = static_cast<const StringLiteral &>(Oper);
944 outputStringLiteral(OS, SL);
945 break;
946 }
947 case OperatorTy::Vcall: {
948 // [thunk]: __cdecl Base::`vcall'{8, {flat}}' }'
949 const VirtualMemberPtrThunk &Thunk =
950 static_cast<const VirtualMemberPtrThunk &>(Oper);
951 OS << "[thunk]: ";
952 outputCallingConvention(OS, Thunk.CC);
953 OS << " ";
954 // Print out namespaces or outer class BackReferences.
955 const Name *N = OuterName;
956 for (; N->Next; N = N->Next) {
957 outputNameComponent(OS, *N, Resolver);
958 OS << "::";
959 }
960 OS << "`vcall'{";
961 OS << Thunk.OffsetInVTable << ", {flat}}";
962 break;
963 }
964 default:
965 // There are no other special operator categories.
966 LLVM_BUILTIN_UNREACHABLE;
967 }
968}
969
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000970namespace {
971
Zachary Turner3461bfa2018-08-17 16:14:05 +0000972bool Name::isStringLiteralOperatorInfo() const {
973 if (!IsOperator)
974 return false;
975 const OperatorInfo &O = static_cast<const OperatorInfo &>(*this);
976 return O.Info->Operator == OperatorTy::StringLiteral;
977}
978
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000979Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +0000980 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000981}
982
983// Write the "first half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +0000984void Type::outputPre(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000985 // Function types require custom handling of const and static so we
986 // handle them separately. All other types use the same decoration
987 // for these modifiers, so handle them here in common code.
988 if (Ty.Prim == PrimTy::Function) {
Zachary Turner172aea12018-08-02 17:08:03 +0000989 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000990 return;
991 }
992
993 switch (Ty.Storage) {
994 case StorageClass::PrivateStatic:
995 case StorageClass::PublicStatic:
996 case StorageClass::ProtectedStatic:
997 OS << "static ";
998 default:
999 break;
1000 }
Zachary Turner172aea12018-08-02 17:08:03 +00001001 Ty.outputPre(OS, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001002
Zachary Turner469f0762018-08-17 21:18:05 +00001003 outputQualifiers(OS, Ty.Quals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001004}
1005
1006// Write the "second half" of a given type.
Zachary Turner172aea12018-08-02 17:08:03 +00001007void Type::outputPost(OutputStream &OS, Type &Ty, NameResolver &Resolver) {
1008 Ty.outputPost(OS, Resolver);
1009}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001010
Zachary Turner172aea12018-08-02 17:08:03 +00001011void Type::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001012 switch (Prim) {
1013 case PrimTy::Void:
1014 OS << "void";
1015 break;
1016 case PrimTy::Bool:
1017 OS << "bool";
1018 break;
1019 case PrimTy::Char:
1020 OS << "char";
1021 break;
1022 case PrimTy::Schar:
1023 OS << "signed char";
1024 break;
1025 case PrimTy::Uchar:
1026 OS << "unsigned char";
1027 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001028 case PrimTy::Char16:
1029 OS << "char16_t";
1030 break;
1031 case PrimTy::Char32:
1032 OS << "char32_t";
1033 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001034 case PrimTy::Short:
1035 OS << "short";
1036 break;
1037 case PrimTy::Ushort:
1038 OS << "unsigned short";
1039 break;
1040 case PrimTy::Int:
1041 OS << "int";
1042 break;
1043 case PrimTy::Uint:
1044 OS << "unsigned int";
1045 break;
1046 case PrimTy::Long:
1047 OS << "long";
1048 break;
1049 case PrimTy::Ulong:
1050 OS << "unsigned long";
1051 break;
1052 case PrimTy::Int64:
1053 OS << "__int64";
1054 break;
1055 case PrimTy::Uint64:
1056 OS << "unsigned __int64";
1057 break;
1058 case PrimTy::Wchar:
1059 OS << "wchar_t";
1060 break;
1061 case PrimTy::Float:
1062 OS << "float";
1063 break;
1064 case PrimTy::Double:
1065 OS << "double";
1066 break;
1067 case PrimTy::Ldouble:
1068 OS << "long double";
1069 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001070 case PrimTy::Nullptr:
1071 OS << "std::nullptr_t";
1072 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001073 case PrimTy::Vbtable:
1074 case PrimTy::Vftable:
1075 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001076 default:
1077 assert(false && "Invalid primitive type!");
1078 }
1079}
Zachary Turner172aea12018-08-02 17:08:03 +00001080void Type::outputPost(OutputStream &OS, NameResolver &Resolver) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001081
1082Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001083 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001084}
1085
Zachary Turner024e1762018-07-26 20:33:48 +00001086static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turner172aea12018-08-02 17:08:03 +00001087 const Name *MemberName, const Type *Pointee,
1088 NameResolver &Resolver) {
Zachary Turner024e1762018-07-26 20:33:48 +00001089 // "[]" and "()" (for function parameters) take precedence over "*",
1090 // so "int *x(int)" means "x is a function returning int *". We need
1091 // parentheses to supercede the default precedence. (e.g. we want to
1092 // emit something like "int (*x)(int)".)
1093 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
1094 OS << "(";
1095 if (Pointee->Prim == PrimTy::Function) {
1096 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
1097 assert(FTy->IsFunctionPointer);
1098 outputCallingConvention(OS, FTy->CallConvention);
1099 OS << " ";
1100 }
1101 }
1102
1103 if (MemberName) {
Zachary Turnera17721c2018-08-10 15:04:56 +00001104 outputName(OS, MemberName, Pointee, Resolver);
Zachary Turner024e1762018-07-26 20:33:48 +00001105 OS << "::";
1106 }
1107
1108 if (Affinity == PointerAffinity::Pointer)
1109 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +00001110 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +00001111 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +00001112 else
1113 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +00001114}
1115
Zachary Turner172aea12018-08-02 17:08:03 +00001116void PointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
1117 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001118
1119 outputSpaceIfNecessary(OS);
1120
1121 if (Quals & Q_Unaligned)
1122 OS << "__unaligned ";
1123
Zachary Turner172aea12018-08-02 17:08:03 +00001124 outputPointerIndicator(OS, Affinity, nullptr, Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001125
Zachary Turner91ecedd2018-07-20 18:07:33 +00001126 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001127 // if (Ty.Quals & Q_Pointer64)
1128 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001129}
1130
Zachary Turner172aea12018-08-02 17:08:03 +00001131void PointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001132 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
1133 OS << ")";
1134
Zachary Turner172aea12018-08-02 17:08:03 +00001135 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001136}
1137
Zachary Turnerd742d642018-07-26 19:56:09 +00001138Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
1139 return Arena.alloc<MemberPointerType>(*this);
1140}
1141
Zachary Turner172aea12018-08-02 17:08:03 +00001142void MemberPointerType::outputPre(OutputStream &OS, NameResolver &Resolver) {
1143 Type::outputPre(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +00001144
1145 outputSpaceIfNecessary(OS);
1146
Zachary Turner172aea12018-08-02 17:08:03 +00001147 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee,
1148 Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +00001149
1150 // FIXME: We should output this, but it requires updating lots of tests.
1151 // if (Ty.Quals & Q_Pointer64)
1152 // OS << " __ptr64";
Zachary Turnerd742d642018-07-26 19:56:09 +00001153}
1154
Zachary Turner172aea12018-08-02 17:08:03 +00001155void MemberPointerType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001156 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
1157 OS << ")";
1158
Zachary Turner172aea12018-08-02 17:08:03 +00001159 Type::outputPost(OS, *Pointee, Resolver);
Zachary Turnerd742d642018-07-26 19:56:09 +00001160}
1161
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001162Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001163 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001164}
1165
Zachary Turner172aea12018-08-02 17:08:03 +00001166void FunctionType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turner469f0762018-08-17 21:18:05 +00001167 if ((FunctionClass & StaticThisAdjust) || (FunctionClass & VirtualThisAdjust))
1168 OS << "[thunk]: ";
1169
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001170 if (!(FunctionClass & Global)) {
1171 if (FunctionClass & Static)
1172 OS << "static ";
1173 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001174 if (FunctionClass & ExternC)
Zachary Turner29ec67b2018-08-10 21:09:05 +00001175 OS << "extern \"C\" ";
Zachary Turner3461bfa2018-08-17 16:14:05 +00001176
1177 if (FunctionClass & Virtual)
1178 OS << "virtual ";
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001179
Zachary Turner38b78a72018-07-26 20:20:10 +00001180 if (ReturnType) {
Zachary Turner172aea12018-08-02 17:08:03 +00001181 Type::outputPre(OS, *ReturnType, Resolver);
Zachary Turner38b78a72018-07-26 20:20:10 +00001182 OS << " ";
1183 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001184
Zachary Turner024e1762018-07-26 20:33:48 +00001185 // Function pointers print the calling convention as void (__cdecl *)(params)
1186 // rather than void __cdecl (*)(params). So we need to let the PointerType
1187 // class handle this.
1188 if (!IsFunctionPointer)
1189 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001190}
1191
Zachary Turner172aea12018-08-02 17:08:03 +00001192void FunctionType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00001193 // extern "C" functions don't have a prototype.
1194 if (FunctionClass & NoPrototype)
1195 return;
1196
Zachary Turner469f0762018-08-17 21:18:05 +00001197 if (FunctionClass & VirtualThisAdjust) {
1198 OS << "`vtordisp{" << ThisAdjust->VtordispOffset << ", "
1199 << ThisAdjust->StaticOffset << "}'";
1200 }
1201
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001202 OS << "(";
Zachary Turner172aea12018-08-02 17:08:03 +00001203 outputParameterList(OS, Params, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001204 OS << ")";
1205 if (Quals & Q_Const)
1206 OS << " const";
1207 if (Quals & Q_Volatile)
1208 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +00001209 if (Quals & Q_Restrict)
1210 OS << " __restrict";
1211 if (Quals & Q_Unaligned)
1212 OS << " __unaligned";
1213
1214 if (RefKind == ReferenceKind::LValueRef)
1215 OS << " &";
1216 else if (RefKind == ReferenceKind::RValueRef)
1217 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +00001218
1219 if (ReturnType)
Zachary Turner172aea12018-08-02 17:08:03 +00001220 Type::outputPost(OS, *ReturnType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001221 return;
1222}
1223
1224Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001225 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001226}
1227
Zachary Turner172aea12018-08-02 17:08:03 +00001228void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001229 switch (Prim) {
1230 case PrimTy::Class:
1231 OS << "class ";
1232 break;
1233 case PrimTy::Struct:
1234 OS << "struct ";
1235 break;
1236 case PrimTy::Union:
1237 OS << "union ";
1238 break;
1239 case PrimTy::Enum:
1240 OS << "enum ";
1241 break;
1242 default:
1243 assert(false && "Not a udt type!");
1244 }
1245
Zachary Turnera17721c2018-08-10 15:04:56 +00001246 outputName(OS, UdtName, this, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001247}
1248
1249Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001250 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001251}
1252
Zachary Turner172aea12018-08-02 17:08:03 +00001253void ArrayType::outputPre(OutputStream &OS, NameResolver &Resolver) {
1254 Type::outputPre(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001255}
1256
Zachary Turner172aea12018-08-02 17:08:03 +00001257void ArrayType::outputPost(OutputStream &OS, NameResolver &Resolver) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001258 ArrayDimension *D = Dims;
1259 while (D) {
1260 OS << "[";
1261 if (D->Dim > 0)
1262 OS << D->Dim;
1263 OS << "]";
1264 D = D->Next;
1265 }
1266
1267 Type::outputPost(OS, *ElementType, Resolver);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001268}
1269
Zachary Turner316109b2018-07-29 16:38:02 +00001270struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001271 SymbolCategory Category;
1272
Zachary Turner469f0762018-08-17 21:18:05 +00001273 Qualifiers SymbolQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001274 Name *SymbolName = nullptr;
1275 Type *SymbolType = nullptr;
1276};
1277
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001278} // namespace
1279
1280namespace {
1281
Zachary Turnerd346cba2018-08-08 17:17:04 +00001282struct BackrefContext {
1283 static constexpr size_t Max = 10;
1284
1285 Type *FunctionParams[Max];
1286 size_t FunctionParamCount = 0;
1287
1288 // The first 10 BackReferences in a mangled name can be back-referenced by
1289 // special name @[0-9]. This is a storage for the first 10 BackReferences.
1290 StringView Names[Max];
1291 size_t NamesCount = 0;
1292};
1293
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001294// Demangler class takes the main role in demangling symbols.
1295// It has a set of functions to parse mangled symbols into Type instances.
1296// It also has a set of functions to cnovert Type instances to strings.
Zachary Turner172aea12018-08-02 17:08:03 +00001297class Demangler : public NameResolver {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001298public:
Zachary Turner316109b2018-07-29 16:38:02 +00001299 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +00001300 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001301
1302 // You are supposed to call parse() first and then check if error is true. If
1303 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +00001304 Symbol *parse(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001305 Symbol *parseOperator(StringView &MangledName);
1306
Zachary Turner316109b2018-07-29 16:38:02 +00001307 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001308
Zachary Turner172aea12018-08-02 17:08:03 +00001309 StringView resolve(StringView N) override;
1310
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001311 // True if an error occurred.
1312 bool Error = false;
1313
Zachary Turner3a758e22018-08-01 18:33:04 +00001314 void dumpBackReferences();
1315
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001316private:
Zachary Turner469f0762018-08-17 21:18:05 +00001317 std::pair<SymbolCategory, Type *>
1318 demangleSymbolCategoryAndType(StringView &MangledName);
1319
1320 Type *demangleVariableEncoding(StringView &MangledName, StorageClass SC);
Zachary Turner316109b2018-07-29 16:38:02 +00001321 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001322 uint64_t demangleThunkThisAdjust(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001323
Zachary Turner316109b2018-07-29 16:38:02 +00001324 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001325
1326 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +00001327 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
1328 Type *demangleBasicType(StringView &MangledName);
1329 UdtType *demangleClassType(StringView &MangledName);
1330 PointerType *demanglePointerType(StringView &MangledName);
1331 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
1332 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
1333 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001334
Zachary Turner316109b2018-07-29 16:38:02 +00001335 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001336
Zachary Turnerd30700f2018-07-31 17:16:44 +00001337 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
1338 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001339
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001340 std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001341 uint64_t demangleUnsigned(StringView &MangledName);
1342 int64_t demangleSigned(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001343
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001344 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +00001345
1346 /// Allocate a copy of \p Borrowed into memory that we own.
1347 StringView copyString(StringView Borrowed);
1348
Zachary Turner316109b2018-07-29 16:38:02 +00001349 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
1350 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001351
Zachary Turner44ebbc22018-08-01 18:32:47 +00001352 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001353 Name *demangleUnqualifiedSymbolName(StringView &MangledName,
1354 NameBackrefBehavior NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001355
Zachary Turner316109b2018-07-29 16:38:02 +00001356 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
1357 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001358
Zachary Turner316109b2018-07-29 16:38:02 +00001359 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001360 Name *demangleTemplateInstantiationName(StringView &MangledName,
1361 NameBackrefBehavior NBB);
Zachary Turner469f0762018-08-17 21:18:05 +00001362 std::pair<OperatorTy, Name *> demangleOperatorName(StringView &MangledName,
1363 bool FullyQualified);
Zachary Turner316109b2018-07-29 16:38:02 +00001364 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
1365 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001366 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001367 StringLiteral *demangleStringLiteral(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001368
Zachary Turner931e8792018-07-30 23:02:10 +00001369 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
1370
Zachary Turner316109b2018-07-29 16:38:02 +00001371 FuncClass demangleFunctionClass(StringView &MangledName);
1372 CallingConv demangleCallingConvention(StringView &MangledName);
1373 StorageClass demangleVariableStorageClass(StringView &MangledName);
1374 ReferenceKind demangleReferenceKind(StringView &MangledName);
1375 void demangleThrowSpecification(StringView &MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001376 wchar_t demangleWcharLiteral(StringView &MangledName);
1377 uint8_t demangleCharLiteral(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001378
Zachary Turner316109b2018-07-29 16:38:02 +00001379 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001380
1381 // Memory allocator.
1382 ArenaAllocator Arena;
1383
Zachary Turner23df1312018-07-26 22:13:39 +00001384 // A single type uses one global back-ref table for all function params.
1385 // This means back-refs can even go "into" other types. Examples:
1386 //
1387 // // Second int* is a back-ref to first.
1388 // void foo(int *, int*);
1389 //
1390 // // Second int* is not a back-ref to first (first is not a function param).
1391 // int* foo(int*);
1392 //
1393 // // Second int* is a back-ref to first (ALL function types share the same
1394 // // back-ref map.
1395 // using F = void(*)(int*);
1396 // F G(int *);
Zachary Turnerd346cba2018-08-08 17:17:04 +00001397 BackrefContext Backrefs;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001398};
1399} // namespace
1400
Zachary Turner71c91f92018-07-30 03:12:34 +00001401StringView Demangler::copyString(StringView Borrowed) {
1402 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
1403 std::strcpy(Stable, Borrowed.begin());
1404
1405 return {Stable, Borrowed.size()};
1406}
1407
Zachary Turner469f0762018-08-17 21:18:05 +00001408Symbol *Demangler::parseOperator(StringView &MangledName) {
Zachary Turner316109b2018-07-29 16:38:02 +00001409 Symbol *S = Arena.alloc<Symbol>();
1410
Zachary Turner469f0762018-08-17 21:18:05 +00001411 bool IsMember = false;
1412 OperatorTy OTy;
1413 std::tie(OTy, S->SymbolName) = demangleOperatorName(MangledName, true);
1414 switch (OTy) {
1415 case OperatorTy::StringLiteral:
1416 case OperatorTy::Vcall:
1417 S->Category = SymbolCategory::SpecialOperator;
1418 break;
1419 case OperatorTy::Vftable: // Foo@@6B@
1420 case OperatorTy::LocalVftable: // Foo@@6B@
1421 case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@
1422 case OperatorTy::Vbtable: // Foo@@7B@
1423 S->Category = SymbolCategory::UnnamedVariable;
1424 switch (MangledName.popFront()) {
1425 case '6':
1426 case '7':
1427 std::tie(S->SymbolQuals, IsMember) = demangleQualifiers(MangledName);
1428 if (!MangledName.consumeFront('@'))
1429 Error = true;
1430 break;
1431 default:
1432 Error = true;
1433 break;
1434 }
1435 break;
1436 case OperatorTy::RttiTypeDescriptor: // <type>@@8
1437 S->Category = SymbolCategory::UnnamedVariable;
1438 S->SymbolType = demangleType(MangledName, QualifierMangleMode::Result);
1439 if (Error)
1440 break;
1441 if (!MangledName.consumeFront("@8"))
1442 Error = true;
1443 if (!MangledName.empty())
1444 Error = true;
1445 break;
1446 case OperatorTy::LocalStaticGuard: {
1447 S->Category = SymbolCategory::UnnamedVariable;
1448 break;
1449 }
1450 default:
1451 if (!Error)
1452 std::tie(S->Category, S->SymbolType) =
1453 demangleSymbolCategoryAndType(MangledName);
1454 break;
1455 }
1456
1457 return (Error) ? nullptr : S;
1458}
1459
1460std::pair<SymbolCategory, Type *>
1461Demangler::demangleSymbolCategoryAndType(StringView &MangledName) {
1462 // Read a variable.
1463 switch (MangledName.front()) {
1464 case '0':
1465 case '1':
1466 case '2':
1467 case '3':
1468 case '4':
1469 return std::make_pair(
1470 SymbolCategory::NamedVariable,
1471 demangleVariableEncoding(MangledName,
1472 demangleVariableStorageClass(MangledName)));
1473 case '8':
1474 MangledName.consumeFront('8');
1475 return std::pair<SymbolCategory, Type *>(SymbolCategory::UnnamedVariable,
1476 nullptr);
1477 }
1478 return std::make_pair(SymbolCategory::NamedFunction,
1479 demangleFunctionEncoding(MangledName));
1480}
1481
1482// Parser entry point.
1483Symbol *Demangler::parse(StringView &MangledName) {
Zachary Turner83313f82018-08-16 16:17:17 +00001484 // We can't demangle MD5 names, just output them as-is.
Zachary Turner469f0762018-08-17 21:18:05 +00001485 // Also, MSVC-style mangled symbols must start with '?'.
1486 if (MangledName.startsWith("??@") || !MangledName.startsWith('?')) {
1487 Symbol *S = Arena.alloc<Symbol>();
Zachary Turner83313f82018-08-16 16:17:17 +00001488 S->Category = SymbolCategory::Unknown;
1489 S->SymbolName = Arena.alloc<Name>();
1490 S->SymbolName->Str = MangledName;
Zachary Turner970fdc32018-08-16 16:17:36 +00001491 S->SymbolType = nullptr;
Zachary Turner83313f82018-08-16 16:17:17 +00001492 MangledName = StringView();
1493 return S;
1494 }
1495
Zachary Turner469f0762018-08-17 21:18:05 +00001496 MangledName.consumeFront('?');
Zachary Turner970fdc32018-08-16 16:17:36 +00001497
Zachary Turner469f0762018-08-17 21:18:05 +00001498 // ?$ is a template instantiation, but all other names that start with ? are
1499 // operators / special names.
1500 if (MangledName.startsWith('?') && !MangledName.startsWith("?$"))
1501 return parseOperator(MangledName);
1502
1503 Symbol *S = Arena.alloc<Symbol>();
1504 // What follows is a main symbol name. This may include namespaces or class
1505 // back references.
Zachary Turner316109b2018-07-29 16:38:02 +00001506 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001507 if (Error)
1508 return nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001509
Zachary Turner469f0762018-08-17 21:18:05 +00001510 std::tie(S->Category, S->SymbolType) =
1511 demangleSymbolCategoryAndType(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001512
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001513 if (Error)
1514 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001515
Zachary Turner316109b2018-07-29 16:38:02 +00001516 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001517}
1518
1519// <type-encoding> ::= <storage-class> <variable-type>
1520// <storage-class> ::= 0 # private static member
1521// ::= 1 # protected static member
1522// ::= 2 # public static member
1523// ::= 3 # global
1524// ::= 4 # static local
1525
Zachary Turner469f0762018-08-17 21:18:05 +00001526Type *Demangler::demangleVariableEncoding(StringView &MangledName,
1527 StorageClass SC) {
Zachary Turner316109b2018-07-29 16:38:02 +00001528 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001529
1530 Ty->Storage = SC;
1531
1532 // <variable-type> ::= <type> <cvr-qualifiers>
1533 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1534 switch (Ty->Prim) {
1535 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001536 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001537 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001538 Ty->Quals =
1539 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001540
Zachary Turnerd742d642018-07-26 19:56:09 +00001541 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001542 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001543
Zachary Turnerd742d642018-07-26 19:56:09 +00001544 if (Ty->Prim == PrimTy::MemberPtr) {
1545 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001546 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001547 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001548 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1549 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1550 } else {
1551 PointerType *PTy = static_cast<PointerType *>(Ty);
1552 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001553 }
1554
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001555 break;
1556 }
1557 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001558 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001559 break;
1560 }
1561
1562 return Ty;
1563}
1564
1565// Sometimes numbers are encoded in mangled symbols. For example,
1566// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1567// length 20), so we need some way to embed numbers as part of symbols.
1568// This function parses it.
1569//
1570// <number> ::= [?] <non-negative integer>
1571//
1572// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1573// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1574//
1575// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001576std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
1577 bool IsNegative = MangledName.consumeFront('?');
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001578
1579 if (startsWithDigit(MangledName)) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001580 uint64_t Ret = MangledName[0] - '0' + 1;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001581 MangledName = MangledName.dropFront(1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001582 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001583 }
1584
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001585 uint64_t Ret = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001586 for (size_t i = 0; i < MangledName.size(); ++i) {
1587 char C = MangledName[i];
1588 if (C == '@') {
1589 MangledName = MangledName.dropFront(i + 1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001590 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001591 }
1592 if ('A' <= C && C <= 'P') {
1593 Ret = (Ret << 4) + (C - 'A');
1594 continue;
1595 }
1596 break;
1597 }
1598
1599 Error = true;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001600 return {0ULL, false};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001601}
1602
Zachary Turner469f0762018-08-17 21:18:05 +00001603uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
1604 bool IsNegative = false;
1605 uint64_t Number = 0;
1606 std::tie(Number, IsNegative) = demangleNumber(MangledName);
1607 if (IsNegative)
1608 Error = true;
1609 return Number;
1610}
1611
1612int64_t Demangler::demangleSigned(StringView &MangledName) {
1613 bool IsNegative = false;
1614 uint64_t Number = 0;
1615 std::tie(Number, IsNegative) = demangleNumber(MangledName);
1616 if (Number > INT64_MAX)
1617 Error = true;
1618 int64_t I = static_cast<int64_t>(Number);
1619 return IsNegative ? -I : I;
1620}
1621
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001622// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1623// Memorize it.
1624void Demangler::memorizeString(StringView S) {
Zachary Turnerd346cba2018-08-08 17:17:04 +00001625 if (Backrefs.NamesCount >= BackrefContext::Max)
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001626 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001627 for (size_t i = 0; i < Backrefs.NamesCount; ++i)
1628 if (S == Backrefs.Names[i])
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001629 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001630 Backrefs.Names[Backrefs.NamesCount++] = S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001631}
1632
Zachary Turner316109b2018-07-29 16:38:02 +00001633Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001634 assert(startsWithDigit(MangledName));
Zachary Turnera7dffb12018-07-28 22:10:42 +00001635 Name *Node = Arena.alloc<Name>();
Zachary Turner172aea12018-08-02 17:08:03 +00001636 Node->IsBackReference = true;
1637 Node->Str = {MangledName.begin(), 1};
1638 MangledName = MangledName.dropFront();
Zachary Turnera7dffb12018-07-28 22:10:42 +00001639 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001640}
1641
Zachary Turner58d29cf2018-08-08 00:43:31 +00001642Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName,
1643 NameBackrefBehavior NBB) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001644 assert(MangledName.startsWith("?$"));
1645 MangledName.consumeFront("?$");
1646
Zachary Turnerd346cba2018-08-08 17:17:04 +00001647 BackrefContext OuterContext;
1648 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001649
Zachary Turnerd346cba2018-08-08 17:17:04 +00001650 Name *Node = demangleUnqualifiedSymbolName(MangledName, NBB_None);
1651 if (!Error)
1652 Node->TParams = demangleTemplateParameterList(MangledName);
1653
1654 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001655 if (Error)
1656 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001657
Zachary Turner44ebbc22018-08-01 18:32:47 +00001658 Node->IsTemplateInstantiation = true;
1659
Zachary Turner58d29cf2018-08-08 00:43:31 +00001660 if (NBB & NBB_Template) {
1661 // Render this class template name into a string buffer so that we can
1662 // memorize it for the purpose of back-referencing.
1663 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turnera17721c2018-08-10 15:04:56 +00001664 outputName(OS, Node, nullptr, *this);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001665 OS << '\0';
1666 char *Name = OS.getBuffer();
Zachary Turner71c91f92018-07-30 03:12:34 +00001667
Zachary Turner58d29cf2018-08-08 00:43:31 +00001668 StringView Owned = copyString(Name);
1669 memorizeString(Owned);
1670 std::free(Name);
1671 }
Zachary Turner71c91f92018-07-30 03:12:34 +00001672
Zachary Turnera7dffb12018-07-28 22:10:42 +00001673 return Node;
1674}
1675
Zachary Turner469f0762018-08-17 21:18:05 +00001676std::pair<OperatorTy, Name *>
1677Demangler::demangleOperatorName(StringView &MangledName, bool FullyQualified) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001678 assert(MangledName.startsWith('?'));
1679 MangledName.consumeFront('?');
1680
Zachary Turner3461bfa2018-08-17 16:14:05 +00001681 const OperatorMapEntry *Entry = nullptr;
1682 for (const auto &MapEntry : OperatorMap) {
1683 if (!MangledName.consumeFront(MapEntry.Prefix))
1684 continue;
1685 Entry = &MapEntry;
1686 break;
Zachary Turnera17721c2018-08-10 15:04:56 +00001687 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001688 if (!Entry) {
1689 Error = true;
Zachary Turner469f0762018-08-17 21:18:05 +00001690 return std::make_pair(OperatorTy::Unknown, nullptr);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001691 }
1692
Zachary Turner469f0762018-08-17 21:18:05 +00001693 Name *N = nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001694 switch (Entry->Operator) {
Zachary Turner469f0762018-08-17 21:18:05 +00001695 case OperatorTy::Vftable: // Foo@@6B@
1696 case OperatorTy::LocalVftable: // Foo@@6B@
1697 case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@
1698 case OperatorTy::Vbtable: { // Foo@@7B@
1699 OperatorInfo *Oper = Arena.alloc<OperatorInfo>(*Entry);
1700 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Oper) : Oper;
1701 break;
1702 }
1703
Zachary Turner3461bfa2018-08-17 16:14:05 +00001704 case OperatorTy::StringLiteral:
Zachary Turner469f0762018-08-17 21:18:05 +00001705 N = demangleStringLiteral(MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001706 break;
1707 case OperatorTy::LiteralOperator:
Zachary Turner469f0762018-08-17 21:18:05 +00001708 N = Arena.alloc<OperatorInfo>(*Entry);
1709 N->Str = demangleSimpleString(MangledName, false);
1710 if (!MangledName.consumeFront('@'))
1711 Error = true;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001712 break;
Zachary Turner469f0762018-08-17 21:18:05 +00001713 case OperatorTy::RttiBaseClassDescriptor: {
1714 RttiBaseClassDescriptor *Temp = Arena.alloc<RttiBaseClassDescriptor>();
1715 Temp->NVOffset = demangleUnsigned(MangledName);
1716 Temp->VBPtrOffset = demangleSigned(MangledName);
1717 Temp->VBTableOffset = demangleUnsigned(MangledName);
1718 Temp->Flags = demangleUnsigned(MangledName);
1719 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Temp) : Temp;
1720 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001721 }
Zachary Turner469f0762018-08-17 21:18:05 +00001722 case OperatorTy::Vcall: {
1723 VirtualMemberPtrThunk *Temp = Arena.alloc<VirtualMemberPtrThunk>();
1724 N = demangleNameScopeChain(MangledName, Temp);
1725 if (Error)
1726 break;
1727 if (!MangledName.consumeFront("$B"))
1728 Error = true;
1729 Temp->OffsetInVTable = demangleUnsigned(MangledName);
1730 if (!MangledName.consumeFront('A'))
1731 Error = true;
1732 Temp->CC = demangleCallingConvention(MangledName);
1733 break;
1734 }
1735 case OperatorTy::RttiTypeDescriptor:
1736 // This one is just followed by a type, not a name scope.
1737 N = Arena.alloc<OperatorInfo>(*Entry);
1738 break;
1739 case OperatorTy::LocalStaticGuard: {
1740 LocalStaticGuardVariable *Temp = Arena.alloc<LocalStaticGuardVariable>();
1741 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Temp) : Temp;
1742 if (MangledName.consumeFront("4IA"))
1743 Temp->IsVisible = false;
1744 else if (MangledName.consumeFront("5"))
1745 Temp->IsVisible = true;
1746 else
1747 Error = true;
1748 if (!MangledName.empty())
1749 Temp->ScopeIndex = demangleUnsigned(MangledName);
1750 break;
1751 }
1752 default:
1753 N = Arena.alloc<OperatorInfo>(*Entry);
1754 N = (FullyQualified) ? demangleNameScopeChain(MangledName, N) : N;
1755 break;
1756 }
Zachary Turner970fdc32018-08-16 16:17:36 +00001757 if (Error)
Zachary Turner469f0762018-08-17 21:18:05 +00001758 return std::make_pair(OperatorTy::Unknown, nullptr);
Zachary Turner970fdc32018-08-16 16:17:36 +00001759
Zachary Turner469f0762018-08-17 21:18:05 +00001760 return std::make_pair(Entry->Operator, N);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001761}
1762
Zachary Turner316109b2018-07-29 16:38:02 +00001763Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001764 StringView S = demangleSimpleString(MangledName, Memorize);
1765 if (Error)
1766 return nullptr;
1767
Zachary Turnera7dffb12018-07-28 22:10:42 +00001768 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001769 Node->Str = S;
1770 return Node;
1771}
1772
Zachary Turner970fdc32018-08-16 16:17:36 +00001773static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); }
1774
1775static uint8_t rebasedHexDigitToNumber(char C) {
1776 assert(isRebasedHexDigit(C));
1777 return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
1778}
1779
1780uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
1781 if (!MangledName.startsWith('?'))
1782 return MangledName.popFront();
1783
1784 MangledName = MangledName.dropFront();
1785 if (MangledName.empty())
1786 goto CharLiteralError;
1787
1788 if (MangledName.consumeFront('$')) {
1789 // Two hex digits
1790 if (MangledName.size() < 2)
1791 goto CharLiteralError;
1792 StringView Nibbles = MangledName.substr(0, 2);
1793 if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
1794 goto CharLiteralError;
1795 // Don't append the null terminator.
1796 uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
1797 uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
1798 MangledName = MangledName.dropFront(2);
1799 return (C1 << 4) | C2;
1800 }
1801
1802 if (startsWithDigit(MangledName)) {
1803 const char *Lookup = ",/\\:. \n\t'-";
1804 char C = Lookup[MangledName[0] - '0'];
1805 MangledName = MangledName.dropFront();
1806 return C;
1807 }
1808
1809 if (MangledName[0] >= 'a' && MangledName[0] <= 'z') {
1810 char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
1811 '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE',
1812 '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
1813 '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
1814 char C = Lookup[MangledName[0] - 'a'];
1815 MangledName = MangledName.dropFront();
1816 return C;
1817 }
1818
1819 if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') {
1820 char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
1821 '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE',
1822 '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
1823 '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
1824 char C = Lookup[MangledName[0] - 'A'];
1825 MangledName = MangledName.dropFront();
1826 return C;
1827 }
1828
1829CharLiteralError:
1830 Error = true;
1831 return '\0';
1832}
1833
1834wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001835 uint8_t C1, C2;
1836
1837 C1 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001838 if (Error)
1839 goto WCharLiteralError;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001840 C2 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001841 if (Error)
1842 goto WCharLiteralError;
1843
1844 return ((wchar_t)C1 << 8) | (wchar_t)C2;
1845
1846WCharLiteralError:
1847 Error = true;
1848 return L'\0';
1849}
1850
1851static void writeHexDigit(char *Buffer, uint8_t Digit) {
1852 assert(Digit <= 15);
1853 *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
1854}
1855
1856static void outputHex(OutputStream &OS, unsigned C) {
1857 if (C == 0) {
1858 OS << "\\x00";
1859 return;
1860 }
1861 // It's easier to do the math if we can work from right to left, but we need
1862 // to print the numbers from left to right. So render this into a temporary
1863 // buffer first, then output the temporary buffer. Each byte is of the form
1864 // \xAB, which means that each byte needs 4 characters. Since there are at
1865 // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
1866 char TempBuffer[17];
1867
1868 ::memset(TempBuffer, 0, sizeof(TempBuffer));
1869 constexpr int MaxPos = 15;
1870
1871 int Pos = MaxPos - 1;
1872 while (C != 0) {
1873 for (int I = 0; I < 2; ++I) {
1874 writeHexDigit(&TempBuffer[Pos--], C % 16);
1875 C /= 16;
1876 }
1877 TempBuffer[Pos--] = 'x';
1878 TempBuffer[Pos--] = '\\';
1879 assert(Pos >= 0);
1880 }
1881 OS << StringView(&TempBuffer[Pos + 1]);
1882}
1883
1884static void outputEscapedChar(OutputStream &OS, unsigned C) {
1885 switch (C) {
1886 case '\'': // single quote
1887 OS << "\\\'";
1888 return;
1889 case '\"': // double quote
1890 OS << "\\\"";
1891 return;
1892 case '\\': // backslash
1893 OS << "\\\\";
1894 return;
1895 case '\a': // bell
1896 OS << "\\a";
1897 return;
1898 case '\b': // backspace
1899 OS << "\\b";
1900 return;
1901 case '\f': // form feed
1902 OS << "\\f";
1903 return;
1904 case '\n': // new line
1905 OS << "\\n";
1906 return;
1907 case '\r': // carriage return
1908 OS << "\\r";
1909 return;
1910 case '\t': // tab
1911 OS << "\\t";
1912 return;
1913 case '\v': // vertical tab
1914 OS << "\\v";
1915 return;
1916 default:
1917 break;
1918 }
1919
1920 if (C > 0x1F && C < 0x7F) {
1921 // Standard ascii char.
1922 OS << (char)C;
1923 return;
1924 }
1925
1926 outputHex(OS, C);
1927}
1928
1929unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
1930 const uint8_t *End = StringBytes + Length - 1;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001931 unsigned Count = 0;
Zachary Turner970fdc32018-08-16 16:17:36 +00001932 while (Length > 0 && *End == 0) {
1933 --Length;
1934 --End;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001935 ++Count;
Zachary Turner970fdc32018-08-16 16:17:36 +00001936 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001937 return Count;
Zachary Turner970fdc32018-08-16 16:17:36 +00001938}
1939
1940unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length) {
1941 unsigned Result = 0;
1942 for (unsigned I = 0; I < Length; ++I) {
1943 if (*StringBytes++ == 0)
1944 ++Result;
1945 }
1946 return Result;
1947}
1948
1949unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
1950 unsigned NumBytes) {
1951 assert(NumBytes > 0);
1952
1953 // If the number of bytes is odd, this is guaranteed to be a char string.
1954 if (NumBytes % 2 == 1)
1955 return 1;
1956
1957 // All strings can encode at most 32 bytes of data. If it's less than that,
1958 // then we encoded the entire string. In this case we check for a 1-byte,
1959 // 2-byte, or 4-byte null terminator.
1960 if (NumBytes < 32) {
1961 unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
1962 if (TrailingNulls >= 4)
1963 return 4;
1964 if (TrailingNulls >= 2)
1965 return 2;
1966 return 1;
1967 }
1968
1969 // The whole string was not able to be encoded. Try to look at embedded null
1970 // terminators to guess. The heuristic is that we count all embedded null
1971 // terminators. If more than 2/3 are null, it's a char32. If more than 1/3
1972 // are null, it's a char16. Otherwise it's a char8. This obviously isn't
1973 // perfect and is biased towards languages that have ascii alphabets, but this
1974 // was always going to be best effort since the encoding is lossy.
1975 unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
1976 if (Nulls >= 2 * NumChars / 3)
1977 return 4;
1978 if (Nulls >= NumChars / 3)
1979 return 2;
1980 return 1;
1981}
1982
1983static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
1984 unsigned CharIndex, unsigned CharBytes) {
1985 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1986 unsigned Offset = CharIndex * CharBytes;
1987 unsigned Result = 0;
1988 StringBytes = StringBytes + Offset;
1989 for (unsigned I = 0; I < CharBytes; ++I) {
1990 unsigned C = static_cast<unsigned>(StringBytes[I]);
1991 Result |= C << (8 * I);
1992 }
1993 return Result;
1994}
1995
Zachary Turner3461bfa2018-08-17 16:14:05 +00001996StringLiteral *Demangler::demangleStringLiteral(StringView &MangledName) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001997 // This function uses goto, so declare all variables up front.
Zachary Turner970fdc32018-08-16 16:17:36 +00001998 OutputStream OS;
1999 StringView CRC;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002000 uint64_t StringByteSize;
2001 bool IsWcharT = false;
2002 bool IsNegative = false;
2003 size_t CrcEndPos = 0;
2004 char *ResultBuffer = nullptr;
2005
Zachary Turner3461bfa2018-08-17 16:14:05 +00002006 StringLiteral *Result = Arena.alloc<StringLiteral>();
Zachary Turner970fdc32018-08-16 16:17:36 +00002007
2008 // Prefix indicating the beginning of a string literal
Zachary Turner3461bfa2018-08-17 16:14:05 +00002009 if (!MangledName.consumeFront("@_"))
2010 goto StringLiteralError;
Zachary Turner970fdc32018-08-16 16:17:36 +00002011 if (MangledName.empty())
2012 goto StringLiteralError;
2013
2014 // Char Type (regular or wchar_t)
Zachary Turner970fdc32018-08-16 16:17:36 +00002015 switch (MangledName.popFront()) {
2016 case '1':
2017 IsWcharT = true;
2018 LLVM_FALLTHROUGH;
2019 case '0':
2020 break;
2021 default:
2022 goto StringLiteralError;
2023 }
2024
2025 // Encoded Length
Zachary Turner970fdc32018-08-16 16:17:36 +00002026 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
2027 if (Error || IsNegative)
2028 goto StringLiteralError;
2029
2030 // CRC 32 (always 8 characters plus a terminator)
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002031 CrcEndPos = MangledName.find('@');
Zachary Turner970fdc32018-08-16 16:17:36 +00002032 if (CrcEndPos == StringView::npos)
2033 goto StringLiteralError;
2034 CRC = MangledName.substr(0, CrcEndPos);
2035 MangledName = MangledName.dropFront(CrcEndPos + 1);
2036 if (MangledName.empty())
2037 goto StringLiteralError;
2038
2039 OS = OutputStream::create(nullptr, nullptr, 1024);
2040 if (IsWcharT) {
Zachary Turner3461bfa2018-08-17 16:14:05 +00002041 Result->CharType = PrimTy::Wchar;
Zachary Turner970fdc32018-08-16 16:17:36 +00002042 if (StringByteSize > 64)
Zachary Turner3461bfa2018-08-17 16:14:05 +00002043 Result->IsTruncated = true;
Zachary Turner970fdc32018-08-16 16:17:36 +00002044
2045 while (!MangledName.consumeFront('@')) {
2046 assert(StringByteSize >= 2);
2047 wchar_t W = demangleWcharLiteral(MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00002048 if (StringByteSize != 2 || Result->IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +00002049 outputEscapedChar(OS, W);
2050 StringByteSize -= 2;
2051 if (Error)
2052 goto StringLiteralError;
2053 }
2054 } else {
2055 if (StringByteSize > 32)
Zachary Turner3461bfa2018-08-17 16:14:05 +00002056 Result->IsTruncated = true;
Zachary Turner970fdc32018-08-16 16:17:36 +00002057
2058 constexpr unsigned MaxStringByteLength = 32;
2059 uint8_t StringBytes[MaxStringByteLength];
2060
2061 unsigned BytesDecoded = 0;
2062 while (!MangledName.consumeFront('@')) {
2063 assert(StringByteSize >= 1);
2064 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
2065 }
2066
2067 unsigned CharBytes =
2068 guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
2069 assert(StringByteSize % CharBytes == 0);
2070 switch (CharBytes) {
2071 case 1:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002072 Result->CharType = PrimTy::Char;
Zachary Turner970fdc32018-08-16 16:17:36 +00002073 break;
2074 case 2:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002075 Result->CharType = PrimTy::Char16;
Zachary Turner970fdc32018-08-16 16:17:36 +00002076 break;
2077 case 4:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002078 Result->CharType = PrimTy::Char32;
Zachary Turner970fdc32018-08-16 16:17:36 +00002079 break;
2080 default:
2081 LLVM_BUILTIN_UNREACHABLE;
2082 }
2083 const unsigned NumChars = BytesDecoded / CharBytes;
2084 for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
2085 unsigned NextChar =
2086 decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
Zachary Turner3461bfa2018-08-17 16:14:05 +00002087 if (CharIndex + 1 < NumChars || Result->IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +00002088 outputEscapedChar(OS, NextChar);
2089 }
2090 }
2091
2092 OS << '\0';
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002093 ResultBuffer = OS.getBuffer();
Zachary Turner970fdc32018-08-16 16:17:36 +00002094 Result->Str = copyString(ResultBuffer);
Zachary Turneraf738f72018-08-16 17:48:32 +00002095 std::free(ResultBuffer);
Zachary Turner970fdc32018-08-16 16:17:36 +00002096 return Result;
2097
2098StringLiteralError:
2099 Error = true;
2100 return nullptr;
2101}
2102
Zachary Turner931e8792018-07-30 23:02:10 +00002103StringView Demangler::demangleSimpleString(StringView &MangledName,
2104 bool Memorize) {
2105 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002106 for (size_t i = 0; i < MangledName.size(); ++i) {
2107 if (MangledName[i] != '@')
2108 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00002109 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002110 MangledName = MangledName.dropFront(i + 1);
2111
2112 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00002113 memorizeString(S);
2114 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002115 }
2116
2117 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00002118 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00002119}
2120
Zachary Turner316109b2018-07-29 16:38:02 +00002121Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002122 assert(MangledName.startsWith("?A"));
2123 MangledName.consumeFront("?A");
2124
2125 Name *Node = Arena.alloc<Name>();
2126 Node->Str = "`anonymous namespace'";
2127 if (MangledName.consumeFront('@'))
2128 return Node;
2129
2130 Error = true;
2131 return nullptr;
2132}
2133
Zachary Turner71c91f92018-07-30 03:12:34 +00002134Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
2135 assert(startsWithLocalScopePattern(MangledName));
2136
2137 Name *Node = Arena.alloc<Name>();
2138 MangledName.consumeFront('?');
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002139 auto Number = demangleNumber(MangledName);
2140 assert(!Number.second);
Zachary Turner71c91f92018-07-30 03:12:34 +00002141
2142 // One ? to terminate the number
2143 MangledName.consumeFront('?');
2144
2145 assert(!Error);
2146 Symbol *Scope = parse(MangledName);
2147 if (Error)
2148 return nullptr;
2149
2150 // Render the parent symbol's name into a buffer.
2151 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
2152 OS << '`';
2153 output(Scope, OS);
2154 OS << '\'';
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002155 OS << "::`" << Number.first << "'";
Zachary Turner71c91f92018-07-30 03:12:34 +00002156 OS << '\0';
2157 char *Result = OS.getBuffer();
2158 Node->Str = copyString(Result);
2159 std::free(Result);
2160 return Node;
2161}
2162
Zachary Turnera7dffb12018-07-28 22:10:42 +00002163// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00002164Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00002165 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002166 if (Error)
2167 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002168 assert(TypeName);
2169
Zachary Turner316109b2018-07-29 16:38:02 +00002170 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002171 if (Error)
2172 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002173 assert(QualName);
2174 return QualName;
2175}
2176
2177// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
2178// Symbol names have slightly different rules regarding what can appear
2179// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00002180Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00002181 // This is the final component of a symbol name (i.e. the leftmost component
2182 // of a mangled name. Since the only possible template instantiation that
2183 // can appear in this context is a function template, and since those are
2184 // not saved for the purposes of name backreferences, only backref simple
2185 // names.
2186 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002187 if (Error)
2188 return nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00002189
Zachary Turner316109b2018-07-29 16:38:02 +00002190 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002191 if (Error)
2192 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002193 assert(QualName);
2194 return QualName;
2195}
2196
Zachary Turner44ebbc22018-08-01 18:32:47 +00002197Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
2198 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002199 // An inner-most name can be a back-reference, because a fully-qualified name
2200 // (e.g. Scope + Inner) can contain other fully qualified names inside of
2201 // them (for example template parameters), and these nested parameters can
2202 // refer to previously mangled types.
2203 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002204 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002205
2206 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002207 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002208
Zachary Turner44ebbc22018-08-01 18:32:47 +00002209 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002210}
2211
Zachary Turner44ebbc22018-08-01 18:32:47 +00002212Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00002213 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00002214 if (startsWithDigit(MangledName))
2215 return demangleBackRefName(MangledName);
2216 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002217 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002218 if (MangledName.startsWith('?'))
Zachary Turner469f0762018-08-17 21:18:05 +00002219 return demangleOperatorName(MangledName, false).second;
Zachary Turner58d29cf2018-08-08 00:43:31 +00002220 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002221}
2222
Zachary Turner316109b2018-07-29 16:38:02 +00002223Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002224 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002225 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002226
2227 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002228 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002229
2230 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00002231 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002232
Zachary Turner71c91f92018-07-30 03:12:34 +00002233 if (startsWithLocalScopePattern(MangledName))
2234 return demangleLocallyScopedNamePiece(MangledName);
2235
Zachary Turner316109b2018-07-29 16:38:02 +00002236 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002237}
2238
Zachary Turner316109b2018-07-29 16:38:02 +00002239Name *Demangler::demangleNameScopeChain(StringView &MangledName,
2240 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002241 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002242
2243 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002244 if (MangledName.empty()) {
2245 Error = true;
2246 return nullptr;
2247 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002248
2249 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00002250 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002251 if (Error)
2252 return nullptr;
2253
2254 Elem->Next = Head;
2255 Head = Elem;
2256 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002257 return Head;
2258}
2259
Zachary Turner316109b2018-07-29 16:38:02 +00002260FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002261 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
2262 RestoreOnError.shouldRestore(false);
2263
2264 switch (MangledName.popFront()) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00002265 case '9':
Zachary Turner469f0762018-08-17 21:18:05 +00002266 return FuncClass(ExternC | NoPrototype);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002267 case 'A':
2268 return Private;
2269 case 'B':
Zachary Turner469f0762018-08-17 21:18:05 +00002270 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002271 case 'C':
Zachary Turner469f0762018-08-17 21:18:05 +00002272 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002273 case 'D':
Zachary Turner469f0762018-08-17 21:18:05 +00002274 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002275 case 'E':
Zachary Turner469f0762018-08-17 21:18:05 +00002276 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002277 case 'F':
Zachary Turner469f0762018-08-17 21:18:05 +00002278 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002279 case 'I':
Zachary Turner469f0762018-08-17 21:18:05 +00002280 return FuncClass(Protected);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002281 case 'J':
Zachary Turner469f0762018-08-17 21:18:05 +00002282 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002283 case 'K':
Zachary Turner469f0762018-08-17 21:18:05 +00002284 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002285 case 'L':
Zachary Turner469f0762018-08-17 21:18:05 +00002286 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002287 case 'M':
Zachary Turner469f0762018-08-17 21:18:05 +00002288 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002289 case 'N':
Zachary Turner469f0762018-08-17 21:18:05 +00002290 return FuncClass(Protected | Virtual | Far);
2291 case 'O':
2292 return FuncClass(Protected | Virtual | StaticThisAdjust);
2293 case 'P':
2294 return FuncClass(Protected | Virtual | StaticThisAdjust | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002295 case 'Q':
Zachary Turner469f0762018-08-17 21:18:05 +00002296 return FuncClass(Public);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002297 case 'R':
Zachary Turner469f0762018-08-17 21:18:05 +00002298 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002299 case 'S':
Zachary Turner469f0762018-08-17 21:18:05 +00002300 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002301 case 'T':
Zachary Turner469f0762018-08-17 21:18:05 +00002302 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002303 case 'U':
Zachary Turner469f0762018-08-17 21:18:05 +00002304 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002305 case 'V':
Zachary Turner469f0762018-08-17 21:18:05 +00002306 return FuncClass(Public | Virtual | Far);
2307 case 'W':
2308 return FuncClass(Public | Virtual | StaticThisAdjust);
2309 case 'X':
2310 return FuncClass(Public | Virtual | StaticThisAdjust | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002311 case 'Y':
Zachary Turner469f0762018-08-17 21:18:05 +00002312 return FuncClass(Global);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002313 case 'Z':
Zachary Turner469f0762018-08-17 21:18:05 +00002314 return FuncClass(Global | Far);
2315 case '$': {
2316 FuncClass VFlag = VirtualThisAdjust;
2317 if (MangledName.consumeFront('R'))
2318 VFlag = FuncClass(VFlag | VirtualThisAdjustEx);
2319
2320 switch (MangledName.popFront()) {
2321 case '0':
2322 return FuncClass(Private | Virtual | VFlag);
2323 case '1':
2324 return FuncClass(Private | Virtual | VFlag | Far);
2325 case '2':
2326 return FuncClass(Protected | Virtual | VFlag);
2327 case '3':
2328 return FuncClass(Protected | Virtual | VFlag | Far);
2329 case '4':
2330 return FuncClass(Public | Virtual | VFlag);
2331 case '5':
2332 return FuncClass(Public | Virtual | VFlag | Far);
2333 }
2334 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002335 }
2336
2337 Error = true;
2338 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002339 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002340}
2341
Zachary Turner316109b2018-07-29 16:38:02 +00002342CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002343 switch (MangledName.popFront()) {
2344 case 'A':
2345 case 'B':
2346 return CallingConv::Cdecl;
2347 case 'C':
2348 case 'D':
2349 return CallingConv::Pascal;
2350 case 'E':
2351 case 'F':
2352 return CallingConv::Thiscall;
2353 case 'G':
2354 case 'H':
2355 return CallingConv::Stdcall;
2356 case 'I':
2357 case 'J':
2358 return CallingConv::Fastcall;
2359 case 'M':
2360 case 'N':
2361 return CallingConv::Clrcall;
2362 case 'O':
2363 case 'P':
2364 return CallingConv::Eabi;
2365 case 'Q':
2366 return CallingConv::Vectorcall;
2367 }
2368
2369 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00002370}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002371
Zachary Turner316109b2018-07-29 16:38:02 +00002372StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002373 assert(std::isdigit(MangledName.front()));
2374
2375 switch (MangledName.popFront()) {
2376 case '0':
2377 return StorageClass::PrivateStatic;
2378 case '1':
2379 return StorageClass::ProtectedStatic;
2380 case '2':
2381 return StorageClass::PublicStatic;
2382 case '3':
2383 return StorageClass::Global;
2384 case '4':
2385 return StorageClass::FunctionLocalStatic;
2386 }
2387 Error = true;
2388 return StorageClass::None;
2389}
2390
Zachary Turner316109b2018-07-29 16:38:02 +00002391std::pair<Qualifiers, bool>
2392Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002393
2394 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002395 // Member qualifiers
2396 case 'Q':
2397 return std::make_pair(Q_None, true);
2398 case 'R':
2399 return std::make_pair(Q_Const, true);
2400 case 'S':
2401 return std::make_pair(Q_Volatile, true);
2402 case 'T':
2403 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
2404 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002405 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00002406 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002407 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00002408 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002409 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00002410 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002411 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00002412 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002413 }
2414 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00002415 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002416}
2417
Zachary Turner931e8792018-07-30 23:02:10 +00002418static bool isTagType(StringView S) {
2419 switch (S.front()) {
2420 case 'T': // union
2421 case 'U': // struct
2422 case 'V': // class
2423 case 'W': // enum
2424 return true;
2425 }
2426 return false;
2427}
2428
2429static bool isPointerType(StringView S) {
2430 if (S.startsWith("$$Q")) // foo &&
2431 return true;
2432
2433 switch (S.front()) {
2434 case 'A': // foo &
2435 case 'P': // foo *
2436 case 'Q': // foo *const
2437 case 'R': // foo *volatile
2438 case 'S': // foo *const volatile
2439 return true;
2440 }
2441 return false;
2442}
2443
2444static bool isArrayType(StringView S) { return S[0] == 'Y'; }
2445
2446static bool isFunctionType(StringView S) {
2447 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
2448}
2449
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002450// <variable-type> ::= <type> <cvr-qualifiers>
2451// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00002452Type *Demangler::demangleType(StringView &MangledName,
2453 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002454 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00002455 bool IsMember = false;
2456 bool IsMemberKnown = false;
2457 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00002458 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002459 IsMemberKnown = true;
2460 } else if (QMM == QualifierMangleMode::Result) {
2461 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00002462 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002463 IsMemberKnown = true;
2464 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002465 }
2466
2467 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00002468 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002469 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002470 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002471 if (!IsMemberKnown)
2472 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002473
Zachary Turnerd742d642018-07-26 19:56:09 +00002474 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00002475 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002476 else
Zachary Turner316109b2018-07-29 16:38:02 +00002477 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002478 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002479 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002480 else if (isFunctionType(MangledName)) {
2481 if (MangledName.consumeFront("$$A8@@"))
2482 Ty = demangleFunctionType(MangledName, true, false);
2483 else {
2484 assert(MangledName.startsWith("$$A6"));
2485 MangledName.consumeFront("$$A6");
2486 Ty = demangleFunctionType(MangledName, false, false);
2487 }
2488 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00002489 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002490 assert(Ty && !Error);
2491 if (!Ty || Error)
2492 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002493 }
Zachary Turner931e8792018-07-30 23:02:10 +00002494
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002495 Ty->Quals = Qualifiers(Ty->Quals | Quals);
2496 return Ty;
2497}
2498
Zachary Turner316109b2018-07-29 16:38:02 +00002499ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002500 if (MangledName.consumeFront('G'))
2501 return ReferenceKind::LValueRef;
2502 else if (MangledName.consumeFront('H'))
2503 return ReferenceKind::RValueRef;
2504 return ReferenceKind::None;
2505}
2506
Zachary Turner316109b2018-07-29 16:38:02 +00002507void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002508 if (MangledName.consumeFront('Z'))
2509 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002510
Zachary Turner38b78a72018-07-26 20:20:10 +00002511 Error = true;
2512}
2513
Zachary Turner316109b2018-07-29 16:38:02 +00002514FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
2515 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00002516 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002517 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002518 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00002519 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00002520
2521 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00002522 FTy->Quals = demanglePointerExtQualifiers(MangledName);
2523 FTy->RefKind = demangleReferenceKind(MangledName);
2524 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002525 }
2526
2527 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00002528 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002529
2530 // <return-type> ::= <type>
2531 // ::= @ # structors (they have no declared return type)
2532 bool IsStructor = MangledName.consumeFront('@');
2533 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00002534 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002535
Zachary Turner316109b2018-07-29 16:38:02 +00002536 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002537
Zachary Turner316109b2018-07-29 16:38:02 +00002538 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002539
2540 return FTy;
2541}
2542
Zachary Turner316109b2018-07-29 16:38:02 +00002543Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
Zachary Turner469f0762018-08-17 21:18:05 +00002544 FuncClass ExtraFlags = FuncClass::None;
2545 if (MangledName.consumeFront("$$J0"))
2546 ExtraFlags = FuncClass::ExternC;
2547
Zachary Turner316109b2018-07-29 16:38:02 +00002548 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00002549 FC = FuncClass(ExtraFlags | FC);
2550
2551 FunctionType::ThisAdjustor *Adjustor = nullptr;
2552 if (FC & FuncClass::StaticThisAdjust) {
2553 Adjustor = Arena.alloc<FunctionType::ThisAdjustor>();
2554 Adjustor->StaticOffset = demangleSigned(MangledName);
2555 } else if (FC & FuncClass::VirtualThisAdjust) {
2556 Adjustor = Arena.alloc<FunctionType::ThisAdjustor>();
2557 if (FC & FuncClass::VirtualThisAdjustEx) {
2558 Adjustor->VBPtrOffset = demangleSigned(MangledName);
2559 Adjustor->VBOffsetOffset = demangleSigned(MangledName);
2560 }
2561 Adjustor->VtordispOffset = demangleSigned(MangledName);
2562 Adjustor->StaticOffset = demangleSigned(MangledName);
2563 }
2564
Zachary Turner29ec67b2018-08-10 21:09:05 +00002565 FunctionType *FTy = nullptr;
2566 if (FC & NoPrototype) {
2567 // This is an extern "C" function whose full signature hasn't been mangled.
2568 // This happens when we need to mangle a local symbol inside of an extern
2569 // "C" function.
2570 FTy = Arena.alloc<FunctionType>();
2571 } else {
2572 bool HasThisQuals = !(FC & (Global | Static));
2573 FTy = demangleFunctionType(MangledName, HasThisQuals, false);
2574 }
Zachary Turner469f0762018-08-17 21:18:05 +00002575 FTy->ThisAdjust = Adjustor;
Zachary Turner38b78a72018-07-26 20:20:10 +00002576 FTy->FunctionClass = FC;
2577
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002578 return FTy;
2579}
2580
2581// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00002582Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002583 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002584
Zachary Turner931e8792018-07-30 23:02:10 +00002585 if (MangledName.consumeFront("$$T")) {
2586 Ty->Prim = PrimTy::Nullptr;
2587 return Ty;
2588 }
2589
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002590 switch (MangledName.popFront()) {
2591 case 'X':
2592 Ty->Prim = PrimTy::Void;
2593 break;
2594 case 'D':
2595 Ty->Prim = PrimTy::Char;
2596 break;
2597 case 'C':
2598 Ty->Prim = PrimTy::Schar;
2599 break;
2600 case 'E':
2601 Ty->Prim = PrimTy::Uchar;
2602 break;
2603 case 'F':
2604 Ty->Prim = PrimTy::Short;
2605 break;
2606 case 'G':
2607 Ty->Prim = PrimTy::Ushort;
2608 break;
2609 case 'H':
2610 Ty->Prim = PrimTy::Int;
2611 break;
2612 case 'I':
2613 Ty->Prim = PrimTy::Uint;
2614 break;
2615 case 'J':
2616 Ty->Prim = PrimTy::Long;
2617 break;
2618 case 'K':
2619 Ty->Prim = PrimTy::Ulong;
2620 break;
2621 case 'M':
2622 Ty->Prim = PrimTy::Float;
2623 break;
2624 case 'N':
2625 Ty->Prim = PrimTy::Double;
2626 break;
2627 case 'O':
2628 Ty->Prim = PrimTy::Ldouble;
2629 break;
2630 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00002631 if (MangledName.empty()) {
2632 Error = true;
2633 return nullptr;
2634 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002635 switch (MangledName.popFront()) {
2636 case 'N':
2637 Ty->Prim = PrimTy::Bool;
2638 break;
2639 case 'J':
2640 Ty->Prim = PrimTy::Int64;
2641 break;
2642 case 'K':
2643 Ty->Prim = PrimTy::Uint64;
2644 break;
2645 case 'W':
2646 Ty->Prim = PrimTy::Wchar;
2647 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002648 case 'S':
2649 Ty->Prim = PrimTy::Char16;
2650 break;
2651 case 'U':
2652 Ty->Prim = PrimTy::Char32;
2653 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00002654 default:
Zachary Turner931e8792018-07-30 23:02:10 +00002655 Error = true;
2656 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002657 }
2658 break;
2659 }
Zachary Turner931e8792018-07-30 23:02:10 +00002660 default:
2661 Error = true;
2662 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002663 }
2664 return Ty;
2665}
2666
Zachary Turner316109b2018-07-29 16:38:02 +00002667UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002668 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002669
2670 switch (MangledName.popFront()) {
2671 case 'T':
2672 UTy->Prim = PrimTy::Union;
2673 break;
2674 case 'U':
2675 UTy->Prim = PrimTy::Struct;
2676 break;
2677 case 'V':
2678 UTy->Prim = PrimTy::Class;
2679 break;
2680 case 'W':
2681 if (MangledName.popFront() != '4') {
2682 Error = true;
2683 return nullptr;
2684 }
2685 UTy->Prim = PrimTy::Enum;
2686 break;
2687 default:
2688 assert(false);
2689 }
2690
Zachary Turner316109b2018-07-29 16:38:02 +00002691 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002692 return UTy;
2693}
2694
Zachary Turnerd742d642018-07-26 19:56:09 +00002695static std::pair<Qualifiers, PointerAffinity>
2696demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00002697 if (MangledName.consumeFront("$$Q"))
2698 return std::make_pair(Q_None, PointerAffinity::RValueReference);
2699
Zachary Turnerd742d642018-07-26 19:56:09 +00002700 switch (MangledName.popFront()) {
2701 case 'A':
2702 return std::make_pair(Q_None, PointerAffinity::Reference);
2703 case 'P':
2704 return std::make_pair(Q_None, PointerAffinity::Pointer);
2705 case 'Q':
2706 return std::make_pair(Q_Const, PointerAffinity::Pointer);
2707 case 'R':
2708 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
2709 case 'S':
2710 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
2711 PointerAffinity::Pointer);
2712 default:
2713 assert(false && "Ty is not a pointer type!");
2714 }
2715 return std::make_pair(Q_None, PointerAffinity::Pointer);
2716}
2717
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002718// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
2719// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00002720PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002721 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002722
Zachary Turner931e8792018-07-30 23:02:10 +00002723 std::tie(Pointer->Quals, Pointer->Affinity) =
2724 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002725
Zachary Turner931e8792018-07-30 23:02:10 +00002726 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002727 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002728 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002729 return Pointer;
2730 }
2731
Zachary Turner316109b2018-07-29 16:38:02 +00002732 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002733 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2734
Zachary Turner316109b2018-07-29 16:38:02 +00002735 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002736 return Pointer;
2737}
2738
Zachary Turner316109b2018-07-29 16:38:02 +00002739MemberPointerType *
2740Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002741 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
2742 Pointer->Prim = PrimTy::MemberPtr;
2743
2744 PointerAffinity Affinity;
2745 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
2746 assert(Affinity == PointerAffinity::Pointer);
2747
Zachary Turner316109b2018-07-29 16:38:02 +00002748 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002749 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2750
Zachary Turner38b78a72018-07-26 20:20:10 +00002751 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002752 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
2753 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002754 } else {
2755 Qualifiers PointeeQuals = Q_None;
2756 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00002757 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002758 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00002759 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002760
Zachary Turner316109b2018-07-29 16:38:02 +00002761 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00002762 Pointer->Pointee->Quals = PointeeQuals;
2763 }
2764
Zachary Turnerd742d642018-07-26 19:56:09 +00002765 return Pointer;
2766}
2767
Zachary Turner316109b2018-07-29 16:38:02 +00002768Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002769 Qualifiers Quals = Q_None;
2770 if (MangledName.consumeFront('E'))
2771 Quals = Qualifiers(Quals | Q_Pointer64);
2772 if (MangledName.consumeFront('I'))
2773 Quals = Qualifiers(Quals | Q_Restrict);
2774 if (MangledName.consumeFront('F'))
2775 Quals = Qualifiers(Quals | Q_Unaligned);
2776
2777 return Quals;
2778}
2779
Zachary Turner316109b2018-07-29 16:38:02 +00002780ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002781 assert(MangledName.front() == 'Y');
2782 MangledName.popFront();
2783
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002784 uint64_t Rank = 0;
2785 bool IsNegative = false;
2786 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2787 if (IsNegative || Rank == 0) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002788 Error = true;
2789 return nullptr;
2790 }
2791
Zachary Turner9d72aa92018-07-20 18:35:06 +00002792 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002793 ATy->Prim = PrimTy::Array;
2794 ATy->Dims = Arena.alloc<ArrayDimension>();
2795 ArrayDimension *Dim = ATy->Dims;
2796 for (uint64_t I = 0; I < Rank; ++I) {
2797 std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
2798 if (IsNegative) {
2799 Error = true;
2800 return nullptr;
2801 }
2802 if (I + 1 < Rank) {
2803 Dim->Next = Arena.alloc<ArrayDimension>();
2804 Dim = Dim->Next;
2805 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002806 }
2807
2808 if (MangledName.consumeFront("$$C")) {
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002809 bool IsMember = false;
2810 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2811 if (IsMember) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002812 Error = true;
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002813 return nullptr;
2814 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002815 }
2816
Zachary Turner316109b2018-07-29 16:38:02 +00002817 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002818 return ATy;
2819}
2820
2821// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002822FunctionParams
2823Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002824 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00002825 if (MangledName.consumeFront('X'))
2826 return {};
2827
Zachary Turnerd30700f2018-07-31 17:16:44 +00002828 FunctionParams *Head;
2829 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002830 while (!Error && !MangledName.startsWith('@') &&
2831 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002832
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002833 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00002834 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002835 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002836 Error = true;
2837 return {};
2838 }
2839 MangledName = MangledName.dropFront();
2840
Zachary Turnerd30700f2018-07-31 17:16:44 +00002841 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00002842 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002843 Current = &(*Current)->Next;
2844 continue;
2845 }
2846
Zachary Turner23df1312018-07-26 22:13:39 +00002847 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002848
Zachary Turnerd30700f2018-07-31 17:16:44 +00002849 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00002850 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002851
Zachary Turner23df1312018-07-26 22:13:39 +00002852 size_t CharsConsumed = OldSize - MangledName.size();
2853 assert(CharsConsumed != 0);
2854
2855 // Single-letter types are ignored for backreferences because memorizing
2856 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002857 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2858 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2859 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002860
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002861 Current = &(*Current)->Next;
2862 }
2863
Zachary Turner38b78a72018-07-26 20:20:10 +00002864 if (Error)
2865 return {};
2866
2867 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2868 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2869 // the following Z could be a throw specifier.
2870 if (MangledName.consumeFront('@'))
2871 return *Head;
2872
2873 if (MangledName.consumeFront('Z')) {
2874 Head->IsVariadic = true;
2875 return *Head;
2876 }
2877
2878 Error = true;
2879 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002880}
2881
Zachary Turnerd30700f2018-07-31 17:16:44 +00002882TemplateParams *
2883Demangler::demangleTemplateParameterList(StringView &MangledName) {
2884 TemplateParams *Head;
2885 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002886 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002887 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002888 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002889
2890 // Empty parameter pack.
2891 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2892 MangledName.consumeFront("$$$V")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002893 (*Current)->IsEmptyParameterPack = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002894 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002895 }
2896
Zachary Turnerd30700f2018-07-31 17:16:44 +00002897 if (MangledName.consumeFront("$$Y")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002898 // Template alias
Zachary Turnerd30700f2018-07-31 17:16:44 +00002899 (*Current)->IsTemplateTemplate = true;
2900 (*Current)->IsAliasTemplate = true;
2901 (*Current)->ParamName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002902 } else if (MangledName.consumeFront("$$B")) {
2903 // Array
2904 (*Current)->ParamType =
2905 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner073620b2018-08-10 19:57:36 +00002906 } else if (MangledName.consumeFront("$$C")) {
2907 // Type has qualifiers.
2908 (*Current)->ParamType =
2909 demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002910 } else if (MangledName.startsWith("$1?")) {
2911 MangledName.consumeFront("$1");
2912 // Pointer to symbol
2913 Symbol *S = parse(MangledName);
2914 (*Current)->ParamName = S->SymbolName;
2915 (*Current)->ParamType = S->SymbolType;
2916 (*Current)->PointerToSymbol = true;
2917 } else if (MangledName.startsWith("$E?")) {
2918 MangledName.consumeFront("$E");
2919 // Reference to symbol
2920 Symbol *S = parse(MangledName);
2921 (*Current)->ParamName = S->SymbolName;
2922 (*Current)->ParamType = S->SymbolType;
2923 (*Current)->ReferenceToSymbol = true;
2924 } else if (MangledName.consumeFront("$0")) {
2925 // Integral non-type template parameter
2926 bool IsNegative = false;
2927 uint64_t Value = 0;
2928 std::tie(Value, IsNegative) = demangleNumber(MangledName);
2929
2930 (*Current)->IsIntegerLiteral = true;
2931 (*Current)->IntegerLiteralIsNegative = IsNegative;
2932 (*Current)->IntegralValue = Value;
Zachary Turnerd30700f2018-07-31 17:16:44 +00002933 } else {
2934 (*Current)->ParamType =
Reid Klecknerd2bad6c2018-07-31 01:08:42 +00002935 demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00002936 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002937 if (Error)
2938 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002939
2940 Current = &(*Current)->Next;
2941 }
2942
2943 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002944 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002945
2946 // Template parameter lists cannot be variadic, so it can only be terminated
2947 // by @.
2948 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00002949 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002950 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002951 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00002952}
2953
Zachary Turner172aea12018-08-02 17:08:03 +00002954StringView Demangler::resolve(StringView N) {
2955 assert(N.size() == 1 && isdigit(N[0]));
Zachary Turner5b0456d2018-08-02 17:18:01 +00002956 size_t Digit = N[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002957 if (Digit >= Backrefs.NamesCount)
Zachary Turner172aea12018-08-02 17:08:03 +00002958 return N;
Zachary Turnerd346cba2018-08-08 17:17:04 +00002959 return Backrefs.Names[Digit];
Zachary Turner172aea12018-08-02 17:08:03 +00002960}
2961
Zachary Turner316109b2018-07-29 16:38:02 +00002962void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turner83313f82018-08-16 16:17:17 +00002963 if (S->Category == SymbolCategory::Unknown) {
2964 outputName(OS, S->SymbolName, S->SymbolType, *this);
2965 return;
2966 }
Zachary Turner970fdc32018-08-16 16:17:36 +00002967
Zachary Turner469f0762018-08-17 21:18:05 +00002968 if (S->Category == SymbolCategory::SpecialOperator) {
2969 outputSpecialOperator(OS, S->SymbolName, *this);
2970 return;
2971 }
2972
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002973 // Converts an AST to a string.
2974 //
2975 // Converting an AST representing a C++ type to a string is tricky due
2976 // to the bad grammar of the C++ declaration inherited from C. You have
2977 // to construct a string from inside to outside. For example, if a type
2978 // X is a pointer to a function returning int, the order you create a
2979 // string becomes something like this:
2980 //
2981 // (1) X is a pointer: *X
2982 // (2) (1) is a function returning int: int (*X)()
2983 //
2984 // So you cannot construct a result just by appending strings to a result.
2985 //
2986 // To deal with this, we split the function into two. outputPre() writes
2987 // the "first half" of type declaration, and outputPost() writes the
2988 // "second half". For example, outputPre() writes a return type for a
2989 // function and outputPost() writes an parameter list.
Zachary Turner3461bfa2018-08-17 16:14:05 +00002990 if (S->SymbolType) {
2991 Type::outputPre(OS, *S->SymbolType, *this);
2992 outputName(OS, S->SymbolName, S->SymbolType, *this);
2993 Type::outputPost(OS, *S->SymbolType, *this);
Zachary Turner469f0762018-08-17 21:18:05 +00002994 } else {
2995 outputQualifiers(OS, S->SymbolQuals);
Zachary Turner3461bfa2018-08-17 16:14:05 +00002996 outputName(OS, S->SymbolName, nullptr, *this);
Zachary Turner469f0762018-08-17 21:18:05 +00002997 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002998}
2999
Zachary Turner3a758e22018-08-01 18:33:04 +00003000void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00003001 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00003002 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00003003
3004 // Create an output stream so we can render each type.
3005 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00003006 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00003007 OS.setCurrentPosition(0);
3008
Zachary Turnerd346cba2018-08-08 17:17:04 +00003009 Type *T = Backrefs.FunctionParams[I];
Zachary Turner172aea12018-08-02 17:08:03 +00003010 Type::outputPre(OS, *T, *this);
3011 Type::outputPost(OS, *T, *this);
Zachary Turner3a758e22018-08-01 18:33:04 +00003012
Zachary Turner7563ebe2018-08-02 17:08:24 +00003013 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00003014 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00003015 }
3016 std::free(OS.getBuffer());
3017
Zachary Turnerd346cba2018-08-08 17:17:04 +00003018 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00003019 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00003020 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
3021 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
3022 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
3023 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00003024 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00003025 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00003026 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00003027}
3028
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003029char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00003030 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00003031 Demangler D;
3032 StringView Name{MangledName};
3033 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003034
Zachary Turner3a758e22018-08-01 18:33:04 +00003035 if (Flags & MSDF_DumpBackrefs)
3036 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00003037 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00003038 if (D.Error) {
3039 OS << MangledName;
3040 *Status = llvm::demangle_invalid_mangled_name;
3041 } else {
3042 D.output(S, OS);
3043 *Status = llvm::demangle_success;
3044 }
3045
Zachary Turner71c91f92018-07-30 03:12:34 +00003046 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003047 return OS.getBuffer();
3048}