LLVM 22.0.0git
MicrosoftDemangleNodes.h
Go to the documentation of this file.
1//===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the AST nodes used in the MSVC demangler.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
14#define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
15
16#include "DemangleConfig.h"
17#include <array>
18#include <cstdint>
19#include <string>
20#include <string_view>
21
22namespace llvm {
23namespace itanium_demangle {
24class OutputBuffer;
25}
26}
27
28using llvm::itanium_demangle::OutputBuffer;
29
30namespace llvm {
31namespace ms_demangle {
32
33// Storage classes
35 Q_None = 0,
36 Q_Const = 1 << 0,
37 Q_Volatile = 1 << 1,
38 Q_Far = 1 << 2,
39 Q_Huge = 1 << 3,
40 Q_Unaligned = 1 << 4,
41 Q_Restrict = 1 << 5,
42 Q_Pointer64 = 1 << 6
43};
44
45enum class StorageClass : uint8_t {
46 None,
50 Global,
52};
53
56
57// Calling conventions
58enum class CallingConv : uint8_t {
59 None,
60 Cdecl,
61 Pascal,
63 Stdcall,
65 Clrcall,
66 Eabi,
68 Regcall,
69 Swift, // Clang-only
70 SwiftAsync, // Clang-only
71};
72
74
83};
84
85// Types
86enum class PrimitiveKind {
87 Void,
88 Bool,
89 Char,
90 Schar,
91 Uchar,
92 Char8,
93 Char16,
94 Char32,
95 Short,
96 Ushort,
97 Int,
98 Uint,
99 Long,
100 Ulong,
101 Int64,
102 Uint64,
103 Wchar,
104 Float,
105 Double,
106 Ldouble,
107 Nullptr,
108 Auto,
110};
111
112enum class CharKind {
113 Char,
114 Char16,
115 Char32,
116 Wchar,
117};
118
120 None,
121 New, // ?2 # operator new
122 Delete, // ?3 # operator delete
123 Assign, // ?4 # operator=
124 RightShift, // ?5 # operator>>
125 LeftShift, // ?6 # operator<<
126 LogicalNot, // ?7 # operator!
127 Equals, // ?8 # operator==
128 NotEquals, // ?9 # operator!=
129 ArraySubscript, // ?A # operator[]
130 Pointer, // ?C # operator->
131 Dereference, // ?D # operator*
132 Increment, // ?E # operator++
133 Decrement, // ?F # operator--
134 Minus, // ?G # operator-
135 Plus, // ?H # operator+
136 BitwiseAnd, // ?I # operator&
137 MemberPointer, // ?J # operator->*
138 Divide, // ?K # operator/
139 Modulus, // ?L # operator%
140 LessThan, // ?M operator<
141 LessThanEqual, // ?N operator<=
142 GreaterThan, // ?O operator>
143 GreaterThanEqual, // ?P operator>=
144 Comma, // ?Q operator,
145 Parens, // ?R operator()
146 BitwiseNot, // ?S operator~
147 BitwiseXor, // ?T operator^
148 BitwiseOr, // ?U operator|
149 LogicalAnd, // ?V operator&&
150 LogicalOr, // ?W operator||
151 TimesEqual, // ?X operator*=
152 PlusEqual, // ?Y operator+=
153 MinusEqual, // ?Z operator-=
154 DivEqual, // ?_0 operator/=
155 ModEqual, // ?_1 operator%=
156 RshEqual, // ?_2 operator>>=
157 LshEqual, // ?_3 operator<<=
158 BitwiseAndEqual, // ?_4 operator&=
159 BitwiseOrEqual, // ?_5 operator|=
160 BitwiseXorEqual, // ?_6 operator^=
161 VbaseDtor, // ?_D # vbase destructor
162 VecDelDtor, // ?_E # vector deleting destructor
163 DefaultCtorClosure, // ?_F # default constructor closure
164 ScalarDelDtor, // ?_G # scalar deleting destructor
165 VecCtorIter, // ?_H # vector constructor iterator
166 VecDtorIter, // ?_I # vector destructor iterator
167 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
168 VdispMap, // ?_K # virtual displacement map
169 EHVecCtorIter, // ?_L # eh vector constructor iterator
170 EHVecDtorIter, // ?_M # eh vector destructor iterator
171 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
172 CopyCtorClosure, // ?_O # copy constructor closure
173 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
174 ArrayNew, // ?_U operator new[]
175 ArrayDelete, // ?_V operator delete[]
176 ManVectorCtorIter, // ?__A managed vector ctor iterator
177 ManVectorDtorIter, // ?__B managed vector dtor iterator
178 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
179 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
180 VectorCopyCtorIter, // ?__G vector copy constructor iterator
181 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
182 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
183 CoAwait, // ?__L operator co_await
184 Spaceship, // ?__M operator<=>
186};
187
189 None,
190 Vftable,
191 Vbtable,
192 Typeof,
197 Unknown,
207};
208
209// Function classes
212 FC_Public = 1 << 0,
213 FC_Protected = 1 << 1,
214 FC_Private = 1 << 2,
215 FC_Global = 1 << 3,
216 FC_Static = 1 << 4,
217 FC_Virtual = 1 << 5,
218 FC_Far = 1 << 6,
219 FC_ExternC = 1 << 7,
224};
225
226enum class TagKind { Class, Struct, Union, Enum };
227
228enum class NodeKind {
229 Unknown,
230
239
251
252 TypeStart,
254 Custom,
255
259
263 TagType,
265
267
269
270 NodeArray,
271
273
275};
276
277struct Node {
278 explicit Node(NodeKind K) : Kind(K) {}
279 virtual ~Node() = default;
280
281 NodeKind kind() const { return Kind; }
282
283 virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
284
285 DEMANGLE_ABI std::string toString(OutputFlags Flags = OF_Default) const;
286
287private:
288 NodeKind Kind;
289};
290
291struct TypeNode;
292struct PrimitiveTypeNode;
294struct IdentifierNode;
301struct ThunkSignatureNode;
302struct PointerTypeNode;
303struct ArrayTypeNode;
304struct TagTypeNode;
305struct NodeArrayNode;
306struct QualifiedNameNode;
309struct IntegerLiteralNode;
312struct SymbolNode;
313struct FunctionSymbolNode;
314struct VariableSymbolNode;
317
318struct TypeNode : public Node {
319 explicit TypeNode(NodeKind K) : Node(K) {}
320
321 virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0;
322 virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
323
324 void output(OutputBuffer &OB, OutputFlags Flags) const override {
325 outputPre(OB, Flags);
326 outputPost(OB, Flags);
327 }
328
329 static bool classof(const Node *N) {
330 return N->kind() >= NodeKind::TypeStart && N->kind() <= NodeKind::TypeEnd;
331 }
332
334};
335
338 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
339
340 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
341 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
342
343 static bool classof(const Node *N) {
344 return N->kind() == NodeKind::PrimitiveType;
345 }
346
348};
349
353
354 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
355 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
356
357 static bool classof(const Node *N) {
358 return N->kind() >= NodeKind::FunctionSignature &&
359 N->kind() <= NodeKind::FunctionSignatureEnd;
360 }
361
362 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
363 // MemberPointerType.
364 PointerAffinity Affinity = PointerAffinity::None;
365
366 // The function's calling convention.
367 CallingConv CallConvention = CallingConv::None;
368
369 // Function flags (global, public, etc)
370 FuncClass FunctionClass = FC_Global;
371
372 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
373
374 // The return type of the function.
375 TypeNode *ReturnType = nullptr;
376
377 // True if this is a C-style ... varargs function.
378 bool IsVariadic = false;
379
380 // Function parameters
381 NodeArrayNode *Params = nullptr;
382
383 // True if the function type is noexcept.
384 bool IsNoexcept = false;
385};
386
387struct IdentifierNode : public Node {
388 explicit IdentifierNode(NodeKind K) : Node(K) {}
389
390 static bool classof(const Node *N) {
391 return N->kind() >= NodeKind::IdentifierStart &&
392 N->kind() <= NodeKind::IdentifierEnd;
393 }
394
396
397protected:
399 OutputFlags Flags) const;
400};
401
404
405 void output(OutputBuffer &OB, OutputFlags Flags) const override;
406
407 static bool classof(const Node *N) {
408 return N->kind() == NodeKind::VcallThunkIdentifier;
409 }
410
411 uint64_t OffsetInVTable = 0;
412};
413
417
418 void output(OutputBuffer &OB, OutputFlags Flags) const override;
419
420 static bool classof(const Node *N) {
421 return N->kind() == NodeKind::DynamicStructorIdentifier;
422 }
423
424 VariableSymbolNode *Variable = nullptr;
426 bool IsDestructor = false;
427};
428
431
432 void output(OutputBuffer &OB, OutputFlags Flags) const override;
433
434 static bool classof(const Node *N) {
435 return N->kind() == NodeKind::NamedIdentifier;
436 }
437
438 std::string_view Name;
439};
440
445
446 void output(OutputBuffer &OB, OutputFlags Flags) const override;
447
448 static bool classof(const Node *N) {
449 return N->kind() == NodeKind::IntrinsicFunctionIdentifier;
450 }
451
453};
454
458
459 void output(OutputBuffer &OB, OutputFlags Flags) const override;
460
461 static bool classof(const Node *N) {
462 return N->kind() == NodeKind::LiteralOperatorIdentifier;
463 }
464
465 std::string_view Name;
466};
467
471
472 void output(OutputBuffer &OB, OutputFlags Flags) const override;
473
474 static bool classof(const Node *N) {
475 return N->kind() == NodeKind::LocalStaticGuardIdentifier;
476 }
477
478 bool IsThread = false;
479 uint32_t ScopeIndex = 0;
480};
481
485
486 void output(OutputBuffer &OB, OutputFlags Flags) const override;
487
488 static bool classof(const Node *N) {
489 return N->kind() == NodeKind::ConversionOperatorIdentifier;
490 }
491
492 // The type that this operator converts too.
493 TypeNode *TargetType = nullptr;
494};
495
498 explicit StructorIdentifierNode(bool IsDestructor)
500 IsDestructor(IsDestructor) {}
501
502 void output(OutputBuffer &OB, OutputFlags Flags) const override;
503
504 static bool classof(const Node *N) {
505 return N->kind() == NodeKind::StructorIdentifier;
506 }
507
508 // The name of the class that this is a structor of.
509 IdentifierNode *Class = nullptr;
510 bool IsDestructor = false;
511};
512
515
516 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
517 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
518
519 static bool classof(const Node *N) {
520 return N->kind() == NodeKind::ThunkSignature;
521 }
522
524 uint32_t StaticOffset = 0;
525 int32_t VBPtrOffset = 0;
526 int32_t VBOffsetOffset = 0;
527 int32_t VtordispOffset = 0;
528 };
529
531};
532
535 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
536 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
537
538 static bool classof(const Node *N) {
539 return N->kind() == NodeKind::PointerType;
540 }
541
542 // Is this a pointer, reference, or rvalue-reference?
543 PointerAffinity Affinity = PointerAffinity::None;
544
545 // If this is a member pointer, this is the class that the member is in.
546 QualifiedNameNode *ClassParent = nullptr;
547
549
550 // Represents a type X in "a pointer to X", "a reference to X", or
551 // "rvalue-reference to X"
552 TypeNode *Pointee = nullptr;
553};
554
556 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
557
558 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
559 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
560
561 static bool classof(const Node *N) { return N->kind() == NodeKind::TagType; }
562
565};
566
569
570 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
571 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
572
573 void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
574 void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const;
575
576 static bool classof(const Node *N) {
577 return N->kind() == NodeKind::ArrayType;
578 }
579
580 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
581 NodeArrayNode *Dimensions = nullptr;
582
583 // The type of array element.
584 TypeNode *ElementType = nullptr;
585};
586
587struct IntrinsicNode : public TypeNode {
589 void output(OutputBuffer &OB, OutputFlags Flags) const override {}
590
591 static bool classof(const Node *N) {
592 return N->kind() == NodeKind::IntrinsicType;
593 }
594};
595
598
599 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
600 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
601
602 static bool classof(const Node *N) { return N->kind() == NodeKind::Custom; }
603
604 IdentifierNode *Identifier = nullptr;
605};
606
609
610 void output(OutputBuffer &OB, OutputFlags Flags) const override;
611
612 void output(OutputBuffer &OB, OutputFlags Flags,
613 std::string_view Separator) const;
614
615 static bool classof(const Node *N) {
616 return N->kind() == NodeKind::NodeArray;
617 }
618
619 Node **Nodes = nullptr;
620 size_t Count = 0;
621};
622
625
626 void output(OutputBuffer &OB, OutputFlags Flags) const override;
627
628 static bool classof(const Node *N) {
629 return N->kind() == NodeKind::QualifiedName;
630 }
631
632 NodeArrayNode *Components = nullptr;
633
635 Node *LastComponent = Components->Nodes[Components->Count - 1];
636 return static_cast<IdentifierNode *>(LastComponent);
637 }
638};
639
643
644 void output(OutputBuffer &OB, OutputFlags Flags) const override;
645
646 static bool classof(const Node *N) {
647 return N->kind() == NodeKind::TemplateParameterReference;
648 }
649
650 SymbolNode *Symbol = nullptr;
651
652 int ThunkOffsetCount = 0;
653 std::array<int64_t, 3> ThunkOffsets;
654 PointerAffinity Affinity = PointerAffinity::None;
655 bool IsMemberPointer = false;
656};
657
661 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
662
663 void output(OutputBuffer &OB, OutputFlags Flags) const override;
664
665 static bool classof(const Node *N) {
666 return N->kind() == NodeKind::IntegerLiteral;
667 }
668
670 bool IsNegative = false;
671};
672
676
677 void output(OutputBuffer &OB, OutputFlags Flags) const override;
678
679 static bool classof(const Node *N) {
680 return N->kind() == NodeKind::RttiBaseClassDescriptor;
681 }
682
683 uint32_t NVOffset = 0;
684 int32_t VBPtrOffset = 0;
685 uint32_t VBTableOffset = 0;
686 uint32_t Flags = 0;
687};
688
689struct DEMANGLE_ABI SymbolNode : public Node {
690 explicit SymbolNode(NodeKind K) : Node(K) {}
691 void output(OutputBuffer &OB, OutputFlags Flags) const override;
692
693 static bool classof(const Node *N) {
694 return N->kind() >= NodeKind::SymbolStart &&
695 N->kind() <= NodeKind::SymbolEnd;
696 }
697
699};
700
704
705 void output(OutputBuffer &OB, OutputFlags Flags) const override;
706
707 static bool classof(const Node *N) {
708 return N->kind() == NodeKind::SpecialTableSymbol;
709 }
710
711 QualifiedNameNode *TargetName = nullptr;
712 Qualifiers Quals = Qualifiers::Q_None;
713};
714
718
719 void output(OutputBuffer &OB, OutputFlags Flags) const override;
720
721 static bool classof(const Node *N) {
722 return N->kind() == NodeKind::LocalStaticGuardVariable;
723 }
724
725 bool IsVisible = false;
726};
727
730
731 void output(OutputBuffer &OB, OutputFlags Flags) const override;
732
733 static bool classof(const Node *N) {
734 return N->kind() == NodeKind::EncodedStringLiteral;
735 }
736
737 std::string_view DecodedString;
738 bool IsTruncated = false;
739 CharKind Char = CharKind::Char;
740};
741
744
745 void output(OutputBuffer &OB, OutputFlags Flags) const override;
746
747 static bool classof(const Node *N) {
748 return N->kind() == NodeKind::VariableSymbol;
749 }
750
751 StorageClass SC = StorageClass::None;
752 TypeNode *Type = nullptr;
753};
754
757
758 void output(OutputBuffer &OB, OutputFlags Flags) const override;
759
760 static bool classof(const Node *N) {
761 return N->kind() == NodeKind::FunctionSymbol;
762 }
763
764 FunctionSignatureNode *Signature = nullptr;
765};
766
769
770 // __ptrauth takes three arguments:
771 // - key
772 // - isAddressDiscriminated
773 // - extra discriminator
774 static constexpr unsigned NumArgs = 3;
775 typedef std::array<uint64_t, NumArgs> ArgArray;
776
777 void output(OutputBuffer &OB, OutputFlags Flags) const override;
778
779 static bool classof(const Node *N) {
780 return N->kind() == NodeKind::PointerAuthQualifier;
781 }
782
783 // List of arguments.
784 NodeArrayNode *Components = nullptr;
785};
786
787} // namespace ms_demangle
788} // namespace llvm
789
790#endif
#define DEMANGLE_ABI
DEMANGLE_ABI is the export/visibility macro used to mark symbols delcared in llvm/Demangle as exporte...
std::string Name
Class to represent array types.
Definition: DerivedTypes.h:398
This is a utility class that provides an abstraction for the common functionality between Instruction...
Definition: Operator.h:33
Class to represent pointers.
Definition: DerivedTypes.h:700
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:75
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
#define N
Determine the kind of a node from its type.
static bool classof(const Node *N)
DEMANGLE_ABI void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const
IntegerLiteralNode(uint64_t Value, bool IsNegative)
IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
static bool classof(const Node *N)
void output(OutputBuffer &OB, OutputFlags Flags) const override
static bool classof(const Node *N)
virtual void output(OutputBuffer &OB, OutputFlags Flags) const =0
virtual ~Node()=default
DEMANGLE_ABI std::string toString(OutputFlags Flags=OF_Default) const
void outputPost(OutputBuffer &OB, OutputFlags Flags) const override
static bool classof(const Node *N)
static bool classof(const Node *N)
void output(OutputBuffer &OB, OutputFlags Flags) const override
virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const =0
virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const =0
static bool classof(const Node *N)