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 = nullptr;
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;
587 Qualifiers Quals = Qualifiers::Q_None;
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