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/StringView.h"
17 #include <array>
18 #include <cstdint>
19 #include <string>
20 
21 namespace llvm {
22 namespace itanium_demangle {
23 class OutputBuffer;
24 }
25 }
26 
27 using llvm::itanium_demangle::OutputBuffer;
28 using llvm::itanium_demangle::StringView;
29 
30 namespace llvm {
31 namespace ms_demangle {
32 
33 // Storage classes
34 enum Qualifiers : uint8_t {
35   Q_None = 0,
36   Q_Const = 1 << 0,
37   Q_Volatile = 1 << 1,
38   Q_Far = 1 << 2,
39   Q_Huge = 1 << 3,
40   Q_Unaligned = 1 << 4,
41   Q_Restrict = 1 << 5,
42   Q_Pointer64 = 1 << 6
43 };
44 
45 enum class StorageClass : uint8_t {
46   None,
47   PrivateStatic,
48   ProtectedStatic,
49   PublicStatic,
50   Global,
51   FunctionLocalStatic,
52 };
53 
54 enum class PointerAffinity { None, Pointer, Reference, RValueReference };
55 enum class FunctionRefQualifier { None, Reference, RValueReference };
56 
57 // Calling conventions
58 enum class CallingConv : uint8_t {
59   None,
60   Cdecl,
61   Pascal,
62   Thiscall,
63   Stdcall,
64   Fastcall,
65   Clrcall,
66   Eabi,
67   Vectorcall,
68   Regcall,
69   Swift,      // Clang-only
70   SwiftAsync, // 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   OF_NoVariableType = 32,
83 };
84 
85 // Types
86 enum class PrimitiveKind {
87   Void,
88   Bool,
89   Char,
90   Schar,
91   Uchar,
92   Char8,
93   Char16,
94   Char32,
95   Short,
96   Ushort,
97   Int,
98   Uint,
99   Long,
100   Ulong,
101   Int64,
102   Uint64,
103   Wchar,
104   Float,
105   Double,
106   Ldouble,
107   Nullptr,
108 };
109 
110 enum class CharKind {
111   Char,
112   Char16,
113   Char32,
114   Wchar,
115 };
116 
117 enum class IntrinsicFunctionKind : uint8_t {
118   None,
119   New,                        // ?2 # operator new
120   Delete,                     // ?3 # operator delete
121   Assign,                     // ?4 # operator=
122   RightShift,                 // ?5 # operator>>
123   LeftShift,                  // ?6 # operator<<
124   LogicalNot,                 // ?7 # operator!
125   Equals,                     // ?8 # operator==
126   NotEquals,                  // ?9 # operator!=
127   ArraySubscript,             // ?A # operator[]
128   Pointer,                    // ?C # operator->
129   Dereference,                // ?D # operator*
130   Increment,                  // ?E # operator++
131   Decrement,                  // ?F # operator--
132   Minus,                      // ?G # operator-
133   Plus,                       // ?H # operator+
134   BitwiseAnd,                 // ?I # operator&
135   MemberPointer,              // ?J # operator->*
136   Divide,                     // ?K # operator/
137   Modulus,                    // ?L # operator%
138   LessThan,                   // ?M operator<
139   LessThanEqual,              // ?N operator<=
140   GreaterThan,                // ?O operator>
141   GreaterThanEqual,           // ?P operator>=
142   Comma,                      // ?Q operator,
143   Parens,                     // ?R operator()
144   BitwiseNot,                 // ?S operator~
145   BitwiseXor,                 // ?T operator^
146   BitwiseOr,                  // ?U operator|
147   LogicalAnd,                 // ?V operator&&
148   LogicalOr,                  // ?W operator||
149   TimesEqual,                 // ?X operator*=
150   PlusEqual,                  // ?Y operator+=
151   MinusEqual,                 // ?Z operator-=
152   DivEqual,                   // ?_0 operator/=
153   ModEqual,                   // ?_1 operator%=
154   RshEqual,                   // ?_2 operator>>=
155   LshEqual,                   // ?_3 operator<<=
156   BitwiseAndEqual,            // ?_4 operator&=
157   BitwiseOrEqual,             // ?_5 operator|=
158   BitwiseXorEqual,            // ?_6 operator^=
159   VbaseDtor,                  // ?_D # vbase destructor
160   VecDelDtor,                 // ?_E # vector deleting destructor
161   DefaultCtorClosure,         // ?_F # default constructor closure
162   ScalarDelDtor,              // ?_G # scalar deleting destructor
163   VecCtorIter,                // ?_H # vector constructor iterator
164   VecDtorIter,                // ?_I # vector destructor iterator
165   VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
166   VdispMap,                   // ?_K # virtual displacement map
167   EHVecCtorIter,              // ?_L # eh vector constructor iterator
168   EHVecDtorIter,              // ?_M # eh vector destructor iterator
169   EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
170   CopyCtorClosure,            // ?_O # copy constructor closure
171   LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
172   ArrayNew,                   // ?_U operator new[]
173   ArrayDelete,                // ?_V operator delete[]
174   ManVectorCtorIter,          // ?__A managed vector ctor iterator
175   ManVectorDtorIter,          // ?__B managed vector dtor iterator
176   EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
177   EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
178   VectorCopyCtorIter,         // ?__G vector copy constructor iterator
179   VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
180   ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
181   CoAwait,                    // ?__L operator co_await
182   Spaceship,                  // ?__M operator<=>
183   MaxIntrinsic
184 };
185 
186 enum class SpecialIntrinsicKind {
187   None,
188   Vftable,
189   Vbtable,
190   Typeof,
191   VcallThunk,
192   LocalStaticGuard,
193   StringLiteralSymbol,
194   UdtReturning,
195   Unknown,
196   DynamicInitializer,
197   DynamicAtexitDestructor,
198   RttiTypeDescriptor,
199   RttiBaseClassDescriptor,
200   RttiBaseClassArray,
201   RttiClassHierarchyDescriptor,
202   RttiCompleteObjLocator,
203   LocalVftable,
204   LocalStaticThreadGuard,
205 };
206 
207 // Function classes
208 enum FuncClass : uint16_t {
209   FC_None = 0,
210   FC_Public = 1 << 0,
211   FC_Protected = 1 << 1,
212   FC_Private = 1 << 2,
213   FC_Global = 1 << 3,
214   FC_Static = 1 << 4,
215   FC_Virtual = 1 << 5,
216   FC_Far = 1 << 6,
217   FC_ExternC = 1 << 7,
218   FC_NoParameterList = 1 << 8,
219   FC_VirtualThisAdjust = 1 << 9,
220   FC_VirtualThisAdjustEx = 1 << 10,
221   FC_StaticThisAdjust = 1 << 11,
222 };
223 
224 enum class TagKind { Class, Struct, Union, Enum };
225 
226 enum class NodeKind {
227   Unknown,
228   Md5Symbol,
229   PrimitiveType,
230   FunctionSignature,
231   Identifier,
232   NamedIdentifier,
233   VcallThunkIdentifier,
234   LocalStaticGuardIdentifier,
235   IntrinsicFunctionIdentifier,
236   ConversionOperatorIdentifier,
237   DynamicStructorIdentifier,
238   StructorIdentifier,
239   LiteralOperatorIdentifier,
240   ThunkSignature,
241   PointerType,
242   TagType,
243   ArrayType,
244   Custom,
245   IntrinsicType,
246   NodeArray,
247   QualifiedName,
248   TemplateParameterReference,
249   EncodedStringLiteral,
250   IntegerLiteral,
251   RttiBaseClassDescriptor,
252   LocalStaticGuardVariable,
253   FunctionSymbol,
254   VariableSymbol,
255   SpecialTableSymbol
256 };
257 
258 struct Node {
NodeNode259   explicit Node(NodeKind K) : Kind(K) {}
260   virtual ~Node() = default;
261 
kindNode262   NodeKind kind() const { return Kind; }
263 
264   virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
265 
266   std::string toString(OutputFlags Flags = OF_Default) const;
267 
268 private:
269   NodeKind Kind;
270 };
271 
272 struct TypeNode;
273 struct PrimitiveTypeNode;
274 struct FunctionSignatureNode;
275 struct IdentifierNode;
276 struct NamedIdentifierNode;
277 struct VcallThunkIdentifierNode;
278 struct IntrinsicFunctionIdentifierNode;
279 struct LiteralOperatorIdentifierNode;
280 struct ConversionOperatorIdentifierNode;
281 struct StructorIdentifierNode;
282 struct ThunkSignatureNode;
283 struct PointerTypeNode;
284 struct ArrayTypeNode;
285 struct TagTypeNode;
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(OutputBuffer &OB, OutputFlags Flags) const = 0;
302   virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
303 
outputTypeNode304   void output(OutputBuffer &OB, OutputFlags Flags) const override {
305     outputPre(OB, Flags);
306     outputPost(OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
outputPostPrimitiveTypeNode317   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
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(OutputBuffer &OB, OutputFlags Flags) const override;
327   void outputPost(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const;
361 };
362 
363 struct VcallThunkIdentifierNode : public IdentifierNode {
VcallThunkIdentifierNodeVcallThunkIdentifierNode364   VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
365 
366   void output(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
446   void outputPost(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
461   void outputPost(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
478   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
479 
480   QualifiedNameNode *QualifiedName = nullptr;
481   TagKind Tag;
482 };
483 
484 struct ArrayTypeNode : public TypeNode {
ArrayTypeNodeArrayTypeNode485   ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
486 
487   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
488   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
489 
490   void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
491   void outputOneDimension(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override {}
503 };
504 
505 struct CustomTypeNode : public TypeNode {
CustomTypeNodeCustomTypeNode506   CustomTypeNode() : TypeNode(NodeKind::Custom) {}
507 
508   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
509   void outputPost(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
518 
519   void output(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, 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(OutputBuffer &OB, OutputFlags Flags) const override;
622 
623   FunctionSignatureNode *Signature = nullptr;
624 };
625 
626 } // namespace ms_demangle
627 } // namespace llvm
628 
629 #endif
630