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