1 //===- TypeRecord.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 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H 10 #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H 11 12 #include "llvm/ADT/APSInt.h" 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/Optional.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/DebugInfo/CodeView/CVRecord.h" 18 #include "llvm/DebugInfo/CodeView/CodeView.h" 19 #include "llvm/DebugInfo/CodeView/GUID.h" 20 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 21 #include "llvm/Support/BinaryStreamArray.h" 22 #include "llvm/Support/Endian.h" 23 #include <algorithm> 24 #include <cstdint> 25 #include <vector> 26 27 namespace llvm { 28 namespace codeview { 29 30 using support::little32_t; 31 using support::ulittle16_t; 32 using support::ulittle32_t; 33 34 struct CVMemberRecord { 35 TypeLeafKind Kind; 36 ArrayRef<uint8_t> Data; 37 }; 38 39 /// Equvalent to CV_fldattr_t in cvinfo.h. 40 struct MemberAttributes { 41 uint16_t Attrs = 0; 42 43 enum { 44 MethodKindShift = 2, 45 }; 46 47 MemberAttributes() = default; 48 49 explicit MemberAttributes(MemberAccess Access) 50 : Attrs(static_cast<uint16_t>(Access)) {} 51 52 MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) { 53 Attrs = static_cast<uint16_t>(Access); 54 Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift); 55 Attrs |= static_cast<uint16_t>(Flags); 56 } 57 58 /// Get the access specifier. Valid for any kind of member. 59 MemberAccess getAccess() const { 60 return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask)); 61 } 62 63 /// Indicates if a method is defined with friend, virtual, static, etc. 64 MethodKind getMethodKind() const { 65 return MethodKind( 66 (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >> 67 MethodKindShift); 68 } 69 70 /// Get the flags that are not included in access control or method 71 /// properties. 72 MethodOptions getFlags() const { 73 return MethodOptions( 74 unsigned(Attrs) & 75 ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask)); 76 } 77 78 /// Is this method virtual. 79 bool isVirtual() const { 80 auto MP = getMethodKind(); 81 return MP != MethodKind::Vanilla && MP != MethodKind::Friend && 82 MP != MethodKind::Static; 83 } 84 85 /// Does this member introduce a new virtual method. 86 bool isIntroducedVirtual() const { 87 auto MP = getMethodKind(); 88 return MP == MethodKind::IntroducingVirtual || 89 MP == MethodKind::PureIntroducingVirtual; 90 } 91 92 /// Is this method static. 93 bool isStatic() const { 94 return getMethodKind() == MethodKind::Static; 95 } 96 }; 97 98 // Does not correspond to any tag, this is the tail of an LF_POINTER record 99 // if it represents a member pointer. 100 class MemberPointerInfo { 101 public: 102 MemberPointerInfo() = default; 103 104 MemberPointerInfo(TypeIndex ContainingType, 105 PointerToMemberRepresentation Representation) 106 : ContainingType(ContainingType), Representation(Representation) {} 107 108 TypeIndex getContainingType() const { return ContainingType; } 109 PointerToMemberRepresentation getRepresentation() const { 110 return Representation; 111 } 112 113 TypeIndex ContainingType; 114 PointerToMemberRepresentation Representation; 115 }; 116 117 class TypeRecord { 118 protected: 119 TypeRecord() = default; 120 explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {} 121 122 public: 123 TypeRecordKind getKind() const { return Kind; } 124 125 TypeRecordKind Kind; 126 }; 127 128 // LF_MODIFIER 129 class ModifierRecord : public TypeRecord { 130 public: 131 ModifierRecord() = default; 132 explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 133 ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers) 134 : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType), 135 Modifiers(Modifiers) {} 136 137 TypeIndex getModifiedType() const { return ModifiedType; } 138 ModifierOptions getModifiers() const { return Modifiers; } 139 140 TypeIndex ModifiedType; 141 ModifierOptions Modifiers = ModifierOptions::None; 142 }; 143 144 // LF_PROCEDURE 145 class ProcedureRecord : public TypeRecord { 146 public: 147 ProcedureRecord() = default; 148 explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 149 ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv, 150 FunctionOptions Options, uint16_t ParameterCount, 151 TypeIndex ArgumentList) 152 : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType), 153 CallConv(CallConv), Options(Options), ParameterCount(ParameterCount), 154 ArgumentList(ArgumentList) {} 155 156 TypeIndex getReturnType() const { return ReturnType; } 157 CallingConvention getCallConv() const { return CallConv; } 158 FunctionOptions getOptions() const { return Options; } 159 uint16_t getParameterCount() const { return ParameterCount; } 160 TypeIndex getArgumentList() const { return ArgumentList; } 161 162 TypeIndex ReturnType; 163 CallingConvention CallConv; 164 FunctionOptions Options; 165 uint16_t ParameterCount = 0; 166 TypeIndex ArgumentList; 167 }; 168 169 // LF_MFUNCTION 170 class MemberFunctionRecord : public TypeRecord { 171 public: 172 MemberFunctionRecord() = default; 173 explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 174 175 MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType, 176 TypeIndex ThisType, CallingConvention CallConv, 177 FunctionOptions Options, uint16_t ParameterCount, 178 TypeIndex ArgumentList, int32_t ThisPointerAdjustment) 179 : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType), 180 ClassType(ClassType), ThisType(ThisType), CallConv(CallConv), 181 Options(Options), ParameterCount(ParameterCount), 182 ArgumentList(ArgumentList), 183 ThisPointerAdjustment(ThisPointerAdjustment) {} 184 185 TypeIndex getReturnType() const { return ReturnType; } 186 TypeIndex getClassType() const { return ClassType; } 187 TypeIndex getThisType() const { return ThisType; } 188 CallingConvention getCallConv() const { return CallConv; } 189 FunctionOptions getOptions() const { return Options; } 190 uint16_t getParameterCount() const { return ParameterCount; } 191 TypeIndex getArgumentList() const { return ArgumentList; } 192 int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; } 193 194 TypeIndex ReturnType; 195 TypeIndex ClassType; 196 TypeIndex ThisType; 197 CallingConvention CallConv; 198 FunctionOptions Options; 199 uint16_t ParameterCount = 0; 200 TypeIndex ArgumentList; 201 int32_t ThisPointerAdjustment = 0; 202 }; 203 204 // LF_LABEL 205 class LabelRecord : public TypeRecord { 206 public: 207 LabelRecord() = default; 208 explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 209 210 LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {} 211 212 LabelType Mode; 213 }; 214 215 // LF_MFUNC_ID 216 class MemberFuncIdRecord : public TypeRecord { 217 public: 218 MemberFuncIdRecord() = default; 219 explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 220 MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType, 221 StringRef Name) 222 : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType), 223 FunctionType(FunctionType), Name(Name) {} 224 225 TypeIndex getClassType() const { return ClassType; } 226 TypeIndex getFunctionType() const { return FunctionType; } 227 StringRef getName() const { return Name; } 228 229 TypeIndex ClassType; 230 TypeIndex FunctionType; 231 StringRef Name; 232 }; 233 234 // LF_ARGLIST 235 class ArgListRecord : public TypeRecord { 236 public: 237 ArgListRecord() = default; 238 explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 239 240 ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) 241 : TypeRecord(Kind), ArgIndices(Indices) {} 242 243 ArrayRef<TypeIndex> getIndices() const { return ArgIndices; } 244 245 std::vector<TypeIndex> ArgIndices; 246 }; 247 248 // LF_SUBSTR_LIST 249 class StringListRecord : public TypeRecord { 250 public: 251 StringListRecord() = default; 252 explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 253 254 StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) 255 : TypeRecord(Kind), StringIndices(Indices) {} 256 257 ArrayRef<TypeIndex> getIndices() const { return StringIndices; } 258 259 std::vector<TypeIndex> StringIndices; 260 }; 261 262 // LF_POINTER 263 class PointerRecord : public TypeRecord { 264 public: 265 // ---------------------------XXXXX 266 static const uint32_t PointerKindShift = 0; 267 static const uint32_t PointerKindMask = 0x1F; 268 269 // ------------------------XXX----- 270 static const uint32_t PointerModeShift = 5; 271 static const uint32_t PointerModeMask = 0x07; 272 273 // ----------XXX------XXXXX-------- 274 static const uint32_t PointerOptionMask = 0x381f00; 275 276 // -------------XXXXXX------------ 277 static const uint32_t PointerSizeShift = 13; 278 static const uint32_t PointerSizeMask = 0xFF; 279 280 PointerRecord() = default; 281 explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 282 283 PointerRecord(TypeIndex ReferentType, uint32_t Attrs) 284 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), 285 Attrs(Attrs) {} 286 287 PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, 288 PointerOptions PO, uint8_t Size) 289 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), 290 Attrs(calcAttrs(PK, PM, PO, Size)) {} 291 292 PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, 293 PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI) 294 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), 295 Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {} 296 297 TypeIndex getReferentType() const { return ReferentType; } 298 299 PointerKind getPointerKind() const { 300 return static_cast<PointerKind>((Attrs >> PointerKindShift) & 301 PointerKindMask); 302 } 303 304 PointerMode getMode() const { 305 return static_cast<PointerMode>((Attrs >> PointerModeShift) & 306 PointerModeMask); 307 } 308 309 PointerOptions getOptions() const { 310 return static_cast<PointerOptions>(Attrs & PointerOptionMask); 311 } 312 313 uint8_t getSize() const { 314 return (Attrs >> PointerSizeShift) & PointerSizeMask; 315 } 316 317 MemberPointerInfo getMemberInfo() const { return *MemberInfo; } 318 319 bool isPointerToMember() const { 320 return getMode() == PointerMode::PointerToDataMember || 321 getMode() == PointerMode::PointerToMemberFunction; 322 } 323 324 bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); } 325 bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); } 326 327 bool isVolatile() const { 328 return !!(Attrs & uint32_t(PointerOptions::Volatile)); 329 } 330 331 bool isUnaligned() const { 332 return !!(Attrs & uint32_t(PointerOptions::Unaligned)); 333 } 334 335 bool isRestrict() const { 336 return !!(Attrs & uint32_t(PointerOptions::Restrict)); 337 } 338 339 bool isLValueReferenceThisPtr() const { 340 return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer)); 341 } 342 343 bool isRValueReferenceThisPtr() const { 344 return !!(Attrs & uint32_t(PointerOptions::RValueRefThisPointer)); 345 } 346 347 TypeIndex ReferentType; 348 uint32_t Attrs = 0; 349 Optional<MemberPointerInfo> MemberInfo; 350 351 void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO, 352 uint8_t Size) { 353 Attrs = calcAttrs(PK, PM, PO, Size); 354 } 355 356 private: 357 static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO, 358 uint8_t Size) { 359 uint32_t A = 0; 360 A |= static_cast<uint32_t>(PK); 361 A |= static_cast<uint32_t>(PO); 362 A |= (static_cast<uint32_t>(PM) << PointerModeShift); 363 A |= (static_cast<uint32_t>(Size) << PointerSizeShift); 364 return A; 365 } 366 }; 367 368 // LF_NESTTYPE 369 class NestedTypeRecord : public TypeRecord { 370 public: 371 NestedTypeRecord() = default; 372 explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 373 NestedTypeRecord(TypeIndex Type, StringRef Name) 374 : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {} 375 376 TypeIndex getNestedType() const { return Type; } 377 StringRef getName() const { return Name; } 378 379 TypeIndex Type; 380 StringRef Name; 381 }; 382 383 // LF_FIELDLIST 384 class FieldListRecord : public TypeRecord { 385 public: 386 FieldListRecord() = default; 387 explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 388 explicit FieldListRecord(ArrayRef<uint8_t> Data) 389 : TypeRecord(TypeRecordKind::FieldList), Data(Data) {} 390 391 ArrayRef<uint8_t> Data; 392 }; 393 394 // LF_ARRAY 395 class ArrayRecord : public TypeRecord { 396 public: 397 ArrayRecord() = default; 398 explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 399 ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size, 400 StringRef Name) 401 : TypeRecord(TypeRecordKind::Array), ElementType(ElementType), 402 IndexType(IndexType), Size(Size), Name(Name) {} 403 404 TypeIndex getElementType() const { return ElementType; } 405 TypeIndex getIndexType() const { return IndexType; } 406 uint64_t getSize() const { return Size; } 407 StringRef getName() const { return Name; } 408 409 TypeIndex ElementType; 410 TypeIndex IndexType; 411 uint64_t Size = 0; 412 StringRef Name; 413 }; 414 415 class TagRecord : public TypeRecord { 416 protected: 417 TagRecord() = default; 418 explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 419 TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, 420 TypeIndex FieldList, StringRef Name, StringRef UniqueName) 421 : TypeRecord(Kind), MemberCount(MemberCount), Options(Options), 422 FieldList(FieldList), Name(Name), UniqueName(UniqueName) {} 423 424 public: 425 static const int HfaKindShift = 11; 426 static const int HfaKindMask = 0x1800; 427 static const int WinRTKindShift = 14; 428 static const int WinRTKindMask = 0xC000; 429 430 bool hasUniqueName() const { 431 return (Options & ClassOptions::HasUniqueName) != ClassOptions::None; 432 } 433 434 bool isNested() const { 435 return (Options & ClassOptions::Nested) != ClassOptions::None; 436 } 437 438 bool isForwardRef() const { 439 return (Options & ClassOptions::ForwardReference) != ClassOptions::None; 440 } 441 442 bool containsNestedClass() const { 443 return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None; 444 } 445 446 bool isScoped() const { 447 return (Options & ClassOptions::Scoped) != ClassOptions::None; 448 } 449 450 uint16_t getMemberCount() const { return MemberCount; } 451 ClassOptions getOptions() const { return Options; } 452 TypeIndex getFieldList() const { return FieldList; } 453 StringRef getName() const { return Name; } 454 StringRef getUniqueName() const { return UniqueName; } 455 456 uint16_t MemberCount = 0; 457 ClassOptions Options; 458 TypeIndex FieldList; 459 StringRef Name; 460 StringRef UniqueName; 461 }; 462 463 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE 464 class ClassRecord : public TagRecord { 465 public: 466 ClassRecord() = default; 467 explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {} 468 ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, 469 TypeIndex FieldList, TypeIndex DerivationList, 470 TypeIndex VTableShape, uint64_t Size, StringRef Name, 471 StringRef UniqueName) 472 : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName), 473 DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {} 474 475 HfaKind getHfa() const { 476 uint16_t Value = static_cast<uint16_t>(Options); 477 Value = (Value & HfaKindMask) >> HfaKindShift; 478 return static_cast<HfaKind>(Value); 479 } 480 481 WindowsRTClassKind getWinRTKind() const { 482 uint16_t Value = static_cast<uint16_t>(Options); 483 Value = (Value & WinRTKindMask) >> WinRTKindShift; 484 return static_cast<WindowsRTClassKind>(Value); 485 } 486 487 TypeIndex getDerivationList() const { return DerivationList; } 488 TypeIndex getVTableShape() const { return VTableShape; } 489 uint64_t getSize() const { return Size; } 490 491 TypeIndex DerivationList; 492 TypeIndex VTableShape; 493 uint64_t Size = 0; 494 }; 495 496 // LF_UNION 497 struct UnionRecord : public TagRecord { 498 UnionRecord() = default; 499 explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {} 500 UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, 501 uint64_t Size, StringRef Name, StringRef UniqueName) 502 : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name, 503 UniqueName), 504 Size(Size) {} 505 506 HfaKind getHfa() const { 507 uint16_t Value = static_cast<uint16_t>(Options); 508 Value = (Value & HfaKindMask) >> HfaKindShift; 509 return static_cast<HfaKind>(Value); 510 } 511 512 uint64_t getSize() const { return Size; } 513 514 uint64_t Size = 0; 515 }; 516 517 // LF_ENUM 518 class EnumRecord : public TagRecord { 519 public: 520 EnumRecord() = default; 521 explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {} 522 EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, 523 StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType) 524 : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name, 525 UniqueName), 526 UnderlyingType(UnderlyingType) {} 527 528 TypeIndex getUnderlyingType() const { return UnderlyingType; } 529 530 TypeIndex UnderlyingType; 531 }; 532 533 // LF_BITFIELD 534 class BitFieldRecord : public TypeRecord { 535 public: 536 BitFieldRecord() = default; 537 explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 538 BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset) 539 : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize), 540 BitOffset(BitOffset) {} 541 542 TypeIndex getType() const { return Type; } 543 uint8_t getBitOffset() const { return BitOffset; } 544 uint8_t getBitSize() const { return BitSize; } 545 546 TypeIndex Type; 547 uint8_t BitSize = 0; 548 uint8_t BitOffset = 0; 549 }; 550 551 // LF_VTSHAPE 552 class VFTableShapeRecord : public TypeRecord { 553 public: 554 VFTableShapeRecord() = default; 555 explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 556 explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots) 557 : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {} 558 explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots) 559 : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {} 560 561 ArrayRef<VFTableSlotKind> getSlots() const { 562 if (!SlotsRef.empty()) 563 return SlotsRef; 564 return Slots; 565 } 566 567 uint32_t getEntryCount() const { return getSlots().size(); } 568 569 ArrayRef<VFTableSlotKind> SlotsRef; 570 std::vector<VFTableSlotKind> Slots; 571 }; 572 573 // LF_TYPESERVER2 574 class TypeServer2Record : public TypeRecord { 575 public: 576 TypeServer2Record() = default; 577 explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {} 578 TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name) 579 : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) { 580 assert(GuidStr.size() == 16 && "guid isn't 16 bytes"); 581 ::memcpy(Guid.Guid, GuidStr.data(), 16); 582 } 583 584 const GUID &getGuid() const { return Guid; } 585 uint32_t getAge() const { return Age; } 586 StringRef getName() const { return Name; } 587 588 GUID Guid; 589 uint32_t Age = 0; 590 StringRef Name; 591 }; 592 593 // LF_STRING_ID 594 class StringIdRecord : public TypeRecord { 595 public: 596 StringIdRecord() = default; 597 explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 598 StringIdRecord(TypeIndex Id, StringRef String) 599 : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {} 600 601 TypeIndex getId() const { return Id; } 602 StringRef getString() const { return String; } 603 604 TypeIndex Id; 605 StringRef String; 606 }; 607 608 // LF_FUNC_ID 609 class FuncIdRecord : public TypeRecord { 610 public: 611 FuncIdRecord() = default; 612 explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 613 FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name) 614 : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope), 615 FunctionType(FunctionType), Name(Name) {} 616 617 TypeIndex getParentScope() const { return ParentScope; } 618 TypeIndex getFunctionType() const { return FunctionType; } 619 StringRef getName() const { return Name; } 620 621 TypeIndex ParentScope; 622 TypeIndex FunctionType; 623 StringRef Name; 624 }; 625 626 // LF_UDT_SRC_LINE 627 class UdtSourceLineRecord : public TypeRecord { 628 public: 629 UdtSourceLineRecord() = default; 630 explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 631 UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber) 632 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), 633 SourceFile(SourceFile), LineNumber(LineNumber) {} 634 635 TypeIndex getUDT() const { return UDT; } 636 TypeIndex getSourceFile() const { return SourceFile; } 637 uint32_t getLineNumber() const { return LineNumber; } 638 639 TypeIndex UDT; 640 TypeIndex SourceFile; 641 uint32_t LineNumber = 0; 642 }; 643 644 // LF_UDT_MOD_SRC_LINE 645 class UdtModSourceLineRecord : public TypeRecord { 646 public: 647 UdtModSourceLineRecord() = default; 648 explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 649 UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, 650 uint32_t LineNumber, uint16_t Module) 651 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), 652 SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {} 653 654 TypeIndex getUDT() const { return UDT; } 655 TypeIndex getSourceFile() const { return SourceFile; } 656 uint32_t getLineNumber() const { return LineNumber; } 657 uint16_t getModule() const { return Module; } 658 659 TypeIndex UDT; 660 TypeIndex SourceFile; 661 uint32_t LineNumber = 0; 662 uint16_t Module = 0; 663 }; 664 665 // LF_BUILDINFO 666 class BuildInfoRecord : public TypeRecord { 667 public: 668 BuildInfoRecord() = default; 669 explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 670 BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices) 671 : TypeRecord(TypeRecordKind::BuildInfo), 672 ArgIndices(ArgIndices.begin(), ArgIndices.end()) {} 673 674 ArrayRef<TypeIndex> getArgs() const { return ArgIndices; } 675 676 /// Indices of known build info arguments. 677 enum BuildInfoArg { 678 CurrentDirectory, ///< Absolute CWD path 679 BuildTool, ///< Absolute compiler path 680 SourceFile, ///< Path to main source file, relative or absolute 681 TypeServerPDB, ///< Absolute path of type server PDB (/Fd) 682 CommandLine, ///< Full canonical command line (maybe -cc1) 683 MaxArgs 684 }; 685 686 SmallVector<TypeIndex, MaxArgs> ArgIndices; 687 }; 688 689 // LF_VFTABLE 690 class VFTableRecord : public TypeRecord { 691 public: 692 VFTableRecord() = default; 693 explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 694 VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable, 695 uint32_t VFPtrOffset, StringRef Name, 696 ArrayRef<StringRef> Methods) 697 : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass), 698 OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) { 699 MethodNames.push_back(Name); 700 llvm::append_range(MethodNames, Methods); 701 } 702 703 TypeIndex getCompleteClass() const { return CompleteClass; } 704 TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } 705 uint32_t getVFPtrOffset() const { return VFPtrOffset; } 706 StringRef getName() const { return makeArrayRef(MethodNames).front(); } 707 708 ArrayRef<StringRef> getMethodNames() const { 709 return makeArrayRef(MethodNames).drop_front(); 710 } 711 712 TypeIndex CompleteClass; 713 TypeIndex OverriddenVFTable; 714 uint32_t VFPtrOffset = 0; 715 std::vector<StringRef> MethodNames; 716 }; 717 718 // LF_ONEMETHOD 719 class OneMethodRecord : public TypeRecord { 720 public: 721 OneMethodRecord() = default; 722 explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 723 OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset, 724 StringRef Name) 725 : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs), 726 VFTableOffset(VFTableOffset), Name(Name) {} 727 OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK, 728 MethodOptions Options, int32_t VFTableOffset, StringRef Name) 729 : TypeRecord(TypeRecordKind::OneMethod), Type(Type), 730 Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {} 731 732 TypeIndex getType() const { return Type; } 733 MethodKind getMethodKind() const { return Attrs.getMethodKind(); } 734 MethodOptions getOptions() const { return Attrs.getFlags(); } 735 MemberAccess getAccess() const { return Attrs.getAccess(); } 736 int32_t getVFTableOffset() const { return VFTableOffset; } 737 StringRef getName() const { return Name; } 738 739 bool isIntroducingVirtual() const { 740 return getMethodKind() == MethodKind::IntroducingVirtual || 741 getMethodKind() == MethodKind::PureIntroducingVirtual; 742 } 743 744 TypeIndex Type; 745 MemberAttributes Attrs; 746 int32_t VFTableOffset = 0; 747 StringRef Name; 748 }; 749 750 // LF_METHODLIST 751 class MethodOverloadListRecord : public TypeRecord { 752 public: 753 MethodOverloadListRecord() = default; 754 explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 755 MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods) 756 : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {} 757 758 ArrayRef<OneMethodRecord> getMethods() const { return Methods; } 759 760 std::vector<OneMethodRecord> Methods; 761 }; 762 763 /// For method overload sets. LF_METHOD 764 class OverloadedMethodRecord : public TypeRecord { 765 public: 766 OverloadedMethodRecord() = default; 767 explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 768 OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList, 769 StringRef Name) 770 : TypeRecord(TypeRecordKind::OverloadedMethod), 771 NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {} 772 773 uint16_t getNumOverloads() const { return NumOverloads; } 774 TypeIndex getMethodList() const { return MethodList; } 775 StringRef getName() const { return Name; } 776 777 uint16_t NumOverloads = 0; 778 TypeIndex MethodList; 779 StringRef Name; 780 }; 781 782 // LF_MEMBER 783 class DataMemberRecord : public TypeRecord { 784 public: 785 DataMemberRecord() = default; 786 explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 787 DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset, 788 StringRef Name) 789 : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type), 790 FieldOffset(Offset), Name(Name) {} 791 DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset, 792 StringRef Name) 793 : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type), 794 FieldOffset(Offset), Name(Name) {} 795 796 MemberAccess getAccess() const { return Attrs.getAccess(); } 797 TypeIndex getType() const { return Type; } 798 uint64_t getFieldOffset() const { return FieldOffset; } 799 StringRef getName() const { return Name; } 800 801 MemberAttributes Attrs; 802 TypeIndex Type; 803 uint64_t FieldOffset = 0; 804 StringRef Name; 805 }; 806 807 // LF_STMEMBER 808 class StaticDataMemberRecord : public TypeRecord { 809 public: 810 StaticDataMemberRecord() = default; 811 explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 812 StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name) 813 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type), 814 Name(Name) {} 815 StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name) 816 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type), 817 Name(Name) {} 818 819 MemberAccess getAccess() const { return Attrs.getAccess(); } 820 TypeIndex getType() const { return Type; } 821 StringRef getName() const { return Name; } 822 823 MemberAttributes Attrs; 824 TypeIndex Type; 825 StringRef Name; 826 }; 827 828 // LF_ENUMERATE 829 class EnumeratorRecord : public TypeRecord { 830 public: 831 EnumeratorRecord() = default; 832 explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 833 EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name) 834 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs), 835 Value(std::move(Value)), Name(Name) {} 836 EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name) 837 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access), 838 Value(std::move(Value)), Name(Name) {} 839 840 MemberAccess getAccess() const { return Attrs.getAccess(); } 841 APSInt getValue() const { return Value; } 842 StringRef getName() const { return Name; } 843 844 MemberAttributes Attrs; 845 APSInt Value; 846 StringRef Name; 847 }; 848 849 // LF_VFUNCTAB 850 class VFPtrRecord : public TypeRecord { 851 public: 852 VFPtrRecord() = default; 853 explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 854 VFPtrRecord(TypeIndex Type) 855 : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {} 856 857 TypeIndex getType() const { return Type; } 858 859 TypeIndex Type; 860 }; 861 862 // LF_BCLASS, LF_BINTERFACE 863 class BaseClassRecord : public TypeRecord { 864 public: 865 BaseClassRecord() = default; 866 explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 867 BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset) 868 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type), 869 Offset(Offset) {} 870 BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset) 871 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type), 872 Offset(Offset) {} 873 874 MemberAccess getAccess() const { return Attrs.getAccess(); } 875 TypeIndex getBaseType() const { return Type; } 876 uint64_t getBaseOffset() const { return Offset; } 877 878 MemberAttributes Attrs; 879 TypeIndex Type; 880 uint64_t Offset = 0; 881 }; 882 883 // LF_VBCLASS, LF_IVBCLASS 884 class VirtualBaseClassRecord : public TypeRecord { 885 public: 886 VirtualBaseClassRecord() = default; 887 explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 888 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs, 889 TypeIndex BaseType, TypeIndex VBPtrType, 890 uint64_t Offset, uint64_t Index) 891 : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType), 892 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} 893 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access, 894 TypeIndex BaseType, TypeIndex VBPtrType, 895 uint64_t Offset, uint64_t Index) 896 : TypeRecord(Kind), Attrs(Access), BaseType(BaseType), 897 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} 898 899 MemberAccess getAccess() const { return Attrs.getAccess(); } 900 TypeIndex getBaseType() const { return BaseType; } 901 TypeIndex getVBPtrType() const { return VBPtrType; } 902 uint64_t getVBPtrOffset() const { return VBPtrOffset; } 903 uint64_t getVTableIndex() const { return VTableIndex; } 904 905 MemberAttributes Attrs; 906 TypeIndex BaseType; 907 TypeIndex VBPtrType; 908 uint64_t VBPtrOffset = 0; 909 uint64_t VTableIndex = 0; 910 }; 911 912 /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records 913 /// together. The first will end in an LF_INDEX record that points to the next. 914 class ListContinuationRecord : public TypeRecord { 915 public: 916 ListContinuationRecord() = default; 917 explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 918 ListContinuationRecord(TypeIndex ContinuationIndex) 919 : TypeRecord(TypeRecordKind::ListContinuation), 920 ContinuationIndex(ContinuationIndex) {} 921 922 TypeIndex getContinuationIndex() const { return ContinuationIndex; } 923 924 TypeIndex ContinuationIndex; 925 }; 926 927 // LF_PRECOMP 928 class PrecompRecord : public TypeRecord { 929 public: 930 PrecompRecord() = default; 931 explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 932 933 uint32_t getStartTypeIndex() const { return StartTypeIndex; } 934 uint32_t getTypesCount() const { return TypesCount; } 935 uint32_t getSignature() const { return Signature; } 936 StringRef getPrecompFilePath() const { return PrecompFilePath; } 937 938 uint32_t StartTypeIndex = 0; 939 uint32_t TypesCount = 0; 940 uint32_t Signature = 0; 941 StringRef PrecompFilePath; 942 }; 943 944 // LF_ENDPRECOMP 945 class EndPrecompRecord : public TypeRecord { 946 public: 947 EndPrecompRecord() = default; 948 explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} 949 950 uint32_t getSignature() const { return Signature; } 951 952 uint32_t Signature = 0; 953 }; 954 955 } // end namespace codeview 956 } // end namespace llvm 957 958 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H 959