1 //===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the AST nodes used in the MSVC demangler.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
14 #define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
16 #include "llvm/Demangle/DemangleConfig.h"
17 #include "llvm/Demangle/StringView.h"
23 namespace itanium_demangle
{
28 using llvm::itanium_demangle::OutputStream
;
29 using llvm::itanium_demangle::StringView
;
32 namespace ms_demangle
{
35 enum Qualifiers
: uint8_t {
46 enum class StorageClass
: uint8_t {
55 enum class PointerAffinity
{ None
, Pointer
, Reference
, RValueReference
};
56 enum class FunctionRefQualifier
{ None
, Reference
, RValueReference
};
58 // Calling conventions
59 enum class CallingConv
: uint8_t {
72 enum class ReferenceKind
: uint8_t { None
, LValueRef
, RValueRef
};
76 OF_NoCallingConvention
= 1,
77 OF_NoTagSpecifier
= 2,
78 OF_NoAccessSpecifier
= 4,
84 enum class PrimitiveKind
{
108 enum class CharKind
{
115 enum class IntrinsicFunctionKind
: uint8_t {
117 New
, // ?2 # operator new
118 Delete
, // ?3 # operator delete
119 Assign
, // ?4 # operator=
120 RightShift
, // ?5 # operator>>
121 LeftShift
, // ?6 # operator<<
122 LogicalNot
, // ?7 # operator!
123 Equals
, // ?8 # operator==
124 NotEquals
, // ?9 # operator!=
125 ArraySubscript
, // ?A # operator[]
126 Pointer
, // ?C # operator->
127 Dereference
, // ?D # operator*
128 Increment
, // ?E # operator++
129 Decrement
, // ?F # operator--
130 Minus
, // ?G # operator-
131 Plus
, // ?H # operator+
132 BitwiseAnd
, // ?I # operator&
133 MemberPointer
, // ?J # operator->*
134 Divide
, // ?K # operator/
135 Modulus
, // ?L # operator%
136 LessThan
, // ?M operator<
137 LessThanEqual
, // ?N operator<=
138 GreaterThan
, // ?O operator>
139 GreaterThanEqual
, // ?P operator>=
140 Comma
, // ?Q operator,
141 Parens
, // ?R operator()
142 BitwiseNot
, // ?S operator~
143 BitwiseXor
, // ?T operator^
144 BitwiseOr
, // ?U operator|
145 LogicalAnd
, // ?V operator&&
146 LogicalOr
, // ?W operator||
147 TimesEqual
, // ?X operator*=
148 PlusEqual
, // ?Y operator+=
149 MinusEqual
, // ?Z operator-=
150 DivEqual
, // ?_0 operator/=
151 ModEqual
, // ?_1 operator%=
152 RshEqual
, // ?_2 operator>>=
153 LshEqual
, // ?_3 operator<<=
154 BitwiseAndEqual
, // ?_4 operator&=
155 BitwiseOrEqual
, // ?_5 operator|=
156 BitwiseXorEqual
, // ?_6 operator^=
157 VbaseDtor
, // ?_D # vbase destructor
158 VecDelDtor
, // ?_E # vector deleting destructor
159 DefaultCtorClosure
, // ?_F # default constructor closure
160 ScalarDelDtor
, // ?_G # scalar deleting destructor
161 VecCtorIter
, // ?_H # vector constructor iterator
162 VecDtorIter
, // ?_I # vector destructor iterator
163 VecVbaseCtorIter
, // ?_J # vector vbase constructor iterator
164 VdispMap
, // ?_K # virtual displacement map
165 EHVecCtorIter
, // ?_L # eh vector constructor iterator
166 EHVecDtorIter
, // ?_M # eh vector destructor iterator
167 EHVecVbaseCtorIter
, // ?_N # eh vector vbase constructor iterator
168 CopyCtorClosure
, // ?_O # copy constructor closure
169 LocalVftableCtorClosure
, // ?_T # local vftable constructor closure
170 ArrayNew
, // ?_U operator new[]
171 ArrayDelete
, // ?_V operator delete[]
172 ManVectorCtorIter
, // ?__A managed vector ctor iterator
173 ManVectorDtorIter
, // ?__B managed vector dtor iterator
174 EHVectorCopyCtorIter
, // ?__C EH vector copy ctor iterator
175 EHVectorVbaseCopyCtorIter
, // ?__D EH vector vbase copy ctor iterator
176 VectorCopyCtorIter
, // ?__G vector copy constructor iterator
177 VectorVbaseCopyCtorIter
, // ?__H vector vbase copy constructor iterator
178 ManVectorVbaseCopyCtorIter
, // ?__I managed vector vbase copy constructor
179 CoAwait
, // ?__L operator co_await
180 Spaceship
, // ?__M operator<=>
184 enum class SpecialIntrinsicKind
{
195 DynamicAtexitDestructor
,
197 RttiBaseClassDescriptor
,
199 RttiClassHierarchyDescriptor
,
200 RttiCompleteObjLocator
,
202 LocalStaticThreadGuard
,
206 enum FuncClass
: uint16_t {
209 FC_Protected
= 1 << 1,
216 FC_NoParameterList
= 1 << 8,
217 FC_VirtualThisAdjust
= 1 << 9,
218 FC_VirtualThisAdjustEx
= 1 << 10,
219 FC_StaticThisAdjust
= 1 << 11,
222 enum class TagKind
{ Class
, Struct
, Union
, Enum
};
224 enum class NodeKind
{
231 VcallThunkIdentifier
,
232 LocalStaticGuardIdentifier
,
233 IntrinsicFunctionIdentifier
,
234 ConversionOperatorIdentifier
,
235 DynamicStructorIdentifier
,
237 LiteralOperatorIdentifier
,
246 TemplateParameterReference
,
247 EncodedStringLiteral
,
249 RttiBaseClassDescriptor
,
250 LocalStaticGuardVariable
,
257 explicit Node(NodeKind K
) : Kind(K
) {}
258 virtual ~Node() = default;
260 NodeKind
kind() const { return Kind
; }
262 virtual void output(OutputStream
&OS
, OutputFlags Flags
) const = 0;
264 std::string
toString(OutputFlags Flags
= OF_Default
) const;
271 struct PrimitiveTypeNode
;
272 struct FunctionSignatureNode
;
273 struct IdentifierNode
;
274 struct NamedIdentifierNode
;
275 struct VcallThunkIdentifierNode
;
276 struct IntrinsicFunctionIdentifierNode
;
277 struct LiteralOperatorIdentifierNode
;
278 struct ConversionOperatorIdentifierNode
;
279 struct StructorIdentifierNode
;
280 struct ThunkSignatureNode
;
281 struct PointerTypeNode
;
282 struct ArrayTypeNode
;
285 struct IntrinsicTypeNode
;
286 struct NodeArrayNode
;
287 struct QualifiedNameNode
;
288 struct TemplateParameterReferenceNode
;
289 struct EncodedStringLiteralNode
;
290 struct IntegerLiteralNode
;
291 struct RttiBaseClassDescriptorNode
;
292 struct LocalStaticGuardVariableNode
;
294 struct FunctionSymbolNode
;
295 struct VariableSymbolNode
;
296 struct SpecialTableSymbolNode
;
298 struct TypeNode
: public Node
{
299 explicit TypeNode(NodeKind K
) : Node(K
) {}
301 virtual void outputPre(OutputStream
&OS
, OutputFlags Flags
) const = 0;
302 virtual void outputPost(OutputStream
&OS
, OutputFlags Flags
) const = 0;
304 void output(OutputStream
&OS
, OutputFlags Flags
) const override
{
305 outputPre(OS
, Flags
);
306 outputPost(OS
, Flags
);
309 Qualifiers Quals
= Q_None
;
312 struct PrimitiveTypeNode
: public TypeNode
{
313 explicit PrimitiveTypeNode(PrimitiveKind K
)
314 : TypeNode(NodeKind::PrimitiveType
), PrimKind(K
) {}
316 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
317 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const {}
319 PrimitiveKind PrimKind
;
322 struct FunctionSignatureNode
: public TypeNode
{
323 explicit FunctionSignatureNode(NodeKind K
) : TypeNode(K
) {}
324 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature
) {}
326 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
327 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
329 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
330 // MemberPointerType.
331 PointerAffinity Affinity
= PointerAffinity::None
;
333 // The function's calling convention.
334 CallingConv CallConvention
= CallingConv::None
;
336 // Function flags (gloabl, public, etc)
337 FuncClass FunctionClass
= FC_Global
;
339 FunctionRefQualifier RefQualifier
= FunctionRefQualifier::None
;
341 // The return type of the function.
342 TypeNode
*ReturnType
= nullptr;
344 // True if this is a C-style ... varargs function.
345 bool IsVariadic
= false;
347 // Function parameters
348 NodeArrayNode
*Params
= nullptr;
350 // True if the function type is noexcept.
351 bool IsNoexcept
= false;
354 struct IdentifierNode
: public Node
{
355 explicit IdentifierNode(NodeKind K
) : Node(K
) {}
357 NodeArrayNode
*TemplateParams
= nullptr;
360 void outputTemplateParameters(OutputStream
&OS
, OutputFlags Flags
) const;
363 struct VcallThunkIdentifierNode
: public IdentifierNode
{
364 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier
) {}
366 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
368 uint64_t OffsetInVTable
= 0;
371 struct DynamicStructorIdentifierNode
: public IdentifierNode
{
372 DynamicStructorIdentifierNode()
373 : IdentifierNode(NodeKind::DynamicStructorIdentifier
) {}
375 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
377 VariableSymbolNode
*Variable
= nullptr;
378 QualifiedNameNode
*Name
= nullptr;
379 bool IsDestructor
= false;
382 struct NamedIdentifierNode
: public IdentifierNode
{
383 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier
) {}
385 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
390 struct IntrinsicFunctionIdentifierNode
: public IdentifierNode
{
391 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator
)
392 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier
),
393 Operator(Operator
) {}
395 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
397 IntrinsicFunctionKind Operator
;
400 struct LiteralOperatorIdentifierNode
: public IdentifierNode
{
401 LiteralOperatorIdentifierNode()
402 : IdentifierNode(NodeKind::LiteralOperatorIdentifier
) {}
404 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
409 struct LocalStaticGuardIdentifierNode
: public IdentifierNode
{
410 LocalStaticGuardIdentifierNode()
411 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier
) {}
413 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
415 bool IsThread
= false;
416 uint32_t ScopeIndex
= 0;
419 struct ConversionOperatorIdentifierNode
: public IdentifierNode
{
420 ConversionOperatorIdentifierNode()
421 : IdentifierNode(NodeKind::ConversionOperatorIdentifier
) {}
423 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
425 // The type that this operator converts too.
426 TypeNode
*TargetType
= nullptr;
429 struct StructorIdentifierNode
: public IdentifierNode
{
430 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier
) {}
431 explicit StructorIdentifierNode(bool IsDestructor
)
432 : IdentifierNode(NodeKind::StructorIdentifier
),
433 IsDestructor(IsDestructor
) {}
435 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
437 // The name of the class that this is a structor of.
438 IdentifierNode
*Class
= nullptr;
439 bool IsDestructor
= false;
442 struct ThunkSignatureNode
: public FunctionSignatureNode
{
443 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature
) {}
445 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
446 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
448 struct ThisAdjustor
{
449 uint32_t StaticOffset
= 0;
450 int32_t VBPtrOffset
= 0;
451 int32_t VBOffsetOffset
= 0;
452 int32_t VtordispOffset
= 0;
455 ThisAdjustor ThisAdjust
;
458 struct PointerTypeNode
: public TypeNode
{
459 PointerTypeNode() : TypeNode(NodeKind::PointerType
) {}
460 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
461 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
463 // Is this a pointer, reference, or rvalue-reference?
464 PointerAffinity Affinity
= PointerAffinity::None
;
466 // If this is a member pointer, this is the class that the member is in.
467 QualifiedNameNode
*ClassParent
= nullptr;
469 // Represents a type X in "a pointer to X", "a reference to X", or
470 // "rvalue-reference to X"
471 TypeNode
*Pointee
= nullptr;
474 struct TagTypeNode
: public TypeNode
{
475 explicit TagTypeNode(TagKind Tag
) : TypeNode(NodeKind::TagType
), Tag(Tag
) {}
477 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
478 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
480 QualifiedNameNode
*QualifiedName
= nullptr;
484 struct ArrayTypeNode
: public TypeNode
{
485 ArrayTypeNode() : TypeNode(NodeKind::ArrayType
) {}
487 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
488 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
490 void outputDimensionsImpl(OutputStream
&OS
, OutputFlags Flags
) const;
491 void outputOneDimension(OutputStream
&OS
, OutputFlags Flags
, Node
*N
) const;
493 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
494 NodeArrayNode
*Dimensions
= nullptr;
496 // The type of array element.
497 TypeNode
*ElementType
= nullptr;
500 struct IntrinsicNode
: public TypeNode
{
501 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType
) {}
502 void output(OutputStream
&OS
, OutputFlags Flags
) const override
{}
505 struct CustomTypeNode
: public TypeNode
{
506 CustomTypeNode() : TypeNode(NodeKind::Custom
) {}
508 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
509 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
511 IdentifierNode
*Identifier
;
514 struct NodeArrayNode
: public Node
{
515 NodeArrayNode() : Node(NodeKind::NodeArray
) {}
517 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
519 void output(OutputStream
&OS
, OutputFlags Flags
, StringView Separator
) const;
521 Node
**Nodes
= nullptr;
525 struct QualifiedNameNode
: public Node
{
526 QualifiedNameNode() : Node(NodeKind::QualifiedName
) {}
528 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
530 NodeArrayNode
*Components
= nullptr;
532 IdentifierNode
*getUnqualifiedIdentifier() {
533 Node
*LastComponent
= Components
->Nodes
[Components
->Count
- 1];
534 return static_cast<IdentifierNode
*>(LastComponent
);
538 struct TemplateParameterReferenceNode
: public Node
{
539 TemplateParameterReferenceNode()
540 : Node(NodeKind::TemplateParameterReference
) {}
542 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
544 SymbolNode
*Symbol
= nullptr;
546 int ThunkOffsetCount
= 0;
547 std::array
<int64_t, 3> ThunkOffsets
;
548 PointerAffinity Affinity
= PointerAffinity::None
;
549 bool IsMemberPointer
= false;
552 struct IntegerLiteralNode
: public Node
{
553 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral
) {}
554 IntegerLiteralNode(uint64_t Value
, bool IsNegative
)
555 : Node(NodeKind::IntegerLiteral
), Value(Value
), IsNegative(IsNegative
) {}
557 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
560 bool IsNegative
= false;
563 struct RttiBaseClassDescriptorNode
: public IdentifierNode
{
564 RttiBaseClassDescriptorNode()
565 : IdentifierNode(NodeKind::RttiBaseClassDescriptor
) {}
567 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
569 uint32_t NVOffset
= 0;
570 int32_t VBPtrOffset
= 0;
571 uint32_t VBTableOffset
= 0;
575 struct SymbolNode
: public Node
{
576 explicit SymbolNode(NodeKind K
) : Node(K
) {}
577 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
578 QualifiedNameNode
*Name
= nullptr;
581 struct SpecialTableSymbolNode
: public SymbolNode
{
582 explicit SpecialTableSymbolNode()
583 : SymbolNode(NodeKind::SpecialTableSymbol
) {}
585 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
586 QualifiedNameNode
*TargetName
= nullptr;
590 struct LocalStaticGuardVariableNode
: public SymbolNode
{
591 LocalStaticGuardVariableNode()
592 : SymbolNode(NodeKind::LocalStaticGuardVariable
) {}
594 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
596 bool IsVisible
= false;
599 struct EncodedStringLiteralNode
: public SymbolNode
{
600 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral
) {}
602 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
604 StringView DecodedString
;
605 bool IsTruncated
= false;
606 CharKind Char
= CharKind::Char
;
609 struct VariableSymbolNode
: public SymbolNode
{
610 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol
) {}
612 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
614 StorageClass SC
= StorageClass::None
;
615 TypeNode
*Type
= nullptr;
618 struct FunctionSymbolNode
: public SymbolNode
{
619 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol
) {}
621 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
623 FunctionSignatureNode
*Signature
= nullptr;
626 } // namespace ms_demangle