blob: 1797403cef512028bc7298f8ff2af462e483bba3 [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 Turner38d2edd2018-08-29 03:59:17 +0000151enum OutputFlags { OF_Default = 0, OF_NoCallingConvention = 1 };
Zachary Turner03312862018-08-27 03:48:03 +0000152
153// Types
154enum class PrimitiveKind {
155 Void,
156 Bool,
157 Char,
158 Schar,
159 Uchar,
160 Char16,
161 Char32,
162 Short,
163 Ushort,
164 Int,
165 Uint,
166 Long,
167 Ulong,
168 Int64,
169 Uint64,
170 Wchar,
171 Float,
172 Double,
173 Ldouble,
174 Nullptr,
175};
176
177enum class CharKind {
178 Char,
179 Char16,
180 Char32,
181 Wchar,
182};
183
184enum class IntrinsicFunctionKind : uint8_t {
185 None,
186 New, // ?2 # operator new
187 Delete, // ?3 # operator delete
188 Assign, // ?4 # operator=
189 RightShift, // ?5 # operator>>
190 LeftShift, // ?6 # operator<<
191 LogicalNot, // ?7 # operator!
192 Equals, // ?8 # operator==
193 NotEquals, // ?9 # operator!=
194 ArraySubscript, // ?A # operator[]
195 Pointer, // ?C # operator->
196 Dereference, // ?D # operator*
197 Increment, // ?E # operator++
198 Decrement, // ?F # operator--
199 Minus, // ?G # operator-
200 Plus, // ?H # operator+
201 BitwiseAnd, // ?I # operator&
202 MemberPointer, // ?J # operator->*
203 Divide, // ?K # operator/
204 Modulus, // ?L # operator%
205 LessThan, // ?M operator<
206 LessThanEqual, // ?N operator<=
207 GreaterThan, // ?O operator>
208 GreaterThanEqual, // ?P operator>=
209 Comma, // ?Q operator,
210 Parens, // ?R operator()
211 BitwiseNot, // ?S operator~
212 BitwiseXor, // ?T operator^
213 BitwiseOr, // ?U operator|
214 LogicalAnd, // ?V operator&&
215 LogicalOr, // ?W operator||
216 TimesEqual, // ?X operator*=
217 PlusEqual, // ?Y operator+=
218 MinusEqual, // ?Z operator-=
219 DivEqual, // ?_0 operator/=
220 ModEqual, // ?_1 operator%=
221 RshEqual, // ?_2 operator>>=
222 LshEqual, // ?_3 operator<<=
223 BitwiseAndEqual, // ?_4 operator&=
224 BitwiseOrEqual, // ?_5 operator|=
225 BitwiseXorEqual, // ?_6 operator^=
226 VbaseDtor, // ?_D # vbase destructor
227 VecDelDtor, // ?_E # vector deleting destructor
228 DefaultCtorClosure, // ?_F # default constructor closure
229 ScalarDelDtor, // ?_G # scalar deleting destructor
230 VecCtorIter, // ?_H # vector constructor iterator
231 VecDtorIter, // ?_I # vector destructor iterator
232 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
233 VdispMap, // ?_K # virtual displacement map
234 EHVecCtorIter, // ?_L # eh vector constructor iterator
235 EHVecDtorIter, // ?_M # eh vector destructor iterator
236 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
237 CopyCtorClosure, // ?_O # copy constructor closure
238 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
239 ArrayNew, // ?_U operator new[]
240 ArrayDelete, // ?_V operator delete[]
241 ManVectorCtorIter, // ?__A managed vector ctor iterator
242 ManVectorDtorIter, // ?__B managed vector dtor iterator
243 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
244 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
245 VectorCopyCtorIter, // ?__G vector copy constructor iterator
246 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
247 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
248 CoAwait, // ?__L co_await
249 Spaceship, // operator<=>
250 MaxIntrinsic
251};
252
253enum class SpecialIntrinsicKind {
254 None,
255 Vftable,
256 Vbtable,
257 Typeof,
258 VcallThunk,
259 LocalStaticGuard,
260 StringLiteralSymbol,
261 UdtReturning,
262 Unknown,
263 DynamicInitializer,
264 DynamicAtexitDestructor,
265 RttiTypeDescriptor,
266 RttiBaseClassDescriptor,
267 RttiBaseClassArray,
268 RttiClassHierarchyDescriptor,
269 RttiCompleteObjLocator,
270 LocalVftable,
271 LocalStaticThreadGuard,
272};
273
274// Function classes
275enum FuncClass : uint16_t {
276 FC_None = 0,
277 FC_Public = 1 << 0,
278 FC_Protected = 1 << 1,
279 FC_Private = 1 << 2,
280 FC_Global = 1 << 3,
281 FC_Static = 1 << 4,
282 FC_Virtual = 1 << 5,
283 FC_Far = 1 << 6,
284 FC_ExternC = 1 << 7,
285 FC_NoParameterList = 1 << 8,
286 FC_VirtualThisAdjust = 1 << 9,
287 FC_VirtualThisAdjustEx = 1 << 10,
288 FC_StaticThisAdjust = 1 << 11,
289};
290
291enum class TagKind { Class, Struct, Union, Enum };
292
293enum class NodeKind {
294 Unknown,
295 Md5Symbol,
296 PrimitiveType,
297 FunctionSignature,
298 Identifier,
299 NamedIdentifier,
300 VcallThunkIdentifier,
301 LocalStaticGuardIdentifier,
302 IntrinsicFunctionIdentifier,
303 ConversionOperatorIdentifier,
304 DynamicStructorIdentifier,
305 StructorIdentifier,
306 LiteralOperatorIdentifier,
307 ThunkSignature,
308 PointerType,
309 TagType,
310 ArrayType,
311 Custom,
312 IntrinsicType,
313 NodeArray,
314 QualifiedName,
315 TemplateParameterReference,
316 EncodedStringLiteral,
317 IntegerLiteral,
318 RttiBaseClassDescriptor,
319 LocalStaticGuardVariable,
320 FunctionSymbol,
321 VariableSymbol,
322 SpecialTableSymbol,
323};
324
325struct Node {
326 explicit Node(NodeKind K) : Kind(K) {}
Zachary Turner03b6f5a2018-08-27 04:04:41 +0000327 virtual ~Node() = default;
Zachary Turner03312862018-08-27 03:48:03 +0000328
329 NodeKind kind() const { return Kind; }
330
Zachary Turner38d2edd2018-08-29 03:59:17 +0000331 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
Zachary Turner03312862018-08-27 03:48:03 +0000332
333private:
334 NodeKind Kind;
335};
336
337struct TypeNode;
338struct PrimitiveTypeNode;
339struct FunctionSignatureNode;
340struct IdentifierNode;
341struct NamedIdentifierNode;
342struct VcallThunkIdentifierNode;
343struct IntrinsicFunctionIdentifierNode;
344struct LiteralOperatorIdentifierNode;
345struct ConversionOperatorIdentifierNode;
346struct StructorIdentifierNode;
347struct ThunkSignatureNode;
348struct PointerTypeNode;
349struct ArrayTypeNode;
350struct CustomNode;
351struct TagTypeNode;
352struct IntrinsicTypeNode;
353struct NodeArrayNode;
354struct QualifiedNameNode;
355struct TemplateParameterReferenceNode;
356struct EncodedStringLiteralNode;
357struct IntegerLiteralNode;
358struct RttiBaseClassDescriptorNode;
359struct LocalStaticGuardVariableNode;
360struct SymbolNode;
361struct FunctionSymbolNode;
362struct VariableSymbolNode;
363struct SpecialTableSymbolNode;
364
365struct TypeNode : public Node {
366 explicit TypeNode(NodeKind K) : Node(K) {}
367
Zachary Turner38d2edd2018-08-29 03:59:17 +0000368 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
369 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
Zachary Turner03312862018-08-27 03:48:03 +0000370
Zachary Turner38d2edd2018-08-29 03:59:17 +0000371 void output(OutputStream &OS, OutputFlags Flags) const override {
372 outputPre(OS, Flags);
373 outputPost(OS, Flags);
Zachary Turner03312862018-08-27 03:48:03 +0000374 }
375
376 void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
377
378 Qualifiers Quals = Q_None;
379};
380
381struct PrimitiveTypeNode : public TypeNode {
382 explicit PrimitiveTypeNode(PrimitiveKind K)
383 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
384
Zachary Turner38d2edd2018-08-29 03:59:17 +0000385 void outputPre(OutputStream &OS, OutputFlags Flags) const;
386 void outputPost(OutputStream &OS, OutputFlags Flags) const {}
Zachary Turner03312862018-08-27 03:48:03 +0000387
388 PrimitiveKind PrimKind;
389};
390
391struct FunctionSignatureNode : public TypeNode {
392 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
393 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
394
Zachary Turner38d2edd2018-08-29 03:59:17 +0000395 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const;
396 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000397
398 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
399 // MemberPointerType.
400 PointerAffinity Affinity = PointerAffinity::None;
401
402 // The function's calling convention.
403 CallingConv CallConvention = CallingConv::None;
404
405 // Function flags (gloabl, public, etc)
406 FuncClass FunctionClass = FC_Global;
407
408 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
409
410 // The return type of the function.
411 TypeNode *ReturnType = nullptr;
412
413 // True if this is a C-style ... varargs function.
414 bool IsVariadic = false;
415
416 // Function parameters
417 NodeArrayNode *Params = nullptr;
418};
419
420struct IdentifierNode : public Node {
421 explicit IdentifierNode(NodeKind K) : Node(K) {}
422
423 NodeArrayNode *TemplateParams = nullptr;
424
425protected:
Zachary Turner38d2edd2018-08-29 03:59:17 +0000426 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000427};
428
429struct VcallThunkIdentifierNode : public IdentifierNode {
430 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
431
Zachary Turner38d2edd2018-08-29 03:59:17 +0000432 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000433
434 uint64_t OffsetInVTable = 0;
435};
436
437struct DynamicStructorIdentifierNode : public IdentifierNode {
438 DynamicStructorIdentifierNode()
439 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
440
Zachary Turner38d2edd2018-08-29 03:59:17 +0000441 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000442
443 QualifiedNameNode *Name = nullptr;
444 bool IsDestructor = false;
445};
446
447struct NamedIdentifierNode : public IdentifierNode {
448 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
449
Zachary Turner38d2edd2018-08-29 03:59:17 +0000450 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000451
452 StringView Name;
453};
454
455struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
456 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
457 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
458 Operator(Operator) {}
459
Zachary Turner38d2edd2018-08-29 03:59:17 +0000460 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000461
462 IntrinsicFunctionKind Operator;
463};
464
465struct LiteralOperatorIdentifierNode : public IdentifierNode {
466 LiteralOperatorIdentifierNode()
467 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
468
Zachary Turner38d2edd2018-08-29 03:59:17 +0000469 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000470
471 StringView Name;
472};
473
474struct LocalStaticGuardIdentifierNode : public IdentifierNode {
475 LocalStaticGuardIdentifierNode()
476 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
477
Zachary Turner38d2edd2018-08-29 03:59:17 +0000478 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000479
480 uint32_t ScopeIndex = 0;
481};
482
483struct ConversionOperatorIdentifierNode : public IdentifierNode {
484 ConversionOperatorIdentifierNode()
485 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
486
Zachary Turner38d2edd2018-08-29 03:59:17 +0000487 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000488
489 // The type that this operator converts too.
490 TypeNode *TargetType = nullptr;
491};
492
493struct StructorIdentifierNode : public IdentifierNode {
494 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
495 explicit StructorIdentifierNode(bool IsDestructor)
496 : IdentifierNode(NodeKind::StructorIdentifier),
497 IsDestructor(IsDestructor) {}
498
Zachary Turner38d2edd2018-08-29 03:59:17 +0000499 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000500
501 // The name of the class that this is a structor of.
502 IdentifierNode *Class = nullptr;
503 bool IsDestructor = false;
504};
505
506struct ThunkSignatureNode : public FunctionSignatureNode {
507 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
508
Zachary Turner38d2edd2018-08-29 03:59:17 +0000509 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
510 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000511
512 struct ThisAdjustor {
513 uint32_t StaticOffset = 0;
514 int32_t VBPtrOffset = 0;
515 int32_t VBOffsetOffset = 0;
516 int32_t VtordispOffset = 0;
517 };
518
519 ThisAdjustor ThisAdjust;
520};
521
522struct PointerTypeNode : public TypeNode {
523 PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000524 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
525 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000526
527 // Is this a pointer, reference, or rvalue-reference?
528 PointerAffinity Affinity = PointerAffinity::None;
529
530 // If this is a member pointer, this is the class that the member is in.
531 QualifiedNameNode *ClassParent = nullptr;
532
533 // Represents a type X in "a pointer to X", "a reference to X", or
534 // "rvalue-reference to X"
535 TypeNode *Pointee = nullptr;
536};
537
538struct TagTypeNode : public TypeNode {
539 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
540
Zachary Turner38d2edd2018-08-29 03:59:17 +0000541 void outputPre(OutputStream &OS, OutputFlags Flags) const;
542 void outputPost(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000543
544 QualifiedNameNode *QualifiedName = nullptr;
545 TagKind Tag;
546};
547
548struct ArrayTypeNode : public TypeNode {
549 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
550
Zachary Turner38d2edd2018-08-29 03:59:17 +0000551 void outputPre(OutputStream &OS, OutputFlags Flags) const;
552 void outputPost(OutputStream &OS, OutputFlags Flags) const;
Zachary Turner03312862018-08-27 03:48:03 +0000553
Zachary Turner38d2edd2018-08-29 03:59:17 +0000554 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
555 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
Zachary Turner03312862018-08-27 03:48:03 +0000556
557 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
558 NodeArrayNode *Dimensions = nullptr;
559
560 // The type of array element.
561 TypeNode *ElementType = nullptr;
562};
563
564struct IntrinsicNode : public TypeNode {
565 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000566 void output(OutputStream &OS, OutputFlags Flags) const override {}
Zachary Turner03312862018-08-27 03:48:03 +0000567};
568
569struct CustomNode : public Node {
570 CustomNode() : Node(NodeKind::Custom) {}
571
Zachary Turner38d2edd2018-08-29 03:59:17 +0000572 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000573
574 // The string to print.
575 StringView Name;
576};
577
578struct NodeArrayNode : public Node {
579 NodeArrayNode() : Node(NodeKind::NodeArray) {}
580
Zachary Turner38d2edd2018-08-29 03:59:17 +0000581 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000582
Zachary Turner38d2edd2018-08-29 03:59:17 +0000583 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
Zachary Turner03312862018-08-27 03:48:03 +0000584
585 Node **Nodes = 0;
586 size_t Count = 0;
587};
588
589struct QualifiedNameNode : public Node {
590 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
591
Zachary Turner38d2edd2018-08-29 03:59:17 +0000592 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000593
594 NodeArrayNode *Components = nullptr;
595
596 IdentifierNode *getUnqualifiedIdentifier() {
597 Node *LastComponent = Components->Nodes[Components->Count - 1];
598 return static_cast<IdentifierNode *>(LastComponent);
599 }
600};
601
602struct TemplateParameterReferenceNode : public Node {
603 TemplateParameterReferenceNode()
604 : Node(NodeKind::TemplateParameterReference) {}
605
Zachary Turner38d2edd2018-08-29 03:59:17 +0000606 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000607
608 SymbolNode *Symbol = nullptr;
609
610 int ThunkOffsetCount = 0;
611 std::array<int64_t, 3> ThunkOffsets;
612 PointerAffinity Affinity = PointerAffinity::None;
613 bool IsMemberPointer = false;
614};
615
616struct IntegerLiteralNode : public Node {
617 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
618 IntegerLiteralNode(uint64_t Value, bool IsNegative)
619 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
620
Zachary Turner38d2edd2018-08-29 03:59:17 +0000621 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000622
623 uint64_t Value = 0;
624 bool IsNegative = false;
625};
626
627struct RttiBaseClassDescriptorNode : public IdentifierNode {
628 RttiBaseClassDescriptorNode()
629 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
630
Zachary Turner38d2edd2018-08-29 03:59:17 +0000631 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000632
633 uint32_t NVOffset = 0;
634 int32_t VBPtrOffset = 0;
635 uint32_t VBTableOffset = 0;
636 uint32_t Flags = 0;
637};
638
639struct SymbolNode : public Node {
640 explicit SymbolNode(NodeKind K) : Node(K) {}
Zachary Turner38d2edd2018-08-29 03:59:17 +0000641 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000642 QualifiedNameNode *Name = nullptr;
643};
644
645struct SpecialTableSymbolNode : public SymbolNode {
646 explicit SpecialTableSymbolNode()
647 : SymbolNode(NodeKind::SpecialTableSymbol) {}
648
Zachary Turner38d2edd2018-08-29 03:59:17 +0000649 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000650 QualifiedNameNode *TargetName = nullptr;
651 Qualifiers Quals;
652};
653
654struct LocalStaticGuardVariableNode : public SymbolNode {
655 LocalStaticGuardVariableNode()
656 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
657
Zachary Turner38d2edd2018-08-29 03:59:17 +0000658 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000659
660 bool IsVisible = false;
661};
662
663struct EncodedStringLiteralNode : public SymbolNode {
664 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
665
Zachary Turner38d2edd2018-08-29 03:59:17 +0000666 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000667
668 StringView DecodedString;
669 bool IsTruncated = false;
670 CharKind Char = CharKind::Char;
671};
672
673struct VariableSymbolNode : public SymbolNode {
674 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
675
Zachary Turner38d2edd2018-08-29 03:59:17 +0000676 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000677
678 StorageClass SC = StorageClass::None;
679 TypeNode *Type = nullptr;
680};
681
682struct FunctionSymbolNode : public SymbolNode {
683 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
684
Zachary Turner38d2edd2018-08-29 03:59:17 +0000685 void output(OutputStream &OS, OutputFlags Flags) const override;
Zachary Turner03312862018-08-27 03:48:03 +0000686
687 FunctionSignatureNode *Signature = nullptr;
688};
689
690} // namespace ms_demangle
691} // namespace llvm
692
693#endif