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 { NodeNode258 explicit Node(NodeKind K) : Kind(K) {} 259 virtual ~Node() = default; 260 kindNode261 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 { TypeNodeTypeNode298 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 outputTypeNode303 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 { PrimitiveTypeNodePrimitiveTypeNode312 explicit PrimitiveTypeNode(PrimitiveKind K) 313 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {} 314 315 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; outputPostPrimitiveTypeNode316 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {} 317 318 PrimitiveKind PrimKind; 319 }; 320 321 struct FunctionSignatureNode : public TypeNode { FunctionSignatureNodeFunctionSignatureNode322 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {} FunctionSignatureNodeFunctionSignatureNode323 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 { IdentifierNodeIdentifierNode354 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 { VcallThunkIdentifierNodeVcallThunkIdentifierNode363 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 { DynamicStructorIdentifierNodeDynamicStructorIdentifierNode371 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 { NamedIdentifierNodeNamedIdentifierNode382 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 { IntrinsicFunctionIdentifierNodeIntrinsicFunctionIdentifierNode390 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 { LiteralOperatorIdentifierNodeLiteralOperatorIdentifierNode400 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 { LocalStaticGuardIdentifierNodeLocalStaticGuardIdentifierNode409 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 { ConversionOperatorIdentifierNodeConversionOperatorIdentifierNode419 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 { StructorIdentifierNodeStructorIdentifierNode429 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {} StructorIdentifierNodeStructorIdentifierNode430 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 { ThunkSignatureNodeThunkSignatureNode442 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 { PointerTypeNodePointerTypeNode458 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 { TagTypeNodeTagTypeNode474 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 { ArrayTypeNodeArrayTypeNode484 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 { IntrinsicNodeIntrinsicNode500 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {} outputIntrinsicNode501 void output(OutputBuffer &OB, OutputFlags Flags) const override {} 502 }; 503 504 struct CustomTypeNode : public TypeNode { CustomTypeNodeCustomTypeNode505 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 { NodeArrayNodeNodeArrayNode514 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 { QualifiedNameNodeQualifiedNameNode526 QualifiedNameNode() : Node(NodeKind::QualifiedName) {} 527 528 void output(OutputBuffer &OB, OutputFlags Flags) const override; 529 530 NodeArrayNode *Components = nullptr; 531 getUnqualifiedIdentifierQualifiedNameNode532 IdentifierNode *getUnqualifiedIdentifier() { 533 Node *LastComponent = Components->Nodes[Components->Count - 1]; 534 return static_cast<IdentifierNode *>(LastComponent); 535 } 536 }; 537 538 struct TemplateParameterReferenceNode : public Node { TemplateParameterReferenceNodeTemplateParameterReferenceNode539 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 { IntegerLiteralNodeIntegerLiteralNode553 IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {} IntegerLiteralNodeIntegerLiteralNode554 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 { RttiBaseClassDescriptorNodeRttiBaseClassDescriptorNode564 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 { SymbolNodeSymbolNode576 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 { SpecialTableSymbolNodeSpecialTableSymbolNode582 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 { LocalStaticGuardVariableNodeLocalStaticGuardVariableNode591 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 { EncodedStringLiteralNodeEncodedStringLiteralNode600 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 { VariableSymbolNodeVariableSymbolNode610 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 { FunctionSymbolNodeFunctionSymbolNode619 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