blob: 58678e9f9080f8e0d3c410025a85674bdb04d488 [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
Zachary Turner66555a72018-08-20 19:15:35 +000023#include <array>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000024#include <cctype>
Zachary Turner5ae08b82018-08-01 18:44:12 +000025#include <cstdio>
Zachary Turnerd742d642018-07-26 19:56:09 +000026#include <tuple>
Zachary Turnerf435a7e2018-07-20 17:27:48 +000027
28// This memory allocator is extremely fast, but it doesn't call dtors
29// for allocated objects. That means you can't use STL containers
30// (such as std::vector) with this allocator. But it pays off --
31// the demangler is 3x faster with this allocator compared to one with
32// STL containers.
33namespace {
Zachary Turnera6869512018-07-30 03:25:27 +000034 constexpr size_t AllocUnit = 4096;
35
Zachary Turnerf435a7e2018-07-20 17:27:48 +000036class ArenaAllocator {
37 struct AllocatorNode {
38 uint8_t *Buf = nullptr;
39 size_t Used = 0;
Zachary Turner71c91f92018-07-30 03:12:34 +000040 size_t Capacity = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000041 AllocatorNode *Next = nullptr;
42 };
43
Zachary Turner71c91f92018-07-30 03:12:34 +000044 void addNode(size_t Capacity) {
45 AllocatorNode *NewHead = new AllocatorNode;
46 NewHead->Buf = new uint8_t[Capacity];
47 NewHead->Next = Head;
48 NewHead->Capacity = Capacity;
49 Head = NewHead;
50 NewHead->Used = 0;
51 }
52
Zachary Turnerf435a7e2018-07-20 17:27:48 +000053public:
Zachary Turnera6869512018-07-30 03:25:27 +000054 ArenaAllocator() { addNode(AllocUnit); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000055
56 ~ArenaAllocator() {
57 while (Head) {
58 assert(Head->Buf);
59 delete[] Head->Buf;
Reid Klecknerdbae8cd2018-07-23 18:21:43 +000060 AllocatorNode *Next = Head->Next;
61 delete Head;
62 Head = Next;
Zachary Turnerf435a7e2018-07-20 17:27:48 +000063 }
64 }
65
Zachary Turner71c91f92018-07-30 03:12:34 +000066 char *allocUnalignedBuffer(size_t Length) {
67 uint8_t *Buf = Head->Buf + Head->Used;
68
69 Head->Used += Length;
70 if (Head->Used > Head->Capacity) {
71 // It's possible we need a buffer which is larger than our default unit
72 // size, so we need to be careful to add a node with capacity that is at
73 // least as large as what we need.
Zachary Turnera6869512018-07-30 03:25:27 +000074 addNode(std::max(AllocUnit, Length));
Zachary Turner71c91f92018-07-30 03:12:34 +000075 Head->Used = Length;
76 Buf = Head->Buf;
77 }
78
79 return reinterpret_cast<char *>(Buf);
80 }
81
Zachary Turner9d72aa92018-07-20 18:35:06 +000082 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
83
84 size_t Size = sizeof(T);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000085 assert(Head && Head->Buf);
86
Zachary Turner9d72aa92018-07-20 18:35:06 +000087 size_t P = (size_t)Head->Buf + Head->Used;
88 uintptr_t AlignedP =
89 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
90 uint8_t *PP = (uint8_t *)AlignedP;
91 size_t Adjustment = AlignedP - P;
92
93 Head->Used += Size + Adjustment;
Zachary Turner71c91f92018-07-30 03:12:34 +000094 if (Head->Used < Head->Capacity)
Zachary Turner9d72aa92018-07-20 18:35:06 +000095 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000096
Zachary Turnera6869512018-07-30 03:25:27 +000097 addNode(AllocUnit);
Zachary Turner71c91f92018-07-30 03:12:34 +000098 Head->Used = Size;
99 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000100 }
101
102private:
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000103 AllocatorNode *Head = nullptr;
104};
105} // namespace
106
107static bool startsWithDigit(StringView S) {
108 return !S.empty() && std::isdigit(S.front());
109}
110
111// Writes a space if the last token does not end with a punctuation.
112static void outputSpaceIfNecessary(OutputStream &OS) {
113 if (OS.empty())
114 return;
115
116 char C = OS.back();
117 if (isalnum(C) || C == '>')
118 OS << " ";
119}
120
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000121// Storage classes
122enum Qualifiers : uint8_t {
123 Q_None = 0,
124 Q_Const = 1 << 0,
125 Q_Volatile = 1 << 1,
126 Q_Far = 1 << 2,
127 Q_Huge = 1 << 3,
128 Q_Unaligned = 1 << 4,
129 Q_Restrict = 1 << 5,
130 Q_Pointer64 = 1 << 6
131};
132
133enum class StorageClass : uint8_t {
134 None,
135 PrivateStatic,
136 ProtectedStatic,
137 PublicStatic,
138 Global,
Zachary Turner3461bfa2018-08-17 16:14:05 +0000139 FunctionLocalStatic,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000140};
141
142enum class QualifierMangleMode { Drop, Mangle, Result };
Zachary Turnerd742d642018-07-26 19:56:09 +0000143
Zachary Turner931e8792018-07-30 23:02:10 +0000144enum class PointerAffinity { Pointer, Reference, RValueReference };
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000145
146// Calling conventions
147enum class CallingConv : uint8_t {
148 None,
149 Cdecl,
150 Pascal,
151 Thiscall,
152 Stdcall,
153 Fastcall,
154 Clrcall,
155 Eabi,
156 Vectorcall,
157 Regcall,
158};
159
160enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
161
162// Types
163enum class PrimTy : uint8_t {
164 Unknown,
165 None,
166 Function,
167 Ptr,
Zachary Turnerd742d642018-07-26 19:56:09 +0000168 MemberPtr,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000169 Array,
170
171 Struct,
172 Union,
173 Class,
174 Enum,
175
176 Void,
177 Bool,
178 Char,
179 Schar,
180 Uchar,
Zachary Turner931e8792018-07-30 23:02:10 +0000181 Char16,
182 Char32,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000183 Short,
184 Ushort,
185 Int,
186 Uint,
187 Long,
188 Ulong,
189 Int64,
190 Uint64,
191 Wchar,
192 Float,
193 Double,
194 Ldouble,
Zachary Turner3461bfa2018-08-17 16:14:05 +0000195 Nullptr,
196 Vftable,
197 Vbtable,
198 LocalStaticGuard
199};
200
201enum class OperatorTy : uint8_t {
202 Ctor, // ?0 # Foo::Foo()
203 Dtor, // ?1 # Foo::~Foo()
204 New, // ?2 # operator new
205 Delete, // ?3 # operator delete
206 Assign, // ?4 # operator=
207 RightShift, // ?5 # operator>>
208 LeftShift, // ?6 # operator<<
209 LogicalNot, // ?7 # operator!
210 Equals, // ?8 # operator==
211 NotEquals, // ?9 # operator!=
212 ArraySubscript, // ?A # operator[]
213 Conversion, // ?B # Foo::operator <type>()
214 Pointer, // ?C # operator->
215 Dereference, // ?D # operator*
216 Increment, // ?E # operator++
217 Decrement, // ?F # operator--
218 Minus, // ?G # operator-
219 Plus, // ?H # operator+
220 BitwiseAnd, // ?I # operator&
221 MemberPointer, // ?J # operator->*
222 Divide, // ?K # operator/
223 Modulus, // ?L # operator%
224 LessThan, // ?M operator<
225 LessThanEqual, // ?N operator<=
226 GreaterThan, // ?O operator>
227 GreaterThanEqual, // ?P operator>=
228 Comma, // ?Q operator,
229 Parens, // ?R operator()
230 BitwiseNot, // ?S operator~
231 BitwiseXor, // ?T operator^
232 BitwiseOr, // ?U operator|
233 LogicalAnd, // ?V operator&&
234 LogicalOr, // ?W operator||
235 TimesEqual, // ?X operator*=
236 PlusEqual, // ?Y operator+=
237 MinusEqual, // ?Z operator-=
238 DivEqual, // ?_0 operator/=
239 ModEqual, // ?_1 operator%=
240 RshEqual, // ?_2 operator>>=
241 LshEqual, // ?_3 operator<<=
242 BitwiseAndEqual, // ?_4 operator&=
243 BitwiseOrEqual, // ?_5 operator|=
244 BitwiseXorEqual, // ?_6 operator^=
245 Vftable, // ?_7 # vftable
246 Vbtable, // ?_8 # vbtable
247 Vcall, // ?_9 # vcall
248 Typeof, // ?_A # typeof
249 LocalStaticGuard, // ?_B # local static guard
250 StringLiteral, // ?_C # string literal
251 VbaseDtor, // ?_D # vbase destructor
252 VecDelDtor, // ?_E # vector deleting destructor
253 DefaultCtorClosure, // ?_F # default constructor closure
254 ScalarDelDtor, // ?_G # scalar deleting destructor
255 VecCtorIter, // ?_H # vector constructor iterator
256 VecDtorIter, // ?_I # vector destructor iterator
257 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
258 VdispMap, // ?_K # virtual displacement map
259 EHVecCtorIter, // ?_L # eh vector constructor iterator
260 EHVecDtorIter, // ?_M # eh vector destructor iterator
261 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
262 CopyCtorClosure, // ?_O # copy constructor closure
263 UdtReturning, // ?_P<name> # udt returning <name>
264 Unknown, // ?_Q # <unknown>
265 RttiTypeDescriptor, // ?_R0 # RTTI Type Descriptor
266 RttiBaseClassDescriptor, // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
267 RttiBaseClassArray, // ?_R2 # RTTI Base Class Array
268 RttiClassHierarchyDescriptor, // ?_R3 # RTTI Class Hierarchy Descriptor
269 RttiCompleteObjLocator, // ?_R4 # RTTI Complete Object Locator
270 LocalVftable, // ?_S # local vftable
271 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
272 ArrayNew, // ?_U operator new[]
273 ArrayDelete, // ?_V operator delete[]
274 LiteralOperator, // ?__K operator ""_name
275 CoAwait, // ?__L co_await
276 Spaceship, // operator<=>
277};
278
279// A map to translate from operator prefix to operator type.
280struct OperatorMapEntry {
281 StringView Prefix;
282 StringView Name;
283 OperatorTy Operator;
284};
285
Zachary Turner469f0762018-08-17 21:18:05 +0000286// The entries here must be in the same order as the enumeration so that it can
287// be indexed by enum value.
Zachary Turner3461bfa2018-08-17 16:14:05 +0000288OperatorMapEntry OperatorMap[] = {
289 {"0", " <ctor>", OperatorTy::Ctor},
290 {"1", " <dtor>", OperatorTy::Dtor},
291 {"2", "operator new", OperatorTy::New},
292 {"3", "operator delete", OperatorTy::Delete},
293 {"4", "operator=", OperatorTy::Assign},
294 {"5", "operator>>", OperatorTy::RightShift},
295 {"6", "operator<<", OperatorTy::LeftShift},
296 {"7", "operator!", OperatorTy::LogicalNot},
297 {"8", "operator==", OperatorTy::Equals},
298 {"9", "operator!=", OperatorTy::NotEquals},
299 {"A", "operator[]", OperatorTy::ArraySubscript},
300 {"B", "operator <conversion>", OperatorTy::Conversion},
301 {"C", "operator->", OperatorTy::Pointer},
302 {"D", "operator*", OperatorTy::Dereference},
303 {"E", "operator++", OperatorTy::Increment},
304 {"F", "operator--", OperatorTy::Decrement},
305 {"G", "operator-", OperatorTy::Minus},
306 {"H", "operator+", OperatorTy::Plus},
307 {"I", "operator&", OperatorTy::BitwiseAnd},
308 {"J", "operator->*", OperatorTy::MemberPointer},
309 {"K", "operator/", OperatorTy::Divide},
310 {"L", "operator%", OperatorTy::Modulus},
311 {"M", "operator<", OperatorTy::LessThan},
312 {"N", "operator<=", OperatorTy::LessThanEqual},
313 {"O", "operator>", OperatorTy::GreaterThan},
314 {"P", "operator>=", OperatorTy::GreaterThanEqual},
315 {"Q", "operator,", OperatorTy::Comma},
316 {"R", "operator()", OperatorTy::Parens},
317 {"S", "operator~", OperatorTy::BitwiseNot},
318 {"T", "operator^", OperatorTy::BitwiseXor},
319 {"U", "operator|", OperatorTy::BitwiseOr},
320 {"V", "operator&&", OperatorTy::LogicalAnd},
321 {"W", "operator||", OperatorTy::LogicalOr},
322 {"X", "operator*=", OperatorTy::TimesEqual},
323 {"Y", "operator+=", OperatorTy::PlusEqual},
324 {"Z", "operator-=", OperatorTy::MinusEqual},
325 {"_0", "operator/=", OperatorTy::DivEqual},
326 {"_1", "operator%=", OperatorTy::ModEqual},
327 {"_2", "operator>>=", OperatorTy::RshEqual},
328 {"_3", "operator<<=", OperatorTy::LshEqual},
329 {"_4", "operator&=", OperatorTy::BitwiseAndEqual},
330 {"_5", "operator|=", OperatorTy::BitwiseOrEqual},
331 {"_6", "operator^=", OperatorTy::BitwiseXorEqual},
332 {"_7", "`vftable'", OperatorTy::Vftable},
333 {"_8", "`vbtable'", OperatorTy::Vbtable},
334 {"_9", "`vcall'", OperatorTy::Vcall},
335 {"_A", "`typeof'", OperatorTy::Typeof},
336 {"_B", "`local static guard'", OperatorTy::LocalStaticGuard},
337 {"_C", "`string'", OperatorTy::StringLiteral},
338 {"_D", "`vbase dtor'", OperatorTy::VbaseDtor},
339 {"_E", "`vector deleting dtor'", OperatorTy::VecDelDtor},
340 {"_F", "`default ctor closure'", OperatorTy::DefaultCtorClosure},
341 {"_G", "`scalar deleting dtor'", OperatorTy::ScalarDelDtor},
342 {"_H", "`vector ctor iterator'", OperatorTy::VecCtorIter},
343 {"_I", "`vector dtor iterator'", OperatorTy::VecDtorIter},
344 {"_J", "`vector vbase ctor iterator'", OperatorTy::VecVbaseCtorIter},
345 {"_K", "`virtual displacement map'", OperatorTy::VdispMap},
346 {"_L", "`eh vector ctor iterator'", OperatorTy::EHVecCtorIter},
347 {"_M", "`eh vector dtor iterator'", OperatorTy::EHVecDtorIter},
348 {"_N", "`eh vector vbase ctor iterator'", OperatorTy::EHVecVbaseCtorIter},
349 {"_O", "`copy ctor closure'", OperatorTy::CopyCtorClosure},
350 {"_P", "`udt returning'", OperatorTy::UdtReturning},
351 {"_Q", "`unknown'", OperatorTy::Unknown},
352 {"_R0", "`RTTI Type Descriptor'", OperatorTy::RttiTypeDescriptor},
Zachary Turner469f0762018-08-17 21:18:05 +0000353 {"_R1", "RTTI Base Class Descriptor", OperatorTy::RttiBaseClassDescriptor},
Zachary Turner3461bfa2018-08-17 16:14:05 +0000354 {"_R2", "`RTTI Base Class Array'", OperatorTy::RttiBaseClassArray},
355 {"_R3", "`RTTI Class Hierarchy Descriptor'",
356 OperatorTy::RttiClassHierarchyDescriptor},
357 {"_R4", "`RTTI Complete Object Locator'",
358 OperatorTy::RttiCompleteObjLocator},
359 {"_S", "`local vftable'", OperatorTy::LocalVftable},
360 {"_T", "`local vftable ctor closure'", OperatorTy::LocalVftableCtorClosure},
361 {"_U", "operator new[]", OperatorTy::ArrayNew},
362 {"_V", "operator delete[]", OperatorTy::ArrayDelete},
363 {"__K", "operator \"\"", OperatorTy::LiteralOperator},
364 {"__L", "co_await", OperatorTy::CoAwait},
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000365};
366
367// Function classes
Zachary Turner29ec67b2018-08-10 21:09:05 +0000368enum FuncClass : uint16_t {
Zachary Turner469f0762018-08-17 21:18:05 +0000369 None = 0,
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000370 Public = 1 << 0,
371 Protected = 1 << 1,
372 Private = 1 << 2,
373 Global = 1 << 3,
374 Static = 1 << 4,
375 Virtual = 1 << 5,
Zachary Turner91ecedd2018-07-20 18:07:33 +0000376 Far = 1 << 6,
Zachary Turner29ec67b2018-08-10 21:09:05 +0000377 ExternC = 1 << 7,
378 NoPrototype = 1 << 8,
Zachary Turner469f0762018-08-17 21:18:05 +0000379 VirtualThisAdjust = 1 << 9,
380 VirtualThisAdjustEx = 1 << 10,
381 StaticThisAdjust = 1 << 11
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000382};
383
Zachary Turner58d29cf2018-08-08 00:43:31 +0000384enum NameBackrefBehavior : uint8_t {
385 NBB_None = 0, // don't save any names as backrefs.
386 NBB_Template = 1 << 0, // save template instanations.
387 NBB_Simple = 1 << 1, // save simple names.
388};
389
Zachary Turner469f0762018-08-17 21:18:05 +0000390enum class SymbolCategory {
391 Unknown,
392 NamedFunction,
393 NamedVariable,
394 UnnamedFunction,
395 UnnamedVariable,
396 SpecialOperator
397};
Zachary Turner44ebbc22018-08-01 18:32:47 +0000398
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000399namespace {
400
401struct Type;
Zachary Turner931e8792018-07-30 23:02:10 +0000402struct Name;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000403
Zachary Turnerd30700f2018-07-31 17:16:44 +0000404struct FunctionParams {
Zachary Turner38b78a72018-07-26 20:20:10 +0000405 bool IsVariadic = false;
406
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000407 Type *Current = nullptr;
408
Zachary Turnerd30700f2018-07-31 17:16:44 +0000409 FunctionParams *Next = nullptr;
410};
Zachary Turner931e8792018-07-30 23:02:10 +0000411
Zachary Turnerd30700f2018-07-31 17:16:44 +0000412struct TemplateParams {
413 bool IsTemplateTemplate = false;
414 bool IsAliasTemplate = false;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000415 bool IsIntegerLiteral = false;
416 bool IntegerLiteralIsNegative = false;
417 bool IsEmptyParameterPack = false;
418 bool PointerToSymbol = false;
Zachary Turner66555a72018-08-20 19:15:35 +0000419 bool NullptrLiteral = false;
420 bool DataMemberPointer = false;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000421 bool ReferenceToSymbol = false;
422
Zachary Turner66555a72018-08-20 19:15:35 +0000423 int ThunkOffsetCount = 0;
424 std::array<int64_t, 3> ThunkOffsets;
425
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000426 // If IsIntegerLiteral is true, this is a non-type template parameter
427 // whose value is contained in this field.
428 uint64_t IntegralValue = 0;
Zachary Turnerd30700f2018-07-31 17:16:44 +0000429
430 // Type can be null if this is a template template parameter. In that case
431 // only Name will be valid.
432 Type *ParamType = nullptr;
433
434 // Name can be valid if this is a template template parameter (see above) or
435 // this is a function declaration (e.g. foo<&SomeFunc>). In the latter case
436 // Name contains the name of the function and Type contains the signature.
437 Name *ParamName = nullptr;
438
439 TemplateParams *Next = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000440};
441
442// The type class. Mangled symbols are first parsed and converted to
443// this type and then converted to string.
444struct Type {
445 virtual ~Type() {}
446
447 virtual Type *clone(ArenaAllocator &Arena) const;
448
449 // Write the "first half" of a given type. This is a static functions to
450 // give the code a chance to do processing that is common to a subset of
451 // subclasses
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000452 static void outputPre(OutputStream &OS, Type &Ty);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000453
454 // Write the "second half" of a given type. This is a static functions to
455 // give the code a chance to do processing that is common to a subset of
456 // subclasses
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000457 static void outputPost(OutputStream &OS, Type &Ty);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000458
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000459 virtual void outputPre(OutputStream &OS);
460 virtual void outputPost(OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000461
462 // Primitive type such as Int.
463 PrimTy Prim = PrimTy::Unknown;
464
465 Qualifiers Quals = Q_None;
466 StorageClass Storage = StorageClass::None; // storage class
467};
468
469// Represents an identifier which may be a template.
470struct Name {
Zachary Turner3461bfa2018-08-17 16:14:05 +0000471 virtual ~Name() = default;
472
Zachary Turner44ebbc22018-08-01 18:32:47 +0000473 bool IsTemplateInstantiation = false;
474 bool IsOperator = false;
Zachary Turner172aea12018-08-02 17:08:03 +0000475 bool IsBackReference = false;
Zachary Turner970fdc32018-08-16 16:17:36 +0000476
Zachary Turner3461bfa2018-08-17 16:14:05 +0000477 bool isStringLiteralOperatorInfo() const;
Zachary Turnera17721c2018-08-10 15:04:56 +0000478
479 // Name read from an MangledName string.
480 StringView Str;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000481
Zachary Turner3461bfa2018-08-17 16:14:05 +0000482 // Template parameters. Only valid if IsTemplateInstantiation is true.
Zachary Turnerd30700f2018-07-31 17:16:44 +0000483 TemplateParams *TParams = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000484
485 // Nested BackReferences (e.g. "A::B::C") are represented as a linked list.
486 Name *Next = nullptr;
487};
488
Zachary Turner3461bfa2018-08-17 16:14:05 +0000489struct OperatorInfo : public Name {
Zachary Turner469f0762018-08-17 21:18:05 +0000490 explicit OperatorInfo(const OperatorMapEntry &Info) : Info(&Info) {
491 this->IsOperator = true;
492 }
493 explicit OperatorInfo(OperatorTy OpType)
494 : OperatorInfo(OperatorMap[(int)OpType]) {}
495
Zachary Turner3461bfa2018-08-17 16:14:05 +0000496 const OperatorMapEntry *Info = nullptr;
497};
498
499struct StringLiteral : public OperatorInfo {
Zachary Turner469f0762018-08-17 21:18:05 +0000500 StringLiteral() : OperatorInfo(OperatorTy::StringLiteral) {}
501
Zachary Turner3461bfa2018-08-17 16:14:05 +0000502 PrimTy CharType;
503 bool IsTruncated = false;
504};
505
Zachary Turner469f0762018-08-17 21:18:05 +0000506struct RttiBaseClassDescriptor : public OperatorInfo {
507 RttiBaseClassDescriptor()
508 : OperatorInfo(OperatorTy::RttiBaseClassDescriptor) {}
509
510 uint32_t NVOffset = 0;
511 int32_t VBPtrOffset = 0;
512 uint32_t VBTableOffset = 0;
513 uint32_t Flags = 0;
514};
515
516struct LocalStaticGuardVariable : public OperatorInfo {
517 LocalStaticGuardVariable() : OperatorInfo(OperatorTy::LocalStaticGuard) {}
518
519 uint32_t ScopeIndex = 0;
520 bool IsVisible = false;
521};
522
523struct VirtualMemberPtrThunk : public OperatorInfo {
524 VirtualMemberPtrThunk() : OperatorInfo(OperatorTy::Vcall) {}
525
526 uint64_t OffsetInVTable = 0;
527 CallingConv CC = CallingConv::Cdecl;
528};
529
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000530struct PointerType : public Type {
531 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000532 void outputPre(OutputStream &OS) override;
533 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000534
Zachary Turner931e8792018-07-30 23:02:10 +0000535 PointerAffinity Affinity;
536
Zachary Turnerd742d642018-07-26 19:56:09 +0000537 // Represents a type X in "a pointer to X", "a reference to X",
538 // "an array of X", or "a function returning X".
539 Type *Pointee = nullptr;
540};
541
542struct MemberPointerType : public Type {
543 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000544 void outputPre(OutputStream &OS) override;
545 void outputPost(OutputStream &OS) override;
Zachary Turnerd742d642018-07-26 19:56:09 +0000546
547 Name *MemberName = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000548
549 // Represents a type X in "a pointer to X", "a reference to X",
550 // "an array of X", or "a function returning X".
551 Type *Pointee = nullptr;
552};
553
554struct FunctionType : public Type {
Zachary Turner469f0762018-08-17 21:18:05 +0000555 struct ThisAdjustor {
556 uint32_t StaticOffset = 0;
557 int32_t VBPtrOffset = 0;
558 int32_t VBOffsetOffset = 0;
559 int32_t VtordispOffset = 0;
560 };
561
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000562 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000563 void outputPre(OutputStream &OS) override;
564 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000565
Zachary Turner024e1762018-07-26 20:33:48 +0000566 // True if this FunctionType instance is the Pointee of a PointerType or
567 // MemberPointerType.
568 bool IsFunctionPointer = false;
Zachary Turner469f0762018-08-17 21:18:05 +0000569 bool IsThunk = false;
Zachary Turner024e1762018-07-26 20:33:48 +0000570
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000571 Type *ReturnType = nullptr;
572 // If this is a reference, the type of reference.
573 ReferenceKind RefKind;
574
575 CallingConv CallConvention;
576 FuncClass FunctionClass;
577
Zachary Turner469f0762018-08-17 21:18:05 +0000578 // Valid if IsThunk is true.
579 ThisAdjustor *ThisAdjust = nullptr;
580
Zachary Turnerd30700f2018-07-31 17:16:44 +0000581 FunctionParams Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000582};
583
584struct UdtType : public Type {
585 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000586 void outputPre(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000587
588 Name *UdtName = nullptr;
589};
590
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000591struct ArrayDimension {
592 uint64_t Dim = 0;
593 ArrayDimension *Next = nullptr;
594};
595
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000596struct ArrayType : public Type {
597 Type *clone(ArenaAllocator &Arena) const override;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000598 void outputPre(OutputStream &OS) override;
599 void outputPost(OutputStream &OS) override;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000600
601 // Either NextDimension or ElementType will be valid.
Zachary Turnerdbefc6c2018-08-10 14:31:04 +0000602 ArrayDimension *Dims = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000603
604 Type *ElementType = nullptr;
605};
606
607} // namespace
608
Zachary Turnerd742d642018-07-26 19:56:09 +0000609static bool isMemberPointer(StringView MangledName) {
610 switch (MangledName.popFront()) {
Zachary Turner931e8792018-07-30 23:02:10 +0000611 case '$':
612 // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
613 // rvalue reference to a member.
614 return false;
Zachary Turnerd742d642018-07-26 19:56:09 +0000615 case 'A':
616 // 'A' indicates a reference, and you cannot have a reference to a member
Zachary Turner931e8792018-07-30 23:02:10 +0000617 // function or member.
Zachary Turnerd742d642018-07-26 19:56:09 +0000618 return false;
619 case 'P':
620 case 'Q':
621 case 'R':
622 case 'S':
623 // These 4 values indicate some kind of pointer, but we still don't know
624 // what.
625 break;
626 default:
627 assert(false && "Ty is not a pointer type!");
628 }
629
630 // If it starts with a number, then 6 indicates a non-member function
631 // pointer, and 8 indicates a member function pointer.
632 if (startsWithDigit(MangledName)) {
633 assert(MangledName[0] == '6' || MangledName[0] == '8');
634 return (MangledName[0] == '8');
635 }
636
637 // Remove ext qualifiers since those can appear on either type and are
638 // therefore not indicative.
639 MangledName.consumeFront('E'); // 64-bit
640 MangledName.consumeFront('I'); // restrict
641 MangledName.consumeFront('F'); // unaligned
642
643 assert(!MangledName.empty());
644
645 // The next value should be either ABCD (non-member) or QRST (member).
646 switch (MangledName.front()) {
647 case 'A':
648 case 'B':
649 case 'C':
650 case 'D':
651 return false;
652 case 'Q':
653 case 'R':
654 case 'S':
655 case 'T':
656 return true;
657 default:
658 assert(false);
659 }
660 return false;
661}
662
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000663static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
664 outputSpaceIfNecessary(OS);
665
666 switch (CC) {
667 case CallingConv::Cdecl:
668 OS << "__cdecl";
669 break;
670 case CallingConv::Fastcall:
671 OS << "__fastcall";
672 break;
673 case CallingConv::Pascal:
674 OS << "__pascal";
675 break;
676 case CallingConv::Regcall:
677 OS << "__regcall";
678 break;
679 case CallingConv::Stdcall:
680 OS << "__stdcall";
681 break;
682 case CallingConv::Thiscall:
683 OS << "__thiscall";
684 break;
685 case CallingConv::Eabi:
686 OS << "__eabi";
687 break;
688 case CallingConv::Vectorcall:
689 OS << "__vectorcall";
690 break;
691 case CallingConv::Clrcall:
692 OS << "__clrcall";
693 break;
694 default:
695 break;
696 }
697}
698
Zachary Turner71c91f92018-07-30 03:12:34 +0000699static bool startsWithLocalScopePattern(StringView S) {
700 if (!S.consumeFront('?'))
701 return false;
702 if (S.size() < 2)
703 return false;
704
705 size_t End = S.find('?');
706 if (End == StringView::npos)
707 return false;
708 StringView Candidate = S.substr(0, End);
709 if (Candidate.empty())
710 return false;
711
712 // \?[0-9]\?
713 // ?@? is the discriminator 0.
714 if (Candidate.size() == 1)
715 return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
716
717 // If it's not 0-9, then it's an encoded number terminated with an @
718 if (Candidate.back() != '@')
719 return false;
720 Candidate = Candidate.dropBack();
721
722 // An encoded number starts with B-P and all subsequent digits are in A-P.
723 // Note that the reason the first digit cannot be A is two fold. First, it
724 // would create an ambiguity with ?A which delimits the beginning of an
725 // anonymous namespace. Second, A represents 0, and you don't start a multi
726 // digit number with a leading 0. Presumably the anonymous namespace
727 // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
728 if (Candidate[0] < 'B' || Candidate[0] > 'P')
729 return false;
730 Candidate = Candidate.dropFront();
731 while (!Candidate.empty()) {
732 if (Candidate[0] < 'A' || Candidate[0] > 'P')
733 return false;
734 Candidate = Candidate.dropFront();
735 }
736
737 return true;
738}
739
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000740// Write a function or template parameter list.
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000741static void outputParameterList(OutputStream &OS,
742 const FunctionParams &Params) {
Zachary Turnerd30700f2018-07-31 17:16:44 +0000743 if (!Params.Current) {
744 OS << "void";
Zachary Turner38b78a72018-07-26 20:20:10 +0000745 return;
746 }
747
Zachary Turnerd30700f2018-07-31 17:16:44 +0000748 const FunctionParams *Head = &Params;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000749 while (Head) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000750 Type::outputPre(OS, *Head->Current);
751 Type::outputPost(OS, *Head->Current);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000752
753 Head = Head->Next;
754
755 if (Head)
756 OS << ", ";
757 }
758}
759
Zachary Turner3461bfa2018-08-17 16:14:05 +0000760static void outputStringLiteral(OutputStream &OS, const StringLiteral &Str) {
761 switch (Str.CharType) {
Zachary Turner970fdc32018-08-16 16:17:36 +0000762 case PrimTy::Wchar:
763 OS << "const wchar_t * {L\"";
764 break;
765 case PrimTy::Char:
766 OS << "const char * {\"";
767 break;
768 case PrimTy::Char16:
769 OS << "const char16_t * {u\"";
770 break;
771 case PrimTy::Char32:
772 OS << "const char32_t * {U\"";
773 break;
774 default:
775 LLVM_BUILTIN_UNREACHABLE;
776 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000777 OS << Str.Str << "\"";
778 if (Str.IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +0000779 OS << "...";
780 OS << "}";
781}
782
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000783static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty);
Zachary Turner172aea12018-08-02 17:08:03 +0000784
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000785static void outputParameterList(OutputStream &OS,
786 const TemplateParams &Params) {
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) {
Zachary Turner66555a72018-08-20 19:15:35 +0000803 if (Head->NullptrLiteral)
804 OS << "nullptr";
805 else {
806 if (Head->ThunkOffsetCount > 0)
807 OS << "{";
808 else if (Head->PointerToSymbol)
809 OS << "&";
810 if (Head->ParamType)
811 Type::outputPre(OS, *Head->ParamType);
812 outputName(OS, Head->ParamName, Head->ParamType);
813 if (Head->ParamType)
814 Type::outputPost(OS, *Head->ParamType);
815 if (Head->ThunkOffsetCount > 0) {
816 for (int I = 0; I < Head->ThunkOffsetCount; ++I) {
817 OS << ", " << Head->ThunkOffsets[I];
818 }
819 OS << "}";
820 }
821 }
822 } else if (Head->DataMemberPointer) {
823 OS << "{" << Head->ThunkOffsets[0];
824 for (int I = 1; I < Head->ThunkOffsetCount; ++I)
825 OS << ", " << Head->ThunkOffsets[I];
826 OS << "}";
Zachary Turnerd30700f2018-07-31 17:16:44 +0000827 } else if (Head->ParamType) {
828 // simple type.
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000829 Type::outputPre(OS, *Head->ParamType);
830 Type::outputPost(OS, *Head->ParamType);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000831 } else {
832 // Template alias.
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000833 outputName(OS, Head->ParamName, Head->ParamType);
Zachary Turnerd30700f2018-07-31 17:16:44 +0000834 }
835
836 Head = Head->Next;
837
838 if (Head)
839 OS << ", ";
840 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000841 OS << ">";
842}
843
Zachary Turner469f0762018-08-17 21:18:05 +0000844static void outputQualifiers(OutputStream &OS, Qualifiers Q) {
845 if (Q & Q_Const) {
846 outputSpaceIfNecessary(OS);
847 OS << "const";
848 }
849
850 if (Q & Q_Volatile) {
851 outputSpaceIfNecessary(OS);
852 OS << "volatile";
853 }
854
855 if (Q & Q_Restrict) {
856 outputSpaceIfNecessary(OS);
857 OS << "__restrict";
858 }
859}
860
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000861static void outputNameComponent(OutputStream &OS, const Name &N) {
862 OS << N.Str;
Zachary Turner3461bfa2018-08-17 16:14:05 +0000863
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000864 if (N.IsTemplateInstantiation && N.TParams)
865 outputParameterList(OS, *N.TParams);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000866}
867
Zachary Turner66555a72018-08-20 19:15:35 +0000868static const OperatorInfo *lastComponentAsOperator(const Name *TheName) {
869 if (!TheName)
870 return nullptr;
871 while (TheName->Next)
872 TheName = TheName->Next;
873 if (TheName->IsOperator)
874 return static_cast<const OperatorInfo *>(TheName);
875 return nullptr;
876}
877
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000878static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000879 if (!TheName)
880 return;
881
882 outputSpaceIfNecessary(OS);
883
Zachary Turner66555a72018-08-20 19:15:35 +0000884 const OperatorInfo *Operator = lastComponentAsOperator(TheName);
885 const VirtualMemberPtrThunk *Thunk = nullptr;
886 if (Operator) {
887 if (Operator->Info->Operator == OperatorTy::Vcall) {
888 Thunk = static_cast<const VirtualMemberPtrThunk *>(Operator);
889 OS << "[thunk]: ";
890 outputCallingConvention(OS, Thunk->CC);
891 OS << " ";
892 }
893 }
894
Zachary Turnera7dffb12018-07-28 22:10:42 +0000895 const Name *Previous = nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000896 // Print out namespaces or outer class BackReferences.
897 for (; TheName->Next; TheName = TheName->Next) {
Zachary Turnera7dffb12018-07-28 22:10:42 +0000898 Previous = TheName;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000899 outputNameComponent(OS, *TheName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000900 OS << "::";
901 }
902
903 // Print out a regular name.
Zachary Turner44ebbc22018-08-01 18:32:47 +0000904 if (!TheName->IsOperator) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000905 outputNameComponent(OS, *TheName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000906 return;
907 }
908
Zachary Turner3461bfa2018-08-17 16:14:05 +0000909
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000910 // Print out ctor or dtor.
Zachary Turner66555a72018-08-20 19:15:35 +0000911 switch (Operator->Info->Operator) {
Zachary Turner3461bfa2018-08-17 16:14:05 +0000912 case OperatorTy::Dtor:
Zachary Turnera7dffb12018-07-28 22:10:42 +0000913 OS << "~";
Zachary Turner3461bfa2018-08-17 16:14:05 +0000914 LLVM_FALLTHROUGH;
915 case OperatorTy::Ctor:
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000916 outputNameComponent(OS, *Previous);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000917 break;
918 case OperatorTy::Conversion:
Zachary Turnera17721c2018-08-10 15:04:56 +0000919 OS << "operator";
920 if (TheName->IsTemplateInstantiation && TheName->TParams)
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000921 outputParameterList(OS, *TheName->TParams);
Zachary Turnera17721c2018-08-10 15:04:56 +0000922 OS << " ";
923 if (Ty) {
924 const FunctionType *FTy = static_cast<const FunctionType *>(Ty);
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000925 Type::outputPre(OS, *FTy->ReturnType);
926 Type::outputPost(OS, *FTy->ReturnType);
Zachary Turnera17721c2018-08-10 15:04:56 +0000927 } else {
928 OS << "<conversion>";
929 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000930 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +0000931 case OperatorTy::LiteralOperator:
Zachary Turner66555a72018-08-20 19:15:35 +0000932 OS << Operator->Info->Name;
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000933 outputNameComponent(OS, *TheName);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000934 break;
Zachary Turner469f0762018-08-17 21:18:05 +0000935 case OperatorTy::RttiBaseClassDescriptor: {
936 const RttiBaseClassDescriptor &BCD =
Zachary Turner66555a72018-08-20 19:15:35 +0000937 static_cast<const RttiBaseClassDescriptor &>(*Operator);
938 OS << "`" << Operator->Info->Name << " at (";
Zachary Turner469f0762018-08-17 21:18:05 +0000939 OS << BCD.NVOffset << ", " << BCD.VBPtrOffset << ", " << BCD.VBTableOffset
940 << ", " << BCD.Flags;
941 OS << ")'";
942 break;
943 }
Zachary Turner66555a72018-08-20 19:15:35 +0000944 case OperatorTy::Vcall: {
945 OS << "`vcall'{";
946 OS << Thunk->OffsetInVTable << ", {flat}}";
947 break;
948 }
949
Zachary Turner469f0762018-08-17 21:18:05 +0000950 case OperatorTy::LocalStaticGuard: {
951 const LocalStaticGuardVariable &LSG =
Zachary Turner66555a72018-08-20 19:15:35 +0000952 static_cast<const LocalStaticGuardVariable &>(*Operator);
953 OS << Operator->Info->Name;
Zachary Turner469f0762018-08-17 21:18:05 +0000954 if (LSG.ScopeIndex > 0)
955 OS << "{" << LSG.ScopeIndex << "}";
956 break;
957 }
Zachary Turner3461bfa2018-08-17 16:14:05 +0000958 default:
Zachary Turner66555a72018-08-20 19:15:35 +0000959 OS << Operator->Info->Name;
960 if (Operator->IsTemplateInstantiation)
961 outputParameterList(OS, *Operator->TParams);
Zachary Turner3461bfa2018-08-17 16:14:05 +0000962 break;
Zachary Turnera17721c2018-08-10 15:04:56 +0000963 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +0000964}
965
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000966static void outputSpecialOperator(OutputStream &OS, const Name *OuterName) {
Zachary Turner469f0762018-08-17 21:18:05 +0000967 assert(OuterName);
968 // The last component should be an operator.
Zachary Turner66555a72018-08-20 19:15:35 +0000969 const OperatorInfo *Operator = lastComponentAsOperator(OuterName);
Zachary Turner469f0762018-08-17 21:18:05 +0000970
Zachary Turner66555a72018-08-20 19:15:35 +0000971 assert(Operator->IsOperator);
972 const OperatorInfo &Oper = static_cast<const OperatorInfo &>(*Operator);
Zachary Turner469f0762018-08-17 21:18:05 +0000973 switch (Oper.Info->Operator) {
974 case OperatorTy::StringLiteral: {
975 const StringLiteral &SL = static_cast<const StringLiteral &>(Oper);
976 outputStringLiteral(OS, SL);
977 break;
978 }
979 case OperatorTy::Vcall: {
Zachary Turner469f0762018-08-17 21:18:05 +0000980 const VirtualMemberPtrThunk &Thunk =
981 static_cast<const VirtualMemberPtrThunk &>(Oper);
982 OS << "[thunk]: ";
983 outputCallingConvention(OS, Thunk.CC);
984 OS << " ";
985 // Print out namespaces or outer class BackReferences.
986 const Name *N = OuterName;
987 for (; N->Next; N = N->Next) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +0000988 outputNameComponent(OS, *N);
Zachary Turner469f0762018-08-17 21:18:05 +0000989 OS << "::";
990 }
991 OS << "`vcall'{";
992 OS << Thunk.OffsetInVTable << ", {flat}}";
993 break;
994 }
995 default:
996 // There are no other special operator categories.
997 LLVM_BUILTIN_UNREACHABLE;
998 }
999}
1000
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001001namespace {
1002
Zachary Turner3461bfa2018-08-17 16:14:05 +00001003bool Name::isStringLiteralOperatorInfo() const {
1004 if (!IsOperator)
1005 return false;
1006 const OperatorInfo &O = static_cast<const OperatorInfo &>(*this);
1007 return O.Info->Operator == OperatorTy::StringLiteral;
1008}
1009
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001010Type *Type::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001011 return Arena.alloc<Type>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001012}
1013
1014// Write the "first half" of a given type.
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001015void Type::outputPre(OutputStream &OS, Type &Ty) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001016 // Function types require custom handling of const and static so we
1017 // handle them separately. All other types use the same decoration
1018 // for these modifiers, so handle them here in common code.
1019 if (Ty.Prim == PrimTy::Function) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001020 Ty.outputPre(OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001021 return;
1022 }
1023
1024 switch (Ty.Storage) {
1025 case StorageClass::PrivateStatic:
1026 case StorageClass::PublicStatic:
1027 case StorageClass::ProtectedStatic:
1028 OS << "static ";
1029 default:
1030 break;
1031 }
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001032 Ty.outputPre(OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001033
Zachary Turner469f0762018-08-17 21:18:05 +00001034 outputQualifiers(OS, Ty.Quals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001035}
1036
1037// Write the "second half" of a given type.
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001038void Type::outputPost(OutputStream &OS, Type &Ty) { Ty.outputPost(OS); }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001039
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001040void Type::outputPre(OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001041 switch (Prim) {
1042 case PrimTy::Void:
1043 OS << "void";
1044 break;
1045 case PrimTy::Bool:
1046 OS << "bool";
1047 break;
1048 case PrimTy::Char:
1049 OS << "char";
1050 break;
1051 case PrimTy::Schar:
1052 OS << "signed char";
1053 break;
1054 case PrimTy::Uchar:
1055 OS << "unsigned char";
1056 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001057 case PrimTy::Char16:
1058 OS << "char16_t";
1059 break;
1060 case PrimTy::Char32:
1061 OS << "char32_t";
1062 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001063 case PrimTy::Short:
1064 OS << "short";
1065 break;
1066 case PrimTy::Ushort:
1067 OS << "unsigned short";
1068 break;
1069 case PrimTy::Int:
1070 OS << "int";
1071 break;
1072 case PrimTy::Uint:
1073 OS << "unsigned int";
1074 break;
1075 case PrimTy::Long:
1076 OS << "long";
1077 break;
1078 case PrimTy::Ulong:
1079 OS << "unsigned long";
1080 break;
1081 case PrimTy::Int64:
1082 OS << "__int64";
1083 break;
1084 case PrimTy::Uint64:
1085 OS << "unsigned __int64";
1086 break;
1087 case PrimTy::Wchar:
1088 OS << "wchar_t";
1089 break;
1090 case PrimTy::Float:
1091 OS << "float";
1092 break;
1093 case PrimTy::Double:
1094 OS << "double";
1095 break;
1096 case PrimTy::Ldouble:
1097 OS << "long double";
1098 break;
Zachary Turner931e8792018-07-30 23:02:10 +00001099 case PrimTy::Nullptr:
1100 OS << "std::nullptr_t";
1101 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001102 case PrimTy::Vbtable:
1103 case PrimTy::Vftable:
1104 break;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001105 default:
1106 assert(false && "Invalid primitive type!");
1107 }
1108}
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001109void Type::outputPost(OutputStream &OS) {}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001110
1111Type *PointerType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001112 return Arena.alloc<PointerType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001113}
1114
Zachary Turner024e1762018-07-26 20:33:48 +00001115static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001116 const Name *MemberName,
1117 const Type *Pointee) {
Zachary Turner024e1762018-07-26 20:33:48 +00001118 // "[]" and "()" (for function parameters) take precedence over "*",
1119 // so "int *x(int)" means "x is a function returning int *". We need
1120 // parentheses to supercede the default precedence. (e.g. we want to
1121 // emit something like "int (*x)(int)".)
1122 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
1123 OS << "(";
1124 if (Pointee->Prim == PrimTy::Function) {
1125 const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
1126 assert(FTy->IsFunctionPointer);
1127 outputCallingConvention(OS, FTy->CallConvention);
1128 OS << " ";
1129 }
1130 }
1131
1132 if (MemberName) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001133 outputName(OS, MemberName, Pointee);
Zachary Turner024e1762018-07-26 20:33:48 +00001134 OS << "::";
1135 }
1136
1137 if (Affinity == PointerAffinity::Pointer)
1138 OS << "*";
Zachary Turner931e8792018-07-30 23:02:10 +00001139 else if (Affinity == PointerAffinity::Reference)
Zachary Turner024e1762018-07-26 20:33:48 +00001140 OS << "&";
Zachary Turner931e8792018-07-30 23:02:10 +00001141 else
1142 OS << "&&";
Zachary Turner024e1762018-07-26 20:33:48 +00001143}
1144
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001145void PointerType::outputPre(OutputStream &OS) {
1146 Type::outputPre(OS, *Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001147
1148 outputSpaceIfNecessary(OS);
1149
1150 if (Quals & Q_Unaligned)
1151 OS << "__unaligned ";
1152
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001153 outputPointerIndicator(OS, Affinity, nullptr, Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001154
Zachary Turner91ecedd2018-07-20 18:07:33 +00001155 // FIXME: We should output this, but it requires updating lots of tests.
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001156 // if (Ty.Quals & Q_Pointer64)
1157 // OS << " __ptr64";
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001158}
1159
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001160void PointerType::outputPost(OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001161 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
1162 OS << ")";
1163
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001164 Type::outputPost(OS, *Pointee);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001165}
1166
Zachary Turnerd742d642018-07-26 19:56:09 +00001167Type *MemberPointerType::clone(ArenaAllocator &Arena) const {
1168 return Arena.alloc<MemberPointerType>(*this);
1169}
1170
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001171void MemberPointerType::outputPre(OutputStream &OS) {
1172 Type::outputPre(OS, *Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +00001173
1174 outputSpaceIfNecessary(OS);
1175
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001176 outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +00001177
1178 // FIXME: We should output this, but it requires updating lots of tests.
1179 // if (Ty.Quals & Q_Pointer64)
1180 // OS << " __ptr64";
Zachary Turnerd742d642018-07-26 19:56:09 +00001181}
1182
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001183void MemberPointerType::outputPost(OutputStream &OS) {
Zachary Turnerd742d642018-07-26 19:56:09 +00001184 if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
1185 OS << ")";
1186
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001187 Type::outputPost(OS, *Pointee);
Zachary Turnerd742d642018-07-26 19:56:09 +00001188}
1189
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001190Type *FunctionType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001191 return Arena.alloc<FunctionType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001192}
1193
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001194void FunctionType::outputPre(OutputStream &OS) {
Zachary Turner469f0762018-08-17 21:18:05 +00001195 if ((FunctionClass & StaticThisAdjust) || (FunctionClass & VirtualThisAdjust))
1196 OS << "[thunk]: ";
1197
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001198 if (!(FunctionClass & Global)) {
1199 if (FunctionClass & Static)
1200 OS << "static ";
1201 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001202 if (FunctionClass & ExternC)
Zachary Turner29ec67b2018-08-10 21:09:05 +00001203 OS << "extern \"C\" ";
Zachary Turner3461bfa2018-08-17 16:14:05 +00001204
1205 if (FunctionClass & Virtual)
1206 OS << "virtual ";
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001207
Zachary Turner38b78a72018-07-26 20:20:10 +00001208 if (ReturnType) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001209 Type::outputPre(OS, *ReturnType);
Zachary Turner38b78a72018-07-26 20:20:10 +00001210 OS << " ";
1211 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001212
Zachary Turner024e1762018-07-26 20:33:48 +00001213 // Function pointers print the calling convention as void (__cdecl *)(params)
1214 // rather than void __cdecl (*)(params). So we need to let the PointerType
1215 // class handle this.
1216 if (!IsFunctionPointer)
1217 outputCallingConvention(OS, CallConvention);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001218}
1219
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001220void FunctionType::outputPost(OutputStream &OS) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00001221 // extern "C" functions don't have a prototype.
1222 if (FunctionClass & NoPrototype)
1223 return;
1224
Zachary Turner4746aa72018-08-17 21:32:07 +00001225 if (FunctionClass & StaticThisAdjust) {
1226 OS << "`adjustor{" << ThisAdjust->StaticOffset << "}'";
1227 } else if (FunctionClass & VirtualThisAdjust) {
1228 if (FunctionClass & VirtualThisAdjustEx) {
1229 OS << "`vtordispex{" << ThisAdjust->VBPtrOffset << ", "
1230 << ThisAdjust->VBOffsetOffset << ", " << ThisAdjust->VtordispOffset
1231 << ", " << ThisAdjust->StaticOffset << "}'";
1232 } else {
1233 OS << "`vtordisp{" << ThisAdjust->VtordispOffset << ", "
1234 << ThisAdjust->StaticOffset << "}'";
1235 }
Zachary Turner469f0762018-08-17 21:18:05 +00001236 }
1237
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001238 OS << "(";
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001239 outputParameterList(OS, Params);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001240 OS << ")";
1241 if (Quals & Q_Const)
1242 OS << " const";
1243 if (Quals & Q_Volatile)
1244 OS << " volatile";
Zachary Turner931e8792018-07-30 23:02:10 +00001245 if (Quals & Q_Restrict)
1246 OS << " __restrict";
1247 if (Quals & Q_Unaligned)
1248 OS << " __unaligned";
1249
1250 if (RefKind == ReferenceKind::LValueRef)
1251 OS << " &";
1252 else if (RefKind == ReferenceKind::RValueRef)
1253 OS << " &&";
Zachary Turner38b78a72018-07-26 20:20:10 +00001254
1255 if (ReturnType)
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001256 Type::outputPost(OS, *ReturnType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001257 return;
1258}
1259
1260Type *UdtType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001261 return Arena.alloc<UdtType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001262}
1263
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001264void UdtType::outputPre(OutputStream &OS) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001265 switch (Prim) {
1266 case PrimTy::Class:
1267 OS << "class ";
1268 break;
1269 case PrimTy::Struct:
1270 OS << "struct ";
1271 break;
1272 case PrimTy::Union:
1273 OS << "union ";
1274 break;
1275 case PrimTy::Enum:
1276 OS << "enum ";
1277 break;
1278 default:
1279 assert(false && "Not a udt type!");
1280 }
1281
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001282 outputName(OS, UdtName, this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001283}
1284
1285Type *ArrayType::clone(ArenaAllocator &Arena) const {
Zachary Turner9d72aa92018-07-20 18:35:06 +00001286 return Arena.alloc<ArrayType>(*this);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001287}
1288
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001289void ArrayType::outputPre(OutputStream &OS) {
1290 Type::outputPre(OS, *ElementType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001291}
1292
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001293void ArrayType::outputPost(OutputStream &OS) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001294 ArrayDimension *D = Dims;
1295 while (D) {
1296 OS << "[";
1297 if (D->Dim > 0)
1298 OS << D->Dim;
1299 OS << "]";
1300 D = D->Next;
1301 }
1302
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001303 Type::outputPost(OS, *ElementType);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001304}
1305
Zachary Turner316109b2018-07-29 16:38:02 +00001306struct Symbol {
Zachary Turner44ebbc22018-08-01 18:32:47 +00001307 SymbolCategory Category;
1308
Zachary Turner469f0762018-08-17 21:18:05 +00001309 Qualifiers SymbolQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001310 Name *SymbolName = nullptr;
1311 Type *SymbolType = nullptr;
1312};
1313
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001314} // namespace
1315
1316namespace {
1317
Zachary Turnerd346cba2018-08-08 17:17:04 +00001318struct BackrefContext {
1319 static constexpr size_t Max = 10;
1320
1321 Type *FunctionParams[Max];
1322 size_t FunctionParamCount = 0;
1323
1324 // The first 10 BackReferences in a mangled name can be back-referenced by
1325 // special name @[0-9]. This is a storage for the first 10 BackReferences.
1326 StringView Names[Max];
1327 size_t NamesCount = 0;
1328};
1329
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001330// Demangler class takes the main role in demangling symbols.
1331// It has a set of functions to parse mangled symbols into Type instances.
1332// It also has a set of functions to cnovert Type instances to strings.
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001333class Demangler {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001334public:
Zachary Turner316109b2018-07-29 16:38:02 +00001335 Demangler() = default;
Zachary Turner5b0456d2018-08-02 17:18:01 +00001336 virtual ~Demangler() = default;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001337
1338 // You are supposed to call parse() first and then check if error is true. If
1339 // it is false, call output() to write the formatted name to the given stream.
Zachary Turner316109b2018-07-29 16:38:02 +00001340 Symbol *parse(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001341 Symbol *parseOperator(StringView &MangledName);
1342
Zachary Turner316109b2018-07-29 16:38:02 +00001343 void output(const Symbol *S, OutputStream &OS);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001344
1345 // True if an error occurred.
1346 bool Error = false;
1347
Zachary Turner3a758e22018-08-01 18:33:04 +00001348 void dumpBackReferences();
1349
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001350private:
Zachary Turner469f0762018-08-17 21:18:05 +00001351 std::pair<SymbolCategory, Type *>
1352 demangleSymbolCategoryAndType(StringView &MangledName);
1353
1354 Type *demangleVariableEncoding(StringView &MangledName, StorageClass SC);
Zachary Turner316109b2018-07-29 16:38:02 +00001355 Type *demangleFunctionEncoding(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001356 uint64_t demangleThunkThisAdjust(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001357
Zachary Turner316109b2018-07-29 16:38:02 +00001358 Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001359
1360 // Parser functions. This is a recursive-descent parser.
Zachary Turner316109b2018-07-29 16:38:02 +00001361 Type *demangleType(StringView &MangledName, QualifierMangleMode QMM);
1362 Type *demangleBasicType(StringView &MangledName);
1363 UdtType *demangleClassType(StringView &MangledName);
1364 PointerType *demanglePointerType(StringView &MangledName);
1365 MemberPointerType *demangleMemberPointerType(StringView &MangledName);
1366 FunctionType *demangleFunctionType(StringView &MangledName, bool HasThisQuals,
1367 bool IsFunctionPointer);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001368
Zachary Turner316109b2018-07-29 16:38:02 +00001369 ArrayType *demangleArrayType(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001370
Zachary Turnerd30700f2018-07-31 17:16:44 +00001371 TemplateParams *demangleTemplateParameterList(StringView &MangledName);
1372 FunctionParams demangleFunctionParameterList(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001373
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001374 std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00001375 uint64_t demangleUnsigned(StringView &MangledName);
1376 int64_t demangleSigned(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001377
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001378 void memorizeString(StringView s);
Zachary Turner71c91f92018-07-30 03:12:34 +00001379
1380 /// Allocate a copy of \p Borrowed into memory that we own.
1381 StringView copyString(StringView Borrowed);
1382
Zachary Turner316109b2018-07-29 16:38:02 +00001383 Name *demangleFullyQualifiedTypeName(StringView &MangledName);
1384 Name *demangleFullyQualifiedSymbolName(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001385
Zachary Turner44ebbc22018-08-01 18:32:47 +00001386 Name *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001387 Name *demangleUnqualifiedSymbolName(StringView &MangledName,
1388 NameBackrefBehavior NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001389
Zachary Turner316109b2018-07-29 16:38:02 +00001390 Name *demangleNameScopeChain(StringView &MangledName, Name *UnqualifiedName);
1391 Name *demangleNameScopePiece(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001392
Zachary Turner316109b2018-07-29 16:38:02 +00001393 Name *demangleBackRefName(StringView &MangledName);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001394 Name *demangleTemplateInstantiationName(StringView &MangledName,
1395 NameBackrefBehavior NBB);
Zachary Turner469f0762018-08-17 21:18:05 +00001396 std::pair<OperatorTy, Name *> demangleOperatorName(StringView &MangledName,
1397 bool FullyQualified);
Zachary Turner316109b2018-07-29 16:38:02 +00001398 Name *demangleSimpleName(StringView &MangledName, bool Memorize);
1399 Name *demangleAnonymousNamespaceName(StringView &MangledName);
Zachary Turner71c91f92018-07-30 03:12:34 +00001400 Name *demangleLocallyScopedNamePiece(StringView &MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001401 StringLiteral *demangleStringLiteral(StringView &MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001402
Zachary Turner931e8792018-07-30 23:02:10 +00001403 StringView demangleSimpleString(StringView &MangledName, bool Memorize);
1404
Zachary Turner316109b2018-07-29 16:38:02 +00001405 FuncClass demangleFunctionClass(StringView &MangledName);
1406 CallingConv demangleCallingConvention(StringView &MangledName);
1407 StorageClass demangleVariableStorageClass(StringView &MangledName);
1408 ReferenceKind demangleReferenceKind(StringView &MangledName);
1409 void demangleThrowSpecification(StringView &MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001410 wchar_t demangleWcharLiteral(StringView &MangledName);
1411 uint8_t demangleCharLiteral(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001412
Zachary Turner316109b2018-07-29 16:38:02 +00001413 std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001414
1415 // Memory allocator.
1416 ArenaAllocator Arena;
1417
Zachary Turner23df1312018-07-26 22:13:39 +00001418 // A single type uses one global back-ref table for all function params.
1419 // This means back-refs can even go "into" other types. Examples:
1420 //
1421 // // Second int* is a back-ref to first.
1422 // void foo(int *, int*);
1423 //
1424 // // Second int* is not a back-ref to first (first is not a function param).
1425 // int* foo(int*);
1426 //
1427 // // Second int* is a back-ref to first (ALL function types share the same
1428 // // back-ref map.
1429 // using F = void(*)(int*);
1430 // F G(int *);
Zachary Turnerd346cba2018-08-08 17:17:04 +00001431 BackrefContext Backrefs;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001432};
1433} // namespace
1434
Zachary Turner71c91f92018-07-30 03:12:34 +00001435StringView Demangler::copyString(StringView Borrowed) {
1436 char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
1437 std::strcpy(Stable, Borrowed.begin());
1438
1439 return {Stable, Borrowed.size()};
1440}
1441
Zachary Turner469f0762018-08-17 21:18:05 +00001442Symbol *Demangler::parseOperator(StringView &MangledName) {
Zachary Turner316109b2018-07-29 16:38:02 +00001443 Symbol *S = Arena.alloc<Symbol>();
1444
Zachary Turner469f0762018-08-17 21:18:05 +00001445 bool IsMember = false;
1446 OperatorTy OTy;
1447 std::tie(OTy, S->SymbolName) = demangleOperatorName(MangledName, true);
1448 switch (OTy) {
1449 case OperatorTy::StringLiteral:
Zachary Turner469f0762018-08-17 21:18:05 +00001450 S->Category = SymbolCategory::SpecialOperator;
1451 break;
Zachary Turner66555a72018-08-20 19:15:35 +00001452 case OperatorTy::Vcall:
1453 S->Category = SymbolCategory::UnnamedFunction;
1454 break;
1455 case OperatorTy::LocalStaticGuard:
1456 S->Category = SymbolCategory::UnnamedVariable;
1457 break;
Zachary Turner469f0762018-08-17 21:18:05 +00001458 case OperatorTy::Vftable: // Foo@@6B@
1459 case OperatorTy::LocalVftable: // Foo@@6B@
1460 case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@
1461 case OperatorTy::Vbtable: // Foo@@7B@
1462 S->Category = SymbolCategory::UnnamedVariable;
1463 switch (MangledName.popFront()) {
1464 case '6':
1465 case '7':
1466 std::tie(S->SymbolQuals, IsMember) = demangleQualifiers(MangledName);
1467 if (!MangledName.consumeFront('@'))
1468 Error = true;
1469 break;
1470 default:
1471 Error = true;
1472 break;
1473 }
1474 break;
1475 case OperatorTy::RttiTypeDescriptor: // <type>@@8
1476 S->Category = SymbolCategory::UnnamedVariable;
1477 S->SymbolType = demangleType(MangledName, QualifierMangleMode::Result);
1478 if (Error)
1479 break;
1480 if (!MangledName.consumeFront("@8"))
1481 Error = true;
1482 if (!MangledName.empty())
1483 Error = true;
1484 break;
Zachary Turner469f0762018-08-17 21:18:05 +00001485 default:
1486 if (!Error)
1487 std::tie(S->Category, S->SymbolType) =
1488 demangleSymbolCategoryAndType(MangledName);
1489 break;
1490 }
1491
1492 return (Error) ? nullptr : S;
1493}
1494
1495std::pair<SymbolCategory, Type *>
1496Demangler::demangleSymbolCategoryAndType(StringView &MangledName) {
1497 // Read a variable.
1498 switch (MangledName.front()) {
1499 case '0':
1500 case '1':
1501 case '2':
1502 case '3':
1503 case '4':
1504 return std::make_pair(
1505 SymbolCategory::NamedVariable,
1506 demangleVariableEncoding(MangledName,
1507 demangleVariableStorageClass(MangledName)));
1508 case '8':
1509 MangledName.consumeFront('8');
1510 return std::pair<SymbolCategory, Type *>(SymbolCategory::UnnamedVariable,
1511 nullptr);
1512 }
1513 return std::make_pair(SymbolCategory::NamedFunction,
1514 demangleFunctionEncoding(MangledName));
1515}
1516
1517// Parser entry point.
1518Symbol *Demangler::parse(StringView &MangledName) {
Zachary Turner83313f82018-08-16 16:17:17 +00001519 // We can't demangle MD5 names, just output them as-is.
Zachary Turner469f0762018-08-17 21:18:05 +00001520 // Also, MSVC-style mangled symbols must start with '?'.
1521 if (MangledName.startsWith("??@") || !MangledName.startsWith('?')) {
1522 Symbol *S = Arena.alloc<Symbol>();
Zachary Turner83313f82018-08-16 16:17:17 +00001523 S->Category = SymbolCategory::Unknown;
1524 S->SymbolName = Arena.alloc<Name>();
1525 S->SymbolName->Str = MangledName;
Zachary Turner970fdc32018-08-16 16:17:36 +00001526 S->SymbolType = nullptr;
Zachary Turner83313f82018-08-16 16:17:17 +00001527 MangledName = StringView();
1528 return S;
1529 }
1530
Zachary Turner469f0762018-08-17 21:18:05 +00001531 MangledName.consumeFront('?');
Zachary Turner970fdc32018-08-16 16:17:36 +00001532
Zachary Turner469f0762018-08-17 21:18:05 +00001533 // ?$ is a template instantiation, but all other names that start with ? are
1534 // operators / special names.
1535 if (MangledName.startsWith('?') && !MangledName.startsWith("?$"))
1536 return parseOperator(MangledName);
1537
1538 Symbol *S = Arena.alloc<Symbol>();
1539 // What follows is a main symbol name. This may include namespaces or class
1540 // back references.
Zachary Turner316109b2018-07-29 16:38:02 +00001541 S->SymbolName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001542 if (Error)
1543 return nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001544
Zachary Turner469f0762018-08-17 21:18:05 +00001545 std::tie(S->Category, S->SymbolType) =
1546 demangleSymbolCategoryAndType(MangledName);
Zachary Turner44ebbc22018-08-01 18:32:47 +00001547
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001548 if (Error)
1549 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001550
Zachary Turner316109b2018-07-29 16:38:02 +00001551 return S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001552}
1553
1554// <type-encoding> ::= <storage-class> <variable-type>
1555// <storage-class> ::= 0 # private static member
1556// ::= 1 # protected static member
1557// ::= 2 # public static member
1558// ::= 3 # global
1559// ::= 4 # static local
1560
Zachary Turner469f0762018-08-17 21:18:05 +00001561Type *Demangler::demangleVariableEncoding(StringView &MangledName,
1562 StorageClass SC) {
Zachary Turner316109b2018-07-29 16:38:02 +00001563 Type *Ty = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001564
1565 Ty->Storage = SC;
1566
1567 // <variable-type> ::= <type> <cvr-qualifiers>
1568 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1569 switch (Ty->Prim) {
1570 case PrimTy::Ptr:
Zachary Turnerd742d642018-07-26 19:56:09 +00001571 case PrimTy::MemberPtr: {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001572 Qualifiers ExtraChildQuals = Q_None;
Zachary Turner316109b2018-07-29 16:38:02 +00001573 Ty->Quals =
1574 Qualifiers(Ty->Quals | demanglePointerExtQualifiers(MangledName));
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001575
Zachary Turnerd742d642018-07-26 19:56:09 +00001576 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00001577 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001578
Zachary Turnerd742d642018-07-26 19:56:09 +00001579 if (Ty->Prim == PrimTy::MemberPtr) {
1580 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00001581 Name *BackRefName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001582 (void)BackRefName;
Zachary Turnerd742d642018-07-26 19:56:09 +00001583 MemberPointerType *MPTy = static_cast<MemberPointerType *>(Ty);
1584 MPTy->Pointee->Quals = Qualifiers(MPTy->Pointee->Quals | ExtraChildQuals);
1585 } else {
1586 PointerType *PTy = static_cast<PointerType *>(Ty);
1587 PTy->Pointee->Quals = Qualifiers(PTy->Pointee->Quals | ExtraChildQuals);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001588 }
1589
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001590 break;
1591 }
1592 default:
Zachary Turner316109b2018-07-29 16:38:02 +00001593 Ty->Quals = demangleQualifiers(MangledName).first;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001594 break;
1595 }
1596
1597 return Ty;
1598}
1599
1600// Sometimes numbers are encoded in mangled symbols. For example,
1601// "int (*x)[20]" is a valid C type (x is a pointer to an array of
1602// length 20), so we need some way to embed numbers as part of symbols.
1603// This function parses it.
1604//
1605// <number> ::= [?] <non-negative integer>
1606//
1607// <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
1608// ::= <hex digit>+ @ # when Numbrer == 0 or >= 10
1609//
1610// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001611std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
1612 bool IsNegative = MangledName.consumeFront('?');
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001613
1614 if (startsWithDigit(MangledName)) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001615 uint64_t Ret = MangledName[0] - '0' + 1;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001616 MangledName = MangledName.dropFront(1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001617 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001618 }
1619
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001620 uint64_t Ret = 0;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001621 for (size_t i = 0; i < MangledName.size(); ++i) {
1622 char C = MangledName[i];
1623 if (C == '@') {
1624 MangledName = MangledName.dropFront(i + 1);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001625 return {Ret, IsNegative};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001626 }
1627 if ('A' <= C && C <= 'P') {
1628 Ret = (Ret << 4) + (C - 'A');
1629 continue;
1630 }
1631 break;
1632 }
1633
1634 Error = true;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00001635 return {0ULL, false};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001636}
1637
Zachary Turner469f0762018-08-17 21:18:05 +00001638uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
1639 bool IsNegative = false;
1640 uint64_t Number = 0;
1641 std::tie(Number, IsNegative) = demangleNumber(MangledName);
1642 if (IsNegative)
1643 Error = true;
1644 return Number;
1645}
1646
1647int64_t Demangler::demangleSigned(StringView &MangledName) {
1648 bool IsNegative = false;
1649 uint64_t Number = 0;
1650 std::tie(Number, IsNegative) = demangleNumber(MangledName);
1651 if (Number > INT64_MAX)
1652 Error = true;
1653 int64_t I = static_cast<int64_t>(Number);
1654 return IsNegative ? -I : I;
1655}
1656
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001657// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
1658// Memorize it.
1659void Demangler::memorizeString(StringView S) {
Zachary Turnerd346cba2018-08-08 17:17:04 +00001660 if (Backrefs.NamesCount >= BackrefContext::Max)
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001661 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001662 for (size_t i = 0; i < Backrefs.NamesCount; ++i)
1663 if (S == Backrefs.Names[i])
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001664 return;
Zachary Turnerd346cba2018-08-08 17:17:04 +00001665 Backrefs.Names[Backrefs.NamesCount++] = S;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001666}
1667
Zachary Turner316109b2018-07-29 16:38:02 +00001668Name *Demangler::demangleBackRefName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001669 assert(startsWithDigit(MangledName));
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001670
1671 size_t I = MangledName[0] - '0';
1672 if (I >= Backrefs.NamesCount) {
1673 Error = true;
1674 return nullptr;
1675 }
1676
Zachary Turner172aea12018-08-02 17:08:03 +00001677 MangledName = MangledName.dropFront();
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001678 Name *Node = Arena.alloc<Name>();
1679 Node->Str = Backrefs.Names[I];
Zachary Turnera7dffb12018-07-28 22:10:42 +00001680 return Node;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001681}
1682
Zachary Turner58d29cf2018-08-08 00:43:31 +00001683Name *Demangler::demangleTemplateInstantiationName(StringView &MangledName,
1684 NameBackrefBehavior NBB) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001685 assert(MangledName.startsWith("?$"));
1686 MangledName.consumeFront("?$");
1687
Zachary Turnerd346cba2018-08-08 17:17:04 +00001688 BackrefContext OuterContext;
1689 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001690
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001691 Name *Node = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turnerd346cba2018-08-08 17:17:04 +00001692 if (!Error)
1693 Node->TParams = demangleTemplateParameterList(MangledName);
1694
1695 std::swap(OuterContext, Backrefs);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00001696 if (Error)
1697 return nullptr;
Zachary Turner71c91f92018-07-30 03:12:34 +00001698
Zachary Turner44ebbc22018-08-01 18:32:47 +00001699 Node->IsTemplateInstantiation = true;
1700
Zachary Turner58d29cf2018-08-08 00:43:31 +00001701 if (NBB & NBB_Template) {
1702 // Render this class template name into a string buffer so that we can
1703 // memorize it for the purpose of back-referencing.
1704 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
Zachary Turnerd9e925f2018-08-18 18:49:48 +00001705 outputName(OS, Node, nullptr);
Zachary Turner58d29cf2018-08-08 00:43:31 +00001706 OS << '\0';
1707 char *Name = OS.getBuffer();
Zachary Turner71c91f92018-07-30 03:12:34 +00001708
Zachary Turner58d29cf2018-08-08 00:43:31 +00001709 StringView Owned = copyString(Name);
1710 memorizeString(Owned);
1711 std::free(Name);
1712 }
Zachary Turner71c91f92018-07-30 03:12:34 +00001713
Zachary Turnera7dffb12018-07-28 22:10:42 +00001714 return Node;
1715}
1716
Zachary Turner469f0762018-08-17 21:18:05 +00001717std::pair<OperatorTy, Name *>
1718Demangler::demangleOperatorName(StringView &MangledName, bool FullyQualified) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00001719 assert(MangledName.startsWith('?'));
1720 MangledName.consumeFront('?');
1721
Zachary Turner3461bfa2018-08-17 16:14:05 +00001722 const OperatorMapEntry *Entry = nullptr;
1723 for (const auto &MapEntry : OperatorMap) {
1724 if (!MangledName.consumeFront(MapEntry.Prefix))
1725 continue;
1726 Entry = &MapEntry;
1727 break;
Zachary Turnera17721c2018-08-10 15:04:56 +00001728 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001729 if (!Entry) {
1730 Error = true;
Zachary Turner469f0762018-08-17 21:18:05 +00001731 return std::make_pair(OperatorTy::Unknown, nullptr);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001732 }
1733
Zachary Turner469f0762018-08-17 21:18:05 +00001734 Name *N = nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001735 switch (Entry->Operator) {
Zachary Turner469f0762018-08-17 21:18:05 +00001736 case OperatorTy::Vftable: // Foo@@6B@
1737 case OperatorTy::LocalVftable: // Foo@@6B@
1738 case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@
1739 case OperatorTy::Vbtable: { // Foo@@7B@
1740 OperatorInfo *Oper = Arena.alloc<OperatorInfo>(*Entry);
1741 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Oper) : Oper;
1742 break;
1743 }
1744
Zachary Turner3461bfa2018-08-17 16:14:05 +00001745 case OperatorTy::StringLiteral:
Zachary Turner469f0762018-08-17 21:18:05 +00001746 N = demangleStringLiteral(MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00001747 break;
1748 case OperatorTy::LiteralOperator:
Zachary Turner469f0762018-08-17 21:18:05 +00001749 N = Arena.alloc<OperatorInfo>(*Entry);
1750 N->Str = demangleSimpleString(MangledName, false);
1751 if (!MangledName.consumeFront('@'))
1752 Error = true;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001753 break;
Zachary Turner469f0762018-08-17 21:18:05 +00001754 case OperatorTy::RttiBaseClassDescriptor: {
1755 RttiBaseClassDescriptor *Temp = Arena.alloc<RttiBaseClassDescriptor>();
1756 Temp->NVOffset = demangleUnsigned(MangledName);
1757 Temp->VBPtrOffset = demangleSigned(MangledName);
1758 Temp->VBTableOffset = demangleUnsigned(MangledName);
1759 Temp->Flags = demangleUnsigned(MangledName);
1760 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Temp) : Temp;
1761 break;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001762 }
Zachary Turner469f0762018-08-17 21:18:05 +00001763 case OperatorTy::Vcall: {
1764 VirtualMemberPtrThunk *Temp = Arena.alloc<VirtualMemberPtrThunk>();
1765 N = demangleNameScopeChain(MangledName, Temp);
1766 if (Error)
1767 break;
1768 if (!MangledName.consumeFront("$B"))
1769 Error = true;
1770 Temp->OffsetInVTable = demangleUnsigned(MangledName);
1771 if (!MangledName.consumeFront('A'))
1772 Error = true;
1773 Temp->CC = demangleCallingConvention(MangledName);
1774 break;
1775 }
1776 case OperatorTy::RttiTypeDescriptor:
1777 // This one is just followed by a type, not a name scope.
1778 N = Arena.alloc<OperatorInfo>(*Entry);
1779 break;
1780 case OperatorTy::LocalStaticGuard: {
1781 LocalStaticGuardVariable *Temp = Arena.alloc<LocalStaticGuardVariable>();
1782 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Temp) : Temp;
1783 if (MangledName.consumeFront("4IA"))
1784 Temp->IsVisible = false;
1785 else if (MangledName.consumeFront("5"))
1786 Temp->IsVisible = true;
1787 else
1788 Error = true;
1789 if (!MangledName.empty())
1790 Temp->ScopeIndex = demangleUnsigned(MangledName);
1791 break;
1792 }
1793 default:
1794 N = Arena.alloc<OperatorInfo>(*Entry);
1795 N = (FullyQualified) ? demangleNameScopeChain(MangledName, N) : N;
1796 break;
1797 }
Zachary Turner970fdc32018-08-16 16:17:36 +00001798 if (Error)
Zachary Turner469f0762018-08-17 21:18:05 +00001799 return std::make_pair(OperatorTy::Unknown, nullptr);
Zachary Turner970fdc32018-08-16 16:17:36 +00001800
Zachary Turner469f0762018-08-17 21:18:05 +00001801 return std::make_pair(Entry->Operator, N);
Zachary Turnera7dffb12018-07-28 22:10:42 +00001802}
1803
Zachary Turner316109b2018-07-29 16:38:02 +00001804Name *Demangler::demangleSimpleName(StringView &MangledName, bool Memorize) {
Zachary Turner931e8792018-07-30 23:02:10 +00001805 StringView S = demangleSimpleString(MangledName, Memorize);
1806 if (Error)
1807 return nullptr;
1808
Zachary Turnera7dffb12018-07-28 22:10:42 +00001809 Name *Node = Arena.alloc<Name>();
Zachary Turner931e8792018-07-30 23:02:10 +00001810 Node->Str = S;
1811 return Node;
1812}
1813
Zachary Turner970fdc32018-08-16 16:17:36 +00001814static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); }
1815
1816static uint8_t rebasedHexDigitToNumber(char C) {
1817 assert(isRebasedHexDigit(C));
1818 return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
1819}
1820
1821uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
1822 if (!MangledName.startsWith('?'))
1823 return MangledName.popFront();
1824
1825 MangledName = MangledName.dropFront();
1826 if (MangledName.empty())
1827 goto CharLiteralError;
1828
1829 if (MangledName.consumeFront('$')) {
1830 // Two hex digits
1831 if (MangledName.size() < 2)
1832 goto CharLiteralError;
1833 StringView Nibbles = MangledName.substr(0, 2);
1834 if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
1835 goto CharLiteralError;
1836 // Don't append the null terminator.
1837 uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
1838 uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
1839 MangledName = MangledName.dropFront(2);
1840 return (C1 << 4) | C2;
1841 }
1842
1843 if (startsWithDigit(MangledName)) {
1844 const char *Lookup = ",/\\:. \n\t'-";
1845 char C = Lookup[MangledName[0] - '0'];
1846 MangledName = MangledName.dropFront();
1847 return C;
1848 }
1849
1850 if (MangledName[0] >= 'a' && MangledName[0] <= 'z') {
1851 char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
1852 '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE',
1853 '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
1854 '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
1855 char C = Lookup[MangledName[0] - 'a'];
1856 MangledName = MangledName.dropFront();
1857 return C;
1858 }
1859
1860 if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') {
1861 char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
1862 '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE',
1863 '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
1864 '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
1865 char C = Lookup[MangledName[0] - 'A'];
1866 MangledName = MangledName.dropFront();
1867 return C;
1868 }
1869
1870CharLiteralError:
1871 Error = true;
1872 return '\0';
1873}
1874
1875wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001876 uint8_t C1, C2;
1877
1878 C1 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001879 if (Error)
1880 goto WCharLiteralError;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00001881 C2 = demangleCharLiteral(MangledName);
Zachary Turner970fdc32018-08-16 16:17:36 +00001882 if (Error)
1883 goto WCharLiteralError;
1884
1885 return ((wchar_t)C1 << 8) | (wchar_t)C2;
1886
1887WCharLiteralError:
1888 Error = true;
1889 return L'\0';
1890}
1891
1892static void writeHexDigit(char *Buffer, uint8_t Digit) {
1893 assert(Digit <= 15);
1894 *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
1895}
1896
1897static void outputHex(OutputStream &OS, unsigned C) {
1898 if (C == 0) {
1899 OS << "\\x00";
1900 return;
1901 }
1902 // It's easier to do the math if we can work from right to left, but we need
1903 // to print the numbers from left to right. So render this into a temporary
1904 // buffer first, then output the temporary buffer. Each byte is of the form
1905 // \xAB, which means that each byte needs 4 characters. Since there are at
1906 // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
1907 char TempBuffer[17];
1908
1909 ::memset(TempBuffer, 0, sizeof(TempBuffer));
1910 constexpr int MaxPos = 15;
1911
1912 int Pos = MaxPos - 1;
1913 while (C != 0) {
1914 for (int I = 0; I < 2; ++I) {
1915 writeHexDigit(&TempBuffer[Pos--], C % 16);
1916 C /= 16;
1917 }
1918 TempBuffer[Pos--] = 'x';
1919 TempBuffer[Pos--] = '\\';
1920 assert(Pos >= 0);
1921 }
1922 OS << StringView(&TempBuffer[Pos + 1]);
1923}
1924
1925static void outputEscapedChar(OutputStream &OS, unsigned C) {
1926 switch (C) {
1927 case '\'': // single quote
1928 OS << "\\\'";
1929 return;
1930 case '\"': // double quote
1931 OS << "\\\"";
1932 return;
1933 case '\\': // backslash
1934 OS << "\\\\";
1935 return;
1936 case '\a': // bell
1937 OS << "\\a";
1938 return;
1939 case '\b': // backspace
1940 OS << "\\b";
1941 return;
1942 case '\f': // form feed
1943 OS << "\\f";
1944 return;
1945 case '\n': // new line
1946 OS << "\\n";
1947 return;
1948 case '\r': // carriage return
1949 OS << "\\r";
1950 return;
1951 case '\t': // tab
1952 OS << "\\t";
1953 return;
1954 case '\v': // vertical tab
1955 OS << "\\v";
1956 return;
1957 default:
1958 break;
1959 }
1960
1961 if (C > 0x1F && C < 0x7F) {
1962 // Standard ascii char.
1963 OS << (char)C;
1964 return;
1965 }
1966
1967 outputHex(OS, C);
1968}
1969
1970unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
1971 const uint8_t *End = StringBytes + Length - 1;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001972 unsigned Count = 0;
Zachary Turner970fdc32018-08-16 16:17:36 +00001973 while (Length > 0 && *End == 0) {
1974 --Length;
1975 --End;
Zachary Turner3461bfa2018-08-17 16:14:05 +00001976 ++Count;
Zachary Turner970fdc32018-08-16 16:17:36 +00001977 }
Zachary Turner3461bfa2018-08-17 16:14:05 +00001978 return Count;
Zachary Turner970fdc32018-08-16 16:17:36 +00001979}
1980
1981unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length) {
1982 unsigned Result = 0;
1983 for (unsigned I = 0; I < Length; ++I) {
1984 if (*StringBytes++ == 0)
1985 ++Result;
1986 }
1987 return Result;
1988}
1989
1990unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
1991 unsigned NumBytes) {
1992 assert(NumBytes > 0);
1993
1994 // If the number of bytes is odd, this is guaranteed to be a char string.
1995 if (NumBytes % 2 == 1)
1996 return 1;
1997
1998 // All strings can encode at most 32 bytes of data. If it's less than that,
1999 // then we encoded the entire string. In this case we check for a 1-byte,
2000 // 2-byte, or 4-byte null terminator.
2001 if (NumBytes < 32) {
2002 unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
2003 if (TrailingNulls >= 4)
2004 return 4;
2005 if (TrailingNulls >= 2)
2006 return 2;
2007 return 1;
2008 }
2009
2010 // The whole string was not able to be encoded. Try to look at embedded null
2011 // terminators to guess. The heuristic is that we count all embedded null
2012 // terminators. If more than 2/3 are null, it's a char32. If more than 1/3
2013 // are null, it's a char16. Otherwise it's a char8. This obviously isn't
2014 // perfect and is biased towards languages that have ascii alphabets, but this
2015 // was always going to be best effort since the encoding is lossy.
2016 unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
2017 if (Nulls >= 2 * NumChars / 3)
2018 return 4;
2019 if (Nulls >= NumChars / 3)
2020 return 2;
2021 return 1;
2022}
2023
2024static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
2025 unsigned CharIndex, unsigned CharBytes) {
2026 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
2027 unsigned Offset = CharIndex * CharBytes;
2028 unsigned Result = 0;
2029 StringBytes = StringBytes + Offset;
2030 for (unsigned I = 0; I < CharBytes; ++I) {
2031 unsigned C = static_cast<unsigned>(StringBytes[I]);
2032 Result |= C << (8 * I);
2033 }
2034 return Result;
2035}
2036
Zachary Turner3461bfa2018-08-17 16:14:05 +00002037StringLiteral *Demangler::demangleStringLiteral(StringView &MangledName) {
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002038 // This function uses goto, so declare all variables up front.
Zachary Turner970fdc32018-08-16 16:17:36 +00002039 OutputStream OS;
2040 StringView CRC;
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002041 uint64_t StringByteSize;
2042 bool IsWcharT = false;
2043 bool IsNegative = false;
2044 size_t CrcEndPos = 0;
2045 char *ResultBuffer = nullptr;
2046
Zachary Turner3461bfa2018-08-17 16:14:05 +00002047 StringLiteral *Result = Arena.alloc<StringLiteral>();
Zachary Turner970fdc32018-08-16 16:17:36 +00002048
2049 // Prefix indicating the beginning of a string literal
Zachary Turner3461bfa2018-08-17 16:14:05 +00002050 if (!MangledName.consumeFront("@_"))
2051 goto StringLiteralError;
Zachary Turner970fdc32018-08-16 16:17:36 +00002052 if (MangledName.empty())
2053 goto StringLiteralError;
2054
2055 // Char Type (regular or wchar_t)
Zachary Turner970fdc32018-08-16 16:17:36 +00002056 switch (MangledName.popFront()) {
2057 case '1':
2058 IsWcharT = true;
2059 LLVM_FALLTHROUGH;
2060 case '0':
2061 break;
2062 default:
2063 goto StringLiteralError;
2064 }
2065
2066 // Encoded Length
Zachary Turner970fdc32018-08-16 16:17:36 +00002067 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
2068 if (Error || IsNegative)
2069 goto StringLiteralError;
2070
2071 // CRC 32 (always 8 characters plus a terminator)
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002072 CrcEndPos = MangledName.find('@');
Zachary Turner970fdc32018-08-16 16:17:36 +00002073 if (CrcEndPos == StringView::npos)
2074 goto StringLiteralError;
2075 CRC = MangledName.substr(0, CrcEndPos);
2076 MangledName = MangledName.dropFront(CrcEndPos + 1);
2077 if (MangledName.empty())
2078 goto StringLiteralError;
2079
2080 OS = OutputStream::create(nullptr, nullptr, 1024);
2081 if (IsWcharT) {
Zachary Turner3461bfa2018-08-17 16:14:05 +00002082 Result->CharType = PrimTy::Wchar;
Zachary Turner970fdc32018-08-16 16:17:36 +00002083 if (StringByteSize > 64)
Zachary Turner3461bfa2018-08-17 16:14:05 +00002084 Result->IsTruncated = true;
Zachary Turner970fdc32018-08-16 16:17:36 +00002085
2086 while (!MangledName.consumeFront('@')) {
2087 assert(StringByteSize >= 2);
2088 wchar_t W = demangleWcharLiteral(MangledName);
Zachary Turner3461bfa2018-08-17 16:14:05 +00002089 if (StringByteSize != 2 || Result->IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +00002090 outputEscapedChar(OS, W);
2091 StringByteSize -= 2;
2092 if (Error)
2093 goto StringLiteralError;
2094 }
2095 } else {
2096 if (StringByteSize > 32)
Zachary Turner3461bfa2018-08-17 16:14:05 +00002097 Result->IsTruncated = true;
Zachary Turner970fdc32018-08-16 16:17:36 +00002098
2099 constexpr unsigned MaxStringByteLength = 32;
2100 uint8_t StringBytes[MaxStringByteLength];
2101
2102 unsigned BytesDecoded = 0;
2103 while (!MangledName.consumeFront('@')) {
2104 assert(StringByteSize >= 1);
2105 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
2106 }
2107
2108 unsigned CharBytes =
2109 guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
2110 assert(StringByteSize % CharBytes == 0);
2111 switch (CharBytes) {
2112 case 1:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002113 Result->CharType = PrimTy::Char;
Zachary Turner970fdc32018-08-16 16:17:36 +00002114 break;
2115 case 2:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002116 Result->CharType = PrimTy::Char16;
Zachary Turner970fdc32018-08-16 16:17:36 +00002117 break;
2118 case 4:
Zachary Turner3461bfa2018-08-17 16:14:05 +00002119 Result->CharType = PrimTy::Char32;
Zachary Turner970fdc32018-08-16 16:17:36 +00002120 break;
2121 default:
2122 LLVM_BUILTIN_UNREACHABLE;
2123 }
2124 const unsigned NumChars = BytesDecoded / CharBytes;
2125 for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
2126 unsigned NextChar =
2127 decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
Zachary Turner3461bfa2018-08-17 16:14:05 +00002128 if (CharIndex + 1 < NumChars || Result->IsTruncated)
Zachary Turner970fdc32018-08-16 16:17:36 +00002129 outputEscapedChar(OS, NextChar);
2130 }
2131 }
2132
2133 OS << '\0';
Zachary Turnerd78fe2f2018-08-16 16:30:27 +00002134 ResultBuffer = OS.getBuffer();
Zachary Turner970fdc32018-08-16 16:17:36 +00002135 Result->Str = copyString(ResultBuffer);
Zachary Turneraf738f72018-08-16 17:48:32 +00002136 std::free(ResultBuffer);
Zachary Turner970fdc32018-08-16 16:17:36 +00002137 return Result;
2138
2139StringLiteralError:
2140 Error = true;
2141 return nullptr;
2142}
2143
Zachary Turner931e8792018-07-30 23:02:10 +00002144StringView Demangler::demangleSimpleString(StringView &MangledName,
2145 bool Memorize) {
2146 StringView S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002147 for (size_t i = 0; i < MangledName.size(); ++i) {
2148 if (MangledName[i] != '@')
2149 continue;
Zachary Turner931e8792018-07-30 23:02:10 +00002150 S = MangledName.substr(0, i);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002151 MangledName = MangledName.dropFront(i + 1);
2152
2153 if (Memorize)
Zachary Turner931e8792018-07-30 23:02:10 +00002154 memorizeString(S);
2155 return S;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002156 }
2157
2158 Error = true;
Zachary Turner931e8792018-07-30 23:02:10 +00002159 return {};
Zachary Turnera7dffb12018-07-28 22:10:42 +00002160}
2161
Zachary Turner316109b2018-07-29 16:38:02 +00002162Name *Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002163 assert(MangledName.startsWith("?A"));
2164 MangledName.consumeFront("?A");
2165
2166 Name *Node = Arena.alloc<Name>();
2167 Node->Str = "`anonymous namespace'";
2168 if (MangledName.consumeFront('@'))
2169 return Node;
2170
2171 Error = true;
2172 return nullptr;
2173}
2174
Zachary Turner71c91f92018-07-30 03:12:34 +00002175Name *Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
2176 assert(startsWithLocalScopePattern(MangledName));
2177
2178 Name *Node = Arena.alloc<Name>();
2179 MangledName.consumeFront('?');
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002180 auto Number = demangleNumber(MangledName);
2181 assert(!Number.second);
Zachary Turner71c91f92018-07-30 03:12:34 +00002182
2183 // One ? to terminate the number
2184 MangledName.consumeFront('?');
2185
2186 assert(!Error);
2187 Symbol *Scope = parse(MangledName);
2188 if (Error)
2189 return nullptr;
2190
2191 // Render the parent symbol's name into a buffer.
2192 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
2193 OS << '`';
2194 output(Scope, OS);
2195 OS << '\'';
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002196 OS << "::`" << Number.first << "'";
Zachary Turner71c91f92018-07-30 03:12:34 +00002197 OS << '\0';
2198 char *Result = OS.getBuffer();
2199 Node->Str = copyString(Result);
2200 std::free(Result);
2201 return Node;
2202}
2203
Zachary Turnera7dffb12018-07-28 22:10:42 +00002204// Parses a type name in the form of A@B@C@@ which represents C::B::A.
Zachary Turner316109b2018-07-29 16:38:02 +00002205Name *Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
Zachary Turner44ebbc22018-08-01 18:32:47 +00002206 Name *TypeName = demangleUnqualifiedTypeName(MangledName, true);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002207 if (Error)
2208 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002209 assert(TypeName);
2210
Zachary Turner316109b2018-07-29 16:38:02 +00002211 Name *QualName = demangleNameScopeChain(MangledName, TypeName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002212 if (Error)
2213 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002214 assert(QualName);
2215 return QualName;
2216}
2217
2218// Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
2219// Symbol names have slightly different rules regarding what can appear
2220// so we separate out the implementations for flexibility.
Zachary Turner316109b2018-07-29 16:38:02 +00002221Name *Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
Zachary Turner58d29cf2018-08-08 00:43:31 +00002222 // This is the final component of a symbol name (i.e. the leftmost component
2223 // of a mangled name. Since the only possible template instantiation that
2224 // can appear in this context is a function template, and since those are
2225 // not saved for the purposes of name backreferences, only backref simple
2226 // names.
2227 Name *SymbolName = demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002228 if (Error)
2229 return nullptr;
Zachary Turner3461bfa2018-08-17 16:14:05 +00002230
Zachary Turner316109b2018-07-29 16:38:02 +00002231 Name *QualName = demangleNameScopeChain(MangledName, SymbolName);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002232 if (Error)
2233 return nullptr;
Zachary Turnera7dffb12018-07-28 22:10:42 +00002234 assert(QualName);
2235 return QualName;
2236}
2237
Zachary Turner44ebbc22018-08-01 18:32:47 +00002238Name *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
2239 bool Memorize) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002240 // An inner-most name can be a back-reference, because a fully-qualified name
2241 // (e.g. Scope + Inner) can contain other fully qualified names inside of
2242 // them (for example template parameters), and these nested parameters can
2243 // refer to previously mangled types.
2244 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002245 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002246
2247 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002248 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002249
Zachary Turner44ebbc22018-08-01 18:32:47 +00002250 return demangleSimpleName(MangledName, Memorize);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002251}
2252
Zachary Turner44ebbc22018-08-01 18:32:47 +00002253Name *Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
Zachary Turner58d29cf2018-08-08 00:43:31 +00002254 NameBackrefBehavior NBB) {
Zachary Turner71c91f92018-07-30 03:12:34 +00002255 if (startsWithDigit(MangledName))
2256 return demangleBackRefName(MangledName);
2257 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002258 return demangleTemplateInstantiationName(MangledName, NBB);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002259 if (MangledName.startsWith('?'))
Zachary Turner469f0762018-08-17 21:18:05 +00002260 return demangleOperatorName(MangledName, false).second;
Zachary Turner58d29cf2018-08-08 00:43:31 +00002261 return demangleSimpleName(MangledName, (NBB & NBB_Simple) != 0);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002262}
2263
Zachary Turner316109b2018-07-29 16:38:02 +00002264Name *Demangler::demangleNameScopePiece(StringView &MangledName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002265 if (startsWithDigit(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002266 return demangleBackRefName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002267
2268 if (MangledName.startsWith("?$"))
Zachary Turner58d29cf2018-08-08 00:43:31 +00002269 return demangleTemplateInstantiationName(MangledName, NBB_Template);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002270
2271 if (MangledName.startsWith("?A"))
Zachary Turner316109b2018-07-29 16:38:02 +00002272 return demangleAnonymousNamespaceName(MangledName);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002273
Zachary Turner71c91f92018-07-30 03:12:34 +00002274 if (startsWithLocalScopePattern(MangledName))
2275 return demangleLocallyScopedNamePiece(MangledName);
2276
Zachary Turner316109b2018-07-29 16:38:02 +00002277 return demangleSimpleName(MangledName, true);
Zachary Turnera7dffb12018-07-28 22:10:42 +00002278}
2279
Zachary Turner316109b2018-07-29 16:38:02 +00002280Name *Demangler::demangleNameScopeChain(StringView &MangledName,
2281 Name *UnqualifiedName) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002282 Name *Head = UnqualifiedName;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002283
2284 while (!MangledName.consumeFront("@")) {
Zachary Turnera7dffb12018-07-28 22:10:42 +00002285 if (MangledName.empty()) {
2286 Error = true;
2287 return nullptr;
2288 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002289
2290 assert(!Error);
Zachary Turner316109b2018-07-29 16:38:02 +00002291 Name *Elem = demangleNameScopePiece(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002292 if (Error)
2293 return nullptr;
2294
2295 Elem->Next = Head;
2296 Head = Elem;
2297 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002298 return Head;
2299}
2300
Zachary Turner316109b2018-07-29 16:38:02 +00002301FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002302 SwapAndRestore<StringView> RestoreOnError(MangledName, MangledName);
2303 RestoreOnError.shouldRestore(false);
2304
2305 switch (MangledName.popFront()) {
Zachary Turner29ec67b2018-08-10 21:09:05 +00002306 case '9':
Zachary Turner469f0762018-08-17 21:18:05 +00002307 return FuncClass(ExternC | NoPrototype);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002308 case 'A':
2309 return Private;
2310 case 'B':
Zachary Turner469f0762018-08-17 21:18:05 +00002311 return FuncClass(Private | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002312 case 'C':
Zachary Turner469f0762018-08-17 21:18:05 +00002313 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002314 case 'D':
Zachary Turner469f0762018-08-17 21:18:05 +00002315 return FuncClass(Private | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002316 case 'E':
Zachary Turner469f0762018-08-17 21:18:05 +00002317 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002318 case 'F':
Zachary Turner469f0762018-08-17 21:18:05 +00002319 return FuncClass(Private | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002320 case 'I':
Zachary Turner469f0762018-08-17 21:18:05 +00002321 return FuncClass(Protected);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002322 case 'J':
Zachary Turner469f0762018-08-17 21:18:05 +00002323 return FuncClass(Protected | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002324 case 'K':
Zachary Turner469f0762018-08-17 21:18:05 +00002325 return FuncClass(Protected | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002326 case 'L':
Zachary Turner469f0762018-08-17 21:18:05 +00002327 return FuncClass(Protected | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002328 case 'M':
Zachary Turner469f0762018-08-17 21:18:05 +00002329 return FuncClass(Protected | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002330 case 'N':
Zachary Turner469f0762018-08-17 21:18:05 +00002331 return FuncClass(Protected | Virtual | Far);
2332 case 'O':
2333 return FuncClass(Protected | Virtual | StaticThisAdjust);
2334 case 'P':
2335 return FuncClass(Protected | Virtual | StaticThisAdjust | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002336 case 'Q':
Zachary Turner469f0762018-08-17 21:18:05 +00002337 return FuncClass(Public);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002338 case 'R':
Zachary Turner469f0762018-08-17 21:18:05 +00002339 return FuncClass(Public | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002340 case 'S':
Zachary Turner469f0762018-08-17 21:18:05 +00002341 return FuncClass(Public | Static);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002342 case 'T':
Zachary Turner469f0762018-08-17 21:18:05 +00002343 return FuncClass(Public | Static | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002344 case 'U':
Zachary Turner469f0762018-08-17 21:18:05 +00002345 return FuncClass(Public | Virtual);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002346 case 'V':
Zachary Turner469f0762018-08-17 21:18:05 +00002347 return FuncClass(Public | Virtual | Far);
2348 case 'W':
2349 return FuncClass(Public | Virtual | StaticThisAdjust);
2350 case 'X':
2351 return FuncClass(Public | Virtual | StaticThisAdjust | Far);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002352 case 'Y':
Zachary Turner469f0762018-08-17 21:18:05 +00002353 return FuncClass(Global);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002354 case 'Z':
Zachary Turner469f0762018-08-17 21:18:05 +00002355 return FuncClass(Global | Far);
2356 case '$': {
2357 FuncClass VFlag = VirtualThisAdjust;
2358 if (MangledName.consumeFront('R'))
2359 VFlag = FuncClass(VFlag | VirtualThisAdjustEx);
2360
2361 switch (MangledName.popFront()) {
2362 case '0':
2363 return FuncClass(Private | Virtual | VFlag);
2364 case '1':
2365 return FuncClass(Private | Virtual | VFlag | Far);
2366 case '2':
2367 return FuncClass(Protected | Virtual | VFlag);
2368 case '3':
2369 return FuncClass(Protected | Virtual | VFlag | Far);
2370 case '4':
2371 return FuncClass(Public | Virtual | VFlag);
2372 case '5':
2373 return FuncClass(Public | Virtual | VFlag | Far);
2374 }
2375 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002376 }
2377
2378 Error = true;
2379 RestoreOnError.shouldRestore(true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002380 return Public;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002381}
2382
Zachary Turner316109b2018-07-29 16:38:02 +00002383CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002384 switch (MangledName.popFront()) {
2385 case 'A':
2386 case 'B':
2387 return CallingConv::Cdecl;
2388 case 'C':
2389 case 'D':
2390 return CallingConv::Pascal;
2391 case 'E':
2392 case 'F':
2393 return CallingConv::Thiscall;
2394 case 'G':
2395 case 'H':
2396 return CallingConv::Stdcall;
2397 case 'I':
2398 case 'J':
2399 return CallingConv::Fastcall;
2400 case 'M':
2401 case 'N':
2402 return CallingConv::Clrcall;
2403 case 'O':
2404 case 'P':
2405 return CallingConv::Eabi;
2406 case 'Q':
2407 return CallingConv::Vectorcall;
2408 }
2409
2410 return CallingConv::None;
Martin Storsjo0f2abd82018-07-20 18:43:42 +00002411}
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002412
Zachary Turner316109b2018-07-29 16:38:02 +00002413StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002414 assert(std::isdigit(MangledName.front()));
2415
2416 switch (MangledName.popFront()) {
2417 case '0':
2418 return StorageClass::PrivateStatic;
2419 case '1':
2420 return StorageClass::ProtectedStatic;
2421 case '2':
2422 return StorageClass::PublicStatic;
2423 case '3':
2424 return StorageClass::Global;
2425 case '4':
2426 return StorageClass::FunctionLocalStatic;
2427 }
2428 Error = true;
2429 return StorageClass::None;
2430}
2431
Zachary Turner316109b2018-07-29 16:38:02 +00002432std::pair<Qualifiers, bool>
2433Demangler::demangleQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002434
2435 switch (MangledName.popFront()) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002436 // Member qualifiers
2437 case 'Q':
2438 return std::make_pair(Q_None, true);
2439 case 'R':
2440 return std::make_pair(Q_Const, true);
2441 case 'S':
2442 return std::make_pair(Q_Volatile, true);
2443 case 'T':
2444 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
2445 // Non-Member qualifiers
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002446 case 'A':
Zachary Turnerd742d642018-07-26 19:56:09 +00002447 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002448 case 'B':
Zachary Turnerd742d642018-07-26 19:56:09 +00002449 return std::make_pair(Q_Const, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002450 case 'C':
Zachary Turnerd742d642018-07-26 19:56:09 +00002451 return std::make_pair(Q_Volatile, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002452 case 'D':
Zachary Turnerd742d642018-07-26 19:56:09 +00002453 return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002454 }
2455 Error = true;
Zachary Turnerd742d642018-07-26 19:56:09 +00002456 return std::make_pair(Q_None, false);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002457}
2458
Zachary Turner931e8792018-07-30 23:02:10 +00002459static bool isTagType(StringView S) {
2460 switch (S.front()) {
2461 case 'T': // union
2462 case 'U': // struct
2463 case 'V': // class
2464 case 'W': // enum
2465 return true;
2466 }
2467 return false;
2468}
2469
2470static bool isPointerType(StringView S) {
2471 if (S.startsWith("$$Q")) // foo &&
2472 return true;
2473
2474 switch (S.front()) {
2475 case 'A': // foo &
2476 case 'P': // foo *
2477 case 'Q': // foo *const
2478 case 'R': // foo *volatile
2479 case 'S': // foo *const volatile
2480 return true;
2481 }
2482 return false;
2483}
2484
2485static bool isArrayType(StringView S) { return S[0] == 'Y'; }
2486
2487static bool isFunctionType(StringView S) {
2488 return S.startsWith("$$A8@@") || S.startsWith("$$A6");
2489}
2490
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002491// <variable-type> ::= <type> <cvr-qualifiers>
2492// ::= <type> <pointee-cvr-qualifiers> # pointers, references
Zachary Turner316109b2018-07-29 16:38:02 +00002493Type *Demangler::demangleType(StringView &MangledName,
2494 QualifierMangleMode QMM) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002495 Qualifiers Quals = Q_None;
Zachary Turnerd742d642018-07-26 19:56:09 +00002496 bool IsMember = false;
2497 bool IsMemberKnown = false;
2498 if (QMM == QualifierMangleMode::Mangle) {
Zachary Turner316109b2018-07-29 16:38:02 +00002499 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002500 IsMemberKnown = true;
2501 } else if (QMM == QualifierMangleMode::Result) {
2502 if (MangledName.consumeFront('?')) {
Zachary Turner316109b2018-07-29 16:38:02 +00002503 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002504 IsMemberKnown = true;
2505 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002506 }
2507
2508 Type *Ty = nullptr;
Zachary Turner931e8792018-07-30 23:02:10 +00002509 if (isTagType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002510 Ty = demangleClassType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002511 else if (isPointerType(MangledName)) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002512 if (!IsMemberKnown)
2513 IsMember = isMemberPointer(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002514
Zachary Turnerd742d642018-07-26 19:56:09 +00002515 if (IsMember)
Zachary Turner316109b2018-07-29 16:38:02 +00002516 Ty = demangleMemberPointerType(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002517 else
Zachary Turner316109b2018-07-29 16:38:02 +00002518 Ty = demanglePointerType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002519 } else if (isArrayType(MangledName))
Zachary Turner316109b2018-07-29 16:38:02 +00002520 Ty = demangleArrayType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002521 else if (isFunctionType(MangledName)) {
2522 if (MangledName.consumeFront("$$A8@@"))
2523 Ty = demangleFunctionType(MangledName, true, false);
2524 else {
2525 assert(MangledName.startsWith("$$A6"));
2526 MangledName.consumeFront("$$A6");
2527 Ty = demangleFunctionType(MangledName, false, false);
2528 }
2529 } else {
Zachary Turner316109b2018-07-29 16:38:02 +00002530 Ty = demangleBasicType(MangledName);
Zachary Turner931e8792018-07-30 23:02:10 +00002531 assert(Ty && !Error);
2532 if (!Ty || Error)
2533 return Ty;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002534 }
Zachary Turner931e8792018-07-30 23:02:10 +00002535
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002536 Ty->Quals = Qualifiers(Ty->Quals | Quals);
2537 return Ty;
2538}
2539
Zachary Turner316109b2018-07-29 16:38:02 +00002540ReferenceKind Demangler::demangleReferenceKind(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002541 if (MangledName.consumeFront('G'))
2542 return ReferenceKind::LValueRef;
2543 else if (MangledName.consumeFront('H'))
2544 return ReferenceKind::RValueRef;
2545 return ReferenceKind::None;
2546}
2547
Zachary Turner316109b2018-07-29 16:38:02 +00002548void Demangler::demangleThrowSpecification(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002549 if (MangledName.consumeFront('Z'))
2550 return;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002551
Zachary Turner38b78a72018-07-26 20:20:10 +00002552 Error = true;
2553}
2554
Zachary Turner316109b2018-07-29 16:38:02 +00002555FunctionType *Demangler::demangleFunctionType(StringView &MangledName,
2556 bool HasThisQuals,
Zachary Turner024e1762018-07-26 20:33:48 +00002557 bool IsFunctionPointer) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002558 FunctionType *FTy = Arena.alloc<FunctionType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002559 FTy->Prim = PrimTy::Function;
Zachary Turner024e1762018-07-26 20:33:48 +00002560 FTy->IsFunctionPointer = IsFunctionPointer;
Zachary Turner38b78a72018-07-26 20:20:10 +00002561
2562 if (HasThisQuals) {
Zachary Turner316109b2018-07-29 16:38:02 +00002563 FTy->Quals = demanglePointerExtQualifiers(MangledName);
2564 FTy->RefKind = demangleReferenceKind(MangledName);
2565 FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002566 }
2567
2568 // Fields that appear on both member and non-member functions.
Zachary Turner316109b2018-07-29 16:38:02 +00002569 FTy->CallConvention = demangleCallingConvention(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002570
2571 // <return-type> ::= <type>
2572 // ::= @ # structors (they have no declared return type)
2573 bool IsStructor = MangledName.consumeFront('@');
2574 if (!IsStructor)
Zachary Turner316109b2018-07-29 16:38:02 +00002575 FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002576
Zachary Turner316109b2018-07-29 16:38:02 +00002577 FTy->Params = demangleFunctionParameterList(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002578
Zachary Turner316109b2018-07-29 16:38:02 +00002579 demangleThrowSpecification(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002580
2581 return FTy;
2582}
2583
Zachary Turner316109b2018-07-29 16:38:02 +00002584Type *Demangler::demangleFunctionEncoding(StringView &MangledName) {
Zachary Turner469f0762018-08-17 21:18:05 +00002585 FuncClass ExtraFlags = FuncClass::None;
2586 if (MangledName.consumeFront("$$J0"))
2587 ExtraFlags = FuncClass::ExternC;
2588
Zachary Turner316109b2018-07-29 16:38:02 +00002589 FuncClass FC = demangleFunctionClass(MangledName);
Zachary Turner469f0762018-08-17 21:18:05 +00002590 FC = FuncClass(ExtraFlags | FC);
2591
2592 FunctionType::ThisAdjustor *Adjustor = nullptr;
2593 if (FC & FuncClass::StaticThisAdjust) {
2594 Adjustor = Arena.alloc<FunctionType::ThisAdjustor>();
2595 Adjustor->StaticOffset = demangleSigned(MangledName);
2596 } else if (FC & FuncClass::VirtualThisAdjust) {
2597 Adjustor = Arena.alloc<FunctionType::ThisAdjustor>();
2598 if (FC & FuncClass::VirtualThisAdjustEx) {
2599 Adjustor->VBPtrOffset = demangleSigned(MangledName);
2600 Adjustor->VBOffsetOffset = demangleSigned(MangledName);
2601 }
2602 Adjustor->VtordispOffset = demangleSigned(MangledName);
2603 Adjustor->StaticOffset = demangleSigned(MangledName);
2604 }
2605
Zachary Turner29ec67b2018-08-10 21:09:05 +00002606 FunctionType *FTy = nullptr;
2607 if (FC & NoPrototype) {
2608 // This is an extern "C" function whose full signature hasn't been mangled.
2609 // This happens when we need to mangle a local symbol inside of an extern
2610 // "C" function.
2611 FTy = Arena.alloc<FunctionType>();
2612 } else {
2613 bool HasThisQuals = !(FC & (Global | Static));
2614 FTy = demangleFunctionType(MangledName, HasThisQuals, false);
2615 }
Zachary Turner469f0762018-08-17 21:18:05 +00002616 FTy->ThisAdjust = Adjustor;
Zachary Turner38b78a72018-07-26 20:20:10 +00002617 FTy->FunctionClass = FC;
2618
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002619 return FTy;
2620}
2621
2622// Reads a primitive type.
Zachary Turner316109b2018-07-29 16:38:02 +00002623Type *Demangler::demangleBasicType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002624 Type *Ty = Arena.alloc<Type>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002625
Zachary Turner931e8792018-07-30 23:02:10 +00002626 if (MangledName.consumeFront("$$T")) {
2627 Ty->Prim = PrimTy::Nullptr;
2628 return Ty;
2629 }
2630
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002631 switch (MangledName.popFront()) {
2632 case 'X':
2633 Ty->Prim = PrimTy::Void;
2634 break;
2635 case 'D':
2636 Ty->Prim = PrimTy::Char;
2637 break;
2638 case 'C':
2639 Ty->Prim = PrimTy::Schar;
2640 break;
2641 case 'E':
2642 Ty->Prim = PrimTy::Uchar;
2643 break;
2644 case 'F':
2645 Ty->Prim = PrimTy::Short;
2646 break;
2647 case 'G':
2648 Ty->Prim = PrimTy::Ushort;
2649 break;
2650 case 'H':
2651 Ty->Prim = PrimTy::Int;
2652 break;
2653 case 'I':
2654 Ty->Prim = PrimTy::Uint;
2655 break;
2656 case 'J':
2657 Ty->Prim = PrimTy::Long;
2658 break;
2659 case 'K':
2660 Ty->Prim = PrimTy::Ulong;
2661 break;
2662 case 'M':
2663 Ty->Prim = PrimTy::Float;
2664 break;
2665 case 'N':
2666 Ty->Prim = PrimTy::Double;
2667 break;
2668 case 'O':
2669 Ty->Prim = PrimTy::Ldouble;
2670 break;
2671 case '_': {
Zachary Turner91ecedd2018-07-20 18:07:33 +00002672 if (MangledName.empty()) {
2673 Error = true;
2674 return nullptr;
2675 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002676 switch (MangledName.popFront()) {
2677 case 'N':
2678 Ty->Prim = PrimTy::Bool;
2679 break;
2680 case 'J':
2681 Ty->Prim = PrimTy::Int64;
2682 break;
2683 case 'K':
2684 Ty->Prim = PrimTy::Uint64;
2685 break;
2686 case 'W':
2687 Ty->Prim = PrimTy::Wchar;
2688 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002689 case 'S':
2690 Ty->Prim = PrimTy::Char16;
2691 break;
2692 case 'U':
2693 Ty->Prim = PrimTy::Char32;
2694 break;
Zachary Turner91ecedd2018-07-20 18:07:33 +00002695 default:
Zachary Turner931e8792018-07-30 23:02:10 +00002696 Error = true;
2697 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002698 }
2699 break;
2700 }
Zachary Turner931e8792018-07-30 23:02:10 +00002701 default:
2702 Error = true;
2703 return nullptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002704 }
2705 return Ty;
2706}
2707
Zachary Turner316109b2018-07-29 16:38:02 +00002708UdtType *Demangler::demangleClassType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002709 UdtType *UTy = Arena.alloc<UdtType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002710
2711 switch (MangledName.popFront()) {
2712 case 'T':
2713 UTy->Prim = PrimTy::Union;
2714 break;
2715 case 'U':
2716 UTy->Prim = PrimTy::Struct;
2717 break;
2718 case 'V':
2719 UTy->Prim = PrimTy::Class;
2720 break;
2721 case 'W':
2722 if (MangledName.popFront() != '4') {
2723 Error = true;
2724 return nullptr;
2725 }
2726 UTy->Prim = PrimTy::Enum;
2727 break;
2728 default:
2729 assert(false);
2730 }
2731
Zachary Turner316109b2018-07-29 16:38:02 +00002732 UTy->UdtName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002733 return UTy;
2734}
2735
Zachary Turnerd742d642018-07-26 19:56:09 +00002736static std::pair<Qualifiers, PointerAffinity>
2737demanglePointerCVQualifiers(StringView &MangledName) {
Zachary Turner931e8792018-07-30 23:02:10 +00002738 if (MangledName.consumeFront("$$Q"))
2739 return std::make_pair(Q_None, PointerAffinity::RValueReference);
2740
Zachary Turnerd742d642018-07-26 19:56:09 +00002741 switch (MangledName.popFront()) {
2742 case 'A':
2743 return std::make_pair(Q_None, PointerAffinity::Reference);
2744 case 'P':
2745 return std::make_pair(Q_None, PointerAffinity::Pointer);
2746 case 'Q':
2747 return std::make_pair(Q_Const, PointerAffinity::Pointer);
2748 case 'R':
2749 return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
2750 case 'S':
2751 return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
2752 PointerAffinity::Pointer);
2753 default:
2754 assert(false && "Ty is not a pointer type!");
2755 }
2756 return std::make_pair(Q_None, PointerAffinity::Pointer);
2757}
2758
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002759// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
2760// # the E is required for 64-bit non-static pointers
Zachary Turner316109b2018-07-29 16:38:02 +00002761PointerType *Demangler::demanglePointerType(StringView &MangledName) {
Zachary Turner9d72aa92018-07-20 18:35:06 +00002762 PointerType *Pointer = Arena.alloc<PointerType>();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002763
Zachary Turner931e8792018-07-30 23:02:10 +00002764 std::tie(Pointer->Quals, Pointer->Affinity) =
2765 demanglePointerCVQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002766
Zachary Turner931e8792018-07-30 23:02:10 +00002767 Pointer->Prim = PrimTy::Ptr;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002768 if (MangledName.consumeFront("6")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002769 Pointer->Pointee = demangleFunctionType(MangledName, false, true);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002770 return Pointer;
2771 }
2772
Zachary Turner316109b2018-07-29 16:38:02 +00002773 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002774 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2775
Zachary Turner316109b2018-07-29 16:38:02 +00002776 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002777 return Pointer;
2778}
2779
Zachary Turner316109b2018-07-29 16:38:02 +00002780MemberPointerType *
2781Demangler::demangleMemberPointerType(StringView &MangledName) {
Zachary Turnerd742d642018-07-26 19:56:09 +00002782 MemberPointerType *Pointer = Arena.alloc<MemberPointerType>();
2783 Pointer->Prim = PrimTy::MemberPtr;
2784
2785 PointerAffinity Affinity;
2786 std::tie(Pointer->Quals, Affinity) = demanglePointerCVQualifiers(MangledName);
2787 assert(Affinity == PointerAffinity::Pointer);
2788
Zachary Turner316109b2018-07-29 16:38:02 +00002789 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002790 Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2791
Zachary Turner38b78a72018-07-26 20:20:10 +00002792 if (MangledName.consumeFront("8")) {
Zachary Turner316109b2018-07-29 16:38:02 +00002793 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
2794 Pointer->Pointee = demangleFunctionType(MangledName, true, true);
Zachary Turner38b78a72018-07-26 20:20:10 +00002795 } else {
2796 Qualifiers PointeeQuals = Q_None;
2797 bool IsMember = false;
Zachary Turner316109b2018-07-29 16:38:02 +00002798 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
Zachary Turner38b78a72018-07-26 20:20:10 +00002799 assert(IsMember);
Zachary Turner316109b2018-07-29 16:38:02 +00002800 Pointer->MemberName = demangleFullyQualifiedSymbolName(MangledName);
Zachary Turnerd742d642018-07-26 19:56:09 +00002801
Zachary Turner316109b2018-07-29 16:38:02 +00002802 Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner38b78a72018-07-26 20:20:10 +00002803 Pointer->Pointee->Quals = PointeeQuals;
2804 }
2805
Zachary Turnerd742d642018-07-26 19:56:09 +00002806 return Pointer;
2807}
2808
Zachary Turner316109b2018-07-29 16:38:02 +00002809Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002810 Qualifiers Quals = Q_None;
2811 if (MangledName.consumeFront('E'))
2812 Quals = Qualifiers(Quals | Q_Pointer64);
2813 if (MangledName.consumeFront('I'))
2814 Quals = Qualifiers(Quals | Q_Restrict);
2815 if (MangledName.consumeFront('F'))
2816 Quals = Qualifiers(Quals | Q_Unaligned);
2817
2818 return Quals;
2819}
2820
Zachary Turner316109b2018-07-29 16:38:02 +00002821ArrayType *Demangler::demangleArrayType(StringView &MangledName) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002822 assert(MangledName.front() == 'Y');
2823 MangledName.popFront();
2824
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002825 uint64_t Rank = 0;
2826 bool IsNegative = false;
2827 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2828 if (IsNegative || Rank == 0) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002829 Error = true;
2830 return nullptr;
2831 }
2832
Zachary Turner9d72aa92018-07-20 18:35:06 +00002833 ArrayType *ATy = Arena.alloc<ArrayType>();
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002834 ATy->Prim = PrimTy::Array;
2835 ATy->Dims = Arena.alloc<ArrayDimension>();
2836 ArrayDimension *Dim = ATy->Dims;
2837 for (uint64_t I = 0; I < Rank; ++I) {
2838 std::tie(Dim->Dim, IsNegative) = demangleNumber(MangledName);
2839 if (IsNegative) {
2840 Error = true;
2841 return nullptr;
2842 }
2843 if (I + 1 < Rank) {
2844 Dim->Next = Arena.alloc<ArrayDimension>();
2845 Dim = Dim->Next;
2846 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002847 }
2848
2849 if (MangledName.consumeFront("$$C")) {
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002850 bool IsMember = false;
2851 std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2852 if (IsMember) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002853 Error = true;
Zachary Turner2bbb23b2018-08-14 18:54:28 +00002854 return nullptr;
2855 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002856 }
2857
Zachary Turner316109b2018-07-29 16:38:02 +00002858 ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002859 return ATy;
2860}
2861
2862// Reads a function or a template parameters.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002863FunctionParams
2864Demangler::demangleFunctionParameterList(StringView &MangledName) {
Zachary Turner38b78a72018-07-26 20:20:10 +00002865 // Empty parameter list.
Zachary Turner38b78a72018-07-26 20:20:10 +00002866 if (MangledName.consumeFront('X'))
2867 return {};
2868
Zachary Turnerd30700f2018-07-31 17:16:44 +00002869 FunctionParams *Head;
2870 FunctionParams **Current = &Head;
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002871 while (!Error && !MangledName.startsWith('@') &&
2872 !MangledName.startsWith('Z')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002873
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002874 if (startsWithDigit(MangledName)) {
Zachary Turner30375de2018-07-26 22:24:01 +00002875 size_t N = MangledName[0] - '0';
Zachary Turnerd346cba2018-08-08 17:17:04 +00002876 if (N >= Backrefs.FunctionParamCount) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002877 Error = true;
2878 return {};
2879 }
2880 MangledName = MangledName.dropFront();
2881
Zachary Turnerd30700f2018-07-31 17:16:44 +00002882 *Current = Arena.alloc<FunctionParams>();
Zachary Turnerd346cba2018-08-08 17:17:04 +00002883 (*Current)->Current = Backrefs.FunctionParams[N]->clone(Arena);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002884 Current = &(*Current)->Next;
2885 continue;
2886 }
2887
Zachary Turner23df1312018-07-26 22:13:39 +00002888 size_t OldSize = MangledName.size();
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002889
Zachary Turnerd30700f2018-07-31 17:16:44 +00002890 *Current = Arena.alloc<FunctionParams>();
Zachary Turner316109b2018-07-29 16:38:02 +00002891 (*Current)->Current = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002892
Zachary Turner23df1312018-07-26 22:13:39 +00002893 size_t CharsConsumed = OldSize - MangledName.size();
2894 assert(CharsConsumed != 0);
2895
2896 // Single-letter types are ignored for backreferences because memorizing
2897 // them doesn't save anything.
Zachary Turnerd346cba2018-08-08 17:17:04 +00002898 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2899 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] =
2900 (*Current)->Current;
Zachary Turner23df1312018-07-26 22:13:39 +00002901
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002902 Current = &(*Current)->Next;
2903 }
2904
Zachary Turner38b78a72018-07-26 20:20:10 +00002905 if (Error)
2906 return {};
2907
2908 // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2909 // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2910 // the following Z could be a throw specifier.
2911 if (MangledName.consumeFront('@'))
2912 return *Head;
2913
2914 if (MangledName.consumeFront('Z')) {
2915 Head->IsVariadic = true;
2916 return *Head;
2917 }
2918
2919 Error = true;
2920 return {};
Zachary Turnerf435a7e2018-07-20 17:27:48 +00002921}
2922
Zachary Turnerd30700f2018-07-31 17:16:44 +00002923TemplateParams *
2924Demangler::demangleTemplateParameterList(StringView &MangledName) {
2925 TemplateParams *Head;
2926 TemplateParams **Current = &Head;
Zachary Turner23df1312018-07-26 22:13:39 +00002927 while (!Error && !MangledName.startsWith('@')) {
Zachary Turner23df1312018-07-26 22:13:39 +00002928 // Template parameter lists don't participate in back-referencing.
Zachary Turnerd30700f2018-07-31 17:16:44 +00002929 *Current = Arena.alloc<TemplateParams>();
Zachary Turner931e8792018-07-30 23:02:10 +00002930
Zachary Turner66555a72018-08-20 19:15:35 +00002931 TemplateParams &TP = **Current;
2932
Zachary Turner931e8792018-07-30 23:02:10 +00002933 // Empty parameter pack.
2934 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2935 MangledName.consumeFront("$$$V")) {
Zachary Turner66555a72018-08-20 19:15:35 +00002936 TP.IsEmptyParameterPack = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00002937 break;
Zachary Turner931e8792018-07-30 23:02:10 +00002938 }
2939
Zachary Turnerd30700f2018-07-31 17:16:44 +00002940 if (MangledName.consumeFront("$$Y")) {
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002941 // Template alias
Zachary Turner66555a72018-08-20 19:15:35 +00002942 TP.IsTemplateTemplate = true;
2943 TP.IsAliasTemplate = true;
2944 TP.ParamName = demangleFullyQualifiedTypeName(MangledName);
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002945 } else if (MangledName.consumeFront("$$B")) {
2946 // Array
Zachary Turner66555a72018-08-20 19:15:35 +00002947 TP.ParamType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turner073620b2018-08-10 19:57:36 +00002948 } else if (MangledName.consumeFront("$$C")) {
2949 // Type has qualifiers.
Zachary Turner66555a72018-08-20 19:15:35 +00002950 TP.ParamType = demangleType(MangledName, QualifierMangleMode::Mangle);
2951 } else if (MangledName.startsWith("$1") || MangledName.startsWith("$H") ||
2952 MangledName.startsWith("$I") || MangledName.startsWith("$J")) {
2953 MangledName = MangledName.dropFront();
2954 // 1 - single inheritance <name>
2955 // H - multiple inheritance <name> <number>
2956 // I - virtual inheritance <name> <number> <number> <number>
2957 // J - unspecified inheritance <name> <number> <number> <number>
2958 char InheritanceSpecifier = MangledName.popFront();
2959 // Pointer to member
2960 Symbol *S = MangledName.startsWith('?') ? parse(MangledName) : nullptr;
2961 switch (InheritanceSpecifier) {
2962 case 'J':
2963 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
2964 LLVM_FALLTHROUGH;
2965 case 'I':
2966 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
2967 LLVM_FALLTHROUGH;
2968 case 'H':
2969 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
2970 LLVM_FALLTHROUGH;
2971 case '1':
2972 break;
2973 default:
2974 Error = true;
2975 break;
2976 }
2977 TP.PointerToSymbol = true;
2978 if (S) {
2979 TP.ParamName = S->SymbolName;
2980 TP.ParamType = S->SymbolType;
2981 } else
2982 TP.NullptrLiteral = true;
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00002983 } else if (MangledName.startsWith("$E?")) {
2984 MangledName.consumeFront("$E");
2985 // Reference to symbol
2986 Symbol *S = parse(MangledName);
Zachary Turner66555a72018-08-20 19:15:35 +00002987 TP.ParamName = S->SymbolName;
2988 TP.ParamType = S->SymbolType;
2989 TP.ReferenceToSymbol = true;
2990 } else if (MangledName.startsWith("$F") || MangledName.startsWith("$G")) {
2991 // Data member pointer.
2992 MangledName = MangledName.dropFront();
2993 char InheritanceSpecifier = MangledName.popFront();
2994
2995 switch (InheritanceSpecifier) {
2996 case 'G':
2997 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
2998 LLVM_FALLTHROUGH;
2999 case 'F':
3000 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
3001 TP.ThunkOffsets[TP.ThunkOffsetCount++] = demangleSigned(MangledName);
3002 LLVM_FALLTHROUGH;
3003 case '0':
3004 break;
3005 default:
3006 Error = true;
3007 break;
3008 }
3009 TP.DataMemberPointer = true;
3010
Zachary Turnerdbefc6c2018-08-10 14:31:04 +00003011 } else if (MangledName.consumeFront("$0")) {
3012 // Integral non-type template parameter
3013 bool IsNegative = false;
3014 uint64_t Value = 0;
3015 std::tie(Value, IsNegative) = demangleNumber(MangledName);
3016
Zachary Turner66555a72018-08-20 19:15:35 +00003017 TP.IsIntegerLiteral = true;
3018 TP.IntegerLiteralIsNegative = IsNegative;
3019 TP.IntegralValue = Value;
Zachary Turnerd30700f2018-07-31 17:16:44 +00003020 } else {
Zachary Turner66555a72018-08-20 19:15:35 +00003021 TP.ParamType = demangleType(MangledName, QualifierMangleMode::Drop);
Zachary Turnerd30700f2018-07-31 17:16:44 +00003022 }
Zachary Turner54d4ffe2018-08-01 18:32:28 +00003023 if (Error)
3024 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00003025
Zachary Turner66555a72018-08-20 19:15:35 +00003026 Current = &TP.Next;
Zachary Turner23df1312018-07-26 22:13:39 +00003027 }
3028
3029 if (Error)
Zachary Turner54d4ffe2018-08-01 18:32:28 +00003030 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00003031
3032 // Template parameter lists cannot be variadic, so it can only be terminated
3033 // by @.
3034 if (MangledName.consumeFront('@'))
Zachary Turner931e8792018-07-30 23:02:10 +00003035 return Head;
Zachary Turner23df1312018-07-26 22:13:39 +00003036 Error = true;
Zachary Turner54d4ffe2018-08-01 18:32:28 +00003037 return nullptr;
Zachary Turner23df1312018-07-26 22:13:39 +00003038}
3039
Zachary Turner316109b2018-07-29 16:38:02 +00003040void Demangler::output(const Symbol *S, OutputStream &OS) {
Zachary Turner83313f82018-08-16 16:17:17 +00003041 if (S->Category == SymbolCategory::Unknown) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00003042 outputName(OS, S->SymbolName, S->SymbolType);
Zachary Turner83313f82018-08-16 16:17:17 +00003043 return;
3044 }
Zachary Turner970fdc32018-08-16 16:17:36 +00003045
Zachary Turner469f0762018-08-17 21:18:05 +00003046 if (S->Category == SymbolCategory::SpecialOperator) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00003047 outputSpecialOperator(OS, S->SymbolName);
Zachary Turner469f0762018-08-17 21:18:05 +00003048 return;
3049 }
3050
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003051 // Converts an AST to a string.
3052 //
3053 // Converting an AST representing a C++ type to a string is tricky due
3054 // to the bad grammar of the C++ declaration inherited from C. You have
3055 // to construct a string from inside to outside. For example, if a type
3056 // X is a pointer to a function returning int, the order you create a
3057 // string becomes something like this:
3058 //
3059 // (1) X is a pointer: *X
3060 // (2) (1) is a function returning int: int (*X)()
3061 //
3062 // So you cannot construct a result just by appending strings to a result.
3063 //
3064 // To deal with this, we split the function into two. outputPre() writes
3065 // the "first half" of type declaration, and outputPost() writes the
3066 // "second half". For example, outputPre() writes a return type for a
3067 // function and outputPost() writes an parameter list.
Zachary Turner3461bfa2018-08-17 16:14:05 +00003068 if (S->SymbolType) {
Zachary Turnerd9e925f2018-08-18 18:49:48 +00003069 Type::outputPre(OS, *S->SymbolType);
3070 outputName(OS, S->SymbolName, S->SymbolType);
3071 Type::outputPost(OS, *S->SymbolType);
Zachary Turner469f0762018-08-17 21:18:05 +00003072 } else {
3073 outputQualifiers(OS, S->SymbolQuals);
Zachary Turnerd9e925f2018-08-18 18:49:48 +00003074 outputName(OS, S->SymbolName, nullptr);
Zachary Turner469f0762018-08-17 21:18:05 +00003075 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003076}
3077
Zachary Turner3a758e22018-08-01 18:33:04 +00003078void Demangler::dumpBackReferences() {
Zachary Turner5ae08b82018-08-01 18:44:12 +00003079 std::printf("%d function parameter backreferences\n",
Zachary Turnerd346cba2018-08-08 17:17:04 +00003080 (int)Backrefs.FunctionParamCount);
Zachary Turner3a758e22018-08-01 18:33:04 +00003081
3082 // Create an output stream so we can render each type.
3083 OutputStream OS = OutputStream::create(nullptr, 0, 1024);
Zachary Turnerd346cba2018-08-08 17:17:04 +00003084 for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
Zachary Turner3a758e22018-08-01 18:33:04 +00003085 OS.setCurrentPosition(0);
3086
Zachary Turnerd346cba2018-08-08 17:17:04 +00003087 Type *T = Backrefs.FunctionParams[I];
Zachary Turnerd9e925f2018-08-18 18:49:48 +00003088 Type::outputPre(OS, *T);
3089 Type::outputPost(OS, *T);
Zachary Turner3a758e22018-08-01 18:33:04 +00003090
Zachary Turner7563ebe2018-08-02 17:08:24 +00003091 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
Zachary Turner5ae08b82018-08-01 18:44:12 +00003092 OS.getBuffer());
Zachary Turner3a758e22018-08-01 18:33:04 +00003093 }
3094 std::free(OS.getBuffer());
3095
Zachary Turnerd346cba2018-08-08 17:17:04 +00003096 if (Backrefs.FunctionParamCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00003097 std::printf("\n");
Zachary Turnerd346cba2018-08-08 17:17:04 +00003098 std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
3099 for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
3100 std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I].size(),
3101 Backrefs.Names[I].begin());
Zachary Turner3a758e22018-08-01 18:33:04 +00003102 }
Zachary Turnerd346cba2018-08-08 17:17:04 +00003103 if (Backrefs.NamesCount > 0)
Zachary Turner5ae08b82018-08-01 18:44:12 +00003104 std::printf("\n");
Zachary Turner3a758e22018-08-01 18:33:04 +00003105}
3106
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003107char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N,
Zachary Turner3a758e22018-08-01 18:33:04 +00003108 int *Status, MSDemangleFlags Flags) {
Zachary Turner316109b2018-07-29 16:38:02 +00003109 Demangler D;
3110 StringView Name{MangledName};
3111 Symbol *S = D.parse(Name);
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003112
Zachary Turner3a758e22018-08-01 18:33:04 +00003113 if (Flags & MSDF_DumpBackrefs)
3114 D.dumpBackReferences();
Zachary Turner316109b2018-07-29 16:38:02 +00003115 OutputStream OS = OutputStream::create(Buf, N, 1024);
Zachary Turner54d4ffe2018-08-01 18:32:28 +00003116 if (D.Error) {
3117 OS << MangledName;
3118 *Status = llvm::demangle_invalid_mangled_name;
3119 } else {
3120 D.output(S, OS);
3121 *Status = llvm::demangle_success;
3122 }
3123
Zachary Turner71c91f92018-07-30 03:12:34 +00003124 OS << '\0';
Zachary Turnerf435a7e2018-07-20 17:27:48 +00003125 return OS.getBuffer();
3126}