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