Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 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_SUPPORT_MICROSOFTDEMANGLENODES_H |
| 14 | #define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H |
| 15 | |
| 16 | #include "llvm/Demangle/DemangleConfig.h" |
| 17 | #include "llvm/Demangle/StringView.h" |
| 18 | #include <array> |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 19 | #include <cstdint> |
| 20 | #include <string> |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 21 | |
| 22 | namespace llvm { |
| 23 | namespace itanium_demangle { |
| 24 | class OutputStream; |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | using llvm::itanium_demangle::OutputStream; |
| 29 | using llvm::itanium_demangle::StringView; |
| 30 | |
| 31 | namespace llvm { |
| 32 | namespace ms_demangle { |
| 33 | |
| 34 | // Storage classes |
| 35 | enum Qualifiers : uint8_t { |
| 36 | Q_None = 0, |
| 37 | Q_Const = 1 << 0, |
| 38 | Q_Volatile = 1 << 1, |
| 39 | Q_Far = 1 << 2, |
| 40 | Q_Huge = 1 << 3, |
| 41 | Q_Unaligned = 1 << 4, |
| 42 | Q_Restrict = 1 << 5, |
| 43 | Q_Pointer64 = 1 << 6 |
| 44 | }; |
| 45 | |
| 46 | enum class StorageClass : uint8_t { |
| 47 | None, |
| 48 | PrivateStatic, |
| 49 | ProtectedStatic, |
| 50 | PublicStatic, |
| 51 | Global, |
| 52 | FunctionLocalStatic, |
| 53 | }; |
| 54 | |
| 55 | enum class PointerAffinity { None, Pointer, Reference, RValueReference }; |
| 56 | enum class FunctionRefQualifier { None, Reference, RValueReference }; |
| 57 | |
| 58 | // Calling conventions |
| 59 | enum class CallingConv : uint8_t { |
| 60 | None, |
| 61 | Cdecl, |
| 62 | Pascal, |
| 63 | Thiscall, |
| 64 | Stdcall, |
| 65 | Fastcall, |
| 66 | Clrcall, |
| 67 | Eabi, |
| 68 | Vectorcall, |
| 69 | Regcall, |
| 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, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 78 | OF_NoAccessSpecifier = 4, |
| 79 | OF_NoMemberType = 8, |
| 80 | OF_NoReturnType = 16, |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 81 | }; |
| 82 | |
| 83 | // Types |
| 84 | enum class PrimitiveKind { |
| 85 | Void, |
| 86 | Bool, |
| 87 | Char, |
| 88 | Schar, |
| 89 | Uchar, |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 90 | Char8, |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 91 | Char16, |
| 92 | Char32, |
| 93 | Short, |
| 94 | Ushort, |
| 95 | Int, |
| 96 | Uint, |
| 97 | Long, |
| 98 | Ulong, |
| 99 | Int64, |
| 100 | Uint64, |
| 101 | Wchar, |
| 102 | Float, |
| 103 | Double, |
| 104 | Ldouble, |
| 105 | Nullptr, |
| 106 | }; |
| 107 | |
| 108 | enum class CharKind { |
| 109 | Char, |
| 110 | Char16, |
| 111 | Char32, |
| 112 | Wchar, |
| 113 | }; |
| 114 | |
| 115 | enum class IntrinsicFunctionKind : uint8_t { |
| 116 | None, |
| 117 | New, // ?2 # operator new |
| 118 | Delete, // ?3 # operator delete |
| 119 | Assign, // ?4 # operator= |
| 120 | RightShift, // ?5 # operator>> |
| 121 | LeftShift, // ?6 # operator<< |
| 122 | LogicalNot, // ?7 # operator! |
| 123 | Equals, // ?8 # operator== |
| 124 | NotEquals, // ?9 # operator!= |
| 125 | ArraySubscript, // ?A # operator[] |
| 126 | Pointer, // ?C # operator-> |
| 127 | Dereference, // ?D # operator* |
| 128 | Increment, // ?E # operator++ |
| 129 | Decrement, // ?F # operator-- |
| 130 | Minus, // ?G # operator- |
| 131 | Plus, // ?H # operator+ |
| 132 | BitwiseAnd, // ?I # operator& |
| 133 | MemberPointer, // ?J # operator->* |
| 134 | Divide, // ?K # operator/ |
| 135 | Modulus, // ?L # operator% |
| 136 | LessThan, // ?M operator< |
| 137 | LessThanEqual, // ?N operator<= |
| 138 | GreaterThan, // ?O operator> |
| 139 | GreaterThanEqual, // ?P operator>= |
| 140 | Comma, // ?Q operator, |
| 141 | Parens, // ?R operator() |
| 142 | BitwiseNot, // ?S operator~ |
| 143 | BitwiseXor, // ?T operator^ |
| 144 | BitwiseOr, // ?U operator| |
| 145 | LogicalAnd, // ?V operator&& |
| 146 | LogicalOr, // ?W operator|| |
| 147 | TimesEqual, // ?X operator*= |
| 148 | PlusEqual, // ?Y operator+= |
| 149 | MinusEqual, // ?Z operator-= |
| 150 | DivEqual, // ?_0 operator/= |
| 151 | ModEqual, // ?_1 operator%= |
| 152 | RshEqual, // ?_2 operator>>= |
| 153 | LshEqual, // ?_3 operator<<= |
| 154 | BitwiseAndEqual, // ?_4 operator&= |
| 155 | BitwiseOrEqual, // ?_5 operator|= |
| 156 | BitwiseXorEqual, // ?_6 operator^= |
| 157 | VbaseDtor, // ?_D # vbase destructor |
| 158 | VecDelDtor, // ?_E # vector deleting destructor |
| 159 | DefaultCtorClosure, // ?_F # default constructor closure |
| 160 | ScalarDelDtor, // ?_G # scalar deleting destructor |
| 161 | VecCtorIter, // ?_H # vector constructor iterator |
| 162 | VecDtorIter, // ?_I # vector destructor iterator |
| 163 | VecVbaseCtorIter, // ?_J # vector vbase constructor iterator |
| 164 | VdispMap, // ?_K # virtual displacement map |
| 165 | EHVecCtorIter, // ?_L # eh vector constructor iterator |
| 166 | EHVecDtorIter, // ?_M # eh vector destructor iterator |
| 167 | EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator |
| 168 | CopyCtorClosure, // ?_O # copy constructor closure |
| 169 | LocalVftableCtorClosure, // ?_T # local vftable constructor closure |
| 170 | ArrayNew, // ?_U operator new[] |
| 171 | ArrayDelete, // ?_V operator delete[] |
| 172 | ManVectorCtorIter, // ?__A managed vector ctor iterator |
| 173 | ManVectorDtorIter, // ?__B managed vector dtor iterator |
| 174 | EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator |
| 175 | EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator |
| 176 | VectorCopyCtorIter, // ?__G vector copy constructor iterator |
| 177 | VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator |
| 178 | ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 179 | CoAwait, // ?__L operator co_await |
| 180 | Spaceship, // ?__M operator<=> |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 181 | MaxIntrinsic |
| 182 | }; |
| 183 | |
| 184 | enum class SpecialIntrinsicKind { |
| 185 | None, |
| 186 | Vftable, |
| 187 | Vbtable, |
| 188 | Typeof, |
| 189 | VcallThunk, |
| 190 | LocalStaticGuard, |
| 191 | StringLiteralSymbol, |
| 192 | UdtReturning, |
| 193 | Unknown, |
| 194 | DynamicInitializer, |
| 195 | DynamicAtexitDestructor, |
| 196 | RttiTypeDescriptor, |
| 197 | RttiBaseClassDescriptor, |
| 198 | RttiBaseClassArray, |
| 199 | RttiClassHierarchyDescriptor, |
| 200 | RttiCompleteObjLocator, |
| 201 | LocalVftable, |
| 202 | LocalStaticThreadGuard, |
| 203 | }; |
| 204 | |
| 205 | // Function classes |
| 206 | enum FuncClass : uint16_t { |
| 207 | FC_None = 0, |
| 208 | FC_Public = 1 << 0, |
| 209 | FC_Protected = 1 << 1, |
| 210 | FC_Private = 1 << 2, |
| 211 | FC_Global = 1 << 3, |
| 212 | FC_Static = 1 << 4, |
| 213 | FC_Virtual = 1 << 5, |
| 214 | FC_Far = 1 << 6, |
| 215 | FC_ExternC = 1 << 7, |
| 216 | FC_NoParameterList = 1 << 8, |
| 217 | FC_VirtualThisAdjust = 1 << 9, |
| 218 | FC_VirtualThisAdjustEx = 1 << 10, |
| 219 | FC_StaticThisAdjust = 1 << 11, |
| 220 | }; |
| 221 | |
| 222 | enum class TagKind { Class, Struct, Union, Enum }; |
| 223 | |
| 224 | enum class NodeKind { |
| 225 | Unknown, |
| 226 | Md5Symbol, |
| 227 | PrimitiveType, |
| 228 | FunctionSignature, |
| 229 | Identifier, |
| 230 | NamedIdentifier, |
| 231 | VcallThunkIdentifier, |
| 232 | LocalStaticGuardIdentifier, |
| 233 | IntrinsicFunctionIdentifier, |
| 234 | ConversionOperatorIdentifier, |
| 235 | DynamicStructorIdentifier, |
| 236 | StructorIdentifier, |
| 237 | LiteralOperatorIdentifier, |
| 238 | ThunkSignature, |
| 239 | PointerType, |
| 240 | TagType, |
| 241 | ArrayType, |
| 242 | Custom, |
| 243 | IntrinsicType, |
| 244 | NodeArray, |
| 245 | QualifiedName, |
| 246 | TemplateParameterReference, |
| 247 | EncodedStringLiteral, |
| 248 | IntegerLiteral, |
| 249 | RttiBaseClassDescriptor, |
| 250 | LocalStaticGuardVariable, |
| 251 | FunctionSymbol, |
| 252 | VariableSymbol, |
| 253 | SpecialTableSymbol |
| 254 | }; |
| 255 | |
| 256 | struct Node { |
| 257 | explicit Node(NodeKind K) : Kind(K) {} |
| 258 | virtual ~Node() = default; |
| 259 | |
| 260 | NodeKind kind() const { return Kind; } |
| 261 | |
| 262 | virtual void output(OutputStream &OS, OutputFlags Flags) const = 0; |
| 263 | |
| 264 | std::string toString(OutputFlags Flags = OF_Default) const; |
| 265 | |
| 266 | private: |
| 267 | NodeKind Kind; |
| 268 | }; |
| 269 | |
| 270 | struct TypeNode; |
| 271 | struct PrimitiveTypeNode; |
| 272 | struct FunctionSignatureNode; |
| 273 | struct IdentifierNode; |
| 274 | struct NamedIdentifierNode; |
| 275 | struct VcallThunkIdentifierNode; |
| 276 | struct IntrinsicFunctionIdentifierNode; |
| 277 | struct LiteralOperatorIdentifierNode; |
| 278 | struct ConversionOperatorIdentifierNode; |
| 279 | struct StructorIdentifierNode; |
| 280 | struct ThunkSignatureNode; |
| 281 | struct PointerTypeNode; |
| 282 | struct ArrayTypeNode; |
| 283 | struct CustomNode; |
| 284 | struct TagTypeNode; |
| 285 | struct IntrinsicTypeNode; |
| 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 { |
| 299 | explicit TypeNode(NodeKind K) : Node(K) {} |
| 300 | |
| 301 | virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0; |
| 302 | virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0; |
| 303 | |
| 304 | void output(OutputStream &OS, OutputFlags Flags) const override { |
| 305 | outputPre(OS, Flags); |
| 306 | outputPost(OS, Flags); |
| 307 | } |
| 308 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 309 | Qualifiers Quals = Q_None; |
| 310 | }; |
| 311 | |
| 312 | struct PrimitiveTypeNode : public TypeNode { |
| 313 | explicit PrimitiveTypeNode(PrimitiveKind K) |
| 314 | : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {} |
| 315 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 316 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 317 | void outputPost(OutputStream &OS, OutputFlags Flags) const override {} |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 318 | |
| 319 | PrimitiveKind PrimKind; |
| 320 | }; |
| 321 | |
| 322 | struct FunctionSignatureNode : public TypeNode { |
| 323 | explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {} |
| 324 | FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {} |
| 325 | |
| 326 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 327 | void outputPost(OutputStream &OS, 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 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 350 | // True if the function type is noexcept. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 351 | bool IsNoexcept = false; |
| 352 | }; |
| 353 | |
| 354 | struct IdentifierNode : public Node { |
| 355 | explicit IdentifierNode(NodeKind K) : Node(K) {} |
| 356 | |
| 357 | NodeArrayNode *TemplateParams = nullptr; |
| 358 | |
| 359 | protected: |
| 360 | void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const; |
| 361 | }; |
| 362 | |
| 363 | struct VcallThunkIdentifierNode : public IdentifierNode { |
| 364 | VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {} |
| 365 | |
| 366 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 367 | |
| 368 | uint64_t OffsetInVTable = 0; |
| 369 | }; |
| 370 | |
| 371 | struct DynamicStructorIdentifierNode : public IdentifierNode { |
| 372 | DynamicStructorIdentifierNode() |
| 373 | : IdentifierNode(NodeKind::DynamicStructorIdentifier) {} |
| 374 | |
| 375 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 376 | |
| 377 | VariableSymbolNode *Variable = nullptr; |
| 378 | QualifiedNameNode *Name = nullptr; |
| 379 | bool IsDestructor = false; |
| 380 | }; |
| 381 | |
| 382 | struct NamedIdentifierNode : public IdentifierNode { |
| 383 | NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {} |
| 384 | |
| 385 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 386 | |
| 387 | StringView Name; |
| 388 | }; |
| 389 | |
| 390 | struct IntrinsicFunctionIdentifierNode : public IdentifierNode { |
| 391 | explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator) |
| 392 | : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier), |
| 393 | Operator(Operator) {} |
| 394 | |
| 395 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 396 | |
| 397 | IntrinsicFunctionKind Operator; |
| 398 | }; |
| 399 | |
| 400 | struct LiteralOperatorIdentifierNode : public IdentifierNode { |
| 401 | LiteralOperatorIdentifierNode() |
| 402 | : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {} |
| 403 | |
| 404 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 405 | |
| 406 | StringView Name; |
| 407 | }; |
| 408 | |
| 409 | struct LocalStaticGuardIdentifierNode : public IdentifierNode { |
| 410 | LocalStaticGuardIdentifierNode() |
| 411 | : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {} |
| 412 | |
| 413 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 414 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 415 | bool IsThread = false; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 416 | uint32_t ScopeIndex = 0; |
| 417 | }; |
| 418 | |
| 419 | struct ConversionOperatorIdentifierNode : public IdentifierNode { |
| 420 | ConversionOperatorIdentifierNode() |
| 421 | : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {} |
| 422 | |
| 423 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 424 | |
| 425 | // The type that this operator converts too. |
| 426 | TypeNode *TargetType = nullptr; |
| 427 | }; |
| 428 | |
| 429 | struct StructorIdentifierNode : public IdentifierNode { |
| 430 | StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {} |
| 431 | explicit StructorIdentifierNode(bool IsDestructor) |
| 432 | : IdentifierNode(NodeKind::StructorIdentifier), |
| 433 | IsDestructor(IsDestructor) {} |
| 434 | |
| 435 | void output(OutputStream &OS, 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 { |
| 443 | ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {} |
| 444 | |
| 445 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 446 | void outputPost(OutputStream &OS, 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 { |
| 459 | PointerTypeNode() : TypeNode(NodeKind::PointerType) {} |
| 460 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 461 | void outputPost(OutputStream &OS, 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 { |
| 475 | explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {} |
| 476 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 477 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 478 | void outputPost(OutputStream &OS, OutputFlags Flags) const override; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 479 | |
| 480 | QualifiedNameNode *QualifiedName = nullptr; |
| 481 | TagKind Tag; |
| 482 | }; |
| 483 | |
| 484 | struct ArrayTypeNode : public TypeNode { |
| 485 | ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {} |
| 486 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 487 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 488 | void outputPost(OutputStream &OS, OutputFlags Flags) const override; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 489 | |
| 490 | void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const; |
| 491 | void outputOneDimension(OutputStream &OS, 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 { |
| 501 | IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {} |
| 502 | void output(OutputStream &OS, OutputFlags Flags) const override {} |
| 503 | }; |
| 504 | |
| 505 | struct CustomTypeNode : public TypeNode { |
| 506 | CustomTypeNode() : TypeNode(NodeKind::Custom) {} |
| 507 | |
| 508 | void outputPre(OutputStream &OS, OutputFlags Flags) const override; |
| 509 | void outputPost(OutputStream &OS, OutputFlags Flags) const override; |
| 510 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 511 | IdentifierNode *Identifier = nullptr; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 512 | }; |
| 513 | |
| 514 | struct NodeArrayNode : public Node { |
| 515 | NodeArrayNode() : Node(NodeKind::NodeArray) {} |
| 516 | |
| 517 | void output(OutputStream &OS, OutputFlags Flags) const override; |
| 518 | |
| 519 | void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const; |
| 520 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 521 | Node **Nodes = nullptr; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 522 | size_t Count = 0; |
| 523 | }; |
| 524 | |
| 525 | struct QualifiedNameNode : public Node { |
| 526 | QualifiedNameNode() : Node(NodeKind::QualifiedName) {} |
| 527 | |
| 528 | void output(OutputStream &OS, 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(OutputStream &OS, 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(OutputStream &OS, 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(OutputStream &OS, 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(OutputStream &OS, 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(OutputStream &OS, OutputFlags Flags) const override; |
| 586 | QualifiedNameNode *TargetName = nullptr; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 587 | Qualifiers Quals = Qualifiers::Q_None; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 588 | }; |
| 589 | |
| 590 | struct LocalStaticGuardVariableNode : public SymbolNode { |
| 591 | LocalStaticGuardVariableNode() |
| 592 | : SymbolNode(NodeKind::LocalStaticGuardVariable) {} |
| 593 | |
| 594 | void output(OutputStream &OS, 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(OutputStream &OS, OutputFlags Flags) const override; |
| 603 | |
| 604 | StringView 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(OutputStream &OS, 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(OutputStream &OS, OutputFlags Flags) const override; |
| 622 | |
| 623 | FunctionSignatureNode *Signature = nullptr; |
| 624 | }; |
| 625 | |
| 626 | } // namespace ms_demangle |
| 627 | } // namespace llvm |
| 628 | |
| 629 | #endif |