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 Qualifiers Quals
= Q_None
;
309 struct PrimitiveTypeNode
: public TypeNode
{
310 explicit PrimitiveTypeNode(PrimitiveKind K
)
311 : TypeNode(NodeKind::PrimitiveType
), PrimKind(K
) {}
313 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
314 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const {}
316 PrimitiveKind PrimKind
;
319 struct FunctionSignatureNode
: public TypeNode
{
320 explicit FunctionSignatureNode(NodeKind K
) : TypeNode(K
) {}
321 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature
) {}
323 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
324 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
326 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
327 // MemberPointerType.
328 PointerAffinity Affinity
= PointerAffinity::None
;
330 // The function's calling convention.
331 CallingConv CallConvention
= CallingConv::None
;
333 // Function flags (gloabl, public, etc)
334 FuncClass FunctionClass
= FC_Global
;
336 FunctionRefQualifier RefQualifier
= FunctionRefQualifier::None
;
338 // The return type of the function.
339 TypeNode
*ReturnType
= nullptr;
341 // True if this is a C-style ... varargs function.
342 bool IsVariadic
= false;
344 // Function parameters
345 NodeArrayNode
*Params
= nullptr;
347 // True if the function type is noexcept.
348 bool IsNoexcept
= false;
351 struct IdentifierNode
: public Node
{
352 explicit IdentifierNode(NodeKind K
) : Node(K
) {}
354 NodeArrayNode
*TemplateParams
= nullptr;
357 void outputTemplateParameters(OutputStream
&OS
, OutputFlags Flags
) const;
360 struct VcallThunkIdentifierNode
: public IdentifierNode
{
361 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier
) {}
363 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
365 uint64_t OffsetInVTable
= 0;
368 struct DynamicStructorIdentifierNode
: public IdentifierNode
{
369 DynamicStructorIdentifierNode()
370 : IdentifierNode(NodeKind::DynamicStructorIdentifier
) {}
372 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
374 VariableSymbolNode
*Variable
= nullptr;
375 QualifiedNameNode
*Name
= nullptr;
376 bool IsDestructor
= false;
379 struct NamedIdentifierNode
: public IdentifierNode
{
380 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier
) {}
382 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
387 struct IntrinsicFunctionIdentifierNode
: public IdentifierNode
{
388 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator
)
389 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier
),
390 Operator(Operator
) {}
392 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
394 IntrinsicFunctionKind Operator
;
397 struct LiteralOperatorIdentifierNode
: public IdentifierNode
{
398 LiteralOperatorIdentifierNode()
399 : IdentifierNode(NodeKind::LiteralOperatorIdentifier
) {}
401 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
406 struct LocalStaticGuardIdentifierNode
: public IdentifierNode
{
407 LocalStaticGuardIdentifierNode()
408 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier
) {}
410 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
412 bool IsThread
= false;
413 uint32_t ScopeIndex
= 0;
416 struct ConversionOperatorIdentifierNode
: public IdentifierNode
{
417 ConversionOperatorIdentifierNode()
418 : IdentifierNode(NodeKind::ConversionOperatorIdentifier
) {}
420 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
422 // The type that this operator converts too.
423 TypeNode
*TargetType
= nullptr;
426 struct StructorIdentifierNode
: public IdentifierNode
{
427 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier
) {}
428 explicit StructorIdentifierNode(bool IsDestructor
)
429 : IdentifierNode(NodeKind::StructorIdentifier
),
430 IsDestructor(IsDestructor
) {}
432 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
434 // The name of the class that this is a structor of.
435 IdentifierNode
*Class
= nullptr;
436 bool IsDestructor
= false;
439 struct ThunkSignatureNode
: public FunctionSignatureNode
{
440 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature
) {}
442 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
443 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
445 struct ThisAdjustor
{
446 uint32_t StaticOffset
= 0;
447 int32_t VBPtrOffset
= 0;
448 int32_t VBOffsetOffset
= 0;
449 int32_t VtordispOffset
= 0;
452 ThisAdjustor ThisAdjust
;
455 struct PointerTypeNode
: public TypeNode
{
456 PointerTypeNode() : TypeNode(NodeKind::PointerType
) {}
457 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
458 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
460 // Is this a pointer, reference, or rvalue-reference?
461 PointerAffinity Affinity
= PointerAffinity::None
;
463 // If this is a member pointer, this is the class that the member is in.
464 QualifiedNameNode
*ClassParent
= nullptr;
466 // Represents a type X in "a pointer to X", "a reference to X", or
467 // "rvalue-reference to X"
468 TypeNode
*Pointee
= nullptr;
471 struct TagTypeNode
: public TypeNode
{
472 explicit TagTypeNode(TagKind Tag
) : TypeNode(NodeKind::TagType
), Tag(Tag
) {}
474 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
475 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
477 QualifiedNameNode
*QualifiedName
= nullptr;
481 struct ArrayTypeNode
: public TypeNode
{
482 ArrayTypeNode() : TypeNode(NodeKind::ArrayType
) {}
484 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const;
485 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const;
487 void outputDimensionsImpl(OutputStream
&OS
, OutputFlags Flags
) const;
488 void outputOneDimension(OutputStream
&OS
, OutputFlags Flags
, Node
*N
) const;
490 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
491 NodeArrayNode
*Dimensions
= nullptr;
493 // The type of array element.
494 TypeNode
*ElementType
= nullptr;
497 struct IntrinsicNode
: public TypeNode
{
498 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType
) {}
499 void output(OutputStream
&OS
, OutputFlags Flags
) const override
{}
502 struct CustomTypeNode
: public TypeNode
{
503 CustomTypeNode() : TypeNode(NodeKind::Custom
) {}
505 void outputPre(OutputStream
&OS
, OutputFlags Flags
) const override
;
506 void outputPost(OutputStream
&OS
, OutputFlags Flags
) const override
;
508 IdentifierNode
*Identifier
;
511 struct NodeArrayNode
: public Node
{
512 NodeArrayNode() : Node(NodeKind::NodeArray
) {}
514 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
516 void output(OutputStream
&OS
, OutputFlags Flags
, StringView Separator
) const;
518 Node
**Nodes
= nullptr;
522 struct QualifiedNameNode
: public Node
{
523 QualifiedNameNode() : Node(NodeKind::QualifiedName
) {}
525 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
527 NodeArrayNode
*Components
= nullptr;
529 IdentifierNode
*getUnqualifiedIdentifier() {
530 Node
*LastComponent
= Components
->Nodes
[Components
->Count
- 1];
531 return static_cast<IdentifierNode
*>(LastComponent
);
535 struct TemplateParameterReferenceNode
: public Node
{
536 TemplateParameterReferenceNode()
537 : Node(NodeKind::TemplateParameterReference
) {}
539 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
541 SymbolNode
*Symbol
= nullptr;
543 int ThunkOffsetCount
= 0;
544 std::array
<int64_t, 3> ThunkOffsets
;
545 PointerAffinity Affinity
= PointerAffinity::None
;
546 bool IsMemberPointer
= false;
549 struct IntegerLiteralNode
: public Node
{
550 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral
) {}
551 IntegerLiteralNode(uint64_t Value
, bool IsNegative
)
552 : Node(NodeKind::IntegerLiteral
), Value(Value
), IsNegative(IsNegative
) {}
554 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
557 bool IsNegative
= false;
560 struct RttiBaseClassDescriptorNode
: public IdentifierNode
{
561 RttiBaseClassDescriptorNode()
562 : IdentifierNode(NodeKind::RttiBaseClassDescriptor
) {}
564 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
566 uint32_t NVOffset
= 0;
567 int32_t VBPtrOffset
= 0;
568 uint32_t VBTableOffset
= 0;
572 struct SymbolNode
: public Node
{
573 explicit SymbolNode(NodeKind K
) : Node(K
) {}
574 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
575 QualifiedNameNode
*Name
= nullptr;
578 struct SpecialTableSymbolNode
: public SymbolNode
{
579 explicit SpecialTableSymbolNode()
580 : SymbolNode(NodeKind::SpecialTableSymbol
) {}
582 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
583 QualifiedNameNode
*TargetName
= nullptr;
587 struct LocalStaticGuardVariableNode
: public SymbolNode
{
588 LocalStaticGuardVariableNode()
589 : SymbolNode(NodeKind::LocalStaticGuardVariable
) {}
591 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
593 bool IsVisible
= false;
596 struct EncodedStringLiteralNode
: public SymbolNode
{
597 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral
) {}
599 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
601 StringView DecodedString
;
602 bool IsTruncated
= false;
603 CharKind Char
= CharKind::Char
;
606 struct VariableSymbolNode
: public SymbolNode
{
607 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol
) {}
609 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
611 StorageClass SC
= StorageClass::None
;
612 TypeNode
*Type
= nullptr;
615 struct FunctionSymbolNode
: public SymbolNode
{
616 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol
) {}
618 void output(OutputStream
&OS
, OutputFlags Flags
) const override
;
620 FunctionSignatureNode
*Signature
= nullptr;
623 } // namespace ms_demangle