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