[PowerPC] Do not emit record-form rotates when record-form andi/andis suffices
[llvm-core.git] / lib / Demangle / MicrosoftDemangleNodes.h
blobcaa7eb3b5262bcb86a62e0efb9173d3bc94cb413
1 #ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
2 #define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
4 #include "llvm/Demangle/Compiler.h"
5 #include "llvm/Demangle/StringView.h"
6 #include <array>
8 class OutputStream;
10 namespace llvm {
11 namespace ms_demangle {
13 // This memory allocator is extremely fast, but it doesn't call dtors
14 // for allocated objects. That means you can't use STL containers
15 // (such as std::vector) with this allocator. But it pays off --
16 // the demangler is 3x faster with this allocator compared to one with
17 // STL containers.
18 constexpr size_t AllocUnit = 4096;
20 class ArenaAllocator {
21 struct AllocatorNode {
22 uint8_t *Buf = nullptr;
23 size_t Used = 0;
24 size_t Capacity = 0;
25 AllocatorNode *Next = nullptr;
28 void addNode(size_t Capacity) {
29 AllocatorNode *NewHead = new AllocatorNode;
30 NewHead->Buf = new uint8_t[Capacity];
31 NewHead->Next = Head;
32 NewHead->Capacity = Capacity;
33 Head = NewHead;
34 NewHead->Used = 0;
37 public:
38 ArenaAllocator() { addNode(AllocUnit); }
40 ~ArenaAllocator() {
41 while (Head) {
42 assert(Head->Buf);
43 delete[] Head->Buf;
44 AllocatorNode *Next = Head->Next;
45 delete Head;
46 Head = Next;
50 char *allocUnalignedBuffer(size_t Length) {
51 uint8_t *Buf = Head->Buf + Head->Used;
53 Head->Used += Length;
54 if (Head->Used > Head->Capacity) {
55 // It's possible we need a buffer which is larger than our default unit
56 // size, so we need to be careful to add a node with capacity that is at
57 // least as large as what we need.
58 addNode(std::max(AllocUnit, Length));
59 Head->Used = Length;
60 Buf = Head->Buf;
63 return reinterpret_cast<char *>(Buf);
66 template <typename T, typename... Args>
67 T *allocArray(size_t Count) {
69 size_t Size = Count * sizeof(T);
70 assert(Head && Head->Buf);
72 size_t P = (size_t)Head->Buf + Head->Used;
73 uintptr_t AlignedP =
74 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
75 uint8_t *PP = (uint8_t *)AlignedP;
76 size_t Adjustment = AlignedP - P;
78 Head->Used += Size + Adjustment;
79 if (Head->Used < Head->Capacity)
80 return new (PP) T[Count]();
82 addNode(AllocUnit);
83 Head->Used = Size;
84 return new (Head->Buf) T[Count]();
87 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
89 size_t Size = sizeof(T);
90 assert(Head && Head->Buf);
92 size_t P = (size_t)Head->Buf + Head->Used;
93 uintptr_t AlignedP =
94 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
95 uint8_t *PP = (uint8_t *)AlignedP;
96 size_t Adjustment = AlignedP - P;
98 Head->Used += Size + Adjustment;
99 if (Head->Used < Head->Capacity)
100 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
102 addNode(AllocUnit);
103 Head->Used = Size;
104 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
107 private:
108 AllocatorNode *Head = nullptr;
111 // Storage classes
112 enum Qualifiers : uint8_t {
113 Q_None = 0,
114 Q_Const = 1 << 0,
115 Q_Volatile = 1 << 1,
116 Q_Far = 1 << 2,
117 Q_Huge = 1 << 3,
118 Q_Unaligned = 1 << 4,
119 Q_Restrict = 1 << 5,
120 Q_Pointer64 = 1 << 6
123 enum class StorageClass : uint8_t {
124 None,
125 PrivateStatic,
126 ProtectedStatic,
127 PublicStatic,
128 Global,
129 FunctionLocalStatic,
132 enum class PointerAffinity { None, Pointer, Reference, RValueReference };
133 enum class FunctionRefQualifier { None, Reference, RValueReference };
135 // Calling conventions
136 enum class CallingConv : uint8_t {
137 None,
138 Cdecl,
139 Pascal,
140 Thiscall,
141 Stdcall,
142 Fastcall,
143 Clrcall,
144 Eabi,
145 Vectorcall,
146 Regcall,
149 enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
151 enum OutputFlags {
152 OF_Default = 0,
153 OF_NoCallingConvention = 1,
156 // Types
157 enum class PrimitiveKind {
158 Void,
159 Bool,
160 Char,
161 Schar,
162 Uchar,
163 Char16,
164 Char32,
165 Short,
166 Ushort,
167 Int,
168 Uint,
169 Long,
170 Ulong,
171 Int64,
172 Uint64,
173 Wchar,
174 Float,
175 Double,
176 Ldouble,
177 Nullptr,
180 enum class CharKind {
181 Char,
182 Char16,
183 Char32,
184 Wchar,
187 enum class IntrinsicFunctionKind : uint8_t {
188 None,
189 New, // ?2 # operator new
190 Delete, // ?3 # operator delete
191 Assign, // ?4 # operator=
192 RightShift, // ?5 # operator>>
193 LeftShift, // ?6 # operator<<
194 LogicalNot, // ?7 # operator!
195 Equals, // ?8 # operator==
196 NotEquals, // ?9 # operator!=
197 ArraySubscript, // ?A # operator[]
198 Pointer, // ?C # operator->
199 Dereference, // ?D # operator*
200 Increment, // ?E # operator++
201 Decrement, // ?F # operator--
202 Minus, // ?G # operator-
203 Plus, // ?H # operator+
204 BitwiseAnd, // ?I # operator&
205 MemberPointer, // ?J # operator->*
206 Divide, // ?K # operator/
207 Modulus, // ?L # operator%
208 LessThan, // ?M operator<
209 LessThanEqual, // ?N operator<=
210 GreaterThan, // ?O operator>
211 GreaterThanEqual, // ?P operator>=
212 Comma, // ?Q operator,
213 Parens, // ?R operator()
214 BitwiseNot, // ?S operator~
215 BitwiseXor, // ?T operator^
216 BitwiseOr, // ?U operator|
217 LogicalAnd, // ?V operator&&
218 LogicalOr, // ?W operator||
219 TimesEqual, // ?X operator*=
220 PlusEqual, // ?Y operator+=
221 MinusEqual, // ?Z operator-=
222 DivEqual, // ?_0 operator/=
223 ModEqual, // ?_1 operator%=
224 RshEqual, // ?_2 operator>>=
225 LshEqual, // ?_3 operator<<=
226 BitwiseAndEqual, // ?_4 operator&=
227 BitwiseOrEqual, // ?_5 operator|=
228 BitwiseXorEqual, // ?_6 operator^=
229 VbaseDtor, // ?_D # vbase destructor
230 VecDelDtor, // ?_E # vector deleting destructor
231 DefaultCtorClosure, // ?_F # default constructor closure
232 ScalarDelDtor, // ?_G # scalar deleting destructor
233 VecCtorIter, // ?_H # vector constructor iterator
234 VecDtorIter, // ?_I # vector destructor iterator
235 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
236 VdispMap, // ?_K # virtual displacement map
237 EHVecCtorIter, // ?_L # eh vector constructor iterator
238 EHVecDtorIter, // ?_M # eh vector destructor iterator
239 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
240 CopyCtorClosure, // ?_O # copy constructor closure
241 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
242 ArrayNew, // ?_U operator new[]
243 ArrayDelete, // ?_V operator delete[]
244 ManVectorCtorIter, // ?__A managed vector ctor iterator
245 ManVectorDtorIter, // ?__B managed vector dtor iterator
246 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
247 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
248 VectorCopyCtorIter, // ?__G vector copy constructor iterator
249 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
250 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
251 CoAwait, // ?__L co_await
252 Spaceship, // operator<=>
253 MaxIntrinsic
256 enum class SpecialIntrinsicKind {
257 None,
258 Vftable,
259 Vbtable,
260 Typeof,
261 VcallThunk,
262 LocalStaticGuard,
263 StringLiteralSymbol,
264 UdtReturning,
265 Unknown,
266 DynamicInitializer,
267 DynamicAtexitDestructor,
268 RttiTypeDescriptor,
269 RttiBaseClassDescriptor,
270 RttiBaseClassArray,
271 RttiClassHierarchyDescriptor,
272 RttiCompleteObjLocator,
273 LocalVftable,
274 LocalStaticThreadGuard,
277 // Function classes
278 enum FuncClass : uint16_t {
279 FC_None = 0,
280 FC_Public = 1 << 0,
281 FC_Protected = 1 << 1,
282 FC_Private = 1 << 2,
283 FC_Global = 1 << 3,
284 FC_Static = 1 << 4,
285 FC_Virtual = 1 << 5,
286 FC_Far = 1 << 6,
287 FC_ExternC = 1 << 7,
288 FC_NoParameterList = 1 << 8,
289 FC_VirtualThisAdjust = 1 << 9,
290 FC_VirtualThisAdjustEx = 1 << 10,
291 FC_StaticThisAdjust = 1 << 11,
294 enum class TagKind { Class, Struct, Union, Enum };
296 enum class NodeKind {
297 Unknown,
298 Md5Symbol,
299 PrimitiveType,
300 FunctionSignature,
301 Identifier,
302 NamedIdentifier,
303 VcallThunkIdentifier,
304 LocalStaticGuardIdentifier,
305 IntrinsicFunctionIdentifier,
306 ConversionOperatorIdentifier,
307 DynamicStructorIdentifier,
308 StructorIdentifier,
309 LiteralOperatorIdentifier,
310 ThunkSignature,
311 PointerType,
312 TagType,
313 ArrayType,
314 Custom,
315 IntrinsicType,
316 NodeArray,
317 QualifiedName,
318 TemplateParameterReference,
319 EncodedStringLiteral,
320 IntegerLiteral,
321 RttiBaseClassDescriptor,
322 LocalStaticGuardVariable,
323 FunctionSymbol,
324 VariableSymbol,
325 SpecialTableSymbol
328 struct Node {
329 explicit Node(NodeKind K) : Kind(K) {}
330 virtual ~Node() = default;
332 NodeKind kind() const { return Kind; }
334 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
336 private:
337 NodeKind Kind;
340 struct TypeNode;
341 struct PrimitiveTypeNode;
342 struct FunctionSignatureNode;
343 struct IdentifierNode;
344 struct NamedIdentifierNode;
345 struct VcallThunkIdentifierNode;
346 struct IntrinsicFunctionIdentifierNode;
347 struct LiteralOperatorIdentifierNode;
348 struct ConversionOperatorIdentifierNode;
349 struct StructorIdentifierNode;
350 struct ThunkSignatureNode;
351 struct PointerTypeNode;
352 struct ArrayTypeNode;
353 struct CustomNode;
354 struct TagTypeNode;
355 struct IntrinsicTypeNode;
356 struct NodeArrayNode;
357 struct QualifiedNameNode;
358 struct TemplateParameterReferenceNode;
359 struct EncodedStringLiteralNode;
360 struct IntegerLiteralNode;
361 struct RttiBaseClassDescriptorNode;
362 struct LocalStaticGuardVariableNode;
363 struct SymbolNode;
364 struct FunctionSymbolNode;
365 struct VariableSymbolNode;
366 struct SpecialTableSymbolNode;
368 struct TypeNode : public Node {
369 explicit TypeNode(NodeKind K) : Node(K) {}
371 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
372 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
374 void output(OutputStream &OS, OutputFlags Flags) const override {
375 outputPre(OS, Flags);
376 outputPost(OS, Flags);
379 void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
381 Qualifiers Quals = Q_None;
384 struct PrimitiveTypeNode : public TypeNode {
385 explicit PrimitiveTypeNode(PrimitiveKind K)
386 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
388 void outputPre(OutputStream &OS, OutputFlags Flags) const;
389 void outputPost(OutputStream &OS, OutputFlags Flags) const {}
391 PrimitiveKind PrimKind;
394 struct FunctionSignatureNode : public TypeNode {
395 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
396 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
398 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
399 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
401 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
402 // MemberPointerType.
403 PointerAffinity Affinity = PointerAffinity::None;
405 // The function's calling convention.
406 CallingConv CallConvention = CallingConv::None;
408 // Function flags (gloabl, public, etc)
409 FuncClass FunctionClass = FC_Global;
411 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
413 // The return type of the function.
414 TypeNode *ReturnType = nullptr;
416 // True if this is a C-style ... varargs function.
417 bool IsVariadic = false;
419 // Function parameters
420 NodeArrayNode *Params = nullptr;
423 struct IdentifierNode : public Node {
424 explicit IdentifierNode(NodeKind K) : Node(K) {}
426 NodeArrayNode *TemplateParams = nullptr;
428 protected:
429 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
432 struct VcallThunkIdentifierNode : public IdentifierNode {
433 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
435 void output(OutputStream &OS, OutputFlags Flags) const override;
437 uint64_t OffsetInVTable = 0;
440 struct DynamicStructorIdentifierNode : public IdentifierNode {
441 DynamicStructorIdentifierNode()
442 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
444 void output(OutputStream &OS, OutputFlags Flags) const override;
446 VariableSymbolNode *Variable = nullptr;
447 QualifiedNameNode *Name = nullptr;
448 bool IsDestructor = false;
451 struct NamedIdentifierNode : public IdentifierNode {
452 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
454 void output(OutputStream &OS, OutputFlags Flags) const override;
456 StringView Name;
459 struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
460 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
461 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
462 Operator(Operator) {}
464 void output(OutputStream &OS, OutputFlags Flags) const override;
466 IntrinsicFunctionKind Operator;
469 struct LiteralOperatorIdentifierNode : public IdentifierNode {
470 LiteralOperatorIdentifierNode()
471 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
473 void output(OutputStream &OS, OutputFlags Flags) const override;
475 StringView Name;
478 struct LocalStaticGuardIdentifierNode : public IdentifierNode {
479 LocalStaticGuardIdentifierNode()
480 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
482 void output(OutputStream &OS, OutputFlags Flags) const override;
484 uint32_t ScopeIndex = 0;
487 struct ConversionOperatorIdentifierNode : public IdentifierNode {
488 ConversionOperatorIdentifierNode()
489 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
491 void output(OutputStream &OS, OutputFlags Flags) const override;
493 // The type that this operator converts too.
494 TypeNode *TargetType = nullptr;
497 struct StructorIdentifierNode : public IdentifierNode {
498 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
499 explicit StructorIdentifierNode(bool IsDestructor)
500 : IdentifierNode(NodeKind::StructorIdentifier),
501 IsDestructor(IsDestructor) {}
503 void output(OutputStream &OS, OutputFlags Flags) const override;
505 // The name of the class that this is a structor of.
506 IdentifierNode *Class = nullptr;
507 bool IsDestructor = false;
510 struct ThunkSignatureNode : public FunctionSignatureNode {
511 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
513 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
514 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
516 struct ThisAdjustor {
517 uint32_t StaticOffset = 0;
518 int32_t VBPtrOffset = 0;
519 int32_t VBOffsetOffset = 0;
520 int32_t VtordispOffset = 0;
523 ThisAdjustor ThisAdjust;
526 struct PointerTypeNode : public TypeNode {
527 PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
528 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
529 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
531 // Is this a pointer, reference, or rvalue-reference?
532 PointerAffinity Affinity = PointerAffinity::None;
534 // If this is a member pointer, this is the class that the member is in.
535 QualifiedNameNode *ClassParent = nullptr;
537 // Represents a type X in "a pointer to X", "a reference to X", or
538 // "rvalue-reference to X"
539 TypeNode *Pointee = nullptr;
542 struct TagTypeNode : public TypeNode {
543 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
545 void outputPre(OutputStream &OS, OutputFlags Flags) const;
546 void outputPost(OutputStream &OS, OutputFlags Flags) const;
548 QualifiedNameNode *QualifiedName = nullptr;
549 TagKind Tag;
552 struct ArrayTypeNode : public TypeNode {
553 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
555 void outputPre(OutputStream &OS, OutputFlags Flags) const;
556 void outputPost(OutputStream &OS, OutputFlags Flags) const;
558 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
559 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
561 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
562 NodeArrayNode *Dimensions = nullptr;
564 // The type of array element.
565 TypeNode *ElementType = nullptr;
568 struct IntrinsicNode : public TypeNode {
569 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
570 void output(OutputStream &OS, OutputFlags Flags) const override {}
573 struct CustomTypeNode : public TypeNode {
574 CustomTypeNode() : TypeNode(NodeKind::Custom) {}
576 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
577 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
579 IdentifierNode *Identifier;
582 struct NodeArrayNode : public Node {
583 NodeArrayNode() : Node(NodeKind::NodeArray) {}
585 void output(OutputStream &OS, OutputFlags Flags) const override;
587 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
589 Node **Nodes = 0;
590 size_t Count = 0;
593 struct QualifiedNameNode : public Node {
594 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
596 void output(OutputStream &OS, OutputFlags Flags) const override;
598 NodeArrayNode *Components = nullptr;
600 IdentifierNode *getUnqualifiedIdentifier() {
601 Node *LastComponent = Components->Nodes[Components->Count - 1];
602 return static_cast<IdentifierNode *>(LastComponent);
606 struct TemplateParameterReferenceNode : public Node {
607 TemplateParameterReferenceNode()
608 : Node(NodeKind::TemplateParameterReference) {}
610 void output(OutputStream &OS, OutputFlags Flags) const override;
612 SymbolNode *Symbol = nullptr;
614 int ThunkOffsetCount = 0;
615 std::array<int64_t, 3> ThunkOffsets;
616 PointerAffinity Affinity = PointerAffinity::None;
617 bool IsMemberPointer = false;
620 struct IntegerLiteralNode : public Node {
621 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
622 IntegerLiteralNode(uint64_t Value, bool IsNegative)
623 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
625 void output(OutputStream &OS, OutputFlags Flags) const override;
627 uint64_t Value = 0;
628 bool IsNegative = false;
631 struct RttiBaseClassDescriptorNode : public IdentifierNode {
632 RttiBaseClassDescriptorNode()
633 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
635 void output(OutputStream &OS, OutputFlags Flags) const override;
637 uint32_t NVOffset = 0;
638 int32_t VBPtrOffset = 0;
639 uint32_t VBTableOffset = 0;
640 uint32_t Flags = 0;
643 struct SymbolNode : public Node {
644 explicit SymbolNode(NodeKind K) : Node(K) {}
645 void output(OutputStream &OS, OutputFlags Flags) const override;
646 QualifiedNameNode *Name = nullptr;
649 struct SpecialTableSymbolNode : public SymbolNode {
650 explicit SpecialTableSymbolNode()
651 : SymbolNode(NodeKind::SpecialTableSymbol) {}
653 void output(OutputStream &OS, OutputFlags Flags) const override;
654 QualifiedNameNode *TargetName = nullptr;
655 Qualifiers Quals;
658 struct LocalStaticGuardVariableNode : public SymbolNode {
659 LocalStaticGuardVariableNode()
660 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
662 void output(OutputStream &OS, OutputFlags Flags) const override;
664 bool IsVisible = false;
667 struct EncodedStringLiteralNode : public SymbolNode {
668 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
670 void output(OutputStream &OS, OutputFlags Flags) const override;
672 StringView DecodedString;
673 bool IsTruncated = false;
674 CharKind Char = CharKind::Char;
677 struct VariableSymbolNode : public SymbolNode {
678 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
680 void output(OutputStream &OS, OutputFlags Flags) const override;
682 StorageClass SC = StorageClass::None;
683 TypeNode *Type = nullptr;
686 struct FunctionSymbolNode : public SymbolNode {
687 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
689 void output(OutputStream &OS, OutputFlags Flags) const override;
691 FunctionSignatureNode *Signature = nullptr;
694 } // namespace ms_demangle
695 } // namespace llvm
697 #endif