• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SUPPORT_MICROSOFTDEMANGLENODES_H
14 #define LLVM_SUPPORT_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 };
71 
72 enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
73 
74 enum OutputFlags {
75   OF_Default = 0,
76   OF_NoCallingConvention = 1,
77   OF_NoTagSpecifier = 2,
78   OF_NoAccessSpecifier = 4,
79   OF_NoMemberType = 8,
80   OF_NoReturnType = 16,
81 };
82 
83 // Types
84 enum class PrimitiveKind {
85   Void,
86   Bool,
87   Char,
88   Schar,
89   Uchar,
90   Char8,
91   Char16,
92   Char32,
93   Short,
94   Ushort,
95   Int,
96   Uint,
97   Long,
98   Ulong,
99   Int64,
100   Uint64,
101   Wchar,
102   Float,
103   Double,
104   Ldouble,
105   Nullptr,
106 };
107 
108 enum class CharKind {
109   Char,
110   Char16,
111   Char32,
112   Wchar,
113 };
114 
115 enum class IntrinsicFunctionKind : uint8_t {
116   None,
117   New,                        // ?2 # operator new
118   Delete,                     // ?3 # operator delete
119   Assign,                     // ?4 # operator=
120   RightShift,                 // ?5 # operator>>
121   LeftShift,                  // ?6 # operator<<
122   LogicalNot,                 // ?7 # operator!
123   Equals,                     // ?8 # operator==
124   NotEquals,                  // ?9 # operator!=
125   ArraySubscript,             // ?A # operator[]
126   Pointer,                    // ?C # operator->
127   Dereference,                // ?D # operator*
128   Increment,                  // ?E # operator++
129   Decrement,                  // ?F # operator--
130   Minus,                      // ?G # operator-
131   Plus,                       // ?H # operator+
132   BitwiseAnd,                 // ?I # operator&
133   MemberPointer,              // ?J # operator->*
134   Divide,                     // ?K # operator/
135   Modulus,                    // ?L # operator%
136   LessThan,                   // ?M operator<
137   LessThanEqual,              // ?N operator<=
138   GreaterThan,                // ?O operator>
139   GreaterThanEqual,           // ?P operator>=
140   Comma,                      // ?Q operator,
141   Parens,                     // ?R operator()
142   BitwiseNot,                 // ?S operator~
143   BitwiseXor,                 // ?T operator^
144   BitwiseOr,                  // ?U operator|
145   LogicalAnd,                 // ?V operator&&
146   LogicalOr,                  // ?W operator||
147   TimesEqual,                 // ?X operator*=
148   PlusEqual,                  // ?Y operator+=
149   MinusEqual,                 // ?Z operator-=
150   DivEqual,                   // ?_0 operator/=
151   ModEqual,                   // ?_1 operator%=
152   RshEqual,                   // ?_2 operator>>=
153   LshEqual,                   // ?_3 operator<<=
154   BitwiseAndEqual,            // ?_4 operator&=
155   BitwiseOrEqual,             // ?_5 operator|=
156   BitwiseXorEqual,            // ?_6 operator^=
157   VbaseDtor,                  // ?_D # vbase destructor
158   VecDelDtor,                 // ?_E # vector deleting destructor
159   DefaultCtorClosure,         // ?_F # default constructor closure
160   ScalarDelDtor,              // ?_G # scalar deleting destructor
161   VecCtorIter,                // ?_H # vector constructor iterator
162   VecDtorIter,                // ?_I # vector destructor iterator
163   VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
164   VdispMap,                   // ?_K # virtual displacement map
165   EHVecCtorIter,              // ?_L # eh vector constructor iterator
166   EHVecDtorIter,              // ?_M # eh vector destructor iterator
167   EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
168   CopyCtorClosure,            // ?_O # copy constructor closure
169   LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
170   ArrayNew,                   // ?_U operator new[]
171   ArrayDelete,                // ?_V operator delete[]
172   ManVectorCtorIter,          // ?__A managed vector ctor iterator
173   ManVectorDtorIter,          // ?__B managed vector dtor iterator
174   EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
175   EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
176   VectorCopyCtorIter,         // ?__G vector copy constructor iterator
177   VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
178   ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
179   CoAwait,                    // ?__L operator co_await
180   Spaceship,                  // ?__M operator<=>
181   MaxIntrinsic
182 };
183 
184 enum class SpecialIntrinsicKind {
185   None,
186   Vftable,
187   Vbtable,
188   Typeof,
189   VcallThunk,
190   LocalStaticGuard,
191   StringLiteralSymbol,
192   UdtReturning,
193   Unknown,
194   DynamicInitializer,
195   DynamicAtexitDestructor,
196   RttiTypeDescriptor,
197   RttiBaseClassDescriptor,
198   RttiBaseClassArray,
199   RttiClassHierarchyDescriptor,
200   RttiCompleteObjLocator,
201   LocalVftable,
202   LocalStaticThreadGuard,
203 };
204 
205 // Function classes
206 enum FuncClass : uint16_t {
207   FC_None = 0,
208   FC_Public = 1 << 0,
209   FC_Protected = 1 << 1,
210   FC_Private = 1 << 2,
211   FC_Global = 1 << 3,
212   FC_Static = 1 << 4,
213   FC_Virtual = 1 << 5,
214   FC_Far = 1 << 6,
215   FC_ExternC = 1 << 7,
216   FC_NoParameterList = 1 << 8,
217   FC_VirtualThisAdjust = 1 << 9,
218   FC_VirtualThisAdjustEx = 1 << 10,
219   FC_StaticThisAdjust = 1 << 11,
220 };
221 
222 enum class TagKind { Class, Struct, Union, Enum };
223 
224 enum class NodeKind {
225   Unknown,
226   Md5Symbol,
227   PrimitiveType,
228   FunctionSignature,
229   Identifier,
230   NamedIdentifier,
231   VcallThunkIdentifier,
232   LocalStaticGuardIdentifier,
233   IntrinsicFunctionIdentifier,
234   ConversionOperatorIdentifier,
235   DynamicStructorIdentifier,
236   StructorIdentifier,
237   LiteralOperatorIdentifier,
238   ThunkSignature,
239   PointerType,
240   TagType,
241   ArrayType,
242   Custom,
243   IntrinsicType,
244   NodeArray,
245   QualifiedName,
246   TemplateParameterReference,
247   EncodedStringLiteral,
248   IntegerLiteral,
249   RttiBaseClassDescriptor,
250   LocalStaticGuardVariable,
251   FunctionSymbol,
252   VariableSymbol,
253   SpecialTableSymbol
254 };
255 
256 struct Node {
NodeNode257   explicit Node(NodeKind K) : Kind(K) {}
258   virtual ~Node() = default;
259 
kindNode260   NodeKind kind() const { return Kind; }
261 
262   virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
263 
264   std::string toString(OutputFlags Flags = OF_Default) const;
265 
266 private:
267   NodeKind Kind;
268 };
269 
270 struct TypeNode;
271 struct PrimitiveTypeNode;
272 struct FunctionSignatureNode;
273 struct IdentifierNode;
274 struct NamedIdentifierNode;
275 struct VcallThunkIdentifierNode;
276 struct IntrinsicFunctionIdentifierNode;
277 struct LiteralOperatorIdentifierNode;
278 struct ConversionOperatorIdentifierNode;
279 struct StructorIdentifierNode;
280 struct ThunkSignatureNode;
281 struct PointerTypeNode;
282 struct ArrayTypeNode;
283 struct CustomNode;
284 struct TagTypeNode;
285 struct IntrinsicTypeNode;
286 struct NodeArrayNode;
287 struct QualifiedNameNode;
288 struct TemplateParameterReferenceNode;
289 struct EncodedStringLiteralNode;
290 struct IntegerLiteralNode;
291 struct RttiBaseClassDescriptorNode;
292 struct LocalStaticGuardVariableNode;
293 struct SymbolNode;
294 struct FunctionSymbolNode;
295 struct VariableSymbolNode;
296 struct SpecialTableSymbolNode;
297 
298 struct TypeNode : public Node {
TypeNodeTypeNode299   explicit TypeNode(NodeKind K) : Node(K) {}
300 
301   virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
302   virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
303 
outputTypeNode304   void output(OutputStream &OS, OutputFlags Flags) const override {
305     outputPre(OS, Flags);
306     outputPost(OS, Flags);
307   }
308 
309   Qualifiers Quals = Q_None;
310 };
311 
312 struct PrimitiveTypeNode : public TypeNode {
PrimitiveTypeNodePrimitiveTypeNode313   explicit PrimitiveTypeNode(PrimitiveKind K)
314       : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
315 
316   void outputPre(OutputStream &OS, OutputFlags Flags) const;
outputPostPrimitiveTypeNode317   void outputPost(OutputStream &OS, OutputFlags Flags) const {}
318 
319   PrimitiveKind PrimKind;
320 };
321 
322 struct FunctionSignatureNode : public TypeNode {
FunctionSignatureNodeFunctionSignatureNode323   explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
FunctionSignatureNodeFunctionSignatureNode324   FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
325 
326   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
327   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
328 
329   // Valid if this FunctionTypeNode is the Pointee of a PointerType or
330   // MemberPointerType.
331   PointerAffinity Affinity = PointerAffinity::None;
332 
333   // The function's calling convention.
334   CallingConv CallConvention = CallingConv::None;
335 
336   // Function flags (gloabl, public, etc)
337   FuncClass FunctionClass = FC_Global;
338 
339   FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
340 
341   // The return type of the function.
342   TypeNode *ReturnType = nullptr;
343 
344   // True if this is a C-style ... varargs function.
345   bool IsVariadic = false;
346 
347   // Function parameters
348   NodeArrayNode *Params = nullptr;
349 
350   // True if the function type is noexcept.
351   bool IsNoexcept = false;
352 };
353 
354 struct IdentifierNode : public Node {
IdentifierNodeIdentifierNode355   explicit IdentifierNode(NodeKind K) : Node(K) {}
356 
357   NodeArrayNode *TemplateParams = nullptr;
358 
359 protected:
360   void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
361 };
362 
363 struct VcallThunkIdentifierNode : public IdentifierNode {
VcallThunkIdentifierNodeVcallThunkIdentifierNode364   VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
365 
366   void output(OutputStream &OS, OutputFlags Flags) const override;
367 
368   uint64_t OffsetInVTable = 0;
369 };
370 
371 struct DynamicStructorIdentifierNode : public IdentifierNode {
DynamicStructorIdentifierNodeDynamicStructorIdentifierNode372   DynamicStructorIdentifierNode()
373       : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
374 
375   void output(OutputStream &OS, OutputFlags Flags) const override;
376 
377   VariableSymbolNode *Variable = nullptr;
378   QualifiedNameNode *Name = nullptr;
379   bool IsDestructor = false;
380 };
381 
382 struct NamedIdentifierNode : public IdentifierNode {
NamedIdentifierNodeNamedIdentifierNode383   NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
384 
385   void output(OutputStream &OS, OutputFlags Flags) const override;
386 
387   StringView Name;
388 };
389 
390 struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
IntrinsicFunctionIdentifierNodeIntrinsicFunctionIdentifierNode391   explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
392       : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
393         Operator(Operator) {}
394 
395   void output(OutputStream &OS, OutputFlags Flags) const override;
396 
397   IntrinsicFunctionKind Operator;
398 };
399 
400 struct LiteralOperatorIdentifierNode : public IdentifierNode {
LiteralOperatorIdentifierNodeLiteralOperatorIdentifierNode401   LiteralOperatorIdentifierNode()
402       : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
403 
404   void output(OutputStream &OS, OutputFlags Flags) const override;
405 
406   StringView Name;
407 };
408 
409 struct LocalStaticGuardIdentifierNode : public IdentifierNode {
LocalStaticGuardIdentifierNodeLocalStaticGuardIdentifierNode410   LocalStaticGuardIdentifierNode()
411       : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
412 
413   void output(OutputStream &OS, OutputFlags Flags) const override;
414 
415   bool IsThread = false;
416   uint32_t ScopeIndex = 0;
417 };
418 
419 struct ConversionOperatorIdentifierNode : public IdentifierNode {
ConversionOperatorIdentifierNodeConversionOperatorIdentifierNode420   ConversionOperatorIdentifierNode()
421       : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
422 
423   void output(OutputStream &OS, OutputFlags Flags) const override;
424 
425   // The type that this operator converts too.
426   TypeNode *TargetType = nullptr;
427 };
428 
429 struct StructorIdentifierNode : public IdentifierNode {
StructorIdentifierNodeStructorIdentifierNode430   StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
StructorIdentifierNodeStructorIdentifierNode431   explicit StructorIdentifierNode(bool IsDestructor)
432       : IdentifierNode(NodeKind::StructorIdentifier),
433         IsDestructor(IsDestructor) {}
434 
435   void output(OutputStream &OS, OutputFlags Flags) const override;
436 
437   // The name of the class that this is a structor of.
438   IdentifierNode *Class = nullptr;
439   bool IsDestructor = false;
440 };
441 
442 struct ThunkSignatureNode : public FunctionSignatureNode {
ThunkSignatureNodeThunkSignatureNode443   ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
444 
445   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
446   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
447 
448   struct ThisAdjustor {
449     uint32_t StaticOffset = 0;
450     int32_t VBPtrOffset = 0;
451     int32_t VBOffsetOffset = 0;
452     int32_t VtordispOffset = 0;
453   };
454 
455   ThisAdjustor ThisAdjust;
456 };
457 
458 struct PointerTypeNode : public TypeNode {
PointerTypeNodePointerTypeNode459   PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
460   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
461   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
462 
463   // Is this a pointer, reference, or rvalue-reference?
464   PointerAffinity Affinity = PointerAffinity::None;
465 
466   // If this is a member pointer, this is the class that the member is in.
467   QualifiedNameNode *ClassParent = nullptr;
468 
469   // Represents a type X in "a pointer to X", "a reference to X", or
470   // "rvalue-reference to X"
471   TypeNode *Pointee = nullptr;
472 };
473 
474 struct TagTypeNode : public TypeNode {
TagTypeNodeTagTypeNode475   explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
476 
477   void outputPre(OutputStream &OS, OutputFlags Flags) const;
478   void outputPost(OutputStream &OS, OutputFlags Flags) const;
479 
480   QualifiedNameNode *QualifiedName = nullptr;
481   TagKind Tag;
482 };
483 
484 struct ArrayTypeNode : public TypeNode {
ArrayTypeNodeArrayTypeNode485   ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
486 
487   void outputPre(OutputStream &OS, OutputFlags Flags) const;
488   void outputPost(OutputStream &OS, OutputFlags Flags) const;
489 
490   void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
491   void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
492 
493   // A list of array dimensions.  e.g. [3,4,5] in `int Foo[3][4][5]`
494   NodeArrayNode *Dimensions = nullptr;
495 
496   // The type of array element.
497   TypeNode *ElementType = nullptr;
498 };
499 
500 struct IntrinsicNode : public TypeNode {
IntrinsicNodeIntrinsicNode501   IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
outputIntrinsicNode502   void output(OutputStream &OS, OutputFlags Flags) const override {}
503 };
504 
505 struct CustomTypeNode : public TypeNode {
CustomTypeNodeCustomTypeNode506   CustomTypeNode() : TypeNode(NodeKind::Custom) {}
507 
508   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
509   void outputPost(OutputStream &OS, OutputFlags Flags) const override;
510 
511   IdentifierNode *Identifier = nullptr;
512 };
513 
514 struct NodeArrayNode : public Node {
NodeArrayNodeNodeArrayNode515   NodeArrayNode() : Node(NodeKind::NodeArray) {}
516 
517   void output(OutputStream &OS, OutputFlags Flags) const override;
518 
519   void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
520 
521   Node **Nodes = nullptr;
522   size_t Count = 0;
523 };
524 
525 struct QualifiedNameNode : public Node {
QualifiedNameNodeQualifiedNameNode526   QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
527 
528   void output(OutputStream &OS, OutputFlags Flags) const override;
529 
530   NodeArrayNode *Components = nullptr;
531 
getUnqualifiedIdentifierQualifiedNameNode532   IdentifierNode *getUnqualifiedIdentifier() {
533     Node *LastComponent = Components->Nodes[Components->Count - 1];
534     return static_cast<IdentifierNode *>(LastComponent);
535   }
536 };
537 
538 struct TemplateParameterReferenceNode : public Node {
TemplateParameterReferenceNodeTemplateParameterReferenceNode539   TemplateParameterReferenceNode()
540       : Node(NodeKind::TemplateParameterReference) {}
541 
542   void output(OutputStream &OS, OutputFlags Flags) const override;
543 
544   SymbolNode *Symbol = nullptr;
545 
546   int ThunkOffsetCount = 0;
547   std::array<int64_t, 3> ThunkOffsets;
548   PointerAffinity Affinity = PointerAffinity::None;
549   bool IsMemberPointer = false;
550 };
551 
552 struct IntegerLiteralNode : public Node {
IntegerLiteralNodeIntegerLiteralNode553   IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
IntegerLiteralNodeIntegerLiteralNode554   IntegerLiteralNode(uint64_t Value, bool IsNegative)
555       : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
556 
557   void output(OutputStream &OS, OutputFlags Flags) const override;
558 
559   uint64_t Value = 0;
560   bool IsNegative = false;
561 };
562 
563 struct RttiBaseClassDescriptorNode : public IdentifierNode {
RttiBaseClassDescriptorNodeRttiBaseClassDescriptorNode564   RttiBaseClassDescriptorNode()
565       : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
566 
567   void output(OutputStream &OS, OutputFlags Flags) const override;
568 
569   uint32_t NVOffset = 0;
570   int32_t VBPtrOffset = 0;
571   uint32_t VBTableOffset = 0;
572   uint32_t Flags = 0;
573 };
574 
575 struct SymbolNode : public Node {
SymbolNodeSymbolNode576   explicit SymbolNode(NodeKind K) : Node(K) {}
577   void output(OutputStream &OS, OutputFlags Flags) const override;
578   QualifiedNameNode *Name = nullptr;
579 };
580 
581 struct SpecialTableSymbolNode : public SymbolNode {
SpecialTableSymbolNodeSpecialTableSymbolNode582   explicit SpecialTableSymbolNode()
583       : SymbolNode(NodeKind::SpecialTableSymbol) {}
584 
585   void output(OutputStream &OS, OutputFlags Flags) const override;
586   QualifiedNameNode *TargetName = nullptr;
587   Qualifiers Quals = Qualifiers::Q_None;
588 };
589 
590 struct LocalStaticGuardVariableNode : public SymbolNode {
LocalStaticGuardVariableNodeLocalStaticGuardVariableNode591   LocalStaticGuardVariableNode()
592       : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
593 
594   void output(OutputStream &OS, OutputFlags Flags) const override;
595 
596   bool IsVisible = false;
597 };
598 
599 struct EncodedStringLiteralNode : public SymbolNode {
EncodedStringLiteralNodeEncodedStringLiteralNode600   EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
601 
602   void output(OutputStream &OS, OutputFlags Flags) const override;
603 
604   StringView DecodedString;
605   bool IsTruncated = false;
606   CharKind Char = CharKind::Char;
607 };
608 
609 struct VariableSymbolNode : public SymbolNode {
VariableSymbolNodeVariableSymbolNode610   VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
611 
612   void output(OutputStream &OS, OutputFlags Flags) const override;
613 
614   StorageClass SC = StorageClass::None;
615   TypeNode *Type = nullptr;
616 };
617 
618 struct FunctionSymbolNode : public SymbolNode {
FunctionSymbolNodeFunctionSymbolNode619   FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
620 
621   void output(OutputStream &OS, OutputFlags Flags) const override;
622 
623   FunctionSignatureNode *Signature = nullptr;
624 };
625 
626 } // namespace ms_demangle
627 } // namespace llvm
628 
629 #endif
630