Line data Source code
1 : #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 :
8 : class OutputStream;
9 :
10 : namespace llvm {
11 : namespace 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.
18 : constexpr size_t AllocUnit = 4096;
19 :
20 : class ArenaAllocator {
21 0 : struct AllocatorNode {
22 : uint8_t *Buf = nullptr;
23 : size_t Used = 0;
24 : size_t Capacity = 0;
25 : AllocatorNode *Next = nullptr;
26 : };
27 :
28 0 : void addNode(size_t Capacity) {
29 0 : AllocatorNode *NewHead = new AllocatorNode;
30 0 : NewHead->Buf = new uint8_t[Capacity];
31 0 : NewHead->Next = Head;
32 0 : NewHead->Capacity = Capacity;
33 0 : Head = NewHead;
34 0 : NewHead->Used = 0;
35 0 : }
36 :
37 : public:
38 1131 : ArenaAllocator() { addNode(AllocUnit); }
39 :
40 1131 : ~ArenaAllocator() {
41 2263 : while (Head) {
42 : assert(Head->Buf);
43 1132 : delete[] Head->Buf;
44 1132 : AllocatorNode *Next = Head->Next;
45 1132 : delete Head;
46 1132 : Head = Next;
47 : }
48 1131 : }
49 :
50 669 : char *allocUnalignedBuffer(size_t Length) {
51 669 : uint8_t *Buf = Head->Buf + Head->Used;
52 :
53 669 : Head->Used += Length;
54 669 : 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 1 : addNode(std::max(AllocUnit, Length));
59 1 : Head->Used = Length;
60 1 : Buf = Head->Buf;
61 : }
62 :
63 669 : return reinterpret_cast<char *>(Buf);
64 : }
65 :
66 : template <typename T, typename... Args>
67 2031 : T *allocArray(size_t Count) {
68 :
69 2031 : size_t Size = Count * sizeof(T);
70 : assert(Head && Head->Buf);
71 :
72 2031 : size_t P = (size_t)Head->Buf + Head->Used;
73 2031 : uintptr_t AlignedP =
74 2031 : (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
75 2031 : uint8_t *PP = (uint8_t *)AlignedP;
76 2031 : size_t Adjustment = AlignedP - P;
77 :
78 2031 : Head->Used += Size + Adjustment;
79 2031 : if (Head->Used < Head->Capacity)
80 4971 : return new (PP) T[Count]();
81 :
82 0 : addNode(AllocUnit);
83 0 : Head->Used = Size;
84 0 : return new (Head->Buf) T[Count]();
85 : }
86 :
87 14296 : template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
88 :
89 : size_t Size = sizeof(T);
90 : assert(Head && Head->Buf);
91 :
92 14296 : size_t P = (size_t)Head->Buf + Head->Used;
93 14296 : uintptr_t AlignedP =
94 14296 : (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
95 14296 : uint8_t *PP = (uint8_t *)AlignedP;
96 14296 : size_t Adjustment = AlignedP - P;
97 :
98 14296 : Head->Used += Size + Adjustment;
99 14296 : if (Head->Used < Head->Capacity)
100 16037 : return new (PP) T(std::forward<Args>(ConstructorArgs)...);
101 :
102 0 : addNode(AllocUnit);
103 0 : Head->Used = Size;
104 0 : return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
105 : }
106 1 :
107 : private:
108 : AllocatorNode *Head = nullptr;
109 : };
110 :
111 1 : // Storage classes
112 1 : enum Qualifiers : uint8_t {
113 1 : Q_None = 0,
114 1 : Q_Const = 1 << 0,
115 1 : Q_Volatile = 1 << 1,
116 : Q_Far = 1 << 2,
117 1 : Q_Huge = 1 << 3,
118 1 : Q_Unaligned = 1 << 4,
119 2 : Q_Restrict = 1 << 5,
120 : Q_Pointer64 = 1 << 6
121 0 : };
122 0 :
123 0 : enum class StorageClass : uint8_t {
124 : None,
125 3246 : PrivateStatic,
126 : ProtectedStatic,
127 : PublicStatic,
128 : Global,
129 : FunctionLocalStatic,
130 3246 : };
131 3246 :
132 3246 : enum class PointerAffinity { None, Pointer, Reference, RValueReference };
133 3246 : enum class FunctionRefQualifier { None, Reference, RValueReference };
134 3246 :
135 : // Calling conventions
136 3246 : enum class CallingConv : uint8_t {
137 3246 : None,
138 3246 : Cdecl,
139 : Pascal,
140 0 : Thiscall,
141 0 : Stdcall,
142 0 : Fastcall,
143 : Clrcall,
144 5 : Eabi,
145 : Vectorcall,
146 : Regcall,
147 : };
148 :
149 5 : enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
150 5 :
151 5 : enum OutputFlags {
152 5 : OF_Default = 0,
153 5 : OF_NoCallingConvention = 1,
154 : };
155 5 :
156 5 : // Types
157 5 : enum class PrimitiveKind {
158 : Void,
159 0 : Bool,
160 0 : Char,
161 0 : Schar,
162 : Uchar,
163 1 : Char16,
164 : Char32,
165 : Short,
166 : Ushort,
167 : Int,
168 1 : Uint,
169 1 : Long,
170 1 : Ulong,
171 1 : Int64,
172 1 : Uint64,
173 : Wchar,
174 1 : Float,
175 1 : Double,
176 1 : Ldouble,
177 : Nullptr,
178 0 : };
179 0 :
180 0 : enum class CharKind {
181 : Char,
182 1 : Char16,
183 : Char32,
184 : Wchar,
185 : };
186 :
187 1 : enum class IntrinsicFunctionKind : uint8_t {
188 1 : None,
189 1 : New, // ?2 # operator new
190 1 : Delete, // ?3 # operator delete
191 1 : Assign, // ?4 # operator=
192 : RightShift, // ?5 # operator>>
193 1 : LeftShift, // ?6 # operator<<
194 1 : LogicalNot, // ?7 # operator!
195 1 : Equals, // ?8 # operator==
196 : NotEquals, // ?9 # operator!=
197 0 : ArraySubscript, // ?A # operator[]
198 0 : Pointer, // ?C # operator->
199 0 : Dereference, // ?D # operator*
200 : Increment, // ?E # operator++
201 1285 : Decrement, // ?F # operator--
202 : Minus, // ?G # operator-
203 : Plus, // ?H # operator+
204 : BitwiseAnd, // ?I # operator&
205 : MemberPointer, // ?J # operator->*
206 1285 : Divide, // ?K # operator/
207 1285 : Modulus, // ?L # operator%
208 1285 : LessThan, // ?M operator<
209 1285 : LessThanEqual, // ?N operator<=
210 1285 : GreaterThan, // ?O operator>
211 : GreaterThanEqual, // ?P operator>=
212 1285 : Comma, // ?Q operator,
213 1285 : Parens, // ?R operator()
214 1285 : BitwiseNot, // ?S operator~
215 : BitwiseXor, // ?T operator^
216 0 : BitwiseOr, // ?U operator|
217 0 : LogicalAnd, // ?V operator&&
218 0 : LogicalOr, // ?W operator||
219 : TimesEqual, // ?X operator*=
220 2031 : PlusEqual, // ?Y operator+=
221 : MinusEqual, // ?Z operator-=
222 : DivEqual, // ?_0 operator/=
223 : ModEqual, // ?_1 operator%=
224 : RshEqual, // ?_2 operator>>=
225 2031 : LshEqual, // ?_3 operator<<=
226 2031 : BitwiseAndEqual, // ?_4 operator&=
227 2031 : BitwiseOrEqual, // ?_5 operator|=
228 2031 : BitwiseXorEqual, // ?_6 operator^=
229 2031 : VbaseDtor, // ?_D # vbase destructor
230 : VecDelDtor, // ?_E # vector deleting destructor
231 2031 : DefaultCtorClosure, // ?_F # default constructor closure
232 2031 : ScalarDelDtor, // ?_G # scalar deleting destructor
233 2031 : VecCtorIter, // ?_H # vector constructor iterator
234 : VecDtorIter, // ?_I # vector destructor iterator
235 0 : VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
236 0 : VdispMap, // ?_K # virtual displacement map
237 0 : EHVecCtorIter, // ?_L # eh vector constructor iterator
238 : EHVecDtorIter, // ?_M # eh vector destructor iterator
239 168 : 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 168 : ManVectorCtorIter, // ?__A managed vector ctor iterator
245 168 : ManVectorDtorIter, // ?__B managed vector dtor iterator
246 168 : EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
247 168 : EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
248 168 : VectorCopyCtorIter, // ?__G vector copy constructor iterator
249 : VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
250 168 : ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
251 168 : CoAwait, // ?__L co_await
252 168 : Spaceship, // operator<=>
253 : MaxIntrinsic
254 0 : };
255 0 :
256 0 : enum class SpecialIntrinsicKind {
257 : None,
258 1 : Vftable,
259 : Vbtable,
260 : Typeof,
261 : VcallThunk,
262 : LocalStaticGuard,
263 1 : StringLiteralSymbol,
264 1 : UdtReturning,
265 1 : Unknown,
266 1 : DynamicInitializer,
267 1 : DynamicAtexitDestructor,
268 : RttiTypeDescriptor,
269 1 : RttiBaseClassDescriptor,
270 1 : RttiBaseClassArray,
271 1 : RttiClassHierarchyDescriptor,
272 : RttiCompleteObjLocator,
273 0 : LocalVftable,
274 0 : LocalStaticThreadGuard,
275 0 : };
276 :
277 3 : // Function classes
278 : enum FuncClass : uint16_t {
279 : FC_None = 0,
280 : FC_Public = 1 << 0,
281 : FC_Protected = 1 << 1,
282 3 : FC_Private = 1 << 2,
283 3 : FC_Global = 1 << 3,
284 3 : FC_Static = 1 << 4,
285 3 : FC_Virtual = 1 << 5,
286 3 : FC_Far = 1 << 6,
287 : FC_ExternC = 1 << 7,
288 3 : FC_NoParameterList = 1 << 8,
289 3 : FC_VirtualThisAdjust = 1 << 9,
290 3 : FC_VirtualThisAdjustEx = 1 << 10,
291 : FC_StaticThisAdjust = 1 << 11,
292 0 : };
293 0 :
294 0 : enum class TagKind { Class, Struct, Union, Enum };
295 :
296 75 : enum class NodeKind {
297 : Unknown,
298 : Md5Symbol,
299 : PrimitiveType,
300 : FunctionSignature,
301 75 : Identifier,
302 75 : NamedIdentifier,
303 75 : VcallThunkIdentifier,
304 75 : LocalStaticGuardIdentifier,
305 75 : IntrinsicFunctionIdentifier,
306 : ConversionOperatorIdentifier,
307 75 : DynamicStructorIdentifier,
308 75 : StructorIdentifier,
309 75 : LiteralOperatorIdentifier,
310 : ThunkSignature,
311 0 : PointerType,
312 0 : TagType,
313 0 : ArrayType,
314 : Custom,
315 17 : IntrinsicType,
316 : NodeArray,
317 : QualifiedName,
318 : TemplateParameterReference,
319 : EncodedStringLiteral,
320 17 : IntegerLiteral,
321 17 : RttiBaseClassDescriptor,
322 17 : LocalStaticGuardVariable,
323 17 : FunctionSymbol,
324 17 : VariableSymbol,
325 : SpecialTableSymbol
326 17 : };
327 17 :
328 17 : struct Node {
329 : explicit Node(NodeKind K) : Kind(K) {}
330 0 : virtual ~Node() = default;
331 0 :
332 0 : NodeKind kind() const { return Kind; }
333 :
334 2 : virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
335 :
336 : private:
337 : NodeKind Kind;
338 : };
339 2 :
340 2 : struct TypeNode;
341 2 : struct PrimitiveTypeNode;
342 2 : struct FunctionSignatureNode;
343 2 : struct IdentifierNode;
344 : struct NamedIdentifierNode;
345 2 : struct VcallThunkIdentifierNode;
346 2 : struct IntrinsicFunctionIdentifierNode;
347 2 : struct LiteralOperatorIdentifierNode;
348 : struct ConversionOperatorIdentifierNode;
349 0 : struct StructorIdentifierNode;
350 0 : struct ThunkSignatureNode;
351 0 : struct PointerTypeNode;
352 : struct ArrayTypeNode;
353 133 : struct CustomNode;
354 : struct TagTypeNode;
355 : struct IntrinsicTypeNode;
356 : struct NodeArrayNode;
357 : struct QualifiedNameNode;
358 133 : struct TemplateParameterReferenceNode;
359 133 : struct EncodedStringLiteralNode;
360 133 : struct IntegerLiteralNode;
361 133 : struct RttiBaseClassDescriptorNode;
362 133 : struct LocalStaticGuardVariableNode;
363 : struct SymbolNode;
364 133 : struct FunctionSymbolNode;
365 133 : struct VariableSymbolNode;
366 266 : struct SpecialTableSymbolNode;
367 :
368 0 : struct TypeNode : public Node {
369 0 : explicit TypeNode(NodeKind K) : Node(K) {}
370 0 :
371 : virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
372 37 : virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
373 :
374 1143 : void output(OutputStream &OS, OutputFlags Flags) const override {
375 1143 : outputPre(OS, Flags);
376 1143 : outputPost(OS, Flags);
377 1180 : }
378 37 :
379 37 : void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
380 37 :
381 37 : Qualifiers Quals = Q_None;
382 : };
383 37 :
384 37 : struct PrimitiveTypeNode : public TypeNode {
385 37 : explicit PrimitiveTypeNode(PrimitiveKind K)
386 : : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
387 0 :
388 0 : void outputPre(OutputStream &OS, OutputFlags Flags) const;
389 1326 : void outputPost(OutputStream &OS, OutputFlags Flags) const {}
390 :
391 670 : PrimitiveKind PrimKind;
392 : };
393 :
394 : struct FunctionSignatureNode : public TypeNode {
395 : explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
396 670 : FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
397 670 :
398 670 : void outputPre(OutputStream &OS, OutputFlags Flags) const override;
399 670 : void outputPost(OutputStream &OS, OutputFlags Flags) const override;
400 670 :
401 : // Valid if this FunctionTypeNode is the Pointee of a PointerType or
402 670 : // MemberPointerType.
403 670 : PointerAffinity Affinity = PointerAffinity::None;
404 670 :
405 : // The function's calling convention.
406 0 : CallingConv CallConvention = CallingConv::None;
407 0 :
408 0 : // Function flags (gloabl, public, etc)
409 : FuncClass FunctionClass = FC_Global;
410 9 :
411 : FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
412 :
413 : // The return type of the function.
414 : TypeNode *ReturnType = nullptr;
415 9 :
416 9 : // True if this is a C-style ... varargs function.
417 9 : bool IsVariadic = false;
418 9 :
419 9 : // Function parameters
420 : NodeArrayNode *Params = nullptr;
421 9 : };
422 9 :
423 9 : struct IdentifierNode : public Node {
424 : explicit IdentifierNode(NodeKind K) : Node(K) {}
425 0 :
426 0 : NodeArrayNode *TemplateParams = nullptr;
427 0 :
428 : protected:
429 13 : void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
430 : };
431 :
432 : struct VcallThunkIdentifierNode : public IdentifierNode {
433 : VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
434 13 :
435 13 : void output(OutputStream &OS, OutputFlags Flags) const override;
436 13 :
437 13 : uint64_t OffsetInVTable = 0;
438 13 : };
439 :
440 13 : struct DynamicStructorIdentifierNode : public IdentifierNode {
441 13 : DynamicStructorIdentifierNode()
442 13 : : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
443 :
444 0 : void output(OutputStream &OS, OutputFlags Flags) const override;
445 0 :
446 0 : VariableSymbolNode *Variable = nullptr;
447 : QualifiedNameNode *Name = nullptr;
448 370 : bool IsDestructor = false;
449 : };
450 :
451 : struct NamedIdentifierNode : public IdentifierNode {
452 : NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
453 370 :
454 370 : void output(OutputStream &OS, OutputFlags Flags) const override;
455 370 :
456 370 : StringView Name;
457 370 : };
458 :
459 370 : struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
460 370 : explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
461 370 : : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
462 : Operator(Operator) {}
463 0 :
464 0 : void output(OutputStream &OS, OutputFlags Flags) const override;
465 0 :
466 : IntrinsicFunctionKind Operator;
467 3351 : };
468 :
469 : struct LiteralOperatorIdentifierNode : public IdentifierNode {
470 : LiteralOperatorIdentifierNode()
471 : : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
472 3351 :
473 3351 : void output(OutputStream &OS, OutputFlags Flags) const override;
474 3351 :
475 3351 : StringView Name;
476 3351 : };
477 :
478 3351 : struct LocalStaticGuardIdentifierNode : public IdentifierNode {
479 3351 : LocalStaticGuardIdentifierNode()
480 3351 : : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
481 :
482 0 : void output(OutputStream &OS, OutputFlags Flags) const override;
483 0 :
484 0 : uint32_t ScopeIndex = 0;
485 : };
486 759 :
487 : struct ConversionOperatorIdentifierNode : public IdentifierNode {
488 : ConversionOperatorIdentifierNode()
489 : : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
490 :
491 759 : void output(OutputStream &OS, OutputFlags Flags) const override;
492 759 :
493 759 : // The type that this operator converts too.
494 759 : TypeNode *TargetType = nullptr;
495 759 : };
496 :
497 759 : struct StructorIdentifierNode : public IdentifierNode {
498 759 : StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
499 759 : explicit StructorIdentifierNode(bool IsDestructor)
500 : : IdentifierNode(NodeKind::StructorIdentifier),
501 0 : IsDestructor(IsDestructor) {}
502 0 :
503 0 : void output(OutputStream &OS, OutputFlags Flags) const override;
504 :
505 9 : // The name of the class that this is a structor of.
506 : IdentifierNode *Class = nullptr;
507 : bool IsDestructor = false;
508 : };
509 :
510 9 : struct ThunkSignatureNode : public FunctionSignatureNode {
511 9 : ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
512 9 :
513 9 : void outputPre(OutputStream &OS, OutputFlags Flags) const override;
514 9 : void outputPost(OutputStream &OS, OutputFlags Flags) const override;
515 :
516 9 : struct ThisAdjustor {
517 9 : uint32_t StaticOffset = 0;
518 9 : int32_t VBPtrOffset = 0;
519 : int32_t VBOffsetOffset = 0;
520 0 : int32_t VtordispOffset = 0;
521 0 : };
522 0 :
523 : ThisAdjustor ThisAdjust;
524 1108 : };
525 :
526 : struct PointerTypeNode : public TypeNode {
527 : PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
528 : void outputPre(OutputStream &OS, OutputFlags Flags) const override;
529 1108 : void outputPost(OutputStream &OS, OutputFlags Flags) const override;
530 1108 :
531 1108 : // Is this a pointer, reference, or rvalue-reference?
532 1108 : PointerAffinity Affinity = PointerAffinity::None;
533 1108 :
534 : // If this is a member pointer, this is the class that the member is in.
535 1108 : QualifiedNameNode *ClassParent = nullptr;
536 1108 :
537 2216 : // Represents a type X in "a pointer to X", "a reference to X", or
538 : // "rvalue-reference to X"
539 0 : TypeNode *Pointee = nullptr;
540 0 : };
541 0 :
542 : struct TagTypeNode : public TypeNode {
543 391 : explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
544 :
545 : void outputPre(OutputStream &OS, OutputFlags Flags) const;
546 : void outputPost(OutputStream &OS, OutputFlags Flags) const;
547 :
548 391 : QualifiedNameNode *QualifiedName = nullptr;
549 391 : TagKind Tag;
550 391 : };
551 391 :
552 391 : struct ArrayTypeNode : public TypeNode {
553 : ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
554 391 :
555 391 : void outputPre(OutputStream &OS, OutputFlags Flags) const;
556 782 : void outputPost(OutputStream &OS, OutputFlags Flags) const;
557 :
558 0 : void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
559 0 : void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
560 0 :
561 : // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
562 466 : NodeArrayNode *Dimensions = nullptr;
563 :
564 : // The type of array element.
565 : TypeNode *ElementType = nullptr;
566 : };
567 466 :
568 466 : struct IntrinsicNode : public TypeNode {
569 466 : IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
570 466 : void output(OutputStream &OS, OutputFlags Flags) const override {}
571 466 : };
572 :
573 466 : struct CustomTypeNode : public TypeNode {
574 466 : CustomTypeNode() : TypeNode(NodeKind::Custom) {}
575 466 :
576 : void outputPre(OutputStream &OS, OutputFlags Flags) const override;
577 0 : void outputPost(OutputStream &OS, OutputFlags Flags) const override;
578 0 :
579 0 : IdentifierNode *Identifier;
580 : };
581 36 :
582 : struct NodeArrayNode : public Node {
583 : NodeArrayNode() : Node(NodeKind::NodeArray) {}
584 :
585 : void output(OutputStream &OS, OutputFlags Flags) const override;
586 36 :
587 36 : void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
588 36 :
589 36 : Node **Nodes = 0;
590 36 : size_t Count = 0;
591 : };
592 36 :
593 36 : struct QualifiedNameNode : public Node {
594 36 : QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
595 :
596 0 : void output(OutputStream &OS, OutputFlags Flags) const override;
597 0 :
598 0 : NodeArrayNode *Components = nullptr;
599 :
600 108 : IdentifierNode *getUnqualifiedIdentifier() {
601 : Node *LastComponent = Components->Nodes[Components->Count - 1];
602 : return static_cast<IdentifierNode *>(LastComponent);
603 : }
604 : };
605 108 :
606 108 : struct TemplateParameterReferenceNode : public Node {
607 108 : TemplateParameterReferenceNode()
608 108 : : Node(NodeKind::TemplateParameterReference) {}
609 108 :
610 : void output(OutputStream &OS, OutputFlags Flags) const override;
611 108 :
612 108 : SymbolNode *Symbol = nullptr;
613 216 :
614 : int ThunkOffsetCount = 0;
615 0 : std::array<int64_t, 3> ThunkOffsets;
616 0 : PointerAffinity Affinity = PointerAffinity::None;
617 0 : bool IsMemberPointer = false;
618 : };
619 :
620 : struct IntegerLiteralNode : public Node {
621 : IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
622 : IntegerLiteralNode(uint64_t Value, bool IsNegative)
623 : : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
624 :
625 : void output(OutputStream &OS, OutputFlags Flags) const override;
626 :
627 : uint64_t Value = 0;
628 : bool IsNegative = false;
629 : };
630 :
631 : struct RttiBaseClassDescriptorNode : public IdentifierNode {
632 : RttiBaseClassDescriptorNode()
633 : : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
634 :
635 : void output(OutputStream &OS, OutputFlags Flags) const override;
636 :
637 : uint32_t NVOffset = 0;
638 : int32_t VBPtrOffset = 0;
639 : uint32_t VBTableOffset = 0;
640 : uint32_t Flags = 0;
641 : };
642 :
643 : struct SymbolNode : public Node {
644 : explicit SymbolNode(NodeKind K) : Node(K) {}
645 : void output(OutputStream &OS, OutputFlags Flags) const override;
646 : QualifiedNameNode *Name = nullptr;
647 : };
648 :
649 : struct SpecialTableSymbolNode : public SymbolNode {
650 : explicit SpecialTableSymbolNode()
651 : : SymbolNode(NodeKind::SpecialTableSymbol) {}
652 :
653 : void output(OutputStream &OS, OutputFlags Flags) const override;
654 : QualifiedNameNode *TargetName = nullptr;
655 : Qualifiers Quals;
656 : };
657 :
658 : struct LocalStaticGuardVariableNode : public SymbolNode {
659 : LocalStaticGuardVariableNode()
660 : : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
661 :
662 : void output(OutputStream &OS, OutputFlags Flags) const override;
663 :
664 : bool IsVisible = false;
665 : };
666 :
667 : struct EncodedStringLiteralNode : public SymbolNode {
668 : EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
669 :
670 : void output(OutputStream &OS, OutputFlags Flags) const override;
671 :
672 : StringView DecodedString;
673 : bool IsTruncated = false;
674 : CharKind Char = CharKind::Char;
675 : };
676 :
677 : struct VariableSymbolNode : public SymbolNode {
678 : VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
679 :
680 : void output(OutputStream &OS, OutputFlags Flags) const override;
681 :
682 : StorageClass SC = StorageClass::None;
683 : TypeNode *Type = nullptr;
684 : };
685 :
686 : struct FunctionSymbolNode : public SymbolNode {
687 : FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
688 :
689 : void output(OutputStream &OS, OutputFlags Flags) const override;
690 :
691 : FunctionSignatureNode *Signature = nullptr;
692 : };
693 :
694 : } // namespace ms_demangle
695 : } // namespace llvm
696 :
697 : #endif
|