xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 //===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the AST nodes used in the MSVC demangler.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
14 #define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
15 
16 #include "llvm/Demangle/DemangleConfig.h"
17 #include "llvm/Demangle/StringView.h"
18 #include <array>
19 #include <cstdint>
20 #include <string>
21 
22 namespace llvm {
23 namespace itanium_demangle {
24 class OutputStream;
25 }
26 }
27 
28 using llvm::itanium_demangle::OutputStream;
29 using llvm::itanium_demangle::StringView;
30 
31 namespace llvm {
32 namespace ms_demangle {
33 
34 // Storage classes
35 enum Qualifiers : uint8_t {
36   Q_None = 0,
37   Q_Const = 1 << 0,
38   Q_Volatile = 1 << 1,
39   Q_Far = 1 << 2,
40   Q_Huge = 1 << 3,
41   Q_Unaligned = 1 << 4,
42   Q_Restrict = 1 << 5,
43   Q_Pointer64 = 1 << 6
44 };
45 
46 enum class StorageClass : uint8_t {
47   None,
48   PrivateStatic,
49   ProtectedStatic,
50   PublicStatic,
51   Global,
52   FunctionLocalStatic,
53 };
54 
55 enum class PointerAffinity { None, Pointer, Reference, RValueReference };
56 enum class FunctionRefQualifier { None, Reference, RValueReference };
57 
58 // Calling conventions
59 enum class CallingConv : uint8_t {
60   None,
61   Cdecl,
62   Pascal,
63   Thiscall,
64   Stdcall,
65   Fastcall,
66   Clrcall,
67   Eabi,
68   Vectorcall,
69   Regcall,
70   Swift, // Clang-only
71 };
72 
73 enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
74 
75 enum OutputFlags {
76   OF_Default = 0,
77   OF_NoCallingConvention = 1,
78   OF_NoTagSpecifier = 2,
79   OF_NoAccessSpecifier = 4,
80   OF_NoMemberType = 8,
81   OF_NoReturnType = 16,
82 };
83 
84 // Types
85 enum class PrimitiveKind {
86   Void,
87   Bool,
88   Char,
89   Schar,
90   Uchar,
91   Char8,
92   Char16,
93   Char32,
94   Short,
95   Ushort,
96   Int,
97   Uint,
98   Long,
99   Ulong,
100   Int64,
101   Uint64,
102   Wchar,
103   Float,
104   Double,
105   Ldouble,
106   Nullptr,
107 };
108 
109 enum class CharKind {
110   Char,
111   Char16,
112   Char32,
113   Wchar,
114 };
115 
116 enum class IntrinsicFunctionKind : uint8_t {
117   None,
118   New,                        // ?2 # operator new
119   Delete,                     // ?3 # operator delete
120   Assign,                     // ?4 # operator=
121   RightShift,                 // ?5 # operator>>
122   LeftShift,                  // ?6 # operator<<
123   LogicalNot,                 // ?7 # operator!
124   Equals,                     // ?8 # operator==
125   NotEquals,                  // ?9 # operator!=
126   ArraySubscript,             // ?A # operator[]
127   Pointer,                    // ?C # operator->
128   Dereference,                // ?D # operator*
129   Increment,                  // ?E # operator++
130   Decrement,                  // ?F # operator--
131   Minus,                      // ?G # operator-
132   Plus,                       // ?H # operator+
133   BitwiseAnd,                 // ?I # operator&
134   MemberPointer,              // ?J # operator->*
135   Divide,                     // ?K # operator/
136   Modulus,                    // ?L # operator%
137   LessThan,                   // ?M operator<
138   LessThanEqual,              // ?N operator<=
139   GreaterThan,                // ?O operator>
140   GreaterThanEqual,           // ?P operator>=
141   Comma,                      // ?Q operator,
142   Parens,                     // ?R operator()
143   BitwiseNot,                 // ?S operator~
144   BitwiseXor,                 // ?T operator^
145   BitwiseOr,                  // ?U operator|
146   LogicalAnd,                 // ?V operator&&
147   LogicalOr,                  // ?W operator||
148   TimesEqual,                 // ?X operator*=
149   PlusEqual,                  // ?Y operator+=
150   MinusEqual,                 // ?Z operator-=
151   DivEqual,                   // ?_0 operator/=
152   ModEqual,                   // ?_1 operator%=
153   RshEqual,                   // ?_2 operator>>=
154   LshEqual,                   // ?_3 operator<<=
155   BitwiseAndEqual,            // ?_4 operator&=
156   BitwiseOrEqual,             // ?_5 operator|=
157   BitwiseXorEqual,            // ?_6 operator^=
158   VbaseDtor,                  // ?_D # vbase destructor
159   VecDelDtor,                 // ?_E # vector deleting destructor
160   DefaultCtorClosure,         // ?_F # default constructor closure
161   ScalarDelDtor,              // ?_G # scalar deleting destructor
162   VecCtorIter,                // ?_H # vector constructor iterator
163   VecDtorIter,                // ?_I # vector destructor iterator
164   VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
165   VdispMap,                   // ?_K # virtual displacement map
166   EHVecCtorIter,              // ?_L # eh vector constructor iterator
167   EHVecDtorIter,              // ?_M # eh vector destructor iterator
168   EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
169   CopyCtorClosure,            // ?_O # copy constructor closure
170   LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
171   ArrayNew,                   // ?_U operator new[]
172   ArrayDelete,                // ?_V operator delete[]
173   ManVectorCtorIter,          // ?__A managed vector ctor iterator
174   ManVectorDtorIter,          // ?__B managed vector dtor iterator
175   EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
176   EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
177   VectorCopyCtorIter,         // ?__G vector copy constructor iterator
178   VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
179   ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
180   CoAwait,                    // ?__L operator co_await
181   Spaceship,                  // ?__M operator<=>
182   MaxIntrinsic
183 };
184 
185 enum class SpecialIntrinsicKind {
186   None,
187   Vftable,
188   Vbtable,
189   Typeof,
190   VcallThunk,
191   LocalStaticGuard,
192   StringLiteralSymbol,
193   UdtReturning,
194   Unknown,
195   DynamicInitializer,
196   DynamicAtexitDestructor,
197   RttiTypeDescriptor,
198   RttiBaseClassDescriptor,
199   RttiBaseClassArray,
200   RttiClassHierarchyDescriptor,
201   RttiCompleteObjLocator,
202   LocalVftable,
203   LocalStaticThreadGuard,
204 };
205 
206 // Function classes
207 enum FuncClass : uint16_t {
208   FC_None = 0,
209   FC_Public = 1 << 0,
210   FC_Protected = 1 << 1,
211   FC_Private = 1 << 2,
212   FC_Global = 1 << 3,
213   FC_Static = 1 << 4,
214   FC_Virtual = 1 << 5,
215   FC_Far = 1 << 6,
216   FC_ExternC = 1 << 7,
217   FC_NoParameterList = 1 << 8,
218   FC_VirtualThisAdjust = 1 << 9,
219   FC_VirtualThisAdjustEx = 1 << 10,
220   FC_StaticThisAdjust = 1 << 11,
221 };
222 
223 enum class TagKind { Class, Struct, Union, Enum };
224 
225 enum class NodeKind {
226   Unknown,
227   Md5Symbol,
228   PrimitiveType,
229   FunctionSignature,
230   Identifier,
231   NamedIdentifier,
232   VcallThunkIdentifier,
233   LocalStaticGuardIdentifier,
234   IntrinsicFunctionIdentifier,
235   ConversionOperatorIdentifier,
236   DynamicStructorIdentifier,
237   StructorIdentifier,
238   LiteralOperatorIdentifier,
239   ThunkSignature,
240   PointerType,
241   TagType,
242   ArrayType,
243   Custom,
244   IntrinsicType,
245   NodeArray,
246   QualifiedName,
247   TemplateParameterReference,
248   EncodedStringLiteral,
249   IntegerLiteral,
250   RttiBaseClassDescriptor,
251   LocalStaticGuardVariable,
252   FunctionSymbol,
253   VariableSymbol,
254   SpecialTableSymbol
255 };
256 
257 struct Node {
NodeNode258   explicit Node(NodeKind K) : Kind(K) {}
259   virtual ~Node() = default;
260 
kindNode261   NodeKind kind() const { return Kind; }
262 
263   virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
264 
265   std::string toString(OutputFlags Flags = OF_Default) const;
266 
267 private:
268   NodeKind Kind;
269 };
270 
271 struct TypeNode;
272 struct PrimitiveTypeNode;
273 struct FunctionSignatureNode;
274 struct IdentifierNode;
275 struct NamedIdentifierNode;
276 struct VcallThunkIdentifierNode;
277 struct IntrinsicFunctionIdentifierNode;
278 struct LiteralOperatorIdentifierNode;
279 struct ConversionOperatorIdentifierNode;
280 struct StructorIdentifierNode;
281 struct ThunkSignatureNode;
282 struct PointerTypeNode;
283 struct ArrayTypeNode;
284 struct CustomNode;
285 struct TagTypeNode;
286 struct IntrinsicTypeNode;
287 struct NodeArrayNode;
288 struct QualifiedNameNode;
289 struct TemplateParameterReferenceNode;
290 struct EncodedStringLiteralNode;
291 struct IntegerLiteralNode;
292 struct RttiBaseClassDescriptorNode;
293 struct LocalStaticGuardVariableNode;
294 struct SymbolNode;
295 struct FunctionSymbolNode;
296 struct VariableSymbolNode;
297 struct SpecialTableSymbolNode;
298 
299 struct TypeNode : public Node {
TypeNodeTypeNode300   explicit TypeNode(NodeKind K) : Node(K) {}
301 
302   virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
303   virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
304 
outputTypeNode305   void output(OutputStream &OS, OutputFlags Flags) const override {
306     outputPre(OS, Flags);
307     outputPost(OS, Flags);
308   }
309 
310   Qualifiers Quals = Q_None;
311 };
312 
313 struct PrimitiveTypeNode : public TypeNode {
PrimitiveTypeNodePrimitiveTypeNode314   explicit PrimitiveTypeNode(PrimitiveKind K)
315       : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
316 
317   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
outputPostPrimitiveTypeNode318   void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
319 
320   PrimitiveKind PrimKind;
321 };
322 
323 struct FunctionSignatureNode : public TypeNode {
FunctionSignatureNodeFunctionSignatureNode324   explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
FunctionSignatureNodeFunctionSignatureNode325   FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
326 
327   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
328   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
329 
330   // Valid if this FunctionTypeNode is the Pointee of a PointerType or
331   // MemberPointerType.
332   PointerAffinity Affinity = PointerAffinity::None;
333 
334   // The function's calling convention.
335   CallingConv CallConvention = CallingConv::None;
336 
337   // Function flags (gloabl, public, etc)
338   FuncClass FunctionClass = FC_Global;
339 
340   FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
341 
342   // The return type of the function.
343   TypeNode *ReturnType = nullptr;
344 
345   // True if this is a C-style ... varargs function.
346   bool IsVariadic = false;
347 
348   // Function parameters
349   NodeArrayNode *Params = nullptr;
350 
351   // True if the function type is noexcept.
352   bool IsNoexcept = false;
353 };
354 
355 struct IdentifierNode : public Node {
IdentifierNodeIdentifierNode356   explicit IdentifierNode(NodeKind K) : Node(K) {}
357 
358   NodeArrayNode *TemplateParams = nullptr;
359 
360 protected:
361   void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
362 };
363 
364 struct VcallThunkIdentifierNode : public IdentifierNode {
VcallThunkIdentifierNodeVcallThunkIdentifierNode365   VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
366 
367   void output(OutputStream &OS, OutputFlags Flags) const override;
368 
369   uint64_t OffsetInVTable = 0;
370 };
371 
372 struct DynamicStructorIdentifierNode : public IdentifierNode {
DynamicStructorIdentifierNodeDynamicStructorIdentifierNode373   DynamicStructorIdentifierNode()
374       : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
375 
376   void output(OutputStream &OS, OutputFlags Flags) const override;
377 
378   VariableSymbolNode *Variable = nullptr;
379   QualifiedNameNode *Name = nullptr;
380   bool IsDestructor = false;
381 };
382 
383 struct NamedIdentifierNode : public IdentifierNode {
NamedIdentifierNodeNamedIdentifierNode384   NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
385 
386   void output(OutputStream &OS, OutputFlags Flags) const override;
387 
388   StringView Name;
389 };
390 
391 struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
IntrinsicFunctionIdentifierNodeIntrinsicFunctionIdentifierNode392   explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
393       : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
394         Operator(Operator) {}
395 
396   void output(OutputStream &OS, OutputFlags Flags) const override;
397 
398   IntrinsicFunctionKind Operator;
399 };
400 
401 struct LiteralOperatorIdentifierNode : public IdentifierNode {
LiteralOperatorIdentifierNodeLiteralOperatorIdentifierNode402   LiteralOperatorIdentifierNode()
403       : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
404 
405   void output(OutputStream &OS, OutputFlags Flags) const override;
406 
407   StringView Name;
408 };
409 
410 struct LocalStaticGuardIdentifierNode : public IdentifierNode {
LocalStaticGuardIdentifierNodeLocalStaticGuardIdentifierNode411   LocalStaticGuardIdentifierNode()
412       : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
413 
414   void output(OutputStream &OS, OutputFlags Flags) const override;
415 
416   bool IsThread = false;
417   uint32_t ScopeIndex = 0;
418 };
419 
420 struct ConversionOperatorIdentifierNode : public IdentifierNode {
ConversionOperatorIdentifierNodeConversionOperatorIdentifierNode421   ConversionOperatorIdentifierNode()
422       : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
423 
424   void output(OutputStream &OS, OutputFlags Flags) const override;
425 
426   // The type that this operator converts too.
427   TypeNode *TargetType = nullptr;
428 };
429 
430 struct StructorIdentifierNode : public IdentifierNode {
StructorIdentifierNodeStructorIdentifierNode431   StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
StructorIdentifierNodeStructorIdentifierNode432   explicit StructorIdentifierNode(bool IsDestructor)
433       : IdentifierNode(NodeKind::StructorIdentifier),
434         IsDestructor(IsDestructor) {}
435 
436   void output(OutputStream &OS, OutputFlags Flags) const override;
437 
438   // The name of the class that this is a structor of.
439   IdentifierNode *Class = nullptr;
440   bool IsDestructor = false;
441 };
442 
443 struct ThunkSignatureNode : public FunctionSignatureNode {
ThunkSignatureNodeThunkSignatureNode444   ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
445 
446   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
447   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
448 
449   struct ThisAdjustor {
450     uint32_t StaticOffset = 0;
451     int32_t VBPtrOffset = 0;
452     int32_t VBOffsetOffset = 0;
453     int32_t VtordispOffset = 0;
454   };
455 
456   ThisAdjustor ThisAdjust;
457 };
458 
459 struct PointerTypeNode : public TypeNode {
PointerTypeNodePointerTypeNode460   PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
461   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
462   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
463 
464   // Is this a pointer, reference, or rvalue-reference?
465   PointerAffinity Affinity = PointerAffinity::None;
466 
467   // If this is a member pointer, this is the class that the member is in.
468   QualifiedNameNode *ClassParent = nullptr;
469 
470   // Represents a type X in "a pointer to X", "a reference to X", or
471   // "rvalue-reference to X"
472   TypeNode *Pointee = nullptr;
473 };
474 
475 struct TagTypeNode : public TypeNode {
TagTypeNodeTagTypeNode476   explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
477 
478   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
479   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
480 
481   QualifiedNameNode *QualifiedName = nullptr;
482   TagKind Tag;
483 };
484 
485 struct ArrayTypeNode : public TypeNode {
ArrayTypeNodeArrayTypeNode486   ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
487 
488   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
489   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
490 
491   void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
492   void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
493 
494   // A list of array dimensions.  e.g. [3,4,5] in `int Foo[3][4][5]`
495   NodeArrayNode *Dimensions = nullptr;
496 
497   // The type of array element.
498   TypeNode *ElementType = nullptr;
499 };
500 
501 struct IntrinsicNode : public TypeNode {
IntrinsicNodeIntrinsicNode502   IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
outputIntrinsicNode503   void output(OutputStream &OS, OutputFlags Flags) const override {}
504 };
505 
506 struct CustomTypeNode : public TypeNode {
CustomTypeNodeCustomTypeNode507   CustomTypeNode() : TypeNode(NodeKind::Custom) {}
508 
509   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
510   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
511 
512   IdentifierNode *Identifier = nullptr;
513 };
514 
515 struct NodeArrayNode : public Node {
NodeArrayNodeNodeArrayNode516   NodeArrayNode() : Node(NodeKind::NodeArray) {}
517 
518   void output(OutputStream &OS, OutputFlags Flags) const override;
519 
520   void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
521 
522   Node **Nodes = nullptr;
523   size_t Count = 0;
524 };
525 
526 struct QualifiedNameNode : public Node {
QualifiedNameNodeQualifiedNameNode527   QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
528 
529   void output(OutputStream &OS, OutputFlags Flags) const override;
530 
531   NodeArrayNode *Components = nullptr;
532 
getUnqualifiedIdentifierQualifiedNameNode533   IdentifierNode *getUnqualifiedIdentifier() {
534     Node *LastComponent = Components->Nodes[Components->Count - 1];
535     return static_cast<IdentifierNode *>(LastComponent);
536   }
537 };
538 
539 struct TemplateParameterReferenceNode : public Node {
TemplateParameterReferenceNodeTemplateParameterReferenceNode540   TemplateParameterReferenceNode()
541       : Node(NodeKind::TemplateParameterReference) {}
542 
543   void output(OutputStream &OS, OutputFlags Flags) const override;
544 
545   SymbolNode *Symbol = nullptr;
546 
547   int ThunkOffsetCount = 0;
548   std::array<int64_t, 3> ThunkOffsets;
549   PointerAffinity Affinity = PointerAffinity::None;
550   bool IsMemberPointer = false;
551 };
552 
553 struct IntegerLiteralNode : public Node {
IntegerLiteralNodeIntegerLiteralNode554   IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
IntegerLiteralNodeIntegerLiteralNode555   IntegerLiteralNode(uint64_t Value, bool IsNegative)
556       : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
557 
558   void output(OutputStream &OS, OutputFlags Flags) const override;
559 
560   uint64_t Value = 0;
561   bool IsNegative = false;
562 };
563 
564 struct RttiBaseClassDescriptorNode : public IdentifierNode {
RttiBaseClassDescriptorNodeRttiBaseClassDescriptorNode565   RttiBaseClassDescriptorNode()
566       : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
567 
568   void output(OutputStream &OS, OutputFlags Flags) const override;
569 
570   uint32_t NVOffset = 0;
571   int32_t VBPtrOffset = 0;
572   uint32_t VBTableOffset = 0;
573   uint32_t Flags = 0;
574 };
575 
576 struct SymbolNode : public Node {
SymbolNodeSymbolNode577   explicit SymbolNode(NodeKind K) : Node(K) {}
578   void output(OutputStream &OS, OutputFlags Flags) const override;
579   QualifiedNameNode *Name = nullptr;
580 };
581 
582 struct SpecialTableSymbolNode : public SymbolNode {
SpecialTableSymbolNodeSpecialTableSymbolNode583   explicit SpecialTableSymbolNode()
584       : SymbolNode(NodeKind::SpecialTableSymbol) {}
585 
586   void output(OutputStream &OS, OutputFlags Flags) const override;
587   QualifiedNameNode *TargetName = nullptr;
588   Qualifiers Quals = Qualifiers::Q_None;
589 };
590 
591 struct LocalStaticGuardVariableNode : public SymbolNode {
LocalStaticGuardVariableNodeLocalStaticGuardVariableNode592   LocalStaticGuardVariableNode()
593       : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
594 
595   void output(OutputStream &OS, OutputFlags Flags) const override;
596 
597   bool IsVisible = false;
598 };
599 
600 struct EncodedStringLiteralNode : public SymbolNode {
EncodedStringLiteralNodeEncodedStringLiteralNode601   EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
602 
603   void output(OutputStream &OS, OutputFlags Flags) const override;
604 
605   StringView DecodedString;
606   bool IsTruncated = false;
607   CharKind Char = CharKind::Char;
608 };
609 
610 struct VariableSymbolNode : public SymbolNode {
VariableSymbolNodeVariableSymbolNode611   VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
612 
613   void output(OutputStream &OS, OutputFlags Flags) const override;
614 
615   StorageClass SC = StorageClass::None;
616   TypeNode *Type = nullptr;
617 };
618 
619 struct FunctionSymbolNode : public SymbolNode {
FunctionSymbolNodeFunctionSymbolNode620   FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
621 
622   void output(OutputStream &OS, OutputFlags Flags) const override;
623 
624   FunctionSignatureNode *Signature = nullptr;
625 };
626 
627 } // namespace ms_demangle
628 } // namespace llvm
629 
630 #endif
631