LiteLoaderBDS-1.16.40/Tools/Demangler/include/MicrosoftDemangleNodes.h
2022-09-21 19:47:03 +08:00

1185 lines
31 KiB
C++

//===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the AST nodes used in the MSVC demangler.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
#define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
#include "StringView.h"
#include <array>
#include <cstdint>
#include <string>
namespace llvm
{
namespace itanium_demangle
{
class OutputBuffer;
}
} // namespace llvm
using llvm::itanium_demangle::OutputBuffer;
using llvm::itanium_demangle::StringView;
namespace llvm
{
namespace ms_demangle
{
// Storage classes
enum Qualifiers : uint8_t
{
Q_None = 0,
Q_Const = 1 << 0,
Q_Volatile = 1 << 1,
Q_Far = 1 << 2,
Q_Huge = 1 << 3,
Q_Unaligned = 1 << 4,
Q_Restrict = 1 << 5,
Q_Pointer64 = 1 << 6
};
class StorageClass
{
public:
enum StorageClassValue : uint8_t
{
None,
PrivateStatic,
ProtectedStatic,
PublicStatic,
Global,
FunctionLocalStatic,
};
StringView* pos = nullptr;
StorageClass() = default;
constexpr StorageClass(StorageClassValue type)
: type(type)
{
}
operator StorageClass() const
{
return type;
}
void set(StorageClassValue type)
{
this->type = type;
}
constexpr bool operator==(StorageClass type) const
{
return this->type == type.type;
}
constexpr bool operator!=(StorageClass type) const
{
return this->type != type.type;
}
constexpr bool operator==(StorageClassValue type) const
{
return this->type == type;
}
constexpr bool operator!=(StorageClassValue type) const
{
return this->type != type;
}
inline std::string toEnumString()
{
std::string ret;
ret += std::to_string((int)this->type);
if (this->type == None)
ret += "\t| None";
if (this->type == PrivateStatic)
ret += "\t| PrivateStatic";
if (this->type == ProtectedStatic)
ret += "\t| ProtectedStatic";
if (this->type == PublicStatic)
ret += "\t| PublicStatic";
if (this->type == Global)
ret += "\t| StaGlobaltic";
if (this->type == FunctionLocalStatic)
ret += "\t| FunctionLocalStatic";
return ret;
}
inline void fromMangledName(StringView& MangledName)
{
switch (MangledName.popFront())
{
case '0':
this->type = PrivateStatic;
case '1':
this->type = ProtectedStatic;
case '2':
this->type = PublicStatic;
case '3':
this->type = Global;
case '4':
this->type = FunctionLocalStatic;
}
DEMANGLE_UNREACHABLE;
}
inline char toChar() const
{
switch (this->type)
{
case PrivateStatic:
return '0';
case ProtectedStatic:
return '1';
case PublicStatic:
return '2';
case Global:
return '3';
case FunctionLocalStatic:
return '4';
}
DEMANGLE_UNREACHABLE;
}
private:
StorageClassValue type;
};
enum class PointerAffinity
{
None,
Pointer,
Reference,
RValueReference
};
enum class FunctionRefQualifier
{
None,
Reference,
RValueReference
};
// Calling conventions
enum class CallingConv : uint8_t
{
None,
Cdecl,
Pascal,
Thiscall,
Stdcall,
Fastcall,
Clrcall,
Eabi,
Vectorcall,
Regcall,
Swift, // Clang-only
SwiftAsync, // Clang-only
};
enum class ReferenceKind : uint8_t
{
None,
LValueRef,
RValueRef
};
enum OutputFlags
{
OF_Default = 0,
OF_NoCallingConvention = 1,
OF_NoTagSpecifier = 2,
OF_NoAccessSpecifier = 4,
OF_NoMemberType = 8,
OF_NoReturnType = 16,
OF_NoVariableType = 32,
};
// Types
enum class PrimitiveKind
{
Void,
Bool,
Char,
Schar,
Uchar,
Char8,
Char16,
Char32,
Short,
Ushort,
Int,
Uint,
Long,
Ulong,
Int64,
Uint64,
Wchar,
Float,
Double,
Ldouble,
Nullptr,
};
enum class CharKind
{
Char,
Char16,
Char32,
Wchar,
};
enum class IntrinsicFunctionKind : uint8_t
{
None,
New, // ?2 # operator new
Delete, // ?3 # operator delete
Assign, // ?4 # operator=
RightShift, // ?5 # operator>>
LeftShift, // ?6 # operator<<
LogicalNot, // ?7 # operator!
Equals, // ?8 # operator==
NotEquals, // ?9 # operator!=
ArraySubscript, // ?A # operator[]
Pointer, // ?C # operator->
Dereference, // ?D # operator*
Increment, // ?E # operator++
Decrement, // ?F # operator--
Minus, // ?G # operator-
Plus, // ?H # operator+
BitwiseAnd, // ?I # operator&
MemberPointer, // ?J # operator->*
Divide, // ?K # operator/
Modulus, // ?L # operator%
LessThan, // ?M operator<
LessThanEqual, // ?N operator<=
GreaterThan, // ?O operator>
GreaterThanEqual, // ?P operator>=
Comma, // ?Q operator,
Parens, // ?R operator()
BitwiseNot, // ?S operator~
BitwiseXor, // ?T operator^
BitwiseOr, // ?U operator|
LogicalAnd, // ?V operator&&
LogicalOr, // ?W operator||
TimesEqual, // ?X operator*=
PlusEqual, // ?Y operator+=
MinusEqual, // ?Z operator-=
DivEqual, // ?_0 operator/=
ModEqual, // ?_1 operator%=
RshEqual, // ?_2 operator>>=
LshEqual, // ?_3 operator<<=
BitwiseAndEqual, // ?_4 operator&=
BitwiseOrEqual, // ?_5 operator|=
BitwiseXorEqual, // ?_6 operator^=
VbaseDtor, // ?_D # vbase destructor
VecDelDtor, // ?_E # vector deleting destructor
DefaultCtorClosure, // ?_F # default constructor closure
ScalarDelDtor, // ?_G # scalar deleting destructor
VecCtorIter, // ?_H # vector constructor iterator
VecDtorIter, // ?_I # vector destructor iterator
VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
VdispMap, // ?_K # virtual displacement map
EHVecCtorIter, // ?_L # eh vector constructor iterator
EHVecDtorIter, // ?_M # eh vector destructor iterator
EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
CopyCtorClosure, // ?_O # copy constructor closure
LocalVftableCtorClosure, // ?_T # local vftable constructor closure
ArrayNew, // ?_U operator new[]
ArrayDelete, // ?_V operator delete[]
ManVectorCtorIter, // ?__A managed vector ctor iterator
ManVectorDtorIter, // ?__B managed vector dtor iterator
EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
VectorCopyCtorIter, // ?__G vector copy constructor iterator
VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
CoAwait, // ?__L operator co_await
Spaceship, // ?__M operator<=>
MaxIntrinsic
};
enum class SpecialIntrinsicKind
{
None,
Vftable,
Vbtable,
Typeof,
VcallThunk,
LocalStaticGuard,
StringLiteralSymbol,
UdtReturning,
Unknown,
DynamicInitializer,
DynamicAtexitDestructor,
RttiTypeDescriptor,
RttiBaseClassDescriptor,
RttiBaseClassArray,
RttiClassHierarchyDescriptor,
RttiCompleteObjLocator,
LocalVftable,
LocalStaticThreadGuard,
};
// Function classes
enum FuncClass : uint16_t
{
FC_None = 0,
FC_Public = 1 << 0,
FC_Protected = 1 << 1,
FC_Private = 1 << 2,
FC_Global = 1 << 3,
FC_Static = 1 << 4,
FC_Virtual = 1 << 5,
FC_Far = 1 << 6,
FC_ExternC = 1 << 7,
FC_NoParameterList = 1 << 8,
FC_VirtualThisAdjust = 1 << 9,
FC_VirtualThisAdjustEx = 1 << 10,
FC_StaticThisAdjust = 1 << 11,
};
class FuncClassType
{
public:
StringView* pos = nullptr;
FuncClassType() = default;
constexpr FuncClassType(FuncClass type)
: type(type)
{
}
operator FuncClass() const
{
return type;
}
void set(FuncClassType type)
{
this->type = type;
}
constexpr bool operator==(FuncClassType type) const
{
return this->type == type.type;
}
constexpr bool operator!=(FuncClassType type) const
{
return this->type != type.type;
}
constexpr bool operator==(FuncClass type) const
{
return this->type == type;
}
constexpr bool operator!=(FuncClass type) const
{
return this->type != type;
}
inline bool has(FuncClass type) const
{
return (this->type & type) == type;
}
inline void remove(FuncClass type)
{
this->type = static_cast<FuncClass>(this->type & ~type);
}
inline void add(FuncClass type)
{
this->type = static_cast<FuncClass>(this->type | type);
}
inline std::string toEnumString()
{
std::string ret;
ret += std::to_string((int)this->type);
if (this->type & FC_Public)
ret += "\t| Public";
if (this->type & FC_Protected)
ret += "\t| Protected";
if (this->type & FC_Private)
ret += "\t| Private";
if (this->type & FC_Global)
ret += "\t| Global";
if (this->type & FC_Static)
ret += "\t| Static";
if (this->type & FC_Virtual)
ret += "\t| Virtual";
if (this->type & FC_ExternC)
ret += "\t| ExternC";
if (this->type & FC_NoParameterList)
ret += "\t| NoParameterList";
if (this->type & FC_VirtualThisAdjust)
ret += "\t| VirtualThisAdjust";
if (this->type & FC_VirtualThisAdjustEx)
ret += "\t| VirtualThisAdjustEx";
if (this->type & FC_StaticThisAdjust)
ret += "\t| StaticThisAdjust";
if (this->type & FC_Far)
ret += "\t| Far";
return ret;
}
inline void fromMangledName(StringView& MangledName)
{
switch (MangledName.popFront())
{
case '9':
this->set(FuncClass(FC_ExternC | FC_NoParameterList));
return;
case 'A':
this->set(FC_Private);
return;
case 'B':
this->set(FuncClass(FC_Private | FC_Far));
return;
case 'C':
this->set(FuncClass(FC_Private | FC_Static));
return;
case 'D':
this->set(FuncClass(FC_Private | FC_Static | FC_Far));
return;
case 'E':
this->set(FuncClass(FC_Private | FC_Virtual));
return;
case 'F':
this->set(FuncClass(FC_Private | FC_Virtual | FC_Far));
return;
case 'G':
this->set(FuncClass(FC_Private | FC_StaticThisAdjust));
return;
case 'H':
this->set(FuncClass(FC_Private | FC_StaticThisAdjust | FC_Far));
return;
case 'I':
this->set(FuncClass(FC_Protected));
return;
case 'J':
this->set(FuncClass(FC_Protected | FC_Far));
return;
case 'K':
this->set(FuncClass(FC_Protected | FC_Static));
return;
case 'L':
this->set(FuncClass(FC_Protected | FC_Static | FC_Far));
return;
case 'M':
this->set(FuncClass(FC_Protected | FC_Virtual));
return;
case 'N':
this->set(FuncClass(FC_Protected | FC_Virtual | FC_Far));
return;
case 'O':
this->set(FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust));
return;
case 'P':
this->set(FuncClass(FC_Protected | FC_Virtual | FC_StaticThisAdjust | FC_Far));
return;
case 'Q':
this->set(FuncClass(FC_Public));
return;
case 'R':
this->set(FuncClass(FC_Public | FC_Far));
return;
case 'S':
this->set(FuncClass(FC_Public | FC_Static));
return;
case 'T':
this->set(FuncClass(FC_Public | FC_Static | FC_Far));
return;
case 'U':
this->set(FuncClass(FC_Public | FC_Virtual));
return;
case 'V':
this->set(FuncClass(FC_Public | FC_Virtual | FC_Far));
return;
case 'W':
this->set(FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust));
return;
case 'X':
this->set(FuncClass(FC_Public | FC_Virtual | FC_StaticThisAdjust | FC_Far));
return;
case 'Y':
this->set(FuncClass(FC_Global));
return;
case 'Z':
this->set(FuncClass(FC_Global | FC_Far));
return;
case '$':
{
FuncClass VFlag = FC_VirtualThisAdjust;
if (MangledName.consumeFront('R'))
VFlag = FuncClass(VFlag | FC_VirtualThisAdjustEx);
if (MangledName.empty())
break;
switch (MangledName.popFront())
{
case '0':
this->set(FuncClass(FC_Private | FC_Virtual | VFlag));
return;
case '1':
this->set(FuncClass(FC_Private | FC_Virtual | VFlag | FC_Far));
return;
case '2':
this->set(FuncClass(FC_Protected | FC_Virtual | VFlag));
return;
case '3':
this->set(FuncClass(FC_Protected | FC_Virtual | VFlag | FC_Far));
return;
case '4':
this->set(FuncClass(FC_Public | FC_Virtual | VFlag));
return;
case '5':
this->set(FuncClass(FC_Public | FC_Virtual | VFlag | FC_Far));
return;
}
}
}
}
inline std::string toString() const
{
switch (this->type)
{
case FC_ExternC | FC_NoParameterList:
return "9";
case FC_Private:
return "A";
case FC_Private | FC_Far:
return "B";
case FC_Private | FC_Static:
return "C";
case FC_Private | FC_Static | FC_Far:
return "D";
case FC_Private | FC_Virtual:
return "E";
case FC_Private | FC_Virtual | FC_Far:
return "F";
case FC_Private | FC_StaticThisAdjust:
return "G";
case FC_Private | FC_StaticThisAdjust | FC_Far:
return "H";
case FC_Protected:
return "I";
case FC_Protected | FC_Far:
return "J";
case FC_Protected | FC_Static:
return "K";
case FC_Protected | FC_Static | FC_Far:
return "L";
case FC_Protected | FC_Virtual:
return "M";
case FC_Protected | FC_Virtual | FC_Far:
return "N";
case FC_Protected | FC_Virtual | FC_StaticThisAdjust:
return "O";
case FC_Protected | FC_Virtual | FC_StaticThisAdjust | FC_Far:
return "P";
case FC_Public:
return "Q";
case FC_Public | FC_Far:
return "R";
case FC_Public | FC_Static:
return "S";
case FC_Public | FC_Static | FC_Far:
return "T";
case FC_Public | FC_Virtual:
return "U";
case FC_Public | FC_Virtual | FC_Far:
return "V";
case FC_Public | FC_Virtual | FC_StaticThisAdjust:
return "W";
case FC_Public | FC_Virtual | FC_StaticThisAdjust | FC_Far:
return "X";
case FC_Global:
return "Y";
case FC_Global | FC_Far:
return "Z";
default:
if (this->type & FC_VirtualThisAdjust)
{
std::string result;
result += '$';
if (this->type & FC_VirtualThisAdjustEx)
result += 'R';
switch (this->type & ~(FC_VirtualThisAdjust | FC_VirtualThisAdjustEx))
{
case FC_Private | FC_Virtual:
result += '0';
break;
case FC_Private | FC_Virtual | FC_Far:
result += '1';
break;
case FC_Protected | FC_Virtual:
result += '2';
break;
case FC_Protected | FC_Virtual | FC_Far:
result += '3';
break;
case FC_Public | FC_Virtual:
result += '4';
break;
case FC_Public | FC_Virtual | FC_Far:
result += '5';
break;
}
return result;
}
}
return "";
}
private:
FuncClass type;
};
enum class TagKind
{
Class,
Struct,
Union,
Enum
};
enum class NodeKind
{
Unknown,
Md5Symbol,
PrimitiveType,
FunctionSignature,
Identifier,
NamedIdentifier,
VcallThunkIdentifier,
LocalStaticGuardIdentifier,
IntrinsicFunctionIdentifier,
ConversionOperatorIdentifier,
DynamicStructorIdentifier,
StructorIdentifier,
LiteralOperatorIdentifier,
ThunkSignature,
PointerType,
TagType,
ArrayType,
Custom,
IntrinsicType,
NodeArray,
QualifiedName,
TemplateParameterReference,
EncodedStringLiteral,
IntegerLiteral,
RttiBaseClassDescriptor,
LocalStaticGuardVariable,
FunctionSymbol,
VariableSymbol,
SpecialTableSymbol
};
struct Node
{
explicit Node(NodeKind K)
: Kind(K)
{
}
virtual ~Node() = default;
NodeKind kind() const
{
return Kind;
}
virtual void output(OutputBuffer& OB, OutputFlags Flags) const = 0;
std::string toString(OutputFlags Flags = OF_Default) const;
private:
NodeKind Kind;
};
struct TypeNode;
struct PrimitiveTypeNode;
struct FunctionSignatureNode;
struct IdentifierNode;
struct NamedIdentifierNode;
struct VcallThunkIdentifierNode;
struct IntrinsicFunctionIdentifierNode;
struct LiteralOperatorIdentifierNode;
struct ConversionOperatorIdentifierNode;
struct StructorIdentifierNode;
struct ThunkSignatureNode;
struct PointerTypeNode;
struct ArrayTypeNode;
struct TagTypeNode;
struct NodeArrayNode;
struct QualifiedNameNode;
struct TemplateParameterReferenceNode;
struct EncodedStringLiteralNode;
struct IntegerLiteralNode;
struct RttiBaseClassDescriptorNode;
struct LocalStaticGuardVariableNode;
struct SymbolNode;
struct FunctionSymbolNode;
struct VariableSymbolNode;
struct SpecialTableSymbolNode;
struct TypeNode : public Node
{
explicit TypeNode(NodeKind K)
: Node(K)
{
}
virtual void outputPre(OutputBuffer& OB, OutputFlags Flags) const = 0;
virtual void outputPost(OutputBuffer& OB, OutputFlags Flags) const = 0;
void output(OutputBuffer& OB, OutputFlags Flags) const override
{
outputPre(OB, Flags);
outputPost(OB, Flags);
}
Qualifiers Quals = Q_None;
};
struct PrimitiveTypeNode : public TypeNode
{
explicit PrimitiveTypeNode(PrimitiveKind K)
: TypeNode(NodeKind::PrimitiveType)
, PrimKind(K)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override
{
}
PrimitiveKind PrimKind;
};
struct FunctionSignatureNode : public TypeNode
{
explicit FunctionSignatureNode(NodeKind K)
: TypeNode(K)
{
}
FunctionSignatureNode()
: TypeNode(NodeKind::FunctionSignature)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
// Valid if this FunctionTypeNode is the Pointee of a PointerType or
// MemberPointerType.
PointerAffinity Affinity = PointerAffinity::None;
// The function's calling convention.
CallingConv CallConvention = CallingConv::None;
// Function flags (gloabl, public, etc)
FuncClassType FunctionClass = FC_Global;
FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
// The return type of the function.
TypeNode* ReturnType = nullptr;
// True if this is a C-style ... varargs function.
bool IsVariadic = false;
// Function parameters
NodeArrayNode* Params = nullptr;
// True if the function type is noexcept.
bool IsNoexcept = false;
};
struct IdentifierNode : public Node
{
explicit IdentifierNode(NodeKind K)
: Node(K)
{
}
NodeArrayNode* TemplateParams = nullptr;
protected:
void outputTemplateParameters(OutputBuffer& OB, OutputFlags Flags) const;
};
struct VcallThunkIdentifierNode : public IdentifierNode
{
VcallThunkIdentifierNode()
: IdentifierNode(NodeKind::VcallThunkIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
uint64_t OffsetInVTable = 0;
};
struct DynamicStructorIdentifierNode : public IdentifierNode
{
DynamicStructorIdentifierNode()
: IdentifierNode(NodeKind::DynamicStructorIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
VariableSymbolNode* Variable = nullptr;
QualifiedNameNode* Name = nullptr;
bool IsDestructor = false;
};
struct NamedIdentifierNode : public IdentifierNode
{
NamedIdentifierNode()
: IdentifierNode(NodeKind::NamedIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
StringView Name;
};
struct IntrinsicFunctionIdentifierNode : public IdentifierNode
{
explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
: IdentifierNode(NodeKind::IntrinsicFunctionIdentifier)
, Operator(Operator)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
IntrinsicFunctionKind Operator;
};
struct LiteralOperatorIdentifierNode : public IdentifierNode
{
LiteralOperatorIdentifierNode()
: IdentifierNode(NodeKind::LiteralOperatorIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
StringView Name;
};
struct LocalStaticGuardIdentifierNode : public IdentifierNode
{
LocalStaticGuardIdentifierNode()
: IdentifierNode(NodeKind::LocalStaticGuardIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
bool IsThread = false;
uint32_t ScopeIndex = 0;
};
struct ConversionOperatorIdentifierNode : public IdentifierNode
{
ConversionOperatorIdentifierNode()
: IdentifierNode(NodeKind::ConversionOperatorIdentifier)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
// The type that this operator converts too.
TypeNode* TargetType = nullptr;
};
struct StructorIdentifierNode : public IdentifierNode
{
StructorIdentifierNode()
: IdentifierNode(NodeKind::StructorIdentifier)
{
}
explicit StructorIdentifierNode(bool IsDestructor)
: IdentifierNode(NodeKind::StructorIdentifier)
, IsDestructor(IsDestructor)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
// The name of the class that this is a structor of.
IdentifierNode* Class = nullptr;
bool IsDestructor = false;
};
struct ThunkSignatureNode : public FunctionSignatureNode
{
ThunkSignatureNode()
: FunctionSignatureNode(NodeKind::ThunkSignature)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
struct ThisAdjustor
{
uint32_t StaticOffset = 0;
int32_t VBPtrOffset = 0;
int32_t VBOffsetOffset = 0;
int32_t VtordispOffset = 0;
};
ThisAdjustor ThisAdjust;
};
struct PointerTypeNode : public TypeNode
{
PointerTypeNode()
: TypeNode(NodeKind::PointerType)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
// Is this a pointer, reference, or rvalue-reference?
PointerAffinity Affinity = PointerAffinity::None;
// If this is a member pointer, this is the class that the member is in.
QualifiedNameNode* ClassParent = nullptr;
// Represents a type X in "a pointer to X", "a reference to X", or
// "rvalue-reference to X"
TypeNode* Pointee = nullptr;
};
struct TagTypeNode : public TypeNode
{
explicit TagTypeNode(TagKind Tag)
: TypeNode(NodeKind::TagType)
, Tag(Tag)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
QualifiedNameNode* QualifiedName = nullptr;
TagKind Tag;
};
struct ArrayTypeNode : public TypeNode
{
ArrayTypeNode()
: TypeNode(NodeKind::ArrayType)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
void outputDimensionsImpl(OutputBuffer& OB, OutputFlags Flags) const;
void outputOneDimension(OutputBuffer& OB, OutputFlags Flags, Node* N) const;
// A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
NodeArrayNode* Dimensions = nullptr;
// The type of array element.
TypeNode* ElementType = nullptr;
};
struct IntrinsicNode : public TypeNode
{
IntrinsicNode()
: TypeNode(NodeKind::IntrinsicType)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override
{
}
};
struct CustomTypeNode : public TypeNode
{
CustomTypeNode()
: TypeNode(NodeKind::Custom)
{
}
void outputPre(OutputBuffer& OB, OutputFlags Flags) const override;
void outputPost(OutputBuffer& OB, OutputFlags Flags) const override;
IdentifierNode* Identifier = nullptr;
};
struct NodeArrayNode : public Node
{
NodeArrayNode()
: Node(NodeKind::NodeArray)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
void output(OutputBuffer& OB, OutputFlags Flags, StringView Separator) const;
Node** Nodes = nullptr;
size_t Count = 0;
};
struct QualifiedNameNode : public Node
{
QualifiedNameNode()
: Node(NodeKind::QualifiedName)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
NodeArrayNode* Components = nullptr;
IdentifierNode* getUnqualifiedIdentifier()
{
Node* LastComponent = Components->Nodes[Components->Count - 1];
return static_cast<IdentifierNode*>(LastComponent);
}
};
struct TemplateParameterReferenceNode : public Node
{
TemplateParameterReferenceNode()
: Node(NodeKind::TemplateParameterReference)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
SymbolNode* Symbol = nullptr;
int ThunkOffsetCount = 0;
std::array<int64_t, 3> ThunkOffsets;
PointerAffinity Affinity = PointerAffinity::None;
bool IsMemberPointer = false;
};
struct IntegerLiteralNode : public Node
{
IntegerLiteralNode()
: Node(NodeKind::IntegerLiteral)
{
}
IntegerLiteralNode(uint64_t Value, bool IsNegative)
: Node(NodeKind::IntegerLiteral)
, Value(Value)
, IsNegative(IsNegative)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
uint64_t Value = 0;
bool IsNegative = false;
};
struct RttiBaseClassDescriptorNode : public IdentifierNode
{
RttiBaseClassDescriptorNode()
: IdentifierNode(NodeKind::RttiBaseClassDescriptor)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
uint32_t NVOffset = 0;
int32_t VBPtrOffset = 0;
uint32_t VBTableOffset = 0;
uint32_t Flags = 0;
};
struct SymbolNode : public Node
{
explicit SymbolNode(NodeKind K)
: Node(K)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
QualifiedNameNode* Name = nullptr;
};
struct SpecialTableSymbolNode : public SymbolNode
{
explicit SpecialTableSymbolNode()
: SymbolNode(NodeKind::SpecialTableSymbol)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
QualifiedNameNode* TargetName = nullptr;
Qualifiers Quals = Qualifiers::Q_None;
};
struct LocalStaticGuardVariableNode : public SymbolNode
{
LocalStaticGuardVariableNode()
: SymbolNode(NodeKind::LocalStaticGuardVariable)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
bool IsVisible = false;
};
struct EncodedStringLiteralNode : public SymbolNode
{
EncodedStringLiteralNode()
: SymbolNode(NodeKind::EncodedStringLiteral)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
StringView DecodedString;
bool IsTruncated = false;
CharKind Char = CharKind::Char;
};
struct VariableSymbolNode : public SymbolNode
{
VariableSymbolNode()
: SymbolNode(NodeKind::VariableSymbol)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
StorageClass SC = StorageClass::None;
TypeNode* Type = nullptr;
};
struct FunctionSymbolNode : public SymbolNode
{
FunctionSymbolNode()
: SymbolNode(NodeKind::FunctionSymbol)
{
}
void output(OutputBuffer& OB, OutputFlags Flags) const override;
FunctionSignatureNode* Signature = nullptr;
};
} // namespace ms_demangle
} // namespace llvm
#endif