LLVM 24.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 {
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
53
56
57// Calling conventions
72
74
85 /// Do not insert a space between template arguments (like MSVC does).
87 /// Add a space between nested closing braces of templates.
89};
90
91// Types
117
124
127 New, // ?2 # operator new
128 Delete, // ?3 # operator delete
129 Assign, // ?4 # operator=
130 RightShift, // ?5 # operator>>
131 LeftShift, // ?6 # operator<<
132 LogicalNot, // ?7 # operator!
133 Equals, // ?8 # operator==
134 NotEquals, // ?9 # operator!=
135 ArraySubscript, // ?A # operator[]
136 Pointer, // ?C # operator->
137 Dereference, // ?D # operator*
138 Increment, // ?E # operator++
139 Decrement, // ?F # operator--
140 Minus, // ?G # operator-
141 Plus, // ?H # operator+
142 BitwiseAnd, // ?I # operator&
143 MemberPointer, // ?J # operator->*
144 Divide, // ?K # operator/
145 Modulus, // ?L # operator%
146 LessThan, // ?M operator<
147 LessThanEqual, // ?N operator<=
148 GreaterThan, // ?O operator>
149 GreaterThanEqual, // ?P operator>=
150 Comma, // ?Q operator,
151 Parens, // ?R operator()
152 BitwiseNot, // ?S operator~
153 BitwiseXor, // ?T operator^
154 BitwiseOr, // ?U operator|
155 LogicalAnd, // ?V operator&&
156 LogicalOr, // ?W operator||
157 TimesEqual, // ?X operator*=
158 PlusEqual, // ?Y operator+=
159 MinusEqual, // ?Z operator-=
160 DivEqual, // ?_0 operator/=
161 ModEqual, // ?_1 operator%=
162 RshEqual, // ?_2 operator>>=
163 LshEqual, // ?_3 operator<<=
164 BitwiseAndEqual, // ?_4 operator&=
165 BitwiseOrEqual, // ?_5 operator|=
166 BitwiseXorEqual, // ?_6 operator^=
167 VbaseDtor, // ?_D # vbase destructor
168 VecDelDtor, // ?_E # vector deleting destructor
169 DefaultCtorClosure, // ?_F # default constructor closure
170 ScalarDelDtor, // ?_G # scalar deleting destructor
171 VecCtorIter, // ?_H # vector constructor iterator
172 VecDtorIter, // ?_I # vector destructor iterator
173 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
174 VdispMap, // ?_K # virtual displacement map
175 EHVecCtorIter, // ?_L # eh vector constructor iterator
176 EHVecDtorIter, // ?_M # eh vector destructor iterator
177 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
178 CopyCtorClosure, // ?_O # copy constructor closure
179 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
180 ArrayNew, // ?_U operator new[]
181 ArrayDelete, // ?_V operator delete[]
182 ManVectorCtorIter, // ?__A managed vector ctor iterator
183 ManVectorDtorIter, // ?__B managed vector dtor iterator
184 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
185 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
186 VectorCopyCtorIter, // ?__G vector copy constructor iterator
187 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
188 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
189 CoAwait, // ?__L operator co_await
190 Spaceship, // ?__M operator<=>
192};
193
214
215// Function classes
218 FC_Public = 1 << 0,
219 FC_Protected = 1 << 1,
220 FC_Private = 1 << 2,
221 FC_Global = 1 << 3,
222 FC_Static = 1 << 4,
223 FC_Virtual = 1 << 5,
224 FC_Far = 1 << 6,
225 FC_ExternC = 1 << 7,
230};
231
232enum class TagKind { Class, Struct, Union, Enum };
233
282
283struct Node {
284 explicit Node(NodeKind K) : Kind(K) {}
285 virtual ~Node() = default;
286
287 NodeKind kind() const { return Kind; }
288
289 virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0;
290
291 DEMANGLE_ABI std::string toString(OutputFlags Flags = OF_Default) const;
292
293private:
294 NodeKind Kind;
295};
296
297struct TypeNode;
298struct PrimitiveTypeNode;
300struct IdentifierNode;
307struct ThunkSignatureNode;
308struct PointerTypeNode;
309struct ArrayTypeNode;
310struct TagTypeNode;
311struct NodeArrayNode;
312struct QualifiedNameNode;
315struct IntegerLiteralNode;
318struct SymbolNode;
319struct FunctionSymbolNode;
320struct VariableSymbolNode;
323
324struct TypeNode : public Node {
325 explicit TypeNode(NodeKind K) : Node(K) {}
326
327 virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0;
328 virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0;
329
330 void output(OutputBuffer &OB, OutputFlags Flags) const override {
331 outputPre(OB, Flags);
332 outputPost(OB, Flags);
333 }
334
335 static bool classof(const Node *N) {
336 return N->kind() >= NodeKind::TypeStart && N->kind() <= NodeKind::TypeEnd;
337 }
338
340};
341
345
346 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
347 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {}
348
349 static bool classof(const Node *N) {
350 return N->kind() == NodeKind::PrimitiveType;
351 }
352
354};
355
359
360 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
361 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
362
363 void outputPreSignature(OutputBuffer &OB, OutputFlags Flags) const;
364
365 static bool classof(const Node *N) {
366 return N->kind() >= NodeKind::FunctionSignature &&
368 }
369
370 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
371 // MemberPointerType.
373
374 // The function's calling convention.
376
377 // Function flags (global, public, etc)
379
381
382 // The return type of the function.
384
385 // True if this is a C-style ... varargs function.
386 bool IsVariadic = false;
387
388 // Function parameters
390
391 // True if the function type is noexcept.
392 bool IsNoexcept = false;
393};
394
395struct IdentifierNode : public Node {
397
398 static bool classof(const Node *N) {
399 return N->kind() >= NodeKind::IdentifierStart &&
400 N->kind() <= NodeKind::IdentifierEnd;
401 }
402
404
405protected:
407 OutputFlags Flags) const;
408};
409
412
413 void output(OutputBuffer &OB, OutputFlags Flags) const override;
414
415 static bool classof(const Node *N) {
416 return N->kind() == NodeKind::VcallThunkIdentifier;
417 }
418
420};
421
425
426 void output(OutputBuffer &OB, OutputFlags Flags) const override;
427
428 static bool classof(const Node *N) {
429 return N->kind() == NodeKind::DynamicStructorIdentifier;
430 }
431
434 bool IsDestructor = false;
435};
436
439
440 void output(OutputBuffer &OB, OutputFlags Flags) const override;
441
442 static bool classof(const Node *N) {
443 return N->kind() == NodeKind::NamedIdentifier;
444 }
445
446 std::string_view Name;
447};
448
462
466
467 void output(OutputBuffer &OB, OutputFlags Flags) const override;
468
469 static bool classof(const Node *N) {
470 return N->kind() == NodeKind::LiteralOperatorIdentifier;
471 }
472
473 std::string_view Name;
474};
475
479
480 void output(OutputBuffer &OB, OutputFlags Flags) const override;
481
482 static bool classof(const Node *N) {
483 return N->kind() == NodeKind::LocalStaticGuardIdentifier;
484 }
485
486 bool IsThread = false;
488};
489
493
494 void output(OutputBuffer &OB, OutputFlags Flags) const override;
495
496 static bool classof(const Node *N) {
498 }
499
500 // The type that this operator converts too.
502};
503
509
510 void output(OutputBuffer &OB, OutputFlags Flags) const override;
511
512 static bool classof(const Node *N) {
513 return N->kind() == NodeKind::StructorIdentifier;
514 }
515
516 // The name of the class that this is a structor of.
518 bool IsDestructor = false;
519};
520
523
524 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
525 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
526
527 static bool classof(const Node *N) {
528 return N->kind() == NodeKind::ThunkSignature;
529 }
530
533 int32_t VBPtrOffset = 0;
534 int32_t VBOffsetOffset = 0;
535 int32_t VtordispOffset = 0;
536 };
537
539};
540
543 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
544 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
545
546 static bool classof(const Node *N) {
547 return N->kind() == NodeKind::PointerType;
548 }
549
550 // Is this a pointer, reference, or rvalue-reference?
552
553 // If this is a member pointer, this is the class that the member is in.
555
557
558 // Represents a type X in "a pointer to X", "a reference to X", or
559 // "rvalue-reference to X"
560 TypeNode *Pointee = nullptr;
561};
562
565
566 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
567 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
568
569 static bool classof(const Node *N) { return N->kind() == NodeKind::TagType; }
570
573};
574
577
578 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
579 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
580
581 void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const;
582 void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const;
583
584 static bool classof(const Node *N) {
585 return N->kind() == NodeKind::ArrayType;
586 }
587
588 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
590
591 // The type of array element.
593};
594
595struct IntrinsicNode : public TypeNode {
597 void output(OutputBuffer &OB, OutputFlags Flags) const override {}
598
599 static bool classof(const Node *N) {
600 return N->kind() == NodeKind::IntrinsicType;
601 }
602};
603
606
607 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override;
608 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override;
609
610 static bool classof(const Node *N) { return N->kind() == NodeKind::Custom; }
611
613};
614
617
618 void output(OutputBuffer &OB, OutputFlags Flags) const override;
619
620 void output(OutputBuffer &OB, OutputFlags Flags,
621 std::string_view Separator) const;
622
623 static bool classof(const Node *N) {
624 return N->kind() == NodeKind::NodeArray;
625 }
626
627 Node **Nodes = nullptr;
628 size_t Count = 0;
629};
630
633
634 void output(OutputBuffer &OB, OutputFlags Flags) const override;
635
636 static bool classof(const Node *N) {
637 return N->kind() == NodeKind::QualifiedName;
638 }
639
641
643 Node *LastComponent = Components->Nodes[Components->Count - 1];
644 return static_cast<IdentifierNode *>(LastComponent);
645 }
646};
647
651
652 void output(OutputBuffer &OB, OutputFlags Flags) const override;
653
654 static bool classof(const Node *N) {
655 return N->kind() == NodeKind::TemplateParameterReference;
656 }
657
658 SymbolNode *Symbol = nullptr;
659
661 std::array<int64_t, 3> ThunkOffsets;
663 bool IsMemberPointer = false;
664};
665
670
671 void output(OutputBuffer &OB, OutputFlags Flags) const override;
672
673 static bool classof(const Node *N) {
674 return N->kind() == NodeKind::IntegerLiteral;
675 }
676
678 bool IsNegative = false;
679};
680
684
685 void output(OutputBuffer &OB, OutputFlags Flags) const override;
686
687 static bool classof(const Node *N) {
688 return N->kind() == NodeKind::RttiBaseClassDescriptor;
689 }
690
692 int32_t VBPtrOffset = 0;
695};
696
697struct DEMANGLE_ABI SymbolNode : public Node {
698 explicit SymbolNode(NodeKind K) : Node(K) {}
699 void output(OutputBuffer &OB, OutputFlags Flags) const override;
700
701 static bool classof(const Node *N) {
702 return N->kind() >= NodeKind::SymbolStart &&
703 N->kind() <= NodeKind::SymbolEnd;
704 }
705
707};
708
712
713 void output(OutputBuffer &OB, OutputFlags Flags) const override;
714
715 static bool classof(const Node *N) {
716 return N->kind() == NodeKind::SpecialTableSymbol;
717 }
718
721};
722
726
727 void output(OutputBuffer &OB, OutputFlags Flags) const override;
728
729 static bool classof(const Node *N) {
730 return N->kind() == NodeKind::LocalStaticGuardVariable;
731 }
732
733 bool IsVisible = false;
734};
735
738
739 void output(OutputBuffer &OB, OutputFlags Flags) const override;
740
741 static bool classof(const Node *N) {
742 return N->kind() == NodeKind::EncodedStringLiteral;
743 }
744
745 std::string_view DecodedString;
746 bool IsTruncated = false;
748};
749
752
753 void output(OutputBuffer &OB, OutputFlags Flags) const override;
754
755 static bool classof(const Node *N) {
756 return N->kind() == NodeKind::VariableSymbol;
757 }
758
759 virtual bool shouldOutputName(OutputFlags Flags) const { return true; }
760
762 TypeNode *Type = nullptr;
763};
764
767
768 bool shouldOutputName(OutputFlags Flags) const override {
769 return !(Flags & OF_NoDecorativeRTTITypeDescriptor);
770 }
771};
772
775
776 void output(OutputBuffer &OB, OutputFlags Flags) const override;
777
778 static bool classof(const Node *N) {
779 return N->kind() == NodeKind::FunctionSymbol;
780 }
781
783};
784
787
788 // __ptrauth takes three arguments:
789 // - key
790 // - isAddressDiscriminated
791 // - extra discriminator
792 static constexpr unsigned NumArgs = 3;
793 typedef std::array<uint64_t, NumArgs> ArgArray;
794
795 void output(OutputBuffer &OB, OutputFlags Flags) const override;
796
797 static bool classof(const Node *N) {
798 return N->kind() == NodeKind::PointerAuthQualifier;
799 }
800
801 // List of arguments.
803};
804
805} // namespace ms_demangle
806} // namespace llvm
807
808#endif
uint64_t uint64_t
#define DEMANGLE_ABI
DEMANGLE_ABI is the export/visibility macro used to mark symbols declared in llvm/Demangle as exporte...
@ OF_CompactTemplateLists
Do not insert a space between template arguments (like MSVC does).
@ OF_SplitTemplateClosers
Add a space between nested closing braces of templates.
This is an optimization pass for GlobalISel generic memory operations.
#define N
DEMANGLE_ABI void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const
IntegerLiteralNode(uint64_t Value, bool IsNegative)
IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
void output(OutputBuffer &OB, OutputFlags Flags) const override
virtual void output(OutputBuffer &OB, OutputFlags Flags) const =0
virtual ~Node()=default
DEMANGLE_ABI std::string toString(OutputFlags Flags=OF_Default) const
void output(OutputBuffer &OB, OutputFlags Flags) const override
PointerAuthQualifierNode * PointerAuthQualifier
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)
bool shouldOutputName(OutputFlags Flags) const override
virtual bool shouldOutputName(OutputFlags Flags) const