1353358Sdim//===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
2353358Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353358Sdim//
7353358Sdim//===----------------------------------------------------------------------===//
8353358Sdim//
9353358Sdim// This file defines the AST nodes used in the MSVC demangler.
10353358Sdim//
11353358Sdim//===----------------------------------------------------------------------===//
12353358Sdim
13343171Sdim#ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
14343171Sdim#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
15343171Sdim
16353358Sdim#include "llvm/Demangle/DemangleConfig.h"
17343171Sdim#include "llvm/Demangle/StringView.h"
18343171Sdim#include <array>
19360661Sdim#include <cstdint>
20360661Sdim#include <string>
21343171Sdim
22353358Sdimnamespace llvm {
23353358Sdimnamespace itanium_demangle {
24343171Sdimclass OutputStream;
25353358Sdim}
26353358Sdim}
27343171Sdim
28353358Sdimusing llvm::itanium_demangle::OutputStream;
29353358Sdimusing llvm::itanium_demangle::StringView;
30353358Sdim
31343171Sdimnamespace llvm {
32343171Sdimnamespace ms_demangle {
33343171Sdim
34343171Sdim// Storage classes
35343171Sdimenum Qualifiers : uint8_t {
36343171Sdim  Q_None = 0,
37343171Sdim  Q_Const = 1 << 0,
38343171Sdim  Q_Volatile = 1 << 1,
39343171Sdim  Q_Far = 1 << 2,
40343171Sdim  Q_Huge = 1 << 3,
41343171Sdim  Q_Unaligned = 1 << 4,
42343171Sdim  Q_Restrict = 1 << 5,
43343171Sdim  Q_Pointer64 = 1 << 6
44343171Sdim};
45343171Sdim
46343171Sdimenum class StorageClass : uint8_t {
47343171Sdim  None,
48343171Sdim  PrivateStatic,
49343171Sdim  ProtectedStatic,
50343171Sdim  PublicStatic,
51343171Sdim  Global,
52343171Sdim  FunctionLocalStatic,
53343171Sdim};
54343171Sdim
55343171Sdimenum class PointerAffinity { None, Pointer, Reference, RValueReference };
56343171Sdimenum class FunctionRefQualifier { None, Reference, RValueReference };
57343171Sdim
58343171Sdim// Calling conventions
59343171Sdimenum class CallingConv : uint8_t {
60343171Sdim  None,
61343171Sdim  Cdecl,
62343171Sdim  Pascal,
63343171Sdim  Thiscall,
64343171Sdim  Stdcall,
65343171Sdim  Fastcall,
66343171Sdim  Clrcall,
67343171Sdim  Eabi,
68343171Sdim  Vectorcall,
69343171Sdim  Regcall,
70343171Sdim};
71343171Sdim
72343171Sdimenum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
73343171Sdim
74343171Sdimenum OutputFlags {
75343171Sdim  OF_Default = 0,
76343171Sdim  OF_NoCallingConvention = 1,
77343171Sdim  OF_NoTagSpecifier = 2,
78360784Sdim  OF_NoAccessSpecifier = 4,
79360784Sdim  OF_NoMemberType = 8,
80360784Sdim  OF_NoReturnType = 16,
81343171Sdim};
82343171Sdim
83343171Sdim// Types
84343171Sdimenum class PrimitiveKind {
85343171Sdim  Void,
86343171Sdim  Bool,
87343171Sdim  Char,
88343171Sdim  Schar,
89343171Sdim  Uchar,
90353358Sdim  Char8,
91343171Sdim  Char16,
92343171Sdim  Char32,
93343171Sdim  Short,
94343171Sdim  Ushort,
95343171Sdim  Int,
96343171Sdim  Uint,
97343171Sdim  Long,
98343171Sdim  Ulong,
99343171Sdim  Int64,
100343171Sdim  Uint64,
101343171Sdim  Wchar,
102343171Sdim  Float,
103343171Sdim  Double,
104343171Sdim  Ldouble,
105343171Sdim  Nullptr,
106343171Sdim};
107343171Sdim
108343171Sdimenum class CharKind {
109343171Sdim  Char,
110343171Sdim  Char16,
111343171Sdim  Char32,
112343171Sdim  Wchar,
113343171Sdim};
114343171Sdim
115343171Sdimenum class IntrinsicFunctionKind : uint8_t {
116343171Sdim  None,
117343171Sdim  New,                        // ?2 # operator new
118343171Sdim  Delete,                     // ?3 # operator delete
119343171Sdim  Assign,                     // ?4 # operator=
120343171Sdim  RightShift,                 // ?5 # operator>>
121343171Sdim  LeftShift,                  // ?6 # operator<<
122343171Sdim  LogicalNot,                 // ?7 # operator!
123343171Sdim  Equals,                     // ?8 # operator==
124343171Sdim  NotEquals,                  // ?9 # operator!=
125343171Sdim  ArraySubscript,             // ?A # operator[]
126343171Sdim  Pointer,                    // ?C # operator->
127343171Sdim  Dereference,                // ?D # operator*
128343171Sdim  Increment,                  // ?E # operator++
129343171Sdim  Decrement,                  // ?F # operator--
130343171Sdim  Minus,                      // ?G # operator-
131343171Sdim  Plus,                       // ?H # operator+
132343171Sdim  BitwiseAnd,                 // ?I # operator&
133343171Sdim  MemberPointer,              // ?J # operator->*
134343171Sdim  Divide,                     // ?K # operator/
135343171Sdim  Modulus,                    // ?L # operator%
136343171Sdim  LessThan,                   // ?M operator<
137343171Sdim  LessThanEqual,              // ?N operator<=
138343171Sdim  GreaterThan,                // ?O operator>
139343171Sdim  GreaterThanEqual,           // ?P operator>=
140343171Sdim  Comma,                      // ?Q operator,
141343171Sdim  Parens,                     // ?R operator()
142343171Sdim  BitwiseNot,                 // ?S operator~
143343171Sdim  BitwiseXor,                 // ?T operator^
144343171Sdim  BitwiseOr,                  // ?U operator|
145343171Sdim  LogicalAnd,                 // ?V operator&&
146343171Sdim  LogicalOr,                  // ?W operator||
147343171Sdim  TimesEqual,                 // ?X operator*=
148343171Sdim  PlusEqual,                  // ?Y operator+=
149343171Sdim  MinusEqual,                 // ?Z operator-=
150343171Sdim  DivEqual,                   // ?_0 operator/=
151343171Sdim  ModEqual,                   // ?_1 operator%=
152343171Sdim  RshEqual,                   // ?_2 operator>>=
153343171Sdim  LshEqual,                   // ?_3 operator<<=
154343171Sdim  BitwiseAndEqual,            // ?_4 operator&=
155343171Sdim  BitwiseOrEqual,             // ?_5 operator|=
156343171Sdim  BitwiseXorEqual,            // ?_6 operator^=
157343171Sdim  VbaseDtor,                  // ?_D # vbase destructor
158343171Sdim  VecDelDtor,                 // ?_E # vector deleting destructor
159343171Sdim  DefaultCtorClosure,         // ?_F # default constructor closure
160343171Sdim  ScalarDelDtor,              // ?_G # scalar deleting destructor
161343171Sdim  VecCtorIter,                // ?_H # vector constructor iterator
162343171Sdim  VecDtorIter,                // ?_I # vector destructor iterator
163343171Sdim  VecVbaseCtorIter,           // ?_J # vector vbase constructor iterator
164343171Sdim  VdispMap,                   // ?_K # virtual displacement map
165343171Sdim  EHVecCtorIter,              // ?_L # eh vector constructor iterator
166343171Sdim  EHVecDtorIter,              // ?_M # eh vector destructor iterator
167343171Sdim  EHVecVbaseCtorIter,         // ?_N # eh vector vbase constructor iterator
168343171Sdim  CopyCtorClosure,            // ?_O # copy constructor closure
169343171Sdim  LocalVftableCtorClosure,    // ?_T # local vftable constructor closure
170343171Sdim  ArrayNew,                   // ?_U operator new[]
171343171Sdim  ArrayDelete,                // ?_V operator delete[]
172343171Sdim  ManVectorCtorIter,          // ?__A managed vector ctor iterator
173343171Sdim  ManVectorDtorIter,          // ?__B managed vector dtor iterator
174343171Sdim  EHVectorCopyCtorIter,       // ?__C EH vector copy ctor iterator
175343171Sdim  EHVectorVbaseCopyCtorIter,  // ?__D EH vector vbase copy ctor iterator
176343171Sdim  VectorCopyCtorIter,         // ?__G vector copy constructor iterator
177343171Sdim  VectorVbaseCopyCtorIter,    // ?__H vector vbase copy constructor iterator
178343171Sdim  ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
179353358Sdim  CoAwait,                    // ?__L operator co_await
180353358Sdim  Spaceship,                  // ?__M operator<=>
181343171Sdim  MaxIntrinsic
182343171Sdim};
183343171Sdim
184343171Sdimenum class SpecialIntrinsicKind {
185343171Sdim  None,
186343171Sdim  Vftable,
187343171Sdim  Vbtable,
188343171Sdim  Typeof,
189343171Sdim  VcallThunk,
190343171Sdim  LocalStaticGuard,
191343171Sdim  StringLiteralSymbol,
192343171Sdim  UdtReturning,
193343171Sdim  Unknown,
194343171Sdim  DynamicInitializer,
195343171Sdim  DynamicAtexitDestructor,
196343171Sdim  RttiTypeDescriptor,
197343171Sdim  RttiBaseClassDescriptor,
198343171Sdim  RttiBaseClassArray,
199343171Sdim  RttiClassHierarchyDescriptor,
200343171Sdim  RttiCompleteObjLocator,
201343171Sdim  LocalVftable,
202343171Sdim  LocalStaticThreadGuard,
203343171Sdim};
204343171Sdim
205343171Sdim// Function classes
206343171Sdimenum FuncClass : uint16_t {
207343171Sdim  FC_None = 0,
208343171Sdim  FC_Public = 1 << 0,
209343171Sdim  FC_Protected = 1 << 1,
210343171Sdim  FC_Private = 1 << 2,
211343171Sdim  FC_Global = 1 << 3,
212343171Sdim  FC_Static = 1 << 4,
213343171Sdim  FC_Virtual = 1 << 5,
214343171Sdim  FC_Far = 1 << 6,
215343171Sdim  FC_ExternC = 1 << 7,
216343171Sdim  FC_NoParameterList = 1 << 8,
217343171Sdim  FC_VirtualThisAdjust = 1 << 9,
218343171Sdim  FC_VirtualThisAdjustEx = 1 << 10,
219343171Sdim  FC_StaticThisAdjust = 1 << 11,
220343171Sdim};
221343171Sdim
222343171Sdimenum class TagKind { Class, Struct, Union, Enum };
223343171Sdim
224343171Sdimenum class NodeKind {
225343171Sdim  Unknown,
226343171Sdim  Md5Symbol,
227343171Sdim  PrimitiveType,
228343171Sdim  FunctionSignature,
229343171Sdim  Identifier,
230343171Sdim  NamedIdentifier,
231343171Sdim  VcallThunkIdentifier,
232343171Sdim  LocalStaticGuardIdentifier,
233343171Sdim  IntrinsicFunctionIdentifier,
234343171Sdim  ConversionOperatorIdentifier,
235343171Sdim  DynamicStructorIdentifier,
236343171Sdim  StructorIdentifier,
237343171Sdim  LiteralOperatorIdentifier,
238343171Sdim  ThunkSignature,
239343171Sdim  PointerType,
240343171Sdim  TagType,
241343171Sdim  ArrayType,
242343171Sdim  Custom,
243343171Sdim  IntrinsicType,
244343171Sdim  NodeArray,
245343171Sdim  QualifiedName,
246343171Sdim  TemplateParameterReference,
247343171Sdim  EncodedStringLiteral,
248343171Sdim  IntegerLiteral,
249343171Sdim  RttiBaseClassDescriptor,
250343171Sdim  LocalStaticGuardVariable,
251343171Sdim  FunctionSymbol,
252343171Sdim  VariableSymbol,
253343171Sdim  SpecialTableSymbol
254343171Sdim};
255343171Sdim
256343171Sdimstruct Node {
257343171Sdim  explicit Node(NodeKind K) : Kind(K) {}
258343171Sdim  virtual ~Node() = default;
259343171Sdim
260343171Sdim  NodeKind kind() const { return Kind; }
261343171Sdim
262343171Sdim  virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
263343171Sdim
264343171Sdim  std::string toString(OutputFlags Flags = OF_Default) const;
265343171Sdim
266343171Sdimprivate:
267343171Sdim  NodeKind Kind;
268343171Sdim};
269343171Sdim
270343171Sdimstruct TypeNode;
271343171Sdimstruct PrimitiveTypeNode;
272343171Sdimstruct FunctionSignatureNode;
273343171Sdimstruct IdentifierNode;
274343171Sdimstruct NamedIdentifierNode;
275343171Sdimstruct VcallThunkIdentifierNode;
276343171Sdimstruct IntrinsicFunctionIdentifierNode;
277343171Sdimstruct LiteralOperatorIdentifierNode;
278343171Sdimstruct ConversionOperatorIdentifierNode;
279343171Sdimstruct StructorIdentifierNode;
280343171Sdimstruct ThunkSignatureNode;
281343171Sdimstruct PointerTypeNode;
282343171Sdimstruct ArrayTypeNode;
283343171Sdimstruct CustomNode;
284343171Sdimstruct TagTypeNode;
285343171Sdimstruct IntrinsicTypeNode;
286343171Sdimstruct NodeArrayNode;
287343171Sdimstruct QualifiedNameNode;
288343171Sdimstruct TemplateParameterReferenceNode;
289343171Sdimstruct EncodedStringLiteralNode;
290343171Sdimstruct IntegerLiteralNode;
291343171Sdimstruct RttiBaseClassDescriptorNode;
292343171Sdimstruct LocalStaticGuardVariableNode;
293343171Sdimstruct SymbolNode;
294343171Sdimstruct FunctionSymbolNode;
295343171Sdimstruct VariableSymbolNode;
296343171Sdimstruct SpecialTableSymbolNode;
297343171Sdim
298343171Sdimstruct TypeNode : public Node {
299343171Sdim  explicit TypeNode(NodeKind K) : Node(K) {}
300343171Sdim
301343171Sdim  virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
302343171Sdim  virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
303343171Sdim
304343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override {
305343171Sdim    outputPre(OS, Flags);
306343171Sdim    outputPost(OS, Flags);
307343171Sdim  }
308343171Sdim
309343171Sdim  Qualifiers Quals = Q_None;
310343171Sdim};
311343171Sdim
312343171Sdimstruct PrimitiveTypeNode : public TypeNode {
313343171Sdim  explicit PrimitiveTypeNode(PrimitiveKind K)
314343171Sdim      : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
315343171Sdim
316343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const;
317343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const {}
318343171Sdim
319343171Sdim  PrimitiveKind PrimKind;
320343171Sdim};
321343171Sdim
322343171Sdimstruct FunctionSignatureNode : public TypeNode {
323343171Sdim  explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
324343171Sdim  FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
325343171Sdim
326343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const override;
327343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const override;
328343171Sdim
329343171Sdim  // Valid if this FunctionTypeNode is the Pointee of a PointerType or
330343171Sdim  // MemberPointerType.
331343171Sdim  PointerAffinity Affinity = PointerAffinity::None;
332343171Sdim
333343171Sdim  // The function's calling convention.
334343171Sdim  CallingConv CallConvention = CallingConv::None;
335343171Sdim
336343171Sdim  // Function flags (gloabl, public, etc)
337343171Sdim  FuncClass FunctionClass = FC_Global;
338343171Sdim
339343171Sdim  FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
340343171Sdim
341343171Sdim  // The return type of the function.
342343171Sdim  TypeNode *ReturnType = nullptr;
343343171Sdim
344343171Sdim  // True if this is a C-style ... varargs function.
345343171Sdim  bool IsVariadic = false;
346343171Sdim
347343171Sdim  // Function parameters
348343171Sdim  NodeArrayNode *Params = nullptr;
349343171Sdim
350353358Sdim  // True if the function type is noexcept.
351343171Sdim  bool IsNoexcept = false;
352343171Sdim};
353343171Sdim
354343171Sdimstruct IdentifierNode : public Node {
355343171Sdim  explicit IdentifierNode(NodeKind K) : Node(K) {}
356343171Sdim
357343171Sdim  NodeArrayNode *TemplateParams = nullptr;
358343171Sdim
359343171Sdimprotected:
360343171Sdim  void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
361343171Sdim};
362343171Sdim
363343171Sdimstruct VcallThunkIdentifierNode : public IdentifierNode {
364343171Sdim  VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
365343171Sdim
366343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
367343171Sdim
368343171Sdim  uint64_t OffsetInVTable = 0;
369343171Sdim};
370343171Sdim
371343171Sdimstruct DynamicStructorIdentifierNode : public IdentifierNode {
372343171Sdim  DynamicStructorIdentifierNode()
373343171Sdim      : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
374343171Sdim
375343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
376343171Sdim
377343171Sdim  VariableSymbolNode *Variable = nullptr;
378343171Sdim  QualifiedNameNode *Name = nullptr;
379343171Sdim  bool IsDestructor = false;
380343171Sdim};
381343171Sdim
382343171Sdimstruct NamedIdentifierNode : public IdentifierNode {
383343171Sdim  NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
384343171Sdim
385343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
386343171Sdim
387343171Sdim  StringView Name;
388343171Sdim};
389343171Sdim
390343171Sdimstruct IntrinsicFunctionIdentifierNode : public IdentifierNode {
391343171Sdim  explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
392343171Sdim      : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
393343171Sdim        Operator(Operator) {}
394343171Sdim
395343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
396343171Sdim
397343171Sdim  IntrinsicFunctionKind Operator;
398343171Sdim};
399343171Sdim
400343171Sdimstruct LiteralOperatorIdentifierNode : public IdentifierNode {
401343171Sdim  LiteralOperatorIdentifierNode()
402343171Sdim      : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
403343171Sdim
404343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
405343171Sdim
406343171Sdim  StringView Name;
407343171Sdim};
408343171Sdim
409343171Sdimstruct LocalStaticGuardIdentifierNode : public IdentifierNode {
410343171Sdim  LocalStaticGuardIdentifierNode()
411343171Sdim      : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
412343171Sdim
413343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
414343171Sdim
415353358Sdim  bool IsThread = false;
416343171Sdim  uint32_t ScopeIndex = 0;
417343171Sdim};
418343171Sdim
419343171Sdimstruct ConversionOperatorIdentifierNode : public IdentifierNode {
420343171Sdim  ConversionOperatorIdentifierNode()
421343171Sdim      : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
422343171Sdim
423343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
424343171Sdim
425343171Sdim  // The type that this operator converts too.
426343171Sdim  TypeNode *TargetType = nullptr;
427343171Sdim};
428343171Sdim
429343171Sdimstruct StructorIdentifierNode : public IdentifierNode {
430343171Sdim  StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
431343171Sdim  explicit StructorIdentifierNode(bool IsDestructor)
432343171Sdim      : IdentifierNode(NodeKind::StructorIdentifier),
433343171Sdim        IsDestructor(IsDestructor) {}
434343171Sdim
435343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
436343171Sdim
437343171Sdim  // The name of the class that this is a structor of.
438343171Sdim  IdentifierNode *Class = nullptr;
439343171Sdim  bool IsDestructor = false;
440343171Sdim};
441343171Sdim
442343171Sdimstruct ThunkSignatureNode : public FunctionSignatureNode {
443343171Sdim  ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
444343171Sdim
445343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const override;
446343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const override;
447343171Sdim
448343171Sdim  struct ThisAdjustor {
449343171Sdim    uint32_t StaticOffset = 0;
450343171Sdim    int32_t VBPtrOffset = 0;
451343171Sdim    int32_t VBOffsetOffset = 0;
452343171Sdim    int32_t VtordispOffset = 0;
453343171Sdim  };
454343171Sdim
455343171Sdim  ThisAdjustor ThisAdjust;
456343171Sdim};
457343171Sdim
458343171Sdimstruct PointerTypeNode : public TypeNode {
459343171Sdim  PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
460343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const override;
461343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const override;
462343171Sdim
463343171Sdim  // Is this a pointer, reference, or rvalue-reference?
464343171Sdim  PointerAffinity Affinity = PointerAffinity::None;
465343171Sdim
466343171Sdim  // If this is a member pointer, this is the class that the member is in.
467343171Sdim  QualifiedNameNode *ClassParent = nullptr;
468343171Sdim
469343171Sdim  // Represents a type X in "a pointer to X", "a reference to X", or
470343171Sdim  // "rvalue-reference to X"
471343171Sdim  TypeNode *Pointee = nullptr;
472343171Sdim};
473343171Sdim
474343171Sdimstruct TagTypeNode : public TypeNode {
475343171Sdim  explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
476343171Sdim
477343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const;
478343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const;
479343171Sdim
480343171Sdim  QualifiedNameNode *QualifiedName = nullptr;
481343171Sdim  TagKind Tag;
482343171Sdim};
483343171Sdim
484343171Sdimstruct ArrayTypeNode : public TypeNode {
485343171Sdim  ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
486343171Sdim
487343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const;
488343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const;
489343171Sdim
490343171Sdim  void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
491343171Sdim  void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
492343171Sdim
493343171Sdim  // A list of array dimensions.  e.g. [3,4,5] in `int Foo[3][4][5]`
494343171Sdim  NodeArrayNode *Dimensions = nullptr;
495343171Sdim
496343171Sdim  // The type of array element.
497343171Sdim  TypeNode *ElementType = nullptr;
498343171Sdim};
499343171Sdim
500343171Sdimstruct IntrinsicNode : public TypeNode {
501343171Sdim  IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
502343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override {}
503343171Sdim};
504343171Sdim
505343171Sdimstruct CustomTypeNode : public TypeNode {
506343171Sdim  CustomTypeNode() : TypeNode(NodeKind::Custom) {}
507343171Sdim
508343171Sdim  void outputPre(OutputStream &OS, OutputFlags Flags) const override;
509343171Sdim  void outputPost(OutputStream &OS, OutputFlags Flags) const override;
510343171Sdim
511360784Sdim  IdentifierNode *Identifier = nullptr;
512343171Sdim};
513343171Sdim
514343171Sdimstruct NodeArrayNode : public Node {
515343171Sdim  NodeArrayNode() : Node(NodeKind::NodeArray) {}
516343171Sdim
517343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
518343171Sdim
519343171Sdim  void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
520343171Sdim
521353358Sdim  Node **Nodes = nullptr;
522343171Sdim  size_t Count = 0;
523343171Sdim};
524343171Sdim
525343171Sdimstruct QualifiedNameNode : public Node {
526343171Sdim  QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
527343171Sdim
528343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
529343171Sdim
530343171Sdim  NodeArrayNode *Components = nullptr;
531343171Sdim
532343171Sdim  IdentifierNode *getUnqualifiedIdentifier() {
533343171Sdim    Node *LastComponent = Components->Nodes[Components->Count - 1];
534343171Sdim    return static_cast<IdentifierNode *>(LastComponent);
535343171Sdim  }
536343171Sdim};
537343171Sdim
538343171Sdimstruct TemplateParameterReferenceNode : public Node {
539343171Sdim  TemplateParameterReferenceNode()
540343171Sdim      : Node(NodeKind::TemplateParameterReference) {}
541343171Sdim
542343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
543343171Sdim
544343171Sdim  SymbolNode *Symbol = nullptr;
545343171Sdim
546343171Sdim  int ThunkOffsetCount = 0;
547343171Sdim  std::array<int64_t, 3> ThunkOffsets;
548343171Sdim  PointerAffinity Affinity = PointerAffinity::None;
549343171Sdim  bool IsMemberPointer = false;
550343171Sdim};
551343171Sdim
552343171Sdimstruct IntegerLiteralNode : public Node {
553343171Sdim  IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
554343171Sdim  IntegerLiteralNode(uint64_t Value, bool IsNegative)
555343171Sdim      : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
556343171Sdim
557343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
558343171Sdim
559343171Sdim  uint64_t Value = 0;
560343171Sdim  bool IsNegative = false;
561343171Sdim};
562343171Sdim
563343171Sdimstruct RttiBaseClassDescriptorNode : public IdentifierNode {
564343171Sdim  RttiBaseClassDescriptorNode()
565343171Sdim      : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
566343171Sdim
567343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
568343171Sdim
569343171Sdim  uint32_t NVOffset = 0;
570343171Sdim  int32_t VBPtrOffset = 0;
571343171Sdim  uint32_t VBTableOffset = 0;
572343171Sdim  uint32_t Flags = 0;
573343171Sdim};
574343171Sdim
575343171Sdimstruct SymbolNode : public Node {
576343171Sdim  explicit SymbolNode(NodeKind K) : Node(K) {}
577343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
578343171Sdim  QualifiedNameNode *Name = nullptr;
579343171Sdim};
580343171Sdim
581343171Sdimstruct SpecialTableSymbolNode : public SymbolNode {
582343171Sdim  explicit SpecialTableSymbolNode()
583343171Sdim      : SymbolNode(NodeKind::SpecialTableSymbol) {}
584343171Sdim
585343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
586343171Sdim  QualifiedNameNode *TargetName = nullptr;
587360784Sdim  Qualifiers Quals = Qualifiers::Q_None;
588343171Sdim};
589343171Sdim
590343171Sdimstruct LocalStaticGuardVariableNode : public SymbolNode {
591343171Sdim  LocalStaticGuardVariableNode()
592343171Sdim      : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
593343171Sdim
594343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
595343171Sdim
596343171Sdim  bool IsVisible = false;
597343171Sdim};
598343171Sdim
599343171Sdimstruct EncodedStringLiteralNode : public SymbolNode {
600343171Sdim  EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
601343171Sdim
602343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
603343171Sdim
604343171Sdim  StringView DecodedString;
605343171Sdim  bool IsTruncated = false;
606343171Sdim  CharKind Char = CharKind::Char;
607343171Sdim};
608343171Sdim
609343171Sdimstruct VariableSymbolNode : public SymbolNode {
610343171Sdim  VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
611343171Sdim
612343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
613343171Sdim
614343171Sdim  StorageClass SC = StorageClass::None;
615343171Sdim  TypeNode *Type = nullptr;
616343171Sdim};
617343171Sdim
618343171Sdimstruct FunctionSymbolNode : public SymbolNode {
619343171Sdim  FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
620343171Sdim
621343171Sdim  void output(OutputStream &OS, OutputFlags Flags) const override;
622343171Sdim
623343171Sdim  FunctionSignatureNode *Signature = nullptr;
624343171Sdim};
625343171Sdim
626343171Sdim} // namespace ms_demangle
627343171Sdim} // namespace llvm
628343171Sdim
629353358Sdim#endif
630