blob: 62e0f4765a69a4cbacb0fb5165dbdb11d7599204 [file] [log] [blame]
Andrew Walbran16937d02019-10-22 13:54:20 +01001//===- 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_SUPPORT_MICROSOFTDEMANGLENODES_H
14#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
15
16#include "llvm/Demangle/DemangleConfig.h"
17#include "llvm/Demangle/StringView.h"
18#include <array>
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020019#include <cstdint>
20#include <string>
Andrew Walbran16937d02019-10-22 13:54:20 +010021
22namespace llvm {
23namespace itanium_demangle {
24class OutputStream;
25}
26}
27
28using llvm::itanium_demangle::OutputStream;
29using llvm::itanium_demangle::StringView;
30
31namespace llvm {
32namespace ms_demangle {
33
34// Storage classes
35enum Qualifiers : uint8_t {
36 Q_None = 0,
37 Q_Const = 1 << 0,
38 Q_Volatile = 1 << 1,
39 Q_Far = 1 << 2,
40 Q_Huge = 1 << 3,
41 Q_Unaligned = 1 << 4,
42 Q_Restrict = 1 << 5,
43 Q_Pointer64 = 1 << 6
44};
45
46enum class StorageClass : uint8_t {
47 None,
48 PrivateStatic,
49 ProtectedStatic,
50 PublicStatic,
51 Global,
52 FunctionLocalStatic,
53};
54
55enum class PointerAffinity { None, Pointer, Reference, RValueReference };
56enum class FunctionRefQualifier { None, Reference, RValueReference };
57
58// Calling conventions
59enum class CallingConv : uint8_t {
60 None,
61 Cdecl,
62 Pascal,
63 Thiscall,
64 Stdcall,
65 Fastcall,
66 Clrcall,
67 Eabi,
68 Vectorcall,
69 Regcall,
70};
71
72enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
73
74enum OutputFlags {
75 OF_Default = 0,
76 OF_NoCallingConvention = 1,
77 OF_NoTagSpecifier = 2,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020078 OF_NoAccessSpecifier = 4,
79 OF_NoMemberType = 8,
80 OF_NoReturnType = 16,
Andrew Walbran16937d02019-10-22 13:54:20 +010081};
82
83// Types
84enum class PrimitiveKind {
85 Void,
86 Bool,
87 Char,
88 Schar,
89 Uchar,
Andrew Walbran3d2c1972020-04-07 12:24:26 +010090 Char8,
Andrew Walbran16937d02019-10-22 13:54:20 +010091 Char16,
92 Char32,
93 Short,
94 Ushort,
95 Int,
96 Uint,
97 Long,
98 Ulong,
99 Int64,
100 Uint64,
101 Wchar,
102 Float,
103 Double,
104 Ldouble,
105 Nullptr,
106};
107
108enum class CharKind {
109 Char,
110 Char16,
111 Char32,
112 Wchar,
113};
114
115enum class IntrinsicFunctionKind : uint8_t {
116 None,
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
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100179 CoAwait, // ?__L operator co_await
180 Spaceship, // ?__M operator<=>
Andrew Walbran16937d02019-10-22 13:54:20 +0100181 MaxIntrinsic
182};
183
184enum class SpecialIntrinsicKind {
185 None,
186 Vftable,
187 Vbtable,
188 Typeof,
189 VcallThunk,
190 LocalStaticGuard,
191 StringLiteralSymbol,
192 UdtReturning,
193 Unknown,
194 DynamicInitializer,
195 DynamicAtexitDestructor,
196 RttiTypeDescriptor,
197 RttiBaseClassDescriptor,
198 RttiBaseClassArray,
199 RttiClassHierarchyDescriptor,
200 RttiCompleteObjLocator,
201 LocalVftable,
202 LocalStaticThreadGuard,
203};
204
205// Function classes
206enum FuncClass : uint16_t {
207 FC_None = 0,
208 FC_Public = 1 << 0,
209 FC_Protected = 1 << 1,
210 FC_Private = 1 << 2,
211 FC_Global = 1 << 3,
212 FC_Static = 1 << 4,
213 FC_Virtual = 1 << 5,
214 FC_Far = 1 << 6,
215 FC_ExternC = 1 << 7,
216 FC_NoParameterList = 1 << 8,
217 FC_VirtualThisAdjust = 1 << 9,
218 FC_VirtualThisAdjustEx = 1 << 10,
219 FC_StaticThisAdjust = 1 << 11,
220};
221
222enum class TagKind { Class, Struct, Union, Enum };
223
224enum class NodeKind {
225 Unknown,
226 Md5Symbol,
227 PrimitiveType,
228 FunctionSignature,
229 Identifier,
230 NamedIdentifier,
231 VcallThunkIdentifier,
232 LocalStaticGuardIdentifier,
233 IntrinsicFunctionIdentifier,
234 ConversionOperatorIdentifier,
235 DynamicStructorIdentifier,
236 StructorIdentifier,
237 LiteralOperatorIdentifier,
238 ThunkSignature,
239 PointerType,
240 TagType,
241 ArrayType,
242 Custom,
243 IntrinsicType,
244 NodeArray,
245 QualifiedName,
246 TemplateParameterReference,
247 EncodedStringLiteral,
248 IntegerLiteral,
249 RttiBaseClassDescriptor,
250 LocalStaticGuardVariable,
251 FunctionSymbol,
252 VariableSymbol,
253 SpecialTableSymbol
254};
255
256struct Node {
257 explicit Node(NodeKind K) : Kind(K) {}
258 virtual ~Node() = default;
259
260 NodeKind kind() const { return Kind; }
261
262 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
263
264 std::string toString(OutputFlags Flags = OF_Default) const;
265
266private:
267 NodeKind Kind;
268};
269
270struct TypeNode;
271struct PrimitiveTypeNode;
272struct FunctionSignatureNode;
273struct IdentifierNode;
274struct NamedIdentifierNode;
275struct VcallThunkIdentifierNode;
276struct IntrinsicFunctionIdentifierNode;
277struct LiteralOperatorIdentifierNode;
278struct ConversionOperatorIdentifierNode;
279struct StructorIdentifierNode;
280struct ThunkSignatureNode;
281struct PointerTypeNode;
282struct ArrayTypeNode;
283struct CustomNode;
284struct TagTypeNode;
285struct IntrinsicTypeNode;
286struct NodeArrayNode;
287struct QualifiedNameNode;
288struct TemplateParameterReferenceNode;
289struct EncodedStringLiteralNode;
290struct IntegerLiteralNode;
291struct RttiBaseClassDescriptorNode;
292struct LocalStaticGuardVariableNode;
293struct SymbolNode;
294struct FunctionSymbolNode;
295struct VariableSymbolNode;
296struct SpecialTableSymbolNode;
297
298struct TypeNode : public Node {
299 explicit TypeNode(NodeKind K) : Node(K) {}
300
301 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
302 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
303
304 void output(OutputStream &OS, OutputFlags Flags) const override {
305 outputPre(OS, Flags);
306 outputPost(OS, Flags);
307 }
308
Andrew Walbran16937d02019-10-22 13:54:20 +0100309 Qualifiers Quals = Q_None;
310};
311
312struct PrimitiveTypeNode : public TypeNode {
313 explicit PrimitiveTypeNode(PrimitiveKind K)
314 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
315
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200316 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
317 void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
Andrew Walbran16937d02019-10-22 13:54:20 +0100318
319 PrimitiveKind PrimKind;
320};
321
322struct FunctionSignatureNode : public TypeNode {
323 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
324 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
325
326 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
327 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
328
329 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
330 // MemberPointerType.
331 PointerAffinity Affinity = PointerAffinity::None;
332
333 // The function's calling convention.
334 CallingConv CallConvention = CallingConv::None;
335
336 // Function flags (gloabl, public, etc)
337 FuncClass FunctionClass = FC_Global;
338
339 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
340
341 // The return type of the function.
342 TypeNode *ReturnType = nullptr;
343
344 // True if this is a C-style ... varargs function.
345 bool IsVariadic = false;
346
347 // Function parameters
348 NodeArrayNode *Params = nullptr;
349
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100350 // True if the function type is noexcept.
Andrew Walbran16937d02019-10-22 13:54:20 +0100351 bool IsNoexcept = false;
352};
353
354struct IdentifierNode : public Node {
355 explicit IdentifierNode(NodeKind K) : Node(K) {}
356
357 NodeArrayNode *TemplateParams = nullptr;
358
359protected:
360 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
361};
362
363struct VcallThunkIdentifierNode : public IdentifierNode {
364 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
365
366 void output(OutputStream &OS, OutputFlags Flags) const override;
367
368 uint64_t OffsetInVTable = 0;
369};
370
371struct DynamicStructorIdentifierNode : public IdentifierNode {
372 DynamicStructorIdentifierNode()
373 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
374
375 void output(OutputStream &OS, OutputFlags Flags) const override;
376
377 VariableSymbolNode *Variable = nullptr;
378 QualifiedNameNode *Name = nullptr;
379 bool IsDestructor = false;
380};
381
382struct NamedIdentifierNode : public IdentifierNode {
383 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
384
385 void output(OutputStream &OS, OutputFlags Flags) const override;
386
387 StringView Name;
388};
389
390struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
391 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
392 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
393 Operator(Operator) {}
394
395 void output(OutputStream &OS, OutputFlags Flags) const override;
396
397 IntrinsicFunctionKind Operator;
398};
399
400struct LiteralOperatorIdentifierNode : public IdentifierNode {
401 LiteralOperatorIdentifierNode()
402 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
403
404 void output(OutputStream &OS, OutputFlags Flags) const override;
405
406 StringView Name;
407};
408
409struct LocalStaticGuardIdentifierNode : public IdentifierNode {
410 LocalStaticGuardIdentifierNode()
411 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
412
413 void output(OutputStream &OS, OutputFlags Flags) const override;
414
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100415 bool IsThread = false;
Andrew Walbran16937d02019-10-22 13:54:20 +0100416 uint32_t ScopeIndex = 0;
417};
418
419struct ConversionOperatorIdentifierNode : public IdentifierNode {
420 ConversionOperatorIdentifierNode()
421 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
422
423 void output(OutputStream &OS, OutputFlags Flags) const override;
424
425 // The type that this operator converts too.
426 TypeNode *TargetType = nullptr;
427};
428
429struct StructorIdentifierNode : public IdentifierNode {
430 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
431 explicit StructorIdentifierNode(bool IsDestructor)
432 : IdentifierNode(NodeKind::StructorIdentifier),
433 IsDestructor(IsDestructor) {}
434
435 void output(OutputStream &OS, OutputFlags Flags) const override;
436
437 // The name of the class that this is a structor of.
438 IdentifierNode *Class = nullptr;
439 bool IsDestructor = false;
440};
441
442struct ThunkSignatureNode : public FunctionSignatureNode {
443 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
444
445 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
446 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
447
448 struct ThisAdjustor {
449 uint32_t StaticOffset = 0;
450 int32_t VBPtrOffset = 0;
451 int32_t VBOffsetOffset = 0;
452 int32_t VtordispOffset = 0;
453 };
454
455 ThisAdjustor ThisAdjust;
456};
457
458struct 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;
462
463 // Is this a pointer, reference, or rvalue-reference?
464 PointerAffinity Affinity = PointerAffinity::None;
465
466 // If this is a member pointer, this is the class that the member is in.
467 QualifiedNameNode *ClassParent = nullptr;
468
469 // Represents a type X in "a pointer to X", "a reference to X", or
470 // "rvalue-reference to X"
471 TypeNode *Pointee = nullptr;
472};
473
474struct TagTypeNode : public TypeNode {
475 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
476
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200477 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
478 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Andrew Walbran16937d02019-10-22 13:54:20 +0100479
480 QualifiedNameNode *QualifiedName = nullptr;
481 TagKind Tag;
482};
483
484struct ArrayTypeNode : public TypeNode {
485 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
486
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200487 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
488 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
Andrew Walbran16937d02019-10-22 13:54:20 +0100489
490 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
491 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
492
493 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
494 NodeArrayNode *Dimensions = nullptr;
495
496 // The type of array element.
497 TypeNode *ElementType = nullptr;
498};
499
500struct IntrinsicNode : public TypeNode {
501 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
502 void output(OutputStream &OS, OutputFlags Flags) const override {}
503};
504
505struct CustomTypeNode : public TypeNode {
506 CustomTypeNode() : TypeNode(NodeKind::Custom) {}
507
508 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
509 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
510
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200511 IdentifierNode *Identifier = nullptr;
Andrew Walbran16937d02019-10-22 13:54:20 +0100512};
513
514struct NodeArrayNode : public Node {
515 NodeArrayNode() : Node(NodeKind::NodeArray) {}
516
517 void output(OutputStream &OS, OutputFlags Flags) const override;
518
519 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
520
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100521 Node **Nodes = nullptr;
Andrew Walbran16937d02019-10-22 13:54:20 +0100522 size_t Count = 0;
523};
524
525struct QualifiedNameNode : public Node {
526 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
527
528 void output(OutputStream &OS, OutputFlags Flags) const override;
529
530 NodeArrayNode *Components = nullptr;
531
532 IdentifierNode *getUnqualifiedIdentifier() {
533 Node *LastComponent = Components->Nodes[Components->Count - 1];
534 return static_cast<IdentifierNode *>(LastComponent);
535 }
536};
537
538struct TemplateParameterReferenceNode : public Node {
539 TemplateParameterReferenceNode()
540 : Node(NodeKind::TemplateParameterReference) {}
541
542 void output(OutputStream &OS, OutputFlags Flags) const override;
543
544 SymbolNode *Symbol = nullptr;
545
546 int ThunkOffsetCount = 0;
547 std::array<int64_t, 3> ThunkOffsets;
548 PointerAffinity Affinity = PointerAffinity::None;
549 bool IsMemberPointer = false;
550};
551
552struct IntegerLiteralNode : public Node {
553 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
554 IntegerLiteralNode(uint64_t Value, bool IsNegative)
555 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
556
557 void output(OutputStream &OS, OutputFlags Flags) const override;
558
559 uint64_t Value = 0;
560 bool IsNegative = false;
561};
562
563struct RttiBaseClassDescriptorNode : public IdentifierNode {
564 RttiBaseClassDescriptorNode()
565 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
566
567 void output(OutputStream &OS, OutputFlags Flags) const override;
568
569 uint32_t NVOffset = 0;
570 int32_t VBPtrOffset = 0;
571 uint32_t VBTableOffset = 0;
572 uint32_t Flags = 0;
573};
574
575struct SymbolNode : public Node {
576 explicit SymbolNode(NodeKind K) : Node(K) {}
577 void output(OutputStream &OS, OutputFlags Flags) const override;
578 QualifiedNameNode *Name = nullptr;
579};
580
581struct SpecialTableSymbolNode : public SymbolNode {
582 explicit SpecialTableSymbolNode()
583 : SymbolNode(NodeKind::SpecialTableSymbol) {}
584
585 void output(OutputStream &OS, OutputFlags Flags) const override;
586 QualifiedNameNode *TargetName = nullptr;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200587 Qualifiers Quals = Qualifiers::Q_None;
Andrew Walbran16937d02019-10-22 13:54:20 +0100588};
589
590struct LocalStaticGuardVariableNode : public SymbolNode {
591 LocalStaticGuardVariableNode()
592 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
593
594 void output(OutputStream &OS, OutputFlags Flags) const override;
595
596 bool IsVisible = false;
597};
598
599struct EncodedStringLiteralNode : public SymbolNode {
600 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
601
602 void output(OutputStream &OS, OutputFlags Flags) const override;
603
604 StringView DecodedString;
605 bool IsTruncated = false;
606 CharKind Char = CharKind::Char;
607};
608
609struct VariableSymbolNode : public SymbolNode {
610 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
611
612 void output(OutputStream &OS, OutputFlags Flags) const override;
613
614 StorageClass SC = StorageClass::None;
615 TypeNode *Type = nullptr;
616};
617
618struct FunctionSymbolNode : public SymbolNode {
619 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
620
621 void output(OutputStream &OS, OutputFlags Flags) const override;
622
623 FunctionSignatureNode *Signature = nullptr;
624};
625
626} // namespace ms_demangle
627} // namespace llvm
628
629#endif