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,
81 enum class PrimitiveKind
{
105 enum class CharKind
{
112 enum class IntrinsicFunctionKind
: uint8_t {
114 New
, // ?2 # operator new
115 Delete
, // ?3 # operator delete
116 Assign
, // ?4 # operator=
117 RightShift
, // ?5 # operator>>
118 LeftShift
, // ?6 # operator<<
119 LogicalNot
, // ?7 # operator!
120 Equals
, // ?8 # operator==
121 NotEquals
, // ?9 # operator!=
122 ArraySubscript
, // ?A # operator[]
123 Pointer
, // ?C # operator->
124 Dereference
, // ?D # operator*
125 Increment
, // ?E # operator++
126 Decrement
, // ?F # operator--
127 Minus
, // ?G # operator-
128 Plus
, // ?H # operator+
129 BitwiseAnd
, // ?I # operator&
130 MemberPointer
, // ?J # operator->*
131 Divide
, // ?K # operator/
132 Modulus
, // ?L # operator%
133 LessThan
, // ?M operator<
134 LessThanEqual
, // ?N operator<=
135 GreaterThan
, // ?O operator>
136 GreaterThanEqual
, // ?P operator>=
137 Comma
, // ?Q operator,
138 Parens
, // ?R operator()
139 BitwiseNot
, // ?S operator~
140 BitwiseXor
, // ?T operator^
141 BitwiseOr
, // ?U operator|
142 LogicalAnd
, // ?V operator&&
143 LogicalOr
, // ?W operator||
144 TimesEqual
, // ?X operator*=
145 PlusEqual
, // ?Y operator+=
146 MinusEqual
, // ?Z operator-=
147 DivEqual
, // ?_0 operator/=
148 ModEqual
, // ?_1 operator%=
149 RshEqual
, // ?_2 operator>>=
150 LshEqual
, // ?_3 operator<<=
151 BitwiseAndEqual
, // ?_4 operator&=
152 BitwiseOrEqual
, // ?_5 operator|=
153 BitwiseXorEqual
, // ?_6 operator^=
154 VbaseDtor
, // ?_D # vbase destructor
155 VecDelDtor
, // ?_E # vector deleting destructor
156 DefaultCtorClosure
, // ?_F # default constructor closure
157 ScalarDelDtor
, // ?_G # scalar deleting destructor
158 VecCtorIter
, // ?_H # vector constructor iterator
159 VecDtorIter
, // ?_I # vector destructor iterator
160 VecVbaseCtorIter
, // ?_J # vector vbase constructor iterator
161 VdispMap
, // ?_K # virtual displacement map
162 EHVecCtorIter
, // ?_L # eh vector constructor iterator
163 EHVecDtorIter
, // ?_M # eh vector destructor iterator
164 EHVecVbaseCtorIter
, // ?_N # eh vector vbase constructor iterator
165 CopyCtorClosure
, // ?_O # copy constructor closure
166 LocalVftableCtorClosure
, // ?_T # local vftable constructor closure
167 ArrayNew
, // ?_U operator new[]
168 ArrayDelete
, // ?_V operator delete[]
169 ManVectorCtorIter
, // ?__A managed vector ctor iterator
170 ManVectorDtorIter
, // ?__B managed vector dtor iterator
171 EHVectorCopyCtorIter
, // ?__C EH vector copy ctor iterator
172 EHVectorVbaseCopyCtorIter
, // ?__D EH vector vbase copy ctor iterator
173 VectorCopyCtorIter
, // ?__G vector copy constructor iterator
174 VectorVbaseCopyCtorIter
, // ?__H vector vbase copy constructor iterator
175 ManVectorVbaseCopyCtorIter
, // ?__I managed vector vbase copy constructor
176 CoAwait
, // ?__L operator co_await
177 Spaceship
, // ?__M operator<=>
181 enum class SpecialIntrinsicKind
{
192 DynamicAtexitDestructor
,
194 RttiBaseClassDescriptor
,
196 RttiClassHierarchyDescriptor
,
197 RttiCompleteObjLocator
,
199 LocalStaticThreadGuard
,
203 enum FuncClass
: uint16_t {
206 FC_Protected
= 1 << 1,
213 FC_NoParameterList
= 1 << 8,
214 FC_VirtualThisAdjust
= 1 << 9,
215 FC_VirtualThisAdjustEx
= 1 << 10,
216 FC_StaticThisAdjust
= 1 << 11,
219 enum class TagKind
{ Class
, Struct
, Union
, Enum
};
221 enum class NodeKind
{
228 VcallThunkIdentifier
,
229 LocalStaticGuardIdentifier
,
230 IntrinsicFunctionIdentifier
,
231 ConversionOperatorIdentifier
,
232 DynamicStructorIdentifier
,
234 LiteralOperatorIdentifier
,
243 TemplateParameterReference
,
244 EncodedStringLiteral
,
246 RttiBaseClassDescriptor
,
247 LocalStaticGuardVariable
,
254 explicit Node(NodeKind K
) : Kind(K
) {}
255 virtual ~Node() = default;
257 NodeKind
kind() const { return Kind
; }
259 virtual void output(OutputStream
&OS
, OutputFlags Flags
) const = 0;
261 std::string
toString(OutputFlags Flags
= OF_Default
) const;
268 struct PrimitiveTypeNode
;
269 struct FunctionSignatureNode
;
270 struct IdentifierNode
;
271 struct NamedIdentifierNode
;
272 struct VcallThunkIdentifierNode
;
273 struct IntrinsicFunctionIdentifierNode
;
274 struct LiteralOperatorIdentifierNode
;
275 struct ConversionOperatorIdentifierNode
;
276 struct StructorIdentifierNode
;
277 struct ThunkSignatureNode
;
278 struct PointerTypeNode
;
279 struct ArrayTypeNode
;
282 struct IntrinsicTypeNode
;
283 struct NodeArrayNode
;
284 struct QualifiedNameNode
;
285 struct TemplateParameterReferenceNode
;
286 struct EncodedStringLiteralNode
;
287 struct IntegerLiteralNode
;
288 struct RttiBaseClassDescriptorNode
;
289 struct LocalStaticGuardVariableNode
;
291 struct FunctionSymbolNode
;
292 struct VariableSymbolNode
;
293 struct SpecialTableSymbolNode
;
295 struct TypeNode
: public Node
{
296 explicit TypeNode(NodeKind K
) : Node(K
) {}
298 virtual void outputPre(OutputStream
&OS
, OutputFlags Flags
) const = 0;
299 virtual void outputPost(OutputStream
&OS
, OutputFlags Flags
) const = 0;
301 void output(OutputStream
&OS
, OutputFlags Flags
) const override
{
302 outputPre(OS
, Flags
);
303 outputPost(OS
, Flags
);
306 void outputQuals(bool SpaceBefore
, bool SpaceAfter
) const;
308 Qualifiers Quals
= Q_None
;
311 struct PrimitiveTypeNode
: public TypeNode
{
312 explicit PrimitiveTypeNode(PrimitiveKind K
)
313 : TypeNode(NodeKind::PrimitiveType
), PrimKind(K
) {}
315 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
316 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const {}
318 PrimitiveKind PrimKind
;
321 struct FunctionSignatureNode
: public TypeNode
{
322 explicit FunctionSignatureNode(NodeKind K
) : TypeNode(K
) {}
323 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature
) {}
325 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
326 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
328 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
329 // MemberPointerType.
330 PointerAffinity Affinity
= PointerAffinity::None
;
332 // The function's calling convention.
333 CallingConv CallConvention
= CallingConv::None
;
335 // Function flags (gloabl, public, etc)
336 FuncClass FunctionClass
= FC_Global
;
338 FunctionRefQualifier RefQualifier
= FunctionRefQualifier::None
;
340 // The return type of the function.
341 TypeNode
*ReturnType
= nullptr;
343 // True if this is a C-style ... varargs function.
344 bool IsVariadic
= false;
346 // Function parameters
347 NodeArrayNode
*Params
= nullptr;
349 // True if the function type is noexcept.
350 bool IsNoexcept
= false;
353 struct IdentifierNode
: public Node
{
354 explicit IdentifierNode(NodeKind K
) : Node(K
) {}
356 NodeArrayNode
*TemplateParams
= nullptr;
359 void outputTemplateParameters(OutputStream
&OS
, OutputFlags Flags
) const;
362 struct VcallThunkIdentifierNode
: public IdentifierNode
{
363 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier
) {}
365 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
367 uint64_t OffsetInVTable
= 0;
370 struct DynamicStructorIdentifierNode
: public IdentifierNode
{
371 DynamicStructorIdentifierNode()
372 : IdentifierNode(NodeKind::DynamicStructorIdentifier
) {}
374 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
376 VariableSymbolNode
*Variable
= nullptr;
377 QualifiedNameNode
*Name
= nullptr;
378 bool IsDestructor
= false;
381 struct NamedIdentifierNode
: public IdentifierNode
{
382 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier
) {}
384 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
389 struct IntrinsicFunctionIdentifierNode
: public IdentifierNode
{
390 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator
)
391 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier
),
392 Operator(Operator
) {}
394 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
396 IntrinsicFunctionKind Operator
;
399 struct LiteralOperatorIdentifierNode
: public IdentifierNode
{
400 LiteralOperatorIdentifierNode()
401 : IdentifierNode(NodeKind::LiteralOperatorIdentifier
) {}
403 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
408 struct LocalStaticGuardIdentifierNode
: public IdentifierNode
{
409 LocalStaticGuardIdentifierNode()
410 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier
) {}
412 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
414 bool IsThread
= false;
415 uint32_t ScopeIndex
= 0;
418 struct ConversionOperatorIdentifierNode
: public IdentifierNode
{
419 ConversionOperatorIdentifierNode()
420 : IdentifierNode(NodeKind::ConversionOperatorIdentifier
) {}
422 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
424 // The type that this operator converts too.
425 TypeNode
*TargetType
= nullptr;
428 struct StructorIdentifierNode
: public IdentifierNode
{
429 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier
) {}
430 explicit StructorIdentifierNode(bool IsDestructor
)
431 : IdentifierNode(NodeKind::StructorIdentifier
),
432 IsDestructor(IsDestructor
) {}
434 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
436 // The name of the class that this is a structor of.
437 IdentifierNode
*Class
= nullptr;
438 bool IsDestructor
= false;
441 struct ThunkSignatureNode
: public FunctionSignatureNode
{
442 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature
) {}
444 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
445 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
447 struct ThisAdjustor
{
448 uint32_t StaticOffset
= 0;
449 int32_t VBPtrOffset
= 0;
450 int32_t VBOffsetOffset
= 0;
451 int32_t VtordispOffset
= 0;
454 ThisAdjustor ThisAdjust
;
457 struct PointerTypeNode
: public TypeNode
{
458 PointerTypeNode() : TypeNode(NodeKind::PointerType
) {}
459 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
460 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
462 // Is this a pointer, reference, or rvalue-reference?
463 PointerAffinity Affinity
= PointerAffinity::None
;
465 // If this is a member pointer, this is the class that the member is in.
466 QualifiedNameNode
*ClassParent
= nullptr;
468 // Represents a type X in "a pointer to X", "a reference to X", or
469 // "rvalue-reference to X"
470 TypeNode
*Pointee
= nullptr;
473 struct TagTypeNode
: public TypeNode
{
474 explicit TagTypeNode(TagKind Tag
) : TypeNode(NodeKind::TagType
), Tag(Tag
) {}
476 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
477 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
479 QualifiedNameNode
*QualifiedName
= nullptr;
483 struct ArrayTypeNode
: public TypeNode
{
484 ArrayTypeNode() : TypeNode(NodeKind::ArrayType
) {}
486 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
487 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
489 void outputDimensionsImpl(OutputStream
&OS
, OutputFlags Flags
) const;
490 void outputOneDimension(OutputStream
&OS
, OutputFlags Flags
, Node
*N
) const;
492 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
493 NodeArrayNode
*Dimensions
= nullptr;
495 // The type of array element.
496 TypeNode
*ElementType
= nullptr;
499 struct IntrinsicNode
: public TypeNode
{
500 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType
) {}
501 void output(OutputStream
&OS
, OutputFlags Flags
) const override
{}
504 struct CustomTypeNode
: public TypeNode
{
505 CustomTypeNode() : TypeNode(NodeKind::Custom
) {}
507 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
508 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
510 IdentifierNode
*Identifier
;
513 struct NodeArrayNode
: public Node
{
514 NodeArrayNode() : Node(NodeKind::NodeArray
) {}
516 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
518 void output(OutputStream
&OS
, OutputFlags Flags
, StringView Separator
) const;
520 Node
**Nodes
= nullptr;
524 struct QualifiedNameNode
: public Node
{
525 QualifiedNameNode() : Node(NodeKind::QualifiedName
) {}
527 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
529 NodeArrayNode
*Components
= nullptr;
531 IdentifierNode
*getUnqualifiedIdentifier() {
532 Node
*LastComponent
= Components
->Nodes
[Components
->Count
- 1];
533 return static_cast<IdentifierNode
*>(LastComponent
);
537 struct TemplateParameterReferenceNode
: public Node
{
538 TemplateParameterReferenceNode()
539 : Node(NodeKind::TemplateParameterReference
) {}
541 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
543 SymbolNode
*Symbol
= nullptr;
545 int ThunkOffsetCount
= 0;
546 std::array
<int64_t, 3> ThunkOffsets
;
547 PointerAffinity Affinity
= PointerAffinity::None
;
548 bool IsMemberPointer
= false;
551 struct IntegerLiteralNode
: public Node
{
552 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral
) {}
553 IntegerLiteralNode(uint64_t Value
, bool IsNegative
)
554 : Node(NodeKind::IntegerLiteral
), Value(Value
), IsNegative(IsNegative
) {}
556 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
559 bool IsNegative
= false;
562 struct RttiBaseClassDescriptorNode
: public IdentifierNode
{
563 RttiBaseClassDescriptorNode()
564 : IdentifierNode(NodeKind::RttiBaseClassDescriptor
) {}
566 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
568 uint32_t NVOffset
= 0;
569 int32_t VBPtrOffset
= 0;
570 uint32_t VBTableOffset
= 0;
574 struct SymbolNode
: public Node
{
575 explicit SymbolNode(NodeKind K
) : Node(K
) {}
576 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
577 QualifiedNameNode
*Name
= nullptr;
580 struct SpecialTableSymbolNode
: public SymbolNode
{
581 explicit SpecialTableSymbolNode()
582 : SymbolNode(NodeKind::SpecialTableSymbol
) {}
584 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
585 QualifiedNameNode
*TargetName
= nullptr;
589 struct LocalStaticGuardVariableNode
: public SymbolNode
{
590 LocalStaticGuardVariableNode()
591 : SymbolNode(NodeKind::LocalStaticGuardVariable
) {}
593 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
595 bool IsVisible
= false;
598 struct EncodedStringLiteralNode
: public SymbolNode
{
599 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral
) {}
601 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
603 StringView DecodedString
;
604 bool IsTruncated
= false;
605 CharKind Char
= CharKind::Char
;
608 struct VariableSymbolNode
: public SymbolNode
{
609 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol
) {}
611 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
613 StorageClass SC
= StorageClass::None
;
614 TypeNode
*Type
= nullptr;
617 struct FunctionSymbolNode
: public SymbolNode
{
618 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol
) {}
620 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
622 FunctionSignatureNode
*Signature
= nullptr;
625 } // namespace ms_demangle