Home | History | Annotate | Line # | Download | only in Demangle
      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 {
    258   explicit Node(NodeKind K) : Kind(K) {}
    259   virtual ~Node() = default;
    260 
    261   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 {
    300   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 
    305   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 {
    314   explicit PrimitiveTypeNode(PrimitiveKind K)
    315       : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
    316 
    317   void outputPre(OutputStream &OS, OutputFlags Flags) const override;
    318   void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
    319 
    320   PrimitiveKind PrimKind;
    321 };
    322 
    323 struct FunctionSignatureNode : public TypeNode {
    324   explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
    325   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 {
    356   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 {
    365   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 {
    373   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 {
    384   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 {
    392   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 {
    402   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 {
    411   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 {
    421   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 {
    431   StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
    432   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 {
    444   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 {
    460   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 {
    476   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 {
    486   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 {
    502   IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
    503   void output(OutputStream &OS, OutputFlags Flags) const override {}
    504 };
    505 
    506 struct CustomTypeNode : public TypeNode {
    507   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 {
    516   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 {
    527   QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
    528 
    529   void output(OutputStream &OS, OutputFlags Flags) const override;
    530 
    531   NodeArrayNode *Components = nullptr;
    532 
    533   IdentifierNode *getUnqualifiedIdentifier() {
    534     Node *LastComponent = Components->Nodes[Components->Count - 1];
    535     return static_cast<IdentifierNode *>(LastComponent);
    536   }
    537 };
    538 
    539 struct TemplateParameterReferenceNode : public Node {
    540   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 {
    554   IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
    555   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 {
    565   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 {
    577   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 {
    583   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 {
    592   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 {
    601   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 {
    611   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 {
    620   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