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