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