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 "llvm/Demangle/StringView.h" 17 #include <array> 18 #include <cstdint> 19 #include <string> 20 21 namespace llvm { 22 namespace itanium_demangle { 23 class OutputBuffer; 24 } 25 } 26 27 using llvm::itanium_demangle::OutputBuffer; 28 using llvm::itanium_demangle::StringView; 29 30 namespace llvm { 31 namespace ms_demangle { 32 33 // Storage classes 34 enum Qualifiers : uint8_t { 35 Q_None = 0, 36 Q_Const = 1 << 0, 37 Q_Volatile = 1 << 1, 38 Q_Far = 1 << 2, 39 Q_Huge = 1 << 3, 40 Q_Unaligned = 1 << 4, 41 Q_Restrict = 1 << 5, 42 Q_Pointer64 = 1 << 6 43 }; 44 45 enum class StorageClass : uint8_t { 46 None, 47 PrivateStatic, 48 ProtectedStatic, 49 PublicStatic, 50 Global, 51 FunctionLocalStatic, 52 }; 53 54 enum class PointerAffinity { None, Pointer, Reference, RValueReference }; 55 enum class FunctionRefQualifier { None, Reference, RValueReference }; 56 57 // Calling conventions 58 enum class CallingConv : uint8_t { 59 None, 60 Cdecl, 61 Pascal, 62 Thiscall, 63 Stdcall, 64 Fastcall, 65 Clrcall, 66 Eabi, 67 Vectorcall, 68 Regcall, 69 Swift, // Clang-only 70 SwiftAsync, // Clang-only 71 }; 72 73 enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef }; 74 75 enum OutputFlags { 76 OF_Default = 0, 77 OF_NoCallingConvention = 1, 78 OF_NoTagSpecifier = 2, 79 OF_NoAccessSpecifier = 4, 80 OF_NoMemberType = 8, 81 OF_NoReturnType = 16, 82 OF_NoVariableType = 32, 83 }; 84 85 // Types 86 enum class PrimitiveKind { 87 Void, 88 Bool, 89 Char, 90 Schar, 91 Uchar, 92 Char8, 93 Char16, 94 Char32, 95 Short, 96 Ushort, 97 Int, 98 Uint, 99 Long, 100 Ulong, 101 Int64, 102 Uint64, 103 Wchar, 104 Float, 105 Double, 106 Ldouble, 107 Nullptr, 108 }; 109 110 enum class CharKind { 111 Char, 112 Char16, 113 Char32, 114 Wchar, 115 }; 116 117 enum class IntrinsicFunctionKind : uint8_t { 118 None, 119 New, // ?2 # operator new 120 Delete, // ?3 # operator delete 121 Assign, // ?4 # operator= 122 RightShift, // ?5 # operator>> 123 LeftShift, // ?6 # operator<< 124 LogicalNot, // ?7 # operator! 125 Equals, // ?8 # operator== 126 NotEquals, // ?9 # operator!= 127 ArraySubscript, // ?A # operator[] 128 Pointer, // ?C # operator-> 129 Dereference, // ?D # operator* 130 Increment, // ?E # operator++ 131 Decrement, // ?F # operator-- 132 Minus, // ?G # operator- 133 Plus, // ?H # operator+ 134 BitwiseAnd, // ?I # operator& 135 MemberPointer, // ?J # operator->* 136 Divide, // ?K # operator/ 137 Modulus, // ?L # operator% 138 LessThan, // ?M operator< 139 LessThanEqual, // ?N operator<= 140 GreaterThan, // ?O operator> 141 GreaterThanEqual, // ?P operator>= 142 Comma, // ?Q operator, 143 Parens, // ?R operator() 144 BitwiseNot, // ?S operator~ 145 BitwiseXor, // ?T operator^ 146 BitwiseOr, // ?U operator| 147 LogicalAnd, // ?V operator&& 148 LogicalOr, // ?W operator|| 149 TimesEqual, // ?X operator*= 150 PlusEqual, // ?Y operator+= 151 MinusEqual, // ?Z operator-= 152 DivEqual, // ?_0 operator/= 153 ModEqual, // ?_1 operator%= 154 RshEqual, // ?_2 operator>>= 155 LshEqual, // ?_3 operator<<= 156 BitwiseAndEqual, // ?_4 operator&= 157 BitwiseOrEqual, // ?_5 operator|= 158 BitwiseXorEqual, // ?_6 operator^= 159 VbaseDtor, // ?_D # vbase destructor 160 VecDelDtor, // ?_E # vector deleting destructor 161 DefaultCtorClosure, // ?_F # default constructor closure 162 ScalarDelDtor, // ?_G # scalar deleting destructor 163 VecCtorIter, // ?_H # vector constructor iterator 164 VecDtorIter, // ?_I # vector destructor iterator 165 VecVbaseCtorIter, // ?_J # vector vbase constructor iterator 166 VdispMap, // ?_K # virtual displacement map 167 EHVecCtorIter, // ?_L # eh vector constructor iterator 168 EHVecDtorIter, // ?_M # eh vector destructor iterator 169 EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator 170 CopyCtorClosure, // ?_O # copy constructor closure 171 LocalVftableCtorClosure, // ?_T # local vftable constructor closure 172 ArrayNew, // ?_U operator new[] 173 ArrayDelete, // ?_V operator delete[] 174 ManVectorCtorIter, // ?__A managed vector ctor iterator 175 ManVectorDtorIter, // ?__B managed vector dtor iterator 176 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator 177 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator 178 VectorCopyCtorIter, // ?__G vector copy constructor iterator 179 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator 180 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor 181 CoAwait, // ?__L operator co_await 182 Spaceship, // ?__M operator<=> 183 MaxIntrinsic 184 }; 185 186 enum class SpecialIntrinsicKind { 187 None, 188 Vftable, 189 Vbtable, 190 Typeof, 191 VcallThunk, 192 LocalStaticGuard, 193 StringLiteralSymbol, 194 UdtReturning, 195 Unknown, 196 DynamicInitializer, 197 DynamicAtexitDestructor, 198 RttiTypeDescriptor, 199 RttiBaseClassDescriptor, 200 RttiBaseClassArray, 201 RttiClassHierarchyDescriptor, 202 RttiCompleteObjLocator, 203 LocalVftable, 204 LocalStaticThreadGuard, 205 }; 206 207 // Function classes 208 enum FuncClass : uint16_t { 209 FC_None = 0, 210 FC_Public = 1 << 0, 211 FC_Protected = 1 << 1, 212 FC_Private = 1 << 2, 213 FC_Global = 1 << 3, 214 FC_Static = 1 << 4, 215 FC_Virtual = 1 << 5, 216 FC_Far = 1 << 6, 217 FC_ExternC = 1 << 7, 218 FC_NoParameterList = 1 << 8, 219 FC_VirtualThisAdjust = 1 << 9, 220 FC_VirtualThisAdjustEx = 1 << 10, 221 FC_StaticThisAdjust = 1 << 11, 222 }; 223 224 enum class TagKind { Class, Struct, Union, Enum }; 225 226 enum class NodeKind { 227 Unknown, 228 Md5Symbol, 229 PrimitiveType, 230 FunctionSignature, 231 Identifier, 232 NamedIdentifier, 233 VcallThunkIdentifier, 234 LocalStaticGuardIdentifier, 235 IntrinsicFunctionIdentifier, 236 ConversionOperatorIdentifier, 237 DynamicStructorIdentifier, 238 StructorIdentifier, 239 LiteralOperatorIdentifier, 240 ThunkSignature, 241 PointerType, 242 TagType, 243 ArrayType, 244 Custom, 245 IntrinsicType, 246 NodeArray, 247 QualifiedName, 248 TemplateParameterReference, 249 EncodedStringLiteral, 250 IntegerLiteral, 251 RttiBaseClassDescriptor, 252 LocalStaticGuardVariable, 253 FunctionSymbol, 254 VariableSymbol, 255 SpecialTableSymbol 256 }; 257 258 struct Node { NodeNode259 explicit Node(NodeKind K) : Kind(K) {} 260 virtual ~Node() = default; 261 kindNode262 NodeKind kind() const { return Kind; } 263 264 virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0; 265 266 std::string toString(OutputFlags Flags = OF_Default) const; 267 268 private: 269 NodeKind Kind; 270 }; 271 272 struct TypeNode; 273 struct PrimitiveTypeNode; 274 struct FunctionSignatureNode; 275 struct IdentifierNode; 276 struct NamedIdentifierNode; 277 struct VcallThunkIdentifierNode; 278 struct IntrinsicFunctionIdentifierNode; 279 struct LiteralOperatorIdentifierNode; 280 struct ConversionOperatorIdentifierNode; 281 struct StructorIdentifierNode; 282 struct ThunkSignatureNode; 283 struct PointerTypeNode; 284 struct ArrayTypeNode; 285 struct TagTypeNode; 286 struct NodeArrayNode; 287 struct QualifiedNameNode; 288 struct TemplateParameterReferenceNode; 289 struct EncodedStringLiteralNode; 290 struct IntegerLiteralNode; 291 struct RttiBaseClassDescriptorNode; 292 struct LocalStaticGuardVariableNode; 293 struct SymbolNode; 294 struct FunctionSymbolNode; 295 struct VariableSymbolNode; 296 struct SpecialTableSymbolNode; 297 298 struct TypeNode : public Node { TypeNodeTypeNode299 explicit TypeNode(NodeKind K) : Node(K) {} 300 301 virtual void outputPre(OutputBuffer &OB, OutputFlags Flags) const = 0; 302 virtual void outputPost(OutputBuffer &OB, OutputFlags Flags) const = 0; 303 outputTypeNode304 void output(OutputBuffer &OB, OutputFlags Flags) const override { 305 outputPre(OB, Flags); 306 outputPost(OB, Flags); 307 } 308 309 Qualifiers Quals = Q_None; 310 }; 311 312 struct PrimitiveTypeNode : public TypeNode { PrimitiveTypeNodePrimitiveTypeNode313 explicit PrimitiveTypeNode(PrimitiveKind K) 314 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {} 315 316 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; outputPostPrimitiveTypeNode317 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override {} 318 319 PrimitiveKind PrimKind; 320 }; 321 322 struct FunctionSignatureNode : public TypeNode { FunctionSignatureNodeFunctionSignatureNode323 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {} FunctionSignatureNodeFunctionSignatureNode324 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {} 325 326 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 327 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 328 329 // Valid if this FunctionTypeNode is the Pointee of a PointerType or 330 // MemberPointerType. 331 PointerAffinity Affinity = PointerAffinity::None; 332 333 // The function's calling convention. 334 CallingConv CallConvention = CallingConv::None; 335 336 // Function flags (gloabl, public, etc) 337 FuncClass FunctionClass = FC_Global; 338 339 FunctionRefQualifier RefQualifier = FunctionRefQualifier::None; 340 341 // The return type of the function. 342 TypeNode *ReturnType = nullptr; 343 344 // True if this is a C-style ... varargs function. 345 bool IsVariadic = false; 346 347 // Function parameters 348 NodeArrayNode *Params = nullptr; 349 350 // True if the function type is noexcept. 351 bool IsNoexcept = false; 352 }; 353 354 struct IdentifierNode : public Node { IdentifierNodeIdentifierNode355 explicit IdentifierNode(NodeKind K) : Node(K) {} 356 357 NodeArrayNode *TemplateParams = nullptr; 358 359 protected: 360 void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const; 361 }; 362 363 struct VcallThunkIdentifierNode : public IdentifierNode { VcallThunkIdentifierNodeVcallThunkIdentifierNode364 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {} 365 366 void output(OutputBuffer &OB, OutputFlags Flags) const override; 367 368 uint64_t OffsetInVTable = 0; 369 }; 370 371 struct DynamicStructorIdentifierNode : public IdentifierNode { DynamicStructorIdentifierNodeDynamicStructorIdentifierNode372 DynamicStructorIdentifierNode() 373 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {} 374 375 void output(OutputBuffer &OB, OutputFlags Flags) const override; 376 377 VariableSymbolNode *Variable = nullptr; 378 QualifiedNameNode *Name = nullptr; 379 bool IsDestructor = false; 380 }; 381 382 struct NamedIdentifierNode : public IdentifierNode { NamedIdentifierNodeNamedIdentifierNode383 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {} 384 385 void output(OutputBuffer &OB, OutputFlags Flags) const override; 386 387 StringView Name; 388 }; 389 390 struct IntrinsicFunctionIdentifierNode : public IdentifierNode { IntrinsicFunctionIdentifierNodeIntrinsicFunctionIdentifierNode391 explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator) 392 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier), 393 Operator(Operator) {} 394 395 void output(OutputBuffer &OB, OutputFlags Flags) const override; 396 397 IntrinsicFunctionKind Operator; 398 }; 399 400 struct LiteralOperatorIdentifierNode : public IdentifierNode { LiteralOperatorIdentifierNodeLiteralOperatorIdentifierNode401 LiteralOperatorIdentifierNode() 402 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {} 403 404 void output(OutputBuffer &OB, OutputFlags Flags) const override; 405 406 StringView Name; 407 }; 408 409 struct LocalStaticGuardIdentifierNode : public IdentifierNode { LocalStaticGuardIdentifierNodeLocalStaticGuardIdentifierNode410 LocalStaticGuardIdentifierNode() 411 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {} 412 413 void output(OutputBuffer &OB, OutputFlags Flags) const override; 414 415 bool IsThread = false; 416 uint32_t ScopeIndex = 0; 417 }; 418 419 struct ConversionOperatorIdentifierNode : public IdentifierNode { ConversionOperatorIdentifierNodeConversionOperatorIdentifierNode420 ConversionOperatorIdentifierNode() 421 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {} 422 423 void output(OutputBuffer &OB, OutputFlags Flags) const override; 424 425 // The type that this operator converts too. 426 TypeNode *TargetType = nullptr; 427 }; 428 429 struct StructorIdentifierNode : public IdentifierNode { StructorIdentifierNodeStructorIdentifierNode430 StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {} StructorIdentifierNodeStructorIdentifierNode431 explicit StructorIdentifierNode(bool IsDestructor) 432 : IdentifierNode(NodeKind::StructorIdentifier), 433 IsDestructor(IsDestructor) {} 434 435 void output(OutputBuffer &OB, OutputFlags Flags) const override; 436 437 // The name of the class that this is a structor of. 438 IdentifierNode *Class = nullptr; 439 bool IsDestructor = false; 440 }; 441 442 struct ThunkSignatureNode : public FunctionSignatureNode { ThunkSignatureNodeThunkSignatureNode443 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {} 444 445 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 446 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 447 448 struct ThisAdjustor { 449 uint32_t StaticOffset = 0; 450 int32_t VBPtrOffset = 0; 451 int32_t VBOffsetOffset = 0; 452 int32_t VtordispOffset = 0; 453 }; 454 455 ThisAdjustor ThisAdjust; 456 }; 457 458 struct PointerTypeNode : public TypeNode { PointerTypeNodePointerTypeNode459 PointerTypeNode() : TypeNode(NodeKind::PointerType) {} 460 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 461 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 462 463 // Is this a pointer, reference, or rvalue-reference? 464 PointerAffinity Affinity = PointerAffinity::None; 465 466 // If this is a member pointer, this is the class that the member is in. 467 QualifiedNameNode *ClassParent = nullptr; 468 469 // Represents a type X in "a pointer to X", "a reference to X", or 470 // "rvalue-reference to X" 471 TypeNode *Pointee = nullptr; 472 }; 473 474 struct TagTypeNode : public TypeNode { TagTypeNodeTagTypeNode475 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {} 476 477 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 478 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 479 480 QualifiedNameNode *QualifiedName = nullptr; 481 TagKind Tag; 482 }; 483 484 struct ArrayTypeNode : public TypeNode { ArrayTypeNodeArrayTypeNode485 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {} 486 487 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 488 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 489 490 void outputDimensionsImpl(OutputBuffer &OB, OutputFlags Flags) const; 491 void outputOneDimension(OutputBuffer &OB, OutputFlags Flags, Node *N) const; 492 493 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]` 494 NodeArrayNode *Dimensions = nullptr; 495 496 // The type of array element. 497 TypeNode *ElementType = nullptr; 498 }; 499 500 struct IntrinsicNode : public TypeNode { IntrinsicNodeIntrinsicNode501 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {} outputIntrinsicNode502 void output(OutputBuffer &OB, OutputFlags Flags) const override {} 503 }; 504 505 struct CustomTypeNode : public TypeNode { CustomTypeNodeCustomTypeNode506 CustomTypeNode() : TypeNode(NodeKind::Custom) {} 507 508 void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; 509 void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; 510 511 IdentifierNode *Identifier = nullptr; 512 }; 513 514 struct NodeArrayNode : public Node { NodeArrayNodeNodeArrayNode515 NodeArrayNode() : Node(NodeKind::NodeArray) {} 516 517 void output(OutputBuffer &OB, OutputFlags Flags) const override; 518 519 void output(OutputBuffer &OB, OutputFlags Flags, StringView 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 StringView 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