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