blob: caa7eb3b5262bcb86a62e0efb9173d3bc94cb413 [file] [log] [blame]
Zachary Turner03312862018-08-27 03:48:03 +00001#ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
2#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
3
4#include "llvm/Demangle/Compiler.h"
5#include "llvm/Demangle/StringView.h"
6#include <array>
7
8class OutputStream;
9
10namespace llvm {
11namespace ms_demangle {
12
13// This memory allocator is extremely fast, but it doesn't call dtors
14// for allocated objects. That means you can't use STL containers
15// (such as std::vector) with this allocator. But it pays off --
16// the demangler is 3x faster with this allocator compared to one with
17// STL containers.
18constexpr size_t AllocUnit = 4096;
19
20class ArenaAllocator {
21 struct AllocatorNode {
22 uint8_t *Buf = nullptr;
23 size_t Used = 0;
24 size_t Capacity = 0;
25 AllocatorNode *Next = nullptr;
26 };
27
28 void addNode(size_t Capacity) {
29 AllocatorNode *NewHead = new AllocatorNode;
30 NewHead->Buf = new uint8_t[Capacity];
31 NewHead->Next = Head;
32 NewHead->Capacity = Capacity;
33 Head = NewHead;
34 NewHead->Used = 0;
35 }
36
37public:
38 ArenaAllocator() { addNode(AllocUnit); }
39
40 ~ArenaAllocator() {
41 while (Head) {
42 assert(Head->Buf);
43 delete[] Head->Buf;
44 AllocatorNode *Next = Head->Next;
45 delete Head;
46 Head = Next;
47 }
48 }
49
50 char *allocUnalignedBuffer(size_t Length) {
51 uint8_t *Buf = Head->Buf + Head->Used;
52
53 Head->Used += Length;
54 if (Head->Used > Head->Capacity) {
55 // It's possible we need a buffer which is larger than our default unit
56 // size, so we need to be careful to add a node with capacity that is at
57 // least as large as what we need.
58 addNode(std::max(AllocUnit, Length));
59 Head->Used = Length;
60 Buf = Head->Buf;
61 }
62
63 return reinterpret_cast<char *>(Buf);
64 }
65
66 template <typename T, typename... Args>
67 T *allocArray(size_t Count) {
68
69 size_t Size = Count * sizeof(T);
70 assert(Head && Head->Buf);
71
72 size_t P = (size_t)Head->Buf + Head->Used;
73 uintptr_t AlignedP =
74 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
75 uint8_t *PP = (uint8_t *)AlignedP;
76 size_t Adjustment = AlignedP - P;
77
78 Head->Used += Size + Adjustment;
79 if (Head->Used < Head->Capacity)
80 return new (PP) T[Count]();
81
82 addNode(AllocUnit);
83 Head->Used = Size;
84 return new (Head->Buf) T[Count]();
85 }
86
87 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
88
89 size_t Size = sizeof(T);
90 assert(Head && Head->Buf);
91
92 size_t P = (size_t)Head->Buf + Head->Used;
93 uintptr_t AlignedP =
94 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
95 uint8_t *PP = (uint8_t *)AlignedP;
96 size_t Adjustment = AlignedP - P;
97
98 Head->Used += Size + Adjustment;
99 if (Head->Used < Head->Capacity)
100 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
101
102 addNode(AllocUnit);
103 Head->Used = Size;
104 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
105 }
106
107private:
108 AllocatorNode *Head = nullptr;
109};
110
111// Storage classes
112enum Qualifiers : uint8_t {
113 Q_None = 0,
114 Q_Const = 1 << 0,
115 Q_Volatile = 1 << 1,
116 Q_Far = 1 << 2,
117 Q_Huge = 1 << 3,
118 Q_Unaligned = 1 << 4,
119 Q_Restrict = 1 << 5,
120 Q_Pointer64 = 1 << 6
121};
122
123enum class StorageClass : uint8_t {
124 None,
125 PrivateStatic,
126 ProtectedStatic,
127 PublicStatic,
128 Global,
129 FunctionLocalStatic,
130};
131
132enum class PointerAffinity { None, Pointer, Reference, RValueReference };
133enum class FunctionRefQualifier { None, Reference, RValueReference };
134
135// Calling conventions
136enum class CallingConv : uint8_t {
137 None,
138 Cdecl,
139 Pascal,
140 Thiscall,
141 Stdcall,
142 Fastcall,
143 Clrcall,
144 Eabi,
145 Vectorcall,
146 Regcall,
147};
148
149enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
150
Zachary Turnerb2fef1a2018-08-29 04:12:44 +0000151enum OutputFlags {
152 OF_Default = 0,
153 OF_NoCallingConvention = 1,
154};
Zachary Turner03312862018-08-27 03:48:03 +0000155
156// Types
157enum class PrimitiveKind {
158 Void,
159 Bool,
160 Char,
161 Schar,
162 Uchar,
163 Char16,
164 Char32,
165 Short,
166 Ushort,
167 Int,
168 Uint,
169 Long,
170 Ulong,
171 Int64,
172 Uint64,
173 Wchar,
174 Float,
175 Double,
176 Ldouble,
177 Nullptr,
178};
179
180enum class CharKind {
181 Char,
182 Char16,
183 Char32,
184 Wchar,
185};
186
187enum class IntrinsicFunctionKind : uint8_t {
188 None,
189 New, // ?2 # operator new
190 Delete, // ?3 # operator delete
191 Assign, // ?4 # operator=
192 RightShift, // ?5 # operator>>
193 LeftShift, // ?6 # operator<<
194 LogicalNot, // ?7 # operator!
195 Equals, // ?8 # operator==
196 NotEquals, // ?9 # operator!=
197 ArraySubscript, // ?A # operator[]
198 Pointer, // ?C # operator->
199 Dereference, // ?D # operator*
200 Increment, // ?E # operator++
201 Decrement, // ?F # operator--
202 Minus, // ?G # operator-
203 Plus, // ?H # operator+
204 BitwiseAnd, // ?I # operator&
205 MemberPointer, // ?J # operator->*
206 Divide, // ?K # operator/
207 Modulus, // ?L # operator%
208 LessThan, // ?M operator<
209 LessThanEqual, // ?N operator<=
210 GreaterThan, // ?O operator>
211 GreaterThanEqual, // ?P operator>=
212 Comma, // ?Q operator,
213 Parens, // ?R operator()
214 BitwiseNot, // ?S operator~
215 BitwiseXor, // ?T operator^
216 BitwiseOr, // ?U operator|
217 LogicalAnd, // ?V operator&&
218 LogicalOr, // ?W operator||
219 TimesEqual, // ?X operator*=
220 PlusEqual, // ?Y operator+=
221 MinusEqual, // ?Z operator-=
222 DivEqual, // ?_0 operator/=
223 ModEqual, // ?_1 operator%=
224 RshEqual, // ?_2 operator>>=
225 LshEqual, // ?_3 operator<<=
226 BitwiseAndEqual, // ?_4 operator&=
227 BitwiseOrEqual, // ?_5 operator|=
228 BitwiseXorEqual, // ?_6 operator^=
229 VbaseDtor, // ?_D # vbase destructor
230 VecDelDtor, // ?_E # vector deleting destructor
231 DefaultCtorClosure, // ?_F # default constructor closure
232 ScalarDelDtor, // ?_G # scalar deleting destructor
233 VecCtorIter, // ?_H # vector constructor iterator
234 VecDtorIter, // ?_I # vector destructor iterator
235 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
236 VdispMap, // ?_K # virtual displacement map
237 EHVecCtorIter, // ?_L # eh vector constructor iterator
238 EHVecDtorIter, // ?_M # eh vector destructor iterator
239 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
240 CopyCtorClosure, // ?_O # copy constructor closure
241 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
242 ArrayNew, // ?_U operator new[]
243 ArrayDelete, // ?_V operator delete[]
244 ManVectorCtorIter, // ?__A managed vector ctor iterator
245 ManVectorDtorIter, // ?__B managed vector dtor iterator
246 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
247 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
248 VectorCopyCtorIter, // ?__G vector copy constructor iterator
249 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
250 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
251 CoAwait, // ?__L co_await
252 Spaceship, // operator<=>
253 MaxIntrinsic
254};
255
256enum class SpecialIntrinsicKind {
257 None,
258 Vftable,
259 Vbtable,
260 Typeof,
261 VcallThunk,
262 LocalStaticGuard,
263 StringLiteralSymbol,
264 UdtReturning,
265 Unknown,
266 DynamicInitializer,
267 DynamicAtexitDestructor,
268 RttiTypeDescriptor,
269 RttiBaseClassDescriptor,
270 RttiBaseClassArray,
271 RttiClassHierarchyDescriptor,
272 RttiCompleteObjLocator,
273 LocalVftable,
274 LocalStaticThreadGuard,
275};
276
277// Function classes
278enum FuncClass : uint16_t {
279 FC_None = 0,
280 FC_Public = 1 << 0,
281 FC_Protected = 1 << 1,
282 FC_Private = 1 << 2,
283 FC_Global = 1 << 3,
284 FC_Static = 1 << 4,
285 FC_Virtual = 1 << 5,
286 FC_Far = 1 << 6,
287 FC_ExternC = 1 << 7,
288 FC_NoParameterList = 1 << 8,
289 FC_VirtualThisAdjust = 1 << 9,
290 FC_VirtualThisAdjustEx = 1 << 10,
291 FC_StaticThisAdjust = 1 << 11,
292};
293
294enum class TagKind { Class, Struct, Union, Enum };
295
296enum class NodeKind {
297 Unknown,
298 Md5Symbol,
299 PrimitiveType,
300 FunctionSignature,
301 Identifier,
302 NamedIdentifier,
303 VcallThunkIdentifier,
304 LocalStaticGuardIdentifier,
305 IntrinsicFunctionIdentifier,
306 ConversionOperatorIdentifier,
307 DynamicStructorIdentifier,
308 StructorIdentifier,
309 LiteralOperatorIdentifier,
310 ThunkSignature,
311 PointerType,
312 TagType,
313 ArrayType,
314 Custom,
315 IntrinsicType,
316 NodeArray,
317 QualifiedName,
318 TemplateParameterReference,
319 EncodedStringLiteral,
320 IntegerLiteral,
321 RttiBaseClassDescriptor,
322 LocalStaticGuardVariable,
323 FunctionSymbol,
324 VariableSymbol,
Zachary Turner32a8a202018-08-29 23:56:09 +0000325 SpecialTableSymbol
Zachary Turner03312862018-08-27 03:48:03 +0000326};
327
328struct Node {
329 explicit Node(NodeKind K) : Kind(K) {}
Zachary Turner03b6f5a2018-08-27 04:04:41 +0000330 virtual ~Node() = default;
Zachary Turner03312862018-08-27 03:48:03 +0000331
332 NodeKind kind() const { return Kind; }
333
Zachary Turner38d2edd2018-08-29 03:59:17 +0000334 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
Zachary Turner03312862018-08-27 03:48:03 +0000335
336private:
337 NodeKind Kind;
338};
339
340struct TypeNode;
341struct PrimitiveTypeNode;
342struct FunctionSignatureNode;
343struct IdentifierNode;
344struct NamedIdentifierNode;
345struct VcallThunkIdentifierNode;
346struct IntrinsicFunctionIdentifierNode;
347struct LiteralOperatorIdentifierNode;
348struct ConversionOperatorIdentifierNode;
349struct StructorIdentifierNode;
350struct ThunkSignatureNode;
351struct PointerTypeNode;
352struct ArrayTypeNode;
353struct CustomNode;
354struct TagTypeNode;
355struct IntrinsicTypeNode;
356struct NodeArrayNode;
357struct QualifiedNameNode;
358struct TemplateParameterReferenceNode;
359struct EncodedStringLiteralNode;
360struct IntegerLiteralNode;
361struct RttiBaseClassDescriptorNode;
362struct LocalStaticGuardVariableNode;
363struct SymbolNode;
364struct FunctionSymbolNode;
365struct VariableSymbolNode;
366struct SpecialTableSymbolNode;
367
368struct TypeNode : public Node {
369 explicit TypeNode(NodeKind K) : Node(K) {}
370
Zachary Turner38d2edd2018-08-29 03:59:17 +0000371 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
372 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
Zachary Turner03312862018-08-27 03:48:03 +0000373
Zachary Turner38d2edd2018-08-29 03:59:17 +0000374 void output(OutputStream &OS, OutputFlags Flags) const override {
375 outputPre(OS, Flags);
376 outputPost(OS, Flags);
Zachary Turner03312862018-08-27 03:48:03 +0000377 }
378
379 void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
380
381 Qualifiers Quals = Q_None;
382};
383
384struct PrimitiveTypeNode : public TypeNode {
385 explicit PrimitiveTypeNode(PrimitiveKind K)
386 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
387
Zachary Turner38d2edd2018-08-29 03:59:17 +0000388 void outputPre(OutputStream &OS, OutputFlags Flags) const;
389 void outputPost(OutputStream &OS, OutputFlags Flags) const {}
Zachary Turner03312862018-08-27 03:48:03 +0000390
391 PrimitiveKind PrimKind;
392};
393
394struct FunctionSignatureNode : public TypeNode {
395 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
396 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
397
Zachary Turnerb2fef1a2018-08-29 04:12:44 +0000398 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
399 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000400
401 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
402 // MemberPointerType.
403 PointerAffinity Affinity = PointerAffinity::None;
404
405 // The function's calling convention.
406 CallingConv CallConvention = CallingConv::None;
407
408 // Function flags (gloabl, public, etc)
409 FuncClass FunctionClass = FC_Global;
410
411 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
412
413 // The return type of the function.
414 TypeNode *ReturnType = nullptr;
415
416 // True if this is a C-style ... varargs function.
417 bool IsVariadic = false;
418
419 // Function parameters
420 NodeArrayNode *Params = nullptr;
421};
422
423struct IdentifierNode : public Node {
424 explicit IdentifierNode(NodeKind K) : Node(K) {}
425
426 NodeArrayNode *TemplateParams = nullptr;
427
428protected:
Zachary Turner38d2edd2018-08-29 03:59:17 +0000429 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000430};
431
432struct VcallThunkIdentifierNode : public IdentifierNode {
433 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
434
Zachary Turner38d2edd2018-08-29 03:59:17 +0000435 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000436
437 uint64_t OffsetInVTable = 0;
438};
439
440struct DynamicStructorIdentifierNode : public IdentifierNode {
441 DynamicStructorIdentifierNode()
442 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
443
Zachary Turner38d2edd2018-08-29 03:59:17 +0000444 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000445
Zachary Turner32a8a202018-08-29 23:56:09 +0000446 VariableSymbolNode *Variable = nullptr;
Zachary Turner03312862018-08-27 03:48:03 +0000447 QualifiedNameNode *Name = nullptr;
448 bool IsDestructor = false;
449};
450
451struct NamedIdentifierNode : public IdentifierNode {
452 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
453
Zachary Turner38d2edd2018-08-29 03:59:17 +0000454 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000455
456 StringView Name;
457};
458
459struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
460 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
461 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
462 Operator(Operator) {}
463
Zachary Turner38d2edd2018-08-29 03:59:17 +0000464 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000465
466 IntrinsicFunctionKind Operator;
467};
468
469struct LiteralOperatorIdentifierNode : public IdentifierNode {
470 LiteralOperatorIdentifierNode()
471 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
472
Zachary Turner38d2edd2018-08-29 03:59:17 +0000473 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000474
475 StringView Name;
476};
477
478struct LocalStaticGuardIdentifierNode : public IdentifierNode {
479 LocalStaticGuardIdentifierNode()
480 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
481
Zachary Turner38d2edd2018-08-29 03:59:17 +0000482 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000483
484 uint32_t ScopeIndex = 0;
485};
486
487struct ConversionOperatorIdentifierNode : public IdentifierNode {
488 ConversionOperatorIdentifierNode()
489 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
490
Zachary Turner38d2edd2018-08-29 03:59:17 +0000491 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000492
493 // The type that this operator converts too.
494 TypeNode *TargetType = nullptr;
495};
496
497struct StructorIdentifierNode : public IdentifierNode {
498 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
499 explicit StructorIdentifierNode(bool IsDestructor)
500 : IdentifierNode(NodeKind::StructorIdentifier),
501 IsDestructor(IsDestructor) {}
502
Zachary Turner38d2edd2018-08-29 03:59:17 +0000503 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000504
505 // The name of the class that this is a structor of.
506 IdentifierNode *Class = nullptr;
507 bool IsDestructor = false;
508};
509
510struct ThunkSignatureNode : public FunctionSignatureNode {
511 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
512
Zachary Turner38d2edd2018-08-29 03:59:17 +0000513 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
514 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000515
516 struct ThisAdjustor {
517 uint32_t StaticOffset = 0;
518 int32_t VBPtrOffset = 0;
519 int32_t VBOffsetOffset = 0;
520 int32_t VtordispOffset = 0;
521 };
522
523 ThisAdjustor ThisAdjust;
524};
525
526struct PointerTypeNode : public TypeNode {
527 PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000528 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
529 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000530
531 // Is this a pointer, reference, or rvalue-reference?
532 PointerAffinity Affinity = PointerAffinity::None;
533
534 // If this is a member pointer, this is the class that the member is in.
535 QualifiedNameNode *ClassParent = nullptr;
536
537 // Represents a type X in "a pointer to X", "a reference to X", or
538 // "rvalue-reference to X"
539 TypeNode *Pointee = nullptr;
540};
541
542struct TagTypeNode : public TypeNode {
543 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
544
Zachary Turner38d2edd2018-08-29 03:59:17 +0000545 void outputPre(OutputStream &OS, OutputFlags Flags) const;
546 void outputPost(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000547
548 QualifiedNameNode *QualifiedName = nullptr;
549 TagKind Tag;
550};
551
552struct ArrayTypeNode : public TypeNode {
553 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
554
Zachary Turner38d2edd2018-08-29 03:59:17 +0000555 void outputPre(OutputStream &OS, OutputFlags Flags) const;
556 void outputPost(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000557
Zachary Turner38d2edd2018-08-29 03:59:17 +0000558 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
559 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
Zachary Turner03312862018-08-27 03:48:03 +0000560
561 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
562 NodeArrayNode *Dimensions = nullptr;
563
564 // The type of array element.
565 TypeNode *ElementType = nullptr;
566};
567
568struct IntrinsicNode : public TypeNode {
569 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000570 void output(OutputStream &OS, OutputFlags Flags) const override {}
Zachary Turner03312862018-08-27 03:48:03 +0000571};
572
Zachary Turnerb2fef1a2018-08-29 04:12:44 +0000573struct CustomTypeNode : public TypeNode {
574 CustomTypeNode() : TypeNode(NodeKind::Custom) {}
Zachary Turner03312862018-08-27 03:48:03 +0000575
Zachary Turnerb2fef1a2018-08-29 04:12:44 +0000576 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
577 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000578
Zachary Turnerb2fef1a2018-08-29 04:12:44 +0000579 IdentifierNode *Identifier;
Zachary Turner03312862018-08-27 03:48:03 +0000580};
581
582struct NodeArrayNode : public Node {
583 NodeArrayNode() : Node(NodeKind::NodeArray) {}
584
Zachary Turner38d2edd2018-08-29 03:59:17 +0000585 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000586
Zachary Turner38d2edd2018-08-29 03:59:17 +0000587 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
Zachary Turner03312862018-08-27 03:48:03 +0000588
589 Node **Nodes = 0;
590 size_t Count = 0;
591};
592
593struct QualifiedNameNode : public Node {
594 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
595
Zachary Turner38d2edd2018-08-29 03:59:17 +0000596 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000597
598 NodeArrayNode *Components = nullptr;
599
600 IdentifierNode *getUnqualifiedIdentifier() {
601 Node *LastComponent = Components->Nodes[Components->Count - 1];
602 return static_cast<IdentifierNode *>(LastComponent);
603 }
604};
605
606struct TemplateParameterReferenceNode : public Node {
607 TemplateParameterReferenceNode()
608 : Node(NodeKind::TemplateParameterReference) {}
609
Zachary Turner38d2edd2018-08-29 03:59:17 +0000610 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000611
612 SymbolNode *Symbol = nullptr;
613
614 int ThunkOffsetCount = 0;
615 std::array<int64_t, 3> ThunkOffsets;
616 PointerAffinity Affinity = PointerAffinity::None;
617 bool IsMemberPointer = false;
618};
619
620struct IntegerLiteralNode : public Node {
621 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
622 IntegerLiteralNode(uint64_t Value, bool IsNegative)
623 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
624
Zachary Turner38d2edd2018-08-29 03:59:17 +0000625 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000626
627 uint64_t Value = 0;
628 bool IsNegative = false;
629};
630
631struct RttiBaseClassDescriptorNode : public IdentifierNode {
632 RttiBaseClassDescriptorNode()
633 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
634
Zachary Turner38d2edd2018-08-29 03:59:17 +0000635 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000636
637 uint32_t NVOffset = 0;
638 int32_t VBPtrOffset = 0;
639 uint32_t VBTableOffset = 0;
640 uint32_t Flags = 0;
641};
642
643struct SymbolNode : public Node {
644 explicit SymbolNode(NodeKind K) : Node(K) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000645 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000646 QualifiedNameNode *Name = nullptr;
647};
648
649struct SpecialTableSymbolNode : public SymbolNode {
650 explicit SpecialTableSymbolNode()
651 : SymbolNode(NodeKind::SpecialTableSymbol) {}
652
Zachary Turner38d2edd2018-08-29 03:59:17 +0000653 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000654 QualifiedNameNode *TargetName = nullptr;
655 Qualifiers Quals;
656};
657
658struct LocalStaticGuardVariableNode : public SymbolNode {
659 LocalStaticGuardVariableNode()
660 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
661
Zachary Turner38d2edd2018-08-29 03:59:17 +0000662 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000663
664 bool IsVisible = false;
665};
666
667struct EncodedStringLiteralNode : public SymbolNode {
668 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
669
Zachary Turner38d2edd2018-08-29 03:59:17 +0000670 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000671
672 StringView DecodedString;
673 bool IsTruncated = false;
674 CharKind Char = CharKind::Char;
675};
676
677struct VariableSymbolNode : public SymbolNode {
678 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
679
Zachary Turner38d2edd2018-08-29 03:59:17 +0000680 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000681
682 StorageClass SC = StorageClass::None;
683 TypeNode *Type = nullptr;
684};
685
686struct FunctionSymbolNode : public SymbolNode {
687 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
688
Zachary Turner38d2edd2018-08-29 03:59:17 +0000689 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000690
691 FunctionSignatureNode *Signature = nullptr;
692};
693
694} // namespace ms_demangle
695} // namespace llvm
696
697#endif