10b57cec5SDimitry Andric //===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the AST nodes used in the MSVC demangler.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
13fe6060f1SDimitry Andric #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
14fe6060f1SDimitry Andric #define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/Demangle/DemangleConfig.h"
170b57cec5SDimitry Andric #include "llvm/Demangle/StringView.h"
180b57cec5SDimitry Andric #include <array>
19c14a5a88SDimitry Andric #include <cstdint>
20c14a5a88SDimitry Andric #include <string>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric namespace itanium_demangle {
24349cc55cSDimitry Andric class OutputBuffer;
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric }
270b57cec5SDimitry Andric 
28349cc55cSDimitry Andric using llvm::itanium_demangle::OutputBuffer;
290b57cec5SDimitry Andric using llvm::itanium_demangle::StringView;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric namespace llvm {
320b57cec5SDimitry Andric namespace ms_demangle {
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric // Storage classes
350b57cec5SDimitry Andric enum Qualifiers : uint8_t {
360b57cec5SDimitry Andric   Q_None = 0,
370b57cec5SDimitry Andric   Q_Const = 1 << 0,
380b57cec5SDimitry Andric   Q_Volatile = 1 << 1,
390b57cec5SDimitry Andric   Q_Far = 1 << 2,
400b57cec5SDimitry Andric   Q_Huge = 1 << 3,
410b57cec5SDimitry Andric   Q_Unaligned = 1 << 4,
420b57cec5SDimitry Andric   Q_Restrict = 1 << 5,
430b57cec5SDimitry Andric   Q_Pointer64 = 1 << 6
440b57cec5SDimitry Andric };
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric enum class StorageClass : uint8_t {
470b57cec5SDimitry Andric   None,
480b57cec5SDimitry Andric   PrivateStatic,
490b57cec5SDimitry Andric   ProtectedStatic,
500b57cec5SDimitry Andric   PublicStatic,
510b57cec5SDimitry Andric   Global,
520b57cec5SDimitry Andric   FunctionLocalStatic,
530b57cec5SDimitry Andric };
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric enum class PointerAffinity { None, Pointer, Reference, RValueReference };
560b57cec5SDimitry Andric enum class FunctionRefQualifier { None, Reference, RValueReference };
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric // Calling conventions
590b57cec5SDimitry Andric enum class CallingConv : uint8_t {
600b57cec5SDimitry Andric   None,
610b57cec5SDimitry Andric   Cdecl,
620b57cec5SDimitry Andric   Pascal,
630b57cec5SDimitry Andric   Thiscall,
640b57cec5SDimitry Andric   Stdcall,
650b57cec5SDimitry Andric   Fastcall,
660b57cec5SDimitry Andric   Clrcall,
670b57cec5SDimitry Andric   Eabi,
680b57cec5SDimitry Andric   Vectorcall,
690b57cec5SDimitry Andric   Regcall,
70fe6060f1SDimitry Andric   Swift,      // Clang-only
71fe6060f1SDimitry Andric   SwiftAsync, // Clang-only
720b57cec5SDimitry Andric };
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric enum OutputFlags {
770b57cec5SDimitry Andric   OF_Default = 0,
780b57cec5SDimitry Andric   OF_NoCallingConvention = 1,
790b57cec5SDimitry Andric   OF_NoTagSpecifier = 2,
808bcb0991SDimitry Andric   OF_NoAccessSpecifier = 4,
818bcb0991SDimitry Andric   OF_NoMemberType = 8,
828bcb0991SDimitry Andric   OF_NoReturnType = 16,
83349cc55cSDimitry Andric   OF_NoVariableType = 32,
840b57cec5SDimitry Andric };
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric // Types
870b57cec5SDimitry Andric enum class PrimitiveKind {
880b57cec5SDimitry Andric   Void,
890b57cec5SDimitry Andric   Bool,
900b57cec5SDimitry Andric   Char,
910b57cec5SDimitry Andric   Schar,
920b57cec5SDimitry Andric   Uchar,
930b57cec5SDimitry Andric   Char8,
940b57cec5SDimitry Andric   Char16,
950b57cec5SDimitry Andric   Char32,
960b57cec5SDimitry Andric   Short,
970b57cec5SDimitry Andric   Ushort,
980b57cec5SDimitry Andric   Int,
990b57cec5SDimitry Andric   Uint,
1000b57cec5SDimitry Andric   Long,
1010b57cec5SDimitry Andric   Ulong,
1020b57cec5SDimitry Andric   Int64,
1030b57cec5SDimitry Andric   Uint64,
1040b57cec5SDimitry Andric   Wchar,
1050b57cec5SDimitry Andric   Float,
1060b57cec5SDimitry Andric   Double,
1070b57cec5SDimitry Andric   Ldouble,
1080b57cec5SDimitry Andric   Nullptr,
1090b57cec5SDimitry Andric };
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric enum class CharKind {
1120b57cec5SDimitry Andric   Char,
1130b57cec5SDimitry Andric   Char16,
1140b57cec5SDimitry Andric   Char32,
1150b57cec5SDimitry Andric   Wchar,
1160b57cec5SDimitry Andric };
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric enum class IntrinsicFunctionKind : uint8_t {
1190b57cec5SDimitry Andric   None,
1200b57cec5SDimitry Andric   New,                        // ?2 # operator new
1210b57cec5SDimitry Andric   Delete,                     // ?3 # operator delete
1220b57cec5SDimitry Andric   Assign,                     // ?4 # operator=
1230b57cec5SDimitry Andric   RightShift,                 // ?5 # operator>>
1240b57cec5SDimitry Andric   LeftShift,                  // ?6 # operator<<
1250b57cec5SDimitry Andric   LogicalNot,                 // ?7 # operator!
1260b57cec5SDimitry Andric   Equals,                     // ?8 # operator==
1270b57cec5SDimitry Andric   NotEquals,                  // ?9 # operator!=
1280b57cec5SDimitry Andric   ArraySubscript,             // ?A # operator[]
1290b57cec5SDimitry Andric   Pointer,                    // ?C # operator->
1300b57cec5SDimitry Andric   Dereference,                // ?D # operator*
1310b57cec5SDimitry Andric   Increment,                  // ?E # operator++
1320b57cec5SDimitry Andric   Decrement,                  // ?F # operator--
1330b57cec5SDimitry Andric   Minus,                      // ?G # operator-
1340b57cec5SDimitry Andric   Plus,                       // ?H # operator+
1350b57cec5SDimitry Andric   BitwiseAnd,                 // ?I # operator&
1360b57cec5SDimitry Andric   MemberPointer,              // ?J # operator->*
1370b57cec5SDimitry Andric   Divide,                     // ?K # operator/
1380b57cec5SDimitry Andric   Modulus,                    // ?L # operator%
1390b57cec5SDimitry Andric   LessThan,                   // ?M operator<
1400b57cec5SDimitry Andric   LessThanEqual,              // ?N operator<=
1410b57cec5SDimitry Andric   GreaterThan,                // ?O operator>
1420b57cec5SDimitry Andric   GreaterThanEqual,           // ?P operator>=
1430b57cec5SDimitry Andric   Comma,                      // ?Q operator,
1440b57cec5SDimitry Andric   Parens,                     // ?R operator()
1450b57cec5SDimitry Andric   BitwiseNot,                 // ?S operator~
1460b57cec5SDimitry Andric   BitwiseXor,                 // ?T operator^
1470b57cec5SDimitry Andric   BitwiseOr,                  // ?U operator|
1480b57cec5SDimitry Andric   LogicalAnd,                 // ?V operator&&
1490b57cec5SDimitry Andric   LogicalOr,                  // ?W operator||
1500b57cec5SDimitry Andric   TimesEqual,                 // ?X operator*=
1510b57cec5SDimitry Andric   PlusEqual,                  // ?Y operator+=
1520b57cec5SDimitry Andric   MinusEqual,                 // ?Z operator-=
1530b57cec5SDimitry Andric   DivEqual,                   // ?_0 operator/=
1540b57cec5SDimitry Andric   ModEqual,                   // ?_1 operator%=
1550b57cec5SDimitry Andric   RshEqual,                   // ?_2 operator>>=
1560b57cec5SDimitry Andric   LshEqual,                   // ?_3 operator<<=
1570b57cec5SDimitry Andric   BitwiseAndEqual,            // ?_4 operator&=
1580b57cec5SDimitry Andric   BitwiseOrEqual,             // ?_5 operator|=
1590b57cec5SDimitry Andric   BitwiseXorEqual,            // ?_6 operator^=
1600b57cec5SDimitry Andric   VbaseDtor,                  // ?_D # vbase destructor
1610b57cec5SDimitry Andric   VecDelDtor,                 // ?_E # vector deleting destructor
1620b57cec5SDimitry Andric   DefaultCtorClosure,         // ?_F # default constructor closure
1630b57cec5SDimitry Andric   ScalarDelDtor,              // ?_G # scalar deleting destructor
1640b57cec5SDimitry Andric   VecCtorIter,                // ?_H # vector constructor iterator
1650b57cec5SDimitry Andric   VecDtorIter,                // ?_I # vector destructor iterator
1660b57cec5SDimitry Andric   VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
1670b57cec5SDimitry Andric   VdispMap,                   // ?_K # virtual displacement map
1680b57cec5SDimitry Andric   EHVecCtorIter,              // ?_L # eh vector constructor iterator
1690b57cec5SDimitry Andric   EHVecDtorIter,              // ?_M # eh vector destructor iterator
1700b57cec5SDimitry Andric   EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
1710b57cec5SDimitry Andric   CopyCtorClosure,            // ?_O # copy constructor closure
1720b57cec5SDimitry Andric   LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
1730b57cec5SDimitry Andric   ArrayNew,                   // ?_U operator new[]
1740b57cec5SDimitry Andric   ArrayDelete,                // ?_V operator delete[]
1750b57cec5SDimitry Andric   ManVectorCtorIter,          // ?__A managed vector ctor iterator
1760b57cec5SDimitry Andric   ManVectorDtorIter,          // ?__B managed vector dtor iterator
1770b57cec5SDimitry Andric   EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
1780b57cec5SDimitry Andric   EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
1790b57cec5SDimitry Andric   VectorCopyCtorIter,         // ?__G vector copy constructor iterator
1800b57cec5SDimitry Andric   VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
1810b57cec5SDimitry Andric   ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
1820b57cec5SDimitry Andric   CoAwait,                    // ?__L operator co_await
1830b57cec5SDimitry Andric   Spaceship,                  // ?__M operator<=>
1840b57cec5SDimitry Andric   MaxIntrinsic
1850b57cec5SDimitry Andric };
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric enum class SpecialIntrinsicKind {
1880b57cec5SDimitry Andric   None,
1890b57cec5SDimitry Andric   Vftable,
1900b57cec5SDimitry Andric   Vbtable,
1910b57cec5SDimitry Andric   Typeof,
1920b57cec5SDimitry Andric   VcallThunk,
1930b57cec5SDimitry Andric   LocalStaticGuard,
1940b57cec5SDimitry Andric   StringLiteralSymbol,
1950b57cec5SDimitry Andric   UdtReturning,
1960b57cec5SDimitry Andric   Unknown,
1970b57cec5SDimitry Andric   DynamicInitializer,
1980b57cec5SDimitry Andric   DynamicAtexitDestructor,
1990b57cec5SDimitry Andric   RttiTypeDescriptor,
2000b57cec5SDimitry Andric   RttiBaseClassDescriptor,
2010b57cec5SDimitry Andric   RttiBaseClassArray,
2020b57cec5SDimitry Andric   RttiClassHierarchyDescriptor,
2030b57cec5SDimitry Andric   RttiCompleteObjLocator,
2040b57cec5SDimitry Andric   LocalVftable,
2050b57cec5SDimitry Andric   LocalStaticThreadGuard,
2060b57cec5SDimitry Andric };
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric // Function classes
2090b57cec5SDimitry Andric enum FuncClass : uint16_t {
2100b57cec5SDimitry Andric   FC_None = 0,
2110b57cec5SDimitry Andric   FC_Public = 1 << 0,
2120b57cec5SDimitry Andric   FC_Protected = 1 << 1,
2130b57cec5SDimitry Andric   FC_Private = 1 << 2,
2140b57cec5SDimitry Andric   FC_Global = 1 << 3,
2150b57cec5SDimitry Andric   FC_Static = 1 << 4,
2160b57cec5SDimitry Andric   FC_Virtual = 1 << 5,
2170b57cec5SDimitry Andric   FC_Far = 1 << 6,
2180b57cec5SDimitry Andric   FC_ExternC = 1 << 7,
2190b57cec5SDimitry Andric   FC_NoParameterList = 1 << 8,
2200b57cec5SDimitry Andric   FC_VirtualThisAdjust = 1 << 9,
2210b57cec5SDimitry Andric   FC_VirtualThisAdjustEx = 1 << 10,
2220b57cec5SDimitry Andric   FC_StaticThisAdjust = 1 << 11,
2230b57cec5SDimitry Andric };
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric enum class TagKind { Class, Struct, Union, Enum };
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric enum class NodeKind {
2280b57cec5SDimitry Andric   Unknown,
2290b57cec5SDimitry Andric   Md5Symbol,
2300b57cec5SDimitry Andric   PrimitiveType,
2310b57cec5SDimitry Andric   FunctionSignature,
2320b57cec5SDimitry Andric   Identifier,
2330b57cec5SDimitry Andric   NamedIdentifier,
2340b57cec5SDimitry Andric   VcallThunkIdentifier,
2350b57cec5SDimitry Andric   LocalStaticGuardIdentifier,
2360b57cec5SDimitry Andric   IntrinsicFunctionIdentifier,
2370b57cec5SDimitry Andric   ConversionOperatorIdentifier,
2380b57cec5SDimitry Andric   DynamicStructorIdentifier,
2390b57cec5SDimitry Andric   StructorIdentifier,
2400b57cec5SDimitry Andric   LiteralOperatorIdentifier,
2410b57cec5SDimitry Andric   ThunkSignature,
2420b57cec5SDimitry Andric   PointerType,
2430b57cec5SDimitry Andric   TagType,
2440b57cec5SDimitry Andric   ArrayType,
2450b57cec5SDimitry Andric   Custom,
2460b57cec5SDimitry Andric   IntrinsicType,
2470b57cec5SDimitry Andric   NodeArray,
2480b57cec5SDimitry Andric   QualifiedName,
2490b57cec5SDimitry Andric   TemplateParameterReference,
2500b57cec5SDimitry Andric   EncodedStringLiteral,
2510b57cec5SDimitry Andric   IntegerLiteral,
2520b57cec5SDimitry Andric   RttiBaseClassDescriptor,
2530b57cec5SDimitry Andric   LocalStaticGuardVariable,
2540b57cec5SDimitry Andric   FunctionSymbol,
2550b57cec5SDimitry Andric   VariableSymbol,
2560b57cec5SDimitry Andric   SpecialTableSymbol
2570b57cec5SDimitry Andric };
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric struct Node {
2600b57cec5SDimitry Andric   explicit Node(NodeKind K) : Kind(K) {}
2610b57cec5SDimitry Andric   virtual ~Node() = default;
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   NodeKind kind() const { return Kind; }
2640b57cec5SDimitry Andric 
265349cc55cSDimitry Andric   virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   std::string toString(OutputFlags Flags = OF_Default) const;
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric private:
2700b57cec5SDimitry Andric   NodeKind Kind;
2710b57cec5SDimitry Andric };
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric struct TypeNode;
2740b57cec5SDimitry Andric struct PrimitiveTypeNode;
2750b57cec5SDimitry Andric struct FunctionSignatureNode;
2760b57cec5SDimitry Andric struct IdentifierNode;
2770b57cec5SDimitry Andric struct NamedIdentifierNode;
2780b57cec5SDimitry Andric struct VcallThunkIdentifierNode;
2790b57cec5SDimitry Andric struct IntrinsicFunctionIdentifierNode;
2800b57cec5SDimitry Andric struct LiteralOperatorIdentifierNode;
2810b57cec5SDimitry Andric struct ConversionOperatorIdentifierNode;
2820b57cec5SDimitry Andric struct StructorIdentifierNode;
2830b57cec5SDimitry Andric struct ThunkSignatureNode;
2840b57cec5SDimitry Andric struct PointerTypeNode;
2850b57cec5SDimitry Andric struct ArrayTypeNode;
2860b57cec5SDimitry Andric struct CustomNode;
2870b57cec5SDimitry Andric struct TagTypeNode;
2880b57cec5SDimitry Andric struct IntrinsicTypeNode;
2890b57cec5SDimitry Andric struct NodeArrayNode;
2900b57cec5SDimitry Andric struct QualifiedNameNode;
2910b57cec5SDimitry Andric struct TemplateParameterReferenceNode;
2920b57cec5SDimitry Andric struct EncodedStringLiteralNode;
2930b57cec5SDimitry Andric struct IntegerLiteralNode;
2940b57cec5SDimitry Andric struct RttiBaseClassDescriptorNode;
2950b57cec5SDimitry Andric struct LocalStaticGuardVariableNode;
2960b57cec5SDimitry Andric struct SymbolNode;
2970b57cec5SDimitry Andric struct FunctionSymbolNode;
2980b57cec5SDimitry Andric struct VariableSymbolNode;
2990b57cec5SDimitry Andric struct SpecialTableSymbolNode;
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric struct TypeNode : public Node {
3020b57cec5SDimitry Andric   explicit TypeNode(NodeKind K) : Node(K) {}
3030b57cec5SDimitry Andric 
304349cc55cSDimitry Andric   virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0;
305349cc55cSDimitry Andric   virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
3060b57cec5SDimitry Andric 
307349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override {
308349cc55cSDimitry Andric     outputPre(OB, Flags);
309349cc55cSDimitry Andric     outputPost(OB, Flags);
3100b57cec5SDimitry Andric   }
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   Qualifiers Quals = Q_None;
3130b57cec5SDimitry Andric };
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric struct PrimitiveTypeNode : public TypeNode {
3160b57cec5SDimitry Andric   explicit PrimitiveTypeNode(PrimitiveKind K)
3170b57cec5SDimitry Andric       : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
3180b57cec5SDimitry Andric 
319349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
320349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   PrimitiveKind PrimKind;
3230b57cec5SDimitry Andric };
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric struct FunctionSignatureNode : public TypeNode {
3260b57cec5SDimitry Andric   explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
3270b57cec5SDimitry Andric   FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
3280b57cec5SDimitry Andric 
329349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
330349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // Valid if this FunctionTypeNode is the Pointee of a PointerType or
3330b57cec5SDimitry Andric   // MemberPointerType.
3340b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   // The function's calling convention.
3370b57cec5SDimitry Andric   CallingConv CallConvention = CallingConv::None;
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   // Function flags (gloabl, public, etc)
3400b57cec5SDimitry Andric   FuncClass FunctionClass = FC_Global;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   // The return type of the function.
3450b57cec5SDimitry Andric   TypeNode *ReturnType = nullptr;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // True if this is a C-style ... varargs function.
3480b57cec5SDimitry Andric   bool IsVariadic = false;
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric   // Function parameters
3510b57cec5SDimitry Andric   NodeArrayNode *Params = nullptr;
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   // True if the function type is noexcept.
3540b57cec5SDimitry Andric   bool IsNoexcept = false;
3550b57cec5SDimitry Andric };
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric struct IdentifierNode : public Node {
3580b57cec5SDimitry Andric   explicit IdentifierNode(NodeKind K) : Node(K) {}
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric   NodeArrayNode *TemplateParams = nullptr;
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric protected:
363349cc55cSDimitry Andric   void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const;
3640b57cec5SDimitry Andric };
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric struct VcallThunkIdentifierNode : public IdentifierNode {
3670b57cec5SDimitry Andric   VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
3680b57cec5SDimitry Andric 
369349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   uint64_t OffsetInVTable = 0;
3720b57cec5SDimitry Andric };
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric struct DynamicStructorIdentifierNode : public IdentifierNode {
3750b57cec5SDimitry Andric   DynamicStructorIdentifierNode()
3760b57cec5SDimitry Andric       : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
3770b57cec5SDimitry Andric 
378349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   VariableSymbolNode *Variable = nullptr;
3810b57cec5SDimitry Andric   QualifiedNameNode *Name = nullptr;
3820b57cec5SDimitry Andric   bool IsDestructor = false;
3830b57cec5SDimitry Andric };
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric struct NamedIdentifierNode : public IdentifierNode {
3860b57cec5SDimitry Andric   NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
3870b57cec5SDimitry Andric 
388349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   StringView Name;
3910b57cec5SDimitry Andric };
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
3940b57cec5SDimitry Andric   explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
3950b57cec5SDimitry Andric       : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
3960b57cec5SDimitry Andric         Operator(Operator) {}
3970b57cec5SDimitry Andric 
398349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   IntrinsicFunctionKind Operator;
4010b57cec5SDimitry Andric };
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric struct LiteralOperatorIdentifierNode : public IdentifierNode {
4040b57cec5SDimitry Andric   LiteralOperatorIdentifierNode()
4050b57cec5SDimitry Andric       : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
4060b57cec5SDimitry Andric 
407349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   StringView Name;
4100b57cec5SDimitry Andric };
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric struct LocalStaticGuardIdentifierNode : public IdentifierNode {
4130b57cec5SDimitry Andric   LocalStaticGuardIdentifierNode()
4140b57cec5SDimitry Andric       : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
4150b57cec5SDimitry Andric 
416349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   bool IsThread = false;
4190b57cec5SDimitry Andric   uint32_t ScopeIndex = 0;
4200b57cec5SDimitry Andric };
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric struct ConversionOperatorIdentifierNode : public IdentifierNode {
4230b57cec5SDimitry Andric   ConversionOperatorIdentifierNode()
4240b57cec5SDimitry Andric       : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
4250b57cec5SDimitry Andric 
426349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric   // The type that this operator converts too.
4290b57cec5SDimitry Andric   TypeNode *TargetType = nullptr;
4300b57cec5SDimitry Andric };
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric struct StructorIdentifierNode : public IdentifierNode {
4330b57cec5SDimitry Andric   StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
4340b57cec5SDimitry Andric   explicit StructorIdentifierNode(bool IsDestructor)
4350b57cec5SDimitry Andric       : IdentifierNode(NodeKind::StructorIdentifier),
4360b57cec5SDimitry Andric         IsDestructor(IsDestructor) {}
4370b57cec5SDimitry Andric 
438349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   // The name of the class that this is a structor of.
4410b57cec5SDimitry Andric   IdentifierNode *Class = nullptr;
4420b57cec5SDimitry Andric   bool IsDestructor = false;
4430b57cec5SDimitry Andric };
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric struct ThunkSignatureNode : public FunctionSignatureNode {
4460b57cec5SDimitry Andric   ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
4470b57cec5SDimitry Andric 
448349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
449349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   struct ThisAdjustor {
4520b57cec5SDimitry Andric     uint32_t StaticOffset = 0;
4530b57cec5SDimitry Andric     int32_t VBPtrOffset = 0;
4540b57cec5SDimitry Andric     int32_t VBOffsetOffset = 0;
4550b57cec5SDimitry Andric     int32_t VtordispOffset = 0;
4560b57cec5SDimitry Andric   };
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   ThisAdjustor ThisAdjust;
4590b57cec5SDimitry Andric };
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric struct PointerTypeNode : public TypeNode {
4620b57cec5SDimitry Andric   PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
463349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
464349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   // Is this a pointer, reference, or rvalue-reference?
4670b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   // If this is a member pointer, this is the class that the member is in.
4700b57cec5SDimitry Andric   QualifiedNameNode *ClassParent = nullptr;
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   // Represents a type X in "a pointer to X", "a reference to X", or
4730b57cec5SDimitry Andric   // "rvalue-reference to X"
4740b57cec5SDimitry Andric   TypeNode *Pointee = nullptr;
4750b57cec5SDimitry Andric };
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric struct TagTypeNode : public TypeNode {
4780b57cec5SDimitry Andric   explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
4790b57cec5SDimitry Andric 
480349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
481349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   QualifiedNameNode *QualifiedName = nullptr;
4840b57cec5SDimitry Andric   TagKind Tag;
4850b57cec5SDimitry Andric };
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric struct ArrayTypeNode : public TypeNode {
4880b57cec5SDimitry Andric   ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
4890b57cec5SDimitry Andric 
490349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
491349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4920b57cec5SDimitry Andric 
493349cc55cSDimitry Andric   void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
494349cc55cSDimitry Andric   void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const;
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric   // A list of array dimensions.  e.g. [3,4,5] in `int Foo[3][4][5]`
4970b57cec5SDimitry Andric   NodeArrayNode *Dimensions = nullptr;
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   // The type of array element.
5000b57cec5SDimitry Andric   TypeNode *ElementType = nullptr;
5010b57cec5SDimitry Andric };
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric struct IntrinsicNode : public TypeNode {
5040b57cec5SDimitry Andric   IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
505349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override {}
5060b57cec5SDimitry Andric };
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric struct CustomTypeNode : public TypeNode {
5090b57cec5SDimitry Andric   CustomTypeNode() : TypeNode(NodeKind::Custom) {}
5100b57cec5SDimitry Andric 
511349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
512349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
5130b57cec5SDimitry Andric 
514480093f4SDimitry Andric   IdentifierNode *Identifier = nullptr;
5150b57cec5SDimitry Andric };
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric struct NodeArrayNode : public Node {
5180b57cec5SDimitry Andric   NodeArrayNode() : Node(NodeKind::NodeArray) {}
5190b57cec5SDimitry Andric 
520349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5210b57cec5SDimitry Andric 
522349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags, StringView Separator) const;
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   Node **Nodes = nullptr;
5250b57cec5SDimitry Andric   size_t Count = 0;
5260b57cec5SDimitry Andric };
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric struct QualifiedNameNode : public Node {
5290b57cec5SDimitry Andric   QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
5300b57cec5SDimitry Andric 
531349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   NodeArrayNode *Components = nullptr;
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   IdentifierNode *getUnqualifiedIdentifier() {
5360b57cec5SDimitry Andric     Node *LastComponent = Components->Nodes[Components->Count - 1];
5370b57cec5SDimitry Andric     return static_cast<IdentifierNode *>(LastComponent);
5380b57cec5SDimitry Andric   }
5390b57cec5SDimitry Andric };
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric struct TemplateParameterReferenceNode : public Node {
5420b57cec5SDimitry Andric   TemplateParameterReferenceNode()
5430b57cec5SDimitry Andric       : Node(NodeKind::TemplateParameterReference) {}
5440b57cec5SDimitry Andric 
545349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   SymbolNode *Symbol = nullptr;
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   int ThunkOffsetCount = 0;
5500b57cec5SDimitry Andric   std::array<int64_t, 3> ThunkOffsets;
5510b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
5520b57cec5SDimitry Andric   bool IsMemberPointer = false;
5530b57cec5SDimitry Andric };
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric struct IntegerLiteralNode : public Node {
5560b57cec5SDimitry Andric   IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
5570b57cec5SDimitry Andric   IntegerLiteralNode(uint64_t Value, bool IsNegative)
5580b57cec5SDimitry Andric       : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
5590b57cec5SDimitry Andric 
560349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   uint64_t Value = 0;
5630b57cec5SDimitry Andric   bool IsNegative = false;
5640b57cec5SDimitry Andric };
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric struct RttiBaseClassDescriptorNode : public IdentifierNode {
5670b57cec5SDimitry Andric   RttiBaseClassDescriptorNode()
5680b57cec5SDimitry Andric       : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
5690b57cec5SDimitry Andric 
570349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   uint32_t NVOffset = 0;
5730b57cec5SDimitry Andric   int32_t VBPtrOffset = 0;
5740b57cec5SDimitry Andric   uint32_t VBTableOffset = 0;
5750b57cec5SDimitry Andric   uint32_t Flags = 0;
5760b57cec5SDimitry Andric };
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric struct SymbolNode : public Node {
5790b57cec5SDimitry Andric   explicit SymbolNode(NodeKind K) : Node(K) {}
580349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5810b57cec5SDimitry Andric   QualifiedNameNode *Name = nullptr;
5820b57cec5SDimitry Andric };
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric struct SpecialTableSymbolNode : public SymbolNode {
5850b57cec5SDimitry Andric   explicit SpecialTableSymbolNode()
5860b57cec5SDimitry Andric       : SymbolNode(NodeKind::SpecialTableSymbol) {}
5870b57cec5SDimitry Andric 
588349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5890b57cec5SDimitry Andric   QualifiedNameNode *TargetName = nullptr;
590480093f4SDimitry Andric   Qualifiers Quals = Qualifiers::Q_None;
5910b57cec5SDimitry Andric };
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric struct LocalStaticGuardVariableNode : public SymbolNode {
5940b57cec5SDimitry Andric   LocalStaticGuardVariableNode()
5950b57cec5SDimitry Andric       : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
5960b57cec5SDimitry Andric 
597349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric   bool IsVisible = false;
6000b57cec5SDimitry Andric };
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric struct EncodedStringLiteralNode : public SymbolNode {
6030b57cec5SDimitry Andric   EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
6040b57cec5SDimitry Andric 
605349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric   StringView DecodedString;
6080b57cec5SDimitry Andric   bool IsTruncated = false;
6090b57cec5SDimitry Andric   CharKind Char = CharKind::Char;
6100b57cec5SDimitry Andric };
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric struct VariableSymbolNode : public SymbolNode {
6130b57cec5SDimitry Andric   VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
6140b57cec5SDimitry Andric 
615349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric   StorageClass SC = StorageClass::None;
6180b57cec5SDimitry Andric   TypeNode *Type = nullptr;
6190b57cec5SDimitry Andric };
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric struct FunctionSymbolNode : public SymbolNode {
6220b57cec5SDimitry Andric   FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
6230b57cec5SDimitry Andric 
624349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric   FunctionSignatureNode *Signature = nullptr;
6270b57cec5SDimitry Andric };
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric } // namespace ms_demangle
6300b57cec5SDimitry Andric } // namespace llvm
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric #endif
633