blob: da9d9d5bfdc0c171062575f07104c1751c384edc [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>
19
20namespace llvm {
21namespace itanium_demangle {
22class OutputStream;
23}
24}
25
26using llvm::itanium_demangle::OutputStream;
27using llvm::itanium_demangle::StringView;
28
29namespace llvm {
30namespace ms_demangle {
31
32// Storage classes
33enum Qualifiers : uint8_t {
34 Q_None = 0,
35 Q_Const = 1 << 0,
36 Q_Volatile = 1 << 1,
37 Q_Far = 1 << 2,
38 Q_Huge = 1 << 3,
39 Q_Unaligned = 1 << 4,
40 Q_Restrict = 1 << 5,
41 Q_Pointer64 = 1 << 6
42};
43
44enum class StorageClass : uint8_t {
45 None,
46 PrivateStatic,
47 ProtectedStatic,
48 PublicStatic,
49 Global,
50 FunctionLocalStatic,
51};
52
53enum class PointerAffinity { None, Pointer, Reference, RValueReference };
54enum class FunctionRefQualifier { None, Reference, RValueReference };
55
56// Calling conventions
57enum class CallingConv : uint8_t {
58 None,
59 Cdecl,
60 Pascal,
61 Thiscall,
62 Stdcall,
63 Fastcall,
64 Clrcall,
65 Eabi,
66 Vectorcall,
67 Regcall,
68};
69
70enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
71
72enum OutputFlags {
73 OF_Default = 0,
74 OF_NoCallingConvention = 1,
75 OF_NoTagSpecifier = 2,
76};
77
78// Types
79enum class PrimitiveKind {
80 Void,
81 Bool,
82 Char,
83 Schar,
84 Uchar,
Andrew Walbran3d2c1972020-04-07 12:24:26 +010085 Char8,
Andrew Walbran16937d02019-10-22 13:54:20 +010086 Char16,
87 Char32,
88 Short,
89 Ushort,
90 Int,
91 Uint,
92 Long,
93 Ulong,
94 Int64,
95 Uint64,
96 Wchar,
97 Float,
98 Double,
99 Ldouble,
100 Nullptr,
101};
102
103enum class CharKind {
104 Char,
105 Char16,
106 Char32,
107 Wchar,
108};
109
110enum class IntrinsicFunctionKind : uint8_t {
111 None,
112 New, // ?2 # operator new
113 Delete, // ?3 # operator delete
114 Assign, // ?4 # operator=
115 RightShift, // ?5 # operator>>
116 LeftShift, // ?6 # operator<<
117 LogicalNot, // ?7 # operator!
118 Equals, // ?8 # operator==
119 NotEquals, // ?9 # operator!=
120 ArraySubscript, // ?A # operator[]
121 Pointer, // ?C # operator->
122 Dereference, // ?D # operator*
123 Increment, // ?E # operator++
124 Decrement, // ?F # operator--
125 Minus, // ?G # operator-
126 Plus, // ?H # operator+
127 BitwiseAnd, // ?I # operator&
128 MemberPointer, // ?J # operator->*
129 Divide, // ?K # operator/
130 Modulus, // ?L # operator%
131 LessThan, // ?M operator<
132 LessThanEqual, // ?N operator<=
133 GreaterThan, // ?O operator>
134 GreaterThanEqual, // ?P operator>=
135 Comma, // ?Q operator,
136 Parens, // ?R operator()
137 BitwiseNot, // ?S operator~
138 BitwiseXor, // ?T operator^
139 BitwiseOr, // ?U operator|
140 LogicalAnd, // ?V operator&&
141 LogicalOr, // ?W operator||
142 TimesEqual, // ?X operator*=
143 PlusEqual, // ?Y operator+=
144 MinusEqual, // ?Z operator-=
145 DivEqual, // ?_0 operator/=
146 ModEqual, // ?_1 operator%=
147 RshEqual, // ?_2 operator>>=
148 LshEqual, // ?_3 operator<<=
149 BitwiseAndEqual, // ?_4 operator&=
150 BitwiseOrEqual, // ?_5 operator|=
151 BitwiseXorEqual, // ?_6 operator^=
152 VbaseDtor, // ?_D # vbase destructor
153 VecDelDtor, // ?_E # vector deleting destructor
154 DefaultCtorClosure, // ?_F # default constructor closure
155 ScalarDelDtor, // ?_G # scalar deleting destructor
156 VecCtorIter, // ?_H # vector constructor iterator
157 VecDtorIter, // ?_I # vector destructor iterator
158 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
159 VdispMap, // ?_K # virtual displacement map
160 EHVecCtorIter, // ?_L # eh vector constructor iterator
161 EHVecDtorIter, // ?_M # eh vector destructor iterator
162 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
163 CopyCtorClosure, // ?_O # copy constructor closure
164 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
165 ArrayNew, // ?_U operator new[]
166 ArrayDelete, // ?_V operator delete[]
167 ManVectorCtorIter, // ?__A managed vector ctor iterator
168 ManVectorDtorIter, // ?__B managed vector dtor iterator
169 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
170 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
171 VectorCopyCtorIter, // ?__G vector copy constructor iterator
172 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
173 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100174 CoAwait, // ?__L operator co_await
175 Spaceship, // ?__M operator<=>
Andrew Walbran16937d02019-10-22 13:54:20 +0100176 MaxIntrinsic
177};
178
179enum class SpecialIntrinsicKind {
180 None,
181 Vftable,
182 Vbtable,
183 Typeof,
184 VcallThunk,
185 LocalStaticGuard,
186 StringLiteralSymbol,
187 UdtReturning,
188 Unknown,
189 DynamicInitializer,
190 DynamicAtexitDestructor,
191 RttiTypeDescriptor,
192 RttiBaseClassDescriptor,
193 RttiBaseClassArray,
194 RttiClassHierarchyDescriptor,
195 RttiCompleteObjLocator,
196 LocalVftable,
197 LocalStaticThreadGuard,
198};
199
200// Function classes
201enum FuncClass : uint16_t {
202 FC_None = 0,
203 FC_Public = 1 << 0,
204 FC_Protected = 1 << 1,
205 FC_Private = 1 << 2,
206 FC_Global = 1 << 3,
207 FC_Static = 1 << 4,
208 FC_Virtual = 1 << 5,
209 FC_Far = 1 << 6,
210 FC_ExternC = 1 << 7,
211 FC_NoParameterList = 1 << 8,
212 FC_VirtualThisAdjust = 1 << 9,
213 FC_VirtualThisAdjustEx = 1 << 10,
214 FC_StaticThisAdjust = 1 << 11,
215};
216
217enum class TagKind { Class, Struct, Union, Enum };
218
219enum class NodeKind {
220 Unknown,
221 Md5Symbol,
222 PrimitiveType,
223 FunctionSignature,
224 Identifier,
225 NamedIdentifier,
226 VcallThunkIdentifier,
227 LocalStaticGuardIdentifier,
228 IntrinsicFunctionIdentifier,
229 ConversionOperatorIdentifier,
230 DynamicStructorIdentifier,
231 StructorIdentifier,
232 LiteralOperatorIdentifier,
233 ThunkSignature,
234 PointerType,
235 TagType,
236 ArrayType,
237 Custom,
238 IntrinsicType,
239 NodeArray,
240 QualifiedName,
241 TemplateParameterReference,
242 EncodedStringLiteral,
243 IntegerLiteral,
244 RttiBaseClassDescriptor,
245 LocalStaticGuardVariable,
246 FunctionSymbol,
247 VariableSymbol,
248 SpecialTableSymbol
249};
250
251struct Node {
252 explicit Node(NodeKind K) : Kind(K) {}
253 virtual ~Node() = default;
254
255 NodeKind kind() const { return Kind; }
256
257 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
258
259 std::string toString(OutputFlags Flags = OF_Default) const;
260
261private:
262 NodeKind Kind;
263};
264
265struct TypeNode;
266struct PrimitiveTypeNode;
267struct FunctionSignatureNode;
268struct IdentifierNode;
269struct NamedIdentifierNode;
270struct VcallThunkIdentifierNode;
271struct IntrinsicFunctionIdentifierNode;
272struct LiteralOperatorIdentifierNode;
273struct ConversionOperatorIdentifierNode;
274struct StructorIdentifierNode;
275struct ThunkSignatureNode;
276struct PointerTypeNode;
277struct ArrayTypeNode;
278struct CustomNode;
279struct TagTypeNode;
280struct IntrinsicTypeNode;
281struct NodeArrayNode;
282struct QualifiedNameNode;
283struct TemplateParameterReferenceNode;
284struct EncodedStringLiteralNode;
285struct IntegerLiteralNode;
286struct RttiBaseClassDescriptorNode;
287struct LocalStaticGuardVariableNode;
288struct SymbolNode;
289struct FunctionSymbolNode;
290struct VariableSymbolNode;
291struct SpecialTableSymbolNode;
292
293struct TypeNode : public Node {
294 explicit TypeNode(NodeKind K) : Node(K) {}
295
296 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
297 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
298
299 void output(OutputStream &OS, OutputFlags Flags) const override {
300 outputPre(OS, Flags);
301 outputPost(OS, Flags);
302 }
303
304 void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
305
306 Qualifiers Quals = Q_None;
307};
308
309struct PrimitiveTypeNode : public TypeNode {
310 explicit PrimitiveTypeNode(PrimitiveKind K)
311 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
312
313 void outputPre(OutputStream &OS, OutputFlags Flags) const;
314 void outputPost(OutputStream &OS, OutputFlags Flags) const {}
315
316 PrimitiveKind PrimKind;
317};
318
319struct FunctionSignatureNode : public TypeNode {
320 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
321 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
322
323 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
324 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
325
326 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
327 // MemberPointerType.
328 PointerAffinity Affinity = PointerAffinity::None;
329
330 // The function's calling convention.
331 CallingConv CallConvention = CallingConv::None;
332
333 // Function flags (gloabl, public, etc)
334 FuncClass FunctionClass = FC_Global;
335
336 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
337
338 // The return type of the function.
339 TypeNode *ReturnType = nullptr;
340
341 // True if this is a C-style ... varargs function.
342 bool IsVariadic = false;
343
344 // Function parameters
345 NodeArrayNode *Params = nullptr;
346
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100347 // True if the function type is noexcept.
Andrew Walbran16937d02019-10-22 13:54:20 +0100348 bool IsNoexcept = false;
349};
350
351struct IdentifierNode : public Node {
352 explicit IdentifierNode(NodeKind K) : Node(K) {}
353
354 NodeArrayNode *TemplateParams = nullptr;
355
356protected:
357 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
358};
359
360struct VcallThunkIdentifierNode : public IdentifierNode {
361 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
362
363 void output(OutputStream &OS, OutputFlags Flags) const override;
364
365 uint64_t OffsetInVTable = 0;
366};
367
368struct DynamicStructorIdentifierNode : public IdentifierNode {
369 DynamicStructorIdentifierNode()
370 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
371
372 void output(OutputStream &OS, OutputFlags Flags) const override;
373
374 VariableSymbolNode *Variable = nullptr;
375 QualifiedNameNode *Name = nullptr;
376 bool IsDestructor = false;
377};
378
379struct NamedIdentifierNode : public IdentifierNode {
380 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
381
382 void output(OutputStream &OS, OutputFlags Flags) const override;
383
384 StringView Name;
385};
386
387struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
388 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
389 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
390 Operator(Operator) {}
391
392 void output(OutputStream &OS, OutputFlags Flags) const override;
393
394 IntrinsicFunctionKind Operator;
395};
396
397struct LiteralOperatorIdentifierNode : public IdentifierNode {
398 LiteralOperatorIdentifierNode()
399 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
400
401 void output(OutputStream &OS, OutputFlags Flags) const override;
402
403 StringView Name;
404};
405
406struct LocalStaticGuardIdentifierNode : public IdentifierNode {
407 LocalStaticGuardIdentifierNode()
408 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
409
410 void output(OutputStream &OS, OutputFlags Flags) const override;
411
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100412 bool IsThread = false;
Andrew Walbran16937d02019-10-22 13:54:20 +0100413 uint32_t ScopeIndex = 0;
414};
415
416struct ConversionOperatorIdentifierNode : public IdentifierNode {
417 ConversionOperatorIdentifierNode()
418 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
419
420 void output(OutputStream &OS, OutputFlags Flags) const override;
421
422 // The type that this operator converts too.
423 TypeNode *TargetType = nullptr;
424};
425
426struct StructorIdentifierNode : public IdentifierNode {
427 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
428 explicit StructorIdentifierNode(bool IsDestructor)
429 : IdentifierNode(NodeKind::StructorIdentifier),
430 IsDestructor(IsDestructor) {}
431
432 void output(OutputStream &OS, OutputFlags Flags) const override;
433
434 // The name of the class that this is a structor of.
435 IdentifierNode *Class = nullptr;
436 bool IsDestructor = false;
437};
438
439struct ThunkSignatureNode : public FunctionSignatureNode {
440 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
441
442 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
443 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
444
445 struct ThisAdjustor {
446 uint32_t StaticOffset = 0;
447 int32_t VBPtrOffset = 0;
448 int32_t VBOffsetOffset = 0;
449 int32_t VtordispOffset = 0;
450 };
451
452 ThisAdjustor ThisAdjust;
453};
454
455struct 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;
459
460 // Is this a pointer, reference, or rvalue-reference?
461 PointerAffinity Affinity = PointerAffinity::None;
462
463 // If this is a member pointer, this is the class that the member is in.
464 QualifiedNameNode *ClassParent = nullptr;
465
466 // Represents a type X in "a pointer to X", "a reference to X", or
467 // "rvalue-reference to X"
468 TypeNode *Pointee = nullptr;
469};
470
471struct TagTypeNode : public TypeNode {
472 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
473
474 void outputPre(OutputStream &OS, OutputFlags Flags) const;
475 void outputPost(OutputStream &OS, OutputFlags Flags) const;
476
477 QualifiedNameNode *QualifiedName = nullptr;
478 TagKind Tag;
479};
480
481struct ArrayTypeNode : public TypeNode {
482 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
483
484 void outputPre(OutputStream &OS, OutputFlags Flags) const;
485 void outputPost(OutputStream &OS, OutputFlags Flags) const;
486
487 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
488 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
489
490 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
491 NodeArrayNode *Dimensions = nullptr;
492
493 // The type of array element.
494 TypeNode *ElementType = nullptr;
495};
496
497struct IntrinsicNode : public TypeNode {
498 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
499 void output(OutputStream &OS, OutputFlags Flags) const override {}
500};
501
502struct CustomTypeNode : public TypeNode {
503 CustomTypeNode() : TypeNode(NodeKind::Custom) {}
504
505 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
506 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
507
508 IdentifierNode *Identifier;
509};
510
511struct NodeArrayNode : public Node {
512 NodeArrayNode() : Node(NodeKind::NodeArray) {}
513
514 void output(OutputStream &OS, OutputFlags Flags) const override;
515
516 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
517
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100518 Node **Nodes = nullptr;
Andrew Walbran16937d02019-10-22 13:54:20 +0100519 size_t Count = 0;
520};
521
522struct QualifiedNameNode : public Node {
523 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
524
525 void output(OutputStream &OS, OutputFlags Flags) const override;
526
527 NodeArrayNode *Components = nullptr;
528
529 IdentifierNode *getUnqualifiedIdentifier() {
530 Node *LastComponent = Components->Nodes[Components->Count - 1];
531 return static_cast<IdentifierNode *>(LastComponent);
532 }
533};
534
535struct TemplateParameterReferenceNode : public Node {
536 TemplateParameterReferenceNode()
537 : Node(NodeKind::TemplateParameterReference) {}
538
539 void output(OutputStream &OS, OutputFlags Flags) const override;
540
541 SymbolNode *Symbol = nullptr;
542
543 int ThunkOffsetCount = 0;
544 std::array<int64_t, 3> ThunkOffsets;
545 PointerAffinity Affinity = PointerAffinity::None;
546 bool IsMemberPointer = false;
547};
548
549struct IntegerLiteralNode : public Node {
550 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
551 IntegerLiteralNode(uint64_t Value, bool IsNegative)
552 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
553
554 void output(OutputStream &OS, OutputFlags Flags) const override;
555
556 uint64_t Value = 0;
557 bool IsNegative = false;
558};
559
560struct RttiBaseClassDescriptorNode : public IdentifierNode {
561 RttiBaseClassDescriptorNode()
562 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
563
564 void output(OutputStream &OS, OutputFlags Flags) const override;
565
566 uint32_t NVOffset = 0;
567 int32_t VBPtrOffset = 0;
568 uint32_t VBTableOffset = 0;
569 uint32_t Flags = 0;
570};
571
572struct SymbolNode : public Node {
573 explicit SymbolNode(NodeKind K) : Node(K) {}
574 void output(OutputStream &OS, OutputFlags Flags) const override;
575 QualifiedNameNode *Name = nullptr;
576};
577
578struct SpecialTableSymbolNode : public SymbolNode {
579 explicit SpecialTableSymbolNode()
580 : SymbolNode(NodeKind::SpecialTableSymbol) {}
581
582 void output(OutputStream &OS, OutputFlags Flags) const override;
583 QualifiedNameNode *TargetName = nullptr;
584 Qualifiers Quals;
585};
586
587struct LocalStaticGuardVariableNode : public SymbolNode {
588 LocalStaticGuardVariableNode()
589 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
590
591 void output(OutputStream &OS, OutputFlags Flags) const override;
592
593 bool IsVisible = false;
594};
595
596struct EncodedStringLiteralNode : public SymbolNode {
597 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
598
599 void output(OutputStream &OS, OutputFlags Flags) const override;
600
601 StringView DecodedString;
602 bool IsTruncated = false;
603 CharKind Char = CharKind::Char;
604};
605
606struct VariableSymbolNode : public SymbolNode {
607 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
608
609 void output(OutputStream &OS, OutputFlags Flags) const override;
610
611 StorageClass SC = StorageClass::None;
612 TypeNode *Type = nullptr;
613};
614
615struct FunctionSymbolNode : public SymbolNode {
616 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
617
618 void output(OutputStream &OS, OutputFlags Flags) const override;
619
620 FunctionSignatureNode *Signature = nullptr;
621};
622
623} // namespace ms_demangle
624} // namespace llvm
625
626#endif