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