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