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 <array>
17c14a5a88SDimitry Andric #include <cstdint>
18c14a5a88SDimitry Andric #include <string>
1906c3fb27SDimitry Andric #include <string_view>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace llvm {
220b57cec5SDimitry Andric namespace itanium_demangle {
23349cc55cSDimitry Andric class OutputBuffer;
240b57cec5SDimitry Andric }
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric 
27349cc55cSDimitry Andric using llvm::itanium_demangle::OutputBuffer;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace llvm {
300b57cec5SDimitry Andric namespace ms_demangle {
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric // Storage classes
330b57cec5SDimitry Andric enum Qualifiers : uint8_t {
340b57cec5SDimitry Andric   Q_None = 0,
350b57cec5SDimitry Andric   Q_Const = 1 << 0,
360b57cec5SDimitry Andric   Q_Volatile = 1 << 1,
370b57cec5SDimitry Andric   Q_Far = 1 << 2,
380b57cec5SDimitry Andric   Q_Huge = 1 << 3,
390b57cec5SDimitry Andric   Q_Unaligned = 1 << 4,
400b57cec5SDimitry Andric   Q_Restrict = 1 << 5,
410b57cec5SDimitry Andric   Q_Pointer64 = 1 << 6
420b57cec5SDimitry Andric };
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric enum class StorageClass : uint8_t {
450b57cec5SDimitry Andric   None,
460b57cec5SDimitry Andric   PrivateStatic,
470b57cec5SDimitry Andric   ProtectedStatic,
480b57cec5SDimitry Andric   PublicStatic,
490b57cec5SDimitry Andric   Global,
500b57cec5SDimitry Andric   FunctionLocalStatic,
510b57cec5SDimitry Andric };
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric enum class PointerAffinity { None, Pointer, Reference, RValueReference };
540b57cec5SDimitry Andric enum class FunctionRefQualifier { None, Reference, RValueReference };
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric // Calling conventions
570b57cec5SDimitry Andric enum class CallingConv : uint8_t {
580b57cec5SDimitry Andric   None,
590b57cec5SDimitry Andric   Cdecl,
600b57cec5SDimitry Andric   Pascal,
610b57cec5SDimitry Andric   Thiscall,
620b57cec5SDimitry Andric   Stdcall,
630b57cec5SDimitry Andric   Fastcall,
640b57cec5SDimitry Andric   Clrcall,
650b57cec5SDimitry Andric   Eabi,
660b57cec5SDimitry Andric   Vectorcall,
670b57cec5SDimitry Andric   Regcall,
68fe6060f1SDimitry Andric   Swift,      // Clang-only
69fe6060f1SDimitry Andric   SwiftAsync, // Clang-only
700b57cec5SDimitry Andric };
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric enum OutputFlags {
750b57cec5SDimitry Andric   OF_Default = 0,
760b57cec5SDimitry Andric   OF_NoCallingConvention = 1,
770b57cec5SDimitry Andric   OF_NoTagSpecifier = 2,
788bcb0991SDimitry Andric   OF_NoAccessSpecifier = 4,
798bcb0991SDimitry Andric   OF_NoMemberType = 8,
808bcb0991SDimitry Andric   OF_NoReturnType = 16,
81349cc55cSDimitry Andric   OF_NoVariableType = 32,
820b57cec5SDimitry Andric };
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric // Types
850b57cec5SDimitry Andric enum class PrimitiveKind {
860b57cec5SDimitry Andric   Void,
870b57cec5SDimitry Andric   Bool,
880b57cec5SDimitry Andric   Char,
890b57cec5SDimitry Andric   Schar,
900b57cec5SDimitry Andric   Uchar,
910b57cec5SDimitry Andric   Char8,
920b57cec5SDimitry Andric   Char16,
930b57cec5SDimitry Andric   Char32,
940b57cec5SDimitry Andric   Short,
950b57cec5SDimitry Andric   Ushort,
960b57cec5SDimitry Andric   Int,
970b57cec5SDimitry Andric   Uint,
980b57cec5SDimitry Andric   Long,
990b57cec5SDimitry Andric   Ulong,
1000b57cec5SDimitry Andric   Int64,
1010b57cec5SDimitry Andric   Uint64,
1020b57cec5SDimitry Andric   Wchar,
1030b57cec5SDimitry Andric   Float,
1040b57cec5SDimitry Andric   Double,
1050b57cec5SDimitry Andric   Ldouble,
1060b57cec5SDimitry Andric   Nullptr,
1070b57cec5SDimitry Andric };
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric enum class CharKind {
1100b57cec5SDimitry Andric   Char,
1110b57cec5SDimitry Andric   Char16,
1120b57cec5SDimitry Andric   Char32,
1130b57cec5SDimitry Andric   Wchar,
1140b57cec5SDimitry Andric };
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric enum class IntrinsicFunctionKind : uint8_t {
1170b57cec5SDimitry Andric   None,
1180b57cec5SDimitry Andric   New,                        // ?2 # operator new
1190b57cec5SDimitry Andric   Delete,                     // ?3 # operator delete
1200b57cec5SDimitry Andric   Assign,                     // ?4 # operator=
1210b57cec5SDimitry Andric   RightShift,                 // ?5 # operator>>
1220b57cec5SDimitry Andric   LeftShift,                  // ?6 # operator<<
1230b57cec5SDimitry Andric   LogicalNot,                 // ?7 # operator!
1240b57cec5SDimitry Andric   Equals,                     // ?8 # operator==
1250b57cec5SDimitry Andric   NotEquals,                  // ?9 # operator!=
1260b57cec5SDimitry Andric   ArraySubscript,             // ?A # operator[]
1270b57cec5SDimitry Andric   Pointer,                    // ?C # operator->
1280b57cec5SDimitry Andric   Dereference,                // ?D # operator*
1290b57cec5SDimitry Andric   Increment,                  // ?E # operator++
1300b57cec5SDimitry Andric   Decrement,                  // ?F # operator--
1310b57cec5SDimitry Andric   Minus,                      // ?G # operator-
1320b57cec5SDimitry Andric   Plus,                       // ?H # operator+
1330b57cec5SDimitry Andric   BitwiseAnd,                 // ?I # operator&
1340b57cec5SDimitry Andric   MemberPointer,              // ?J # operator->*
1350b57cec5SDimitry Andric   Divide,                     // ?K # operator/
1360b57cec5SDimitry Andric   Modulus,                    // ?L # operator%
1370b57cec5SDimitry Andric   LessThan,                   // ?M operator<
1380b57cec5SDimitry Andric   LessThanEqual,              // ?N operator<=
1390b57cec5SDimitry Andric   GreaterThan,                // ?O operator>
1400b57cec5SDimitry Andric   GreaterThanEqual,           // ?P operator>=
1410b57cec5SDimitry Andric   Comma,                      // ?Q operator,
1420b57cec5SDimitry Andric   Parens,                     // ?R operator()
1430b57cec5SDimitry Andric   BitwiseNot,                 // ?S operator~
1440b57cec5SDimitry Andric   BitwiseXor,                 // ?T operator^
1450b57cec5SDimitry Andric   BitwiseOr,                  // ?U operator|
1460b57cec5SDimitry Andric   LogicalAnd,                 // ?V operator&&
1470b57cec5SDimitry Andric   LogicalOr,                  // ?W operator||
1480b57cec5SDimitry Andric   TimesEqual,                 // ?X operator*=
1490b57cec5SDimitry Andric   PlusEqual,                  // ?Y operator+=
1500b57cec5SDimitry Andric   MinusEqual,                 // ?Z operator-=
1510b57cec5SDimitry Andric   DivEqual,                   // ?_0 operator/=
1520b57cec5SDimitry Andric   ModEqual,                   // ?_1 operator%=
1530b57cec5SDimitry Andric   RshEqual,                   // ?_2 operator>>=
1540b57cec5SDimitry Andric   LshEqual,                   // ?_3 operator<<=
1550b57cec5SDimitry Andric   BitwiseAndEqual,            // ?_4 operator&=
1560b57cec5SDimitry Andric   BitwiseOrEqual,             // ?_5 operator|=
1570b57cec5SDimitry Andric   BitwiseXorEqual,            // ?_6 operator^=
1580b57cec5SDimitry Andric   VbaseDtor,                  // ?_D # vbase destructor
1590b57cec5SDimitry Andric   VecDelDtor,                 // ?_E # vector deleting destructor
1600b57cec5SDimitry Andric   DefaultCtorClosure,         // ?_F # default constructor closure
1610b57cec5SDimitry Andric   ScalarDelDtor,              // ?_G # scalar deleting destructor
1620b57cec5SDimitry Andric   VecCtorIter,                // ?_H # vector constructor iterator
1630b57cec5SDimitry Andric   VecDtorIter,                // ?_I # vector destructor iterator
1640b57cec5SDimitry Andric   VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
1650b57cec5SDimitry Andric   VdispMap,                   // ?_K # virtual displacement map
1660b57cec5SDimitry Andric   EHVecCtorIter,              // ?_L # eh vector constructor iterator
1670b57cec5SDimitry Andric   EHVecDtorIter,              // ?_M # eh vector destructor iterator
1680b57cec5SDimitry Andric   EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
1690b57cec5SDimitry Andric   CopyCtorClosure,            // ?_O # copy constructor closure
1700b57cec5SDimitry Andric   LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
1710b57cec5SDimitry Andric   ArrayNew,                   // ?_U operator new[]
1720b57cec5SDimitry Andric   ArrayDelete,                // ?_V operator delete[]
1730b57cec5SDimitry Andric   ManVectorCtorIter,          // ?__A managed vector ctor iterator
1740b57cec5SDimitry Andric   ManVectorDtorIter,          // ?__B managed vector dtor iterator
1750b57cec5SDimitry Andric   EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
1760b57cec5SDimitry Andric   EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
1770b57cec5SDimitry Andric   VectorCopyCtorIter,         // ?__G vector copy constructor iterator
1780b57cec5SDimitry Andric   VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
1790b57cec5SDimitry Andric   ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
1800b57cec5SDimitry Andric   CoAwait,                    // ?__L operator co_await
1810b57cec5SDimitry Andric   Spaceship,                  // ?__M operator<=>
1820b57cec5SDimitry Andric   MaxIntrinsic
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric enum class SpecialIntrinsicKind {
1860b57cec5SDimitry Andric   None,
1870b57cec5SDimitry Andric   Vftable,
1880b57cec5SDimitry Andric   Vbtable,
1890b57cec5SDimitry Andric   Typeof,
1900b57cec5SDimitry Andric   VcallThunk,
1910b57cec5SDimitry Andric   LocalStaticGuard,
1920b57cec5SDimitry Andric   StringLiteralSymbol,
1930b57cec5SDimitry Andric   UdtReturning,
1940b57cec5SDimitry Andric   Unknown,
1950b57cec5SDimitry Andric   DynamicInitializer,
1960b57cec5SDimitry Andric   DynamicAtexitDestructor,
1970b57cec5SDimitry Andric   RttiTypeDescriptor,
1980b57cec5SDimitry Andric   RttiBaseClassDescriptor,
1990b57cec5SDimitry Andric   RttiBaseClassArray,
2000b57cec5SDimitry Andric   RttiClassHierarchyDescriptor,
2010b57cec5SDimitry Andric   RttiCompleteObjLocator,
2020b57cec5SDimitry Andric   LocalVftable,
2030b57cec5SDimitry Andric   LocalStaticThreadGuard,
2040b57cec5SDimitry Andric };
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric // Function classes
2070b57cec5SDimitry Andric enum FuncClass : uint16_t {
2080b57cec5SDimitry Andric   FC_None = 0,
2090b57cec5SDimitry Andric   FC_Public = 1 << 0,
2100b57cec5SDimitry Andric   FC_Protected = 1 << 1,
2110b57cec5SDimitry Andric   FC_Private = 1 << 2,
2120b57cec5SDimitry Andric   FC_Global = 1 << 3,
2130b57cec5SDimitry Andric   FC_Static = 1 << 4,
2140b57cec5SDimitry Andric   FC_Virtual = 1 << 5,
2150b57cec5SDimitry Andric   FC_Far = 1 << 6,
2160b57cec5SDimitry Andric   FC_ExternC = 1 << 7,
2170b57cec5SDimitry Andric   FC_NoParameterList = 1 << 8,
2180b57cec5SDimitry Andric   FC_VirtualThisAdjust = 1 << 9,
2190b57cec5SDimitry Andric   FC_VirtualThisAdjustEx = 1 << 10,
2200b57cec5SDimitry Andric   FC_StaticThisAdjust = 1 << 11,
2210b57cec5SDimitry Andric };
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric enum class TagKind { Class, Struct, Union, Enum };
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric enum class NodeKind {
2260b57cec5SDimitry Andric   Unknown,
2270b57cec5SDimitry Andric   Md5Symbol,
2280b57cec5SDimitry Andric   PrimitiveType,
2290b57cec5SDimitry Andric   FunctionSignature,
2300b57cec5SDimitry Andric   Identifier,
2310b57cec5SDimitry Andric   NamedIdentifier,
2320b57cec5SDimitry Andric   VcallThunkIdentifier,
2330b57cec5SDimitry Andric   LocalStaticGuardIdentifier,
2340b57cec5SDimitry Andric   IntrinsicFunctionIdentifier,
2350b57cec5SDimitry Andric   ConversionOperatorIdentifier,
2360b57cec5SDimitry Andric   DynamicStructorIdentifier,
2370b57cec5SDimitry Andric   StructorIdentifier,
2380b57cec5SDimitry Andric   LiteralOperatorIdentifier,
2390b57cec5SDimitry Andric   ThunkSignature,
2400b57cec5SDimitry Andric   PointerType,
2410b57cec5SDimitry Andric   TagType,
2420b57cec5SDimitry Andric   ArrayType,
2430b57cec5SDimitry Andric   Custom,
2440b57cec5SDimitry Andric   IntrinsicType,
2450b57cec5SDimitry Andric   NodeArray,
2460b57cec5SDimitry Andric   QualifiedName,
2470b57cec5SDimitry Andric   TemplateParameterReference,
2480b57cec5SDimitry Andric   EncodedStringLiteral,
2490b57cec5SDimitry Andric   IntegerLiteral,
2500b57cec5SDimitry Andric   RttiBaseClassDescriptor,
2510b57cec5SDimitry Andric   LocalStaticGuardVariable,
2520b57cec5SDimitry Andric   FunctionSymbol,
2530b57cec5SDimitry Andric   VariableSymbol,
2540b57cec5SDimitry Andric   SpecialTableSymbol
2550b57cec5SDimitry Andric };
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric struct Node {
NodeNode2580b57cec5SDimitry Andric   explicit Node(NodeKind K) : Kind(K) {}
2590b57cec5SDimitry Andric   virtual ~Node() = default;
2600b57cec5SDimitry Andric 
kindNode2610b57cec5SDimitry Andric   NodeKind kind() const { return Kind; }
2620b57cec5SDimitry Andric 
263349cc55cSDimitry Andric   virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   std::string toString(OutputFlags Flags = OF_Default) const;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric private:
2680b57cec5SDimitry Andric   NodeKind Kind;
2690b57cec5SDimitry Andric };
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric struct TypeNode;
2720b57cec5SDimitry Andric struct PrimitiveTypeNode;
2730b57cec5SDimitry Andric struct FunctionSignatureNode;
2740b57cec5SDimitry Andric struct IdentifierNode;
2750b57cec5SDimitry Andric struct NamedIdentifierNode;
2760b57cec5SDimitry Andric struct VcallThunkIdentifierNode;
2770b57cec5SDimitry Andric struct IntrinsicFunctionIdentifierNode;
2780b57cec5SDimitry Andric struct LiteralOperatorIdentifierNode;
2790b57cec5SDimitry Andric struct ConversionOperatorIdentifierNode;
2800b57cec5SDimitry Andric struct StructorIdentifierNode;
2810b57cec5SDimitry Andric struct ThunkSignatureNode;
2820b57cec5SDimitry Andric struct PointerTypeNode;
2830b57cec5SDimitry Andric struct ArrayTypeNode;
2840b57cec5SDimitry Andric struct TagTypeNode;
2850b57cec5SDimitry Andric struct NodeArrayNode;
2860b57cec5SDimitry Andric struct QualifiedNameNode;
2870b57cec5SDimitry Andric struct TemplateParameterReferenceNode;
2880b57cec5SDimitry Andric struct EncodedStringLiteralNode;
2890b57cec5SDimitry Andric struct IntegerLiteralNode;
2900b57cec5SDimitry Andric struct RttiBaseClassDescriptorNode;
2910b57cec5SDimitry Andric struct LocalStaticGuardVariableNode;
2920b57cec5SDimitry Andric struct SymbolNode;
2930b57cec5SDimitry Andric struct FunctionSymbolNode;
2940b57cec5SDimitry Andric struct VariableSymbolNode;
2950b57cec5SDimitry Andric struct SpecialTableSymbolNode;
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric struct TypeNode : public Node {
TypeNodeTypeNode2980b57cec5SDimitry Andric   explicit TypeNode(NodeKind K) : Node(K) {}
2990b57cec5SDimitry Andric 
300349cc55cSDimitry Andric   virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0;
301349cc55cSDimitry Andric   virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
3020b57cec5SDimitry Andric 
outputTypeNode303349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override {
304349cc55cSDimitry Andric     outputPre(OB, Flags);
305349cc55cSDimitry Andric     outputPost(OB, Flags);
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   Qualifiers Quals = Q_None;
3090b57cec5SDimitry Andric };
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric struct PrimitiveTypeNode : public TypeNode {
PrimitiveTypeNodePrimitiveTypeNode3120b57cec5SDimitry Andric   explicit PrimitiveTypeNode(PrimitiveKind K)
3130b57cec5SDimitry Andric       : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
3140b57cec5SDimitry Andric 
315349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
outputPostPrimitiveTypeNode316349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric   PrimitiveKind PrimKind;
3190b57cec5SDimitry Andric };
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric struct FunctionSignatureNode : public TypeNode {
FunctionSignatureNodeFunctionSignatureNode3220b57cec5SDimitry Andric   explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
FunctionSignatureNodeFunctionSignatureNode3230b57cec5SDimitry Andric   FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
3240b57cec5SDimitry Andric 
325349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
326349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   // Valid if this FunctionTypeNode is the Pointee of a PointerType or
3290b57cec5SDimitry Andric   // MemberPointerType.
3300b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // The function's calling convention.
3330b57cec5SDimitry Andric   CallingConv CallConvention = CallingConv::None;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   // Function flags (gloabl, public, etc)
3360b57cec5SDimitry Andric   FuncClass FunctionClass = FC_Global;
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric   // The return type of the function.
3410b57cec5SDimitry Andric   TypeNode *ReturnType = nullptr;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   // True if this is a C-style ... varargs function.
3440b57cec5SDimitry Andric   bool IsVariadic = false;
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   // Function parameters
3470b57cec5SDimitry Andric   NodeArrayNode *Params = nullptr;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // True if the function type is noexcept.
3500b57cec5SDimitry Andric   bool IsNoexcept = false;
3510b57cec5SDimitry Andric };
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric struct IdentifierNode : public Node {
IdentifierNodeIdentifierNode3540b57cec5SDimitry Andric   explicit IdentifierNode(NodeKind K) : Node(K) {}
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   NodeArrayNode *TemplateParams = nullptr;
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric protected:
359349cc55cSDimitry Andric   void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const;
3600b57cec5SDimitry Andric };
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric struct VcallThunkIdentifierNode : public IdentifierNode {
VcallThunkIdentifierNodeVcallThunkIdentifierNode3630b57cec5SDimitry Andric   VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
3640b57cec5SDimitry Andric 
365349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   uint64_t OffsetInVTable = 0;
3680b57cec5SDimitry Andric };
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric struct DynamicStructorIdentifierNode : public IdentifierNode {
DynamicStructorIdentifierNodeDynamicStructorIdentifierNode3710b57cec5SDimitry Andric   DynamicStructorIdentifierNode()
3720b57cec5SDimitry Andric       : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
3730b57cec5SDimitry Andric 
374349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   VariableSymbolNode *Variable = nullptr;
3770b57cec5SDimitry Andric   QualifiedNameNode *Name = nullptr;
3780b57cec5SDimitry Andric   bool IsDestructor = false;
3790b57cec5SDimitry Andric };
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric struct NamedIdentifierNode : public IdentifierNode {
NamedIdentifierNodeNamedIdentifierNode3820b57cec5SDimitry Andric   NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
3830b57cec5SDimitry Andric 
384349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3850b57cec5SDimitry Andric 
38606c3fb27SDimitry Andric   std::string_view Name;
3870b57cec5SDimitry Andric };
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
IntrinsicFunctionIdentifierNodeIntrinsicFunctionIdentifierNode3900b57cec5SDimitry Andric   explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
3910b57cec5SDimitry Andric       : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
3920b57cec5SDimitry Andric         Operator(Operator) {}
3930b57cec5SDimitry Andric 
394349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   IntrinsicFunctionKind Operator;
3970b57cec5SDimitry Andric };
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric struct LiteralOperatorIdentifierNode : public IdentifierNode {
LiteralOperatorIdentifierNodeLiteralOperatorIdentifierNode4000b57cec5SDimitry Andric   LiteralOperatorIdentifierNode()
4010b57cec5SDimitry Andric       : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
4020b57cec5SDimitry Andric 
403349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4040b57cec5SDimitry Andric 
40506c3fb27SDimitry Andric   std::string_view Name;
4060b57cec5SDimitry Andric };
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric struct LocalStaticGuardIdentifierNode : public IdentifierNode {
LocalStaticGuardIdentifierNodeLocalStaticGuardIdentifierNode4090b57cec5SDimitry Andric   LocalStaticGuardIdentifierNode()
4100b57cec5SDimitry Andric       : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
4110b57cec5SDimitry Andric 
412349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   bool IsThread = false;
4150b57cec5SDimitry Andric   uint32_t ScopeIndex = 0;
4160b57cec5SDimitry Andric };
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric struct ConversionOperatorIdentifierNode : public IdentifierNode {
ConversionOperatorIdentifierNodeConversionOperatorIdentifierNode4190b57cec5SDimitry Andric   ConversionOperatorIdentifierNode()
4200b57cec5SDimitry Andric       : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
4210b57cec5SDimitry Andric 
422349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric   // The type that this operator converts too.
4250b57cec5SDimitry Andric   TypeNode *TargetType = nullptr;
4260b57cec5SDimitry Andric };
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric struct StructorIdentifierNode : public IdentifierNode {
StructorIdentifierNodeStructorIdentifierNode4290b57cec5SDimitry Andric   StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
StructorIdentifierNodeStructorIdentifierNode4300b57cec5SDimitry Andric   explicit StructorIdentifierNode(bool IsDestructor)
4310b57cec5SDimitry Andric       : IdentifierNode(NodeKind::StructorIdentifier),
4320b57cec5SDimitry Andric         IsDestructor(IsDestructor) {}
4330b57cec5SDimitry Andric 
434349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // The name of the class that this is a structor of.
4370b57cec5SDimitry Andric   IdentifierNode *Class = nullptr;
4380b57cec5SDimitry Andric   bool IsDestructor = false;
4390b57cec5SDimitry Andric };
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric struct ThunkSignatureNode : public FunctionSignatureNode {
ThunkSignatureNodeThunkSignatureNode4420b57cec5SDimitry Andric   ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
4430b57cec5SDimitry Andric 
444349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
445349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   struct ThisAdjustor {
4480b57cec5SDimitry Andric     uint32_t StaticOffset = 0;
4490b57cec5SDimitry Andric     int32_t VBPtrOffset = 0;
4500b57cec5SDimitry Andric     int32_t VBOffsetOffset = 0;
4510b57cec5SDimitry Andric     int32_t VtordispOffset = 0;
4520b57cec5SDimitry Andric   };
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric   ThisAdjustor ThisAdjust;
4550b57cec5SDimitry Andric };
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric struct PointerTypeNode : public TypeNode {
PointerTypeNodePointerTypeNode4580b57cec5SDimitry Andric   PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
459349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
460349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   // Is this a pointer, reference, or rvalue-reference?
4630b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // If this is a member pointer, this is the class that the member is in.
4660b57cec5SDimitry Andric   QualifiedNameNode *ClassParent = nullptr;
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // Represents a type X in "a pointer to X", "a reference to X", or
4690b57cec5SDimitry Andric   // "rvalue-reference to X"
4700b57cec5SDimitry Andric   TypeNode *Pointee = nullptr;
4710b57cec5SDimitry Andric };
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric struct TagTypeNode : public TypeNode {
TagTypeNodeTagTypeNode4740b57cec5SDimitry Andric   explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
4750b57cec5SDimitry Andric 
476349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
477349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   QualifiedNameNode *QualifiedName = nullptr;
4800b57cec5SDimitry Andric   TagKind Tag;
4810b57cec5SDimitry Andric };
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric struct ArrayTypeNode : public TypeNode {
ArrayTypeNodeArrayTypeNode4840b57cec5SDimitry Andric   ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
4850b57cec5SDimitry Andric 
486349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
487349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
4880b57cec5SDimitry Andric 
489349cc55cSDimitry Andric   void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
490349cc55cSDimitry Andric   void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   // A list of array dimensions.  e.g. [3,4,5] in `int Foo[3][4][5]`
4930b57cec5SDimitry Andric   NodeArrayNode *Dimensions = nullptr;
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   // The type of array element.
4960b57cec5SDimitry Andric   TypeNode *ElementType = nullptr;
4970b57cec5SDimitry Andric };
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric struct IntrinsicNode : public TypeNode {
IntrinsicNodeIntrinsicNode5000b57cec5SDimitry Andric   IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
outputIntrinsicNode501349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override {}
5020b57cec5SDimitry Andric };
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric struct CustomTypeNode : public TypeNode {
CustomTypeNodeCustomTypeNode5050b57cec5SDimitry Andric   CustomTypeNode() : TypeNode(NodeKind::Custom) {}
5060b57cec5SDimitry Andric 
507349cc55cSDimitry Andric   void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
508349cc55cSDimitry Andric   void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
5090b57cec5SDimitry Andric 
510480093f4SDimitry Andric   IdentifierNode *Identifier = nullptr;
5110b57cec5SDimitry Andric };
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric struct NodeArrayNode : public Node {
NodeArrayNodeNodeArrayNode5140b57cec5SDimitry Andric   NodeArrayNode() : Node(NodeKind::NodeArray) {}
5150b57cec5SDimitry Andric 
516349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5170b57cec5SDimitry Andric 
51806c3fb27SDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags,
51906c3fb27SDimitry Andric               std::string_view Separator) const;
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   Node **Nodes = nullptr;
5220b57cec5SDimitry Andric   size_t Count = 0;
5230b57cec5SDimitry Andric };
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric struct QualifiedNameNode : public Node {
QualifiedNameNodeQualifiedNameNode5260b57cec5SDimitry Andric   QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
5270b57cec5SDimitry Andric 
528349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric   NodeArrayNode *Components = nullptr;
5310b57cec5SDimitry Andric 
getUnqualifiedIdentifierQualifiedNameNode5320b57cec5SDimitry Andric   IdentifierNode *getUnqualifiedIdentifier() {
5330b57cec5SDimitry Andric     Node *LastComponent = Components->Nodes[Components->Count - 1];
5340b57cec5SDimitry Andric     return static_cast<IdentifierNode *>(LastComponent);
5350b57cec5SDimitry Andric   }
5360b57cec5SDimitry Andric };
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric struct TemplateParameterReferenceNode : public Node {
TemplateParameterReferenceNodeTemplateParameterReferenceNode5390b57cec5SDimitry Andric   TemplateParameterReferenceNode()
5400b57cec5SDimitry Andric       : Node(NodeKind::TemplateParameterReference) {}
5410b57cec5SDimitry Andric 
542349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   SymbolNode *Symbol = nullptr;
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   int ThunkOffsetCount = 0;
5470b57cec5SDimitry Andric   std::array<int64_t, 3> ThunkOffsets;
5480b57cec5SDimitry Andric   PointerAffinity Affinity = PointerAffinity::None;
5490b57cec5SDimitry Andric   bool IsMemberPointer = false;
5500b57cec5SDimitry Andric };
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric struct IntegerLiteralNode : public Node {
IntegerLiteralNodeIntegerLiteralNode5530b57cec5SDimitry Andric   IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
IntegerLiteralNodeIntegerLiteralNode5540b57cec5SDimitry Andric   IntegerLiteralNode(uint64_t Value, bool IsNegative)
5550b57cec5SDimitry Andric       : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
5560b57cec5SDimitry Andric 
557349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   uint64_t Value = 0;
5600b57cec5SDimitry Andric   bool IsNegative = false;
5610b57cec5SDimitry Andric };
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric struct RttiBaseClassDescriptorNode : public IdentifierNode {
RttiBaseClassDescriptorNodeRttiBaseClassDescriptorNode5640b57cec5SDimitry Andric   RttiBaseClassDescriptorNode()
5650b57cec5SDimitry Andric       : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
5660b57cec5SDimitry Andric 
567349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   uint32_t NVOffset = 0;
5700b57cec5SDimitry Andric   int32_t VBPtrOffset = 0;
5710b57cec5SDimitry Andric   uint32_t VBTableOffset = 0;
5720b57cec5SDimitry Andric   uint32_t Flags = 0;
5730b57cec5SDimitry Andric };
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric struct SymbolNode : public Node {
SymbolNodeSymbolNode5760b57cec5SDimitry Andric   explicit SymbolNode(NodeKind K) : Node(K) {}
577349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5780b57cec5SDimitry Andric   QualifiedNameNode *Name = nullptr;
5790b57cec5SDimitry Andric };
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric struct SpecialTableSymbolNode : public SymbolNode {
SpecialTableSymbolNodeSpecialTableSymbolNode5820b57cec5SDimitry Andric   explicit SpecialTableSymbolNode()
5830b57cec5SDimitry Andric       : SymbolNode(NodeKind::SpecialTableSymbol) {}
5840b57cec5SDimitry Andric 
585349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5860b57cec5SDimitry Andric   QualifiedNameNode *TargetName = nullptr;
587480093f4SDimitry Andric   Qualifiers Quals = Qualifiers::Q_None;
5880b57cec5SDimitry Andric };
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric struct LocalStaticGuardVariableNode : public SymbolNode {
LocalStaticGuardVariableNodeLocalStaticGuardVariableNode5910b57cec5SDimitry Andric   LocalStaticGuardVariableNode()
5920b57cec5SDimitry Andric       : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
5930b57cec5SDimitry Andric 
594349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric   bool IsVisible = false;
5970b57cec5SDimitry Andric };
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric struct EncodedStringLiteralNode : public SymbolNode {
EncodedStringLiteralNodeEncodedStringLiteralNode6000b57cec5SDimitry Andric   EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
6010b57cec5SDimitry Andric 
602349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6030b57cec5SDimitry Andric 
60406c3fb27SDimitry Andric   std::string_view DecodedString;
6050b57cec5SDimitry Andric   bool IsTruncated = false;
6060b57cec5SDimitry Andric   CharKind Char = CharKind::Char;
6070b57cec5SDimitry Andric };
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric struct VariableSymbolNode : public SymbolNode {
VariableSymbolNodeVariableSymbolNode6100b57cec5SDimitry Andric   VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
6110b57cec5SDimitry Andric 
612349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric   StorageClass SC = StorageClass::None;
6150b57cec5SDimitry Andric   TypeNode *Type = nullptr;
6160b57cec5SDimitry Andric };
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric struct FunctionSymbolNode : public SymbolNode {
FunctionSymbolNodeFunctionSymbolNode6190b57cec5SDimitry Andric   FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
6200b57cec5SDimitry Andric 
621349cc55cSDimitry Andric   void output(OutputBuffer &OB, OutputFlags Flags) const override;
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   FunctionSignatureNode *Signature = nullptr;
6240b57cec5SDimitry Andric };
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric } // namespace ms_demangle
6270b57cec5SDimitry Andric } // namespace llvm
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric #endif
630