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/StringRef.h"
     16 #include "llvm/DebugInfo/CodeView/CVRecord.h"
     17 #include "llvm/DebugInfo/CodeView/CodeView.h"
     18 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
     19 #include "llvm/Support/ErrorOr.h"
     20 #include <cinttypes>
     21 #include <utility>
     22 
     23 namespace llvm {
     24 namespace codeview {
     25 
     26 using llvm::support::little32_t;
     27 using llvm::support::ulittle16_t;
     28 using llvm::support::ulittle32_t;
     29 
     30 /// Equvalent to CV_fldattr_t in cvinfo.h.
     31 struct MemberAttributes {
     32   ulittle16_t Attrs;
     33   enum {
     34     MethodKindShift = 2,
     35   };
     36 
     37   /// Get the access specifier. Valid for any kind of member.
     38   MemberAccess getAccess() const {
     39     return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
     40   }
     41 
     42   /// Indicates if a method is defined with friend, virtual, static, etc.
     43   MethodKind getMethodKind() const {
     44     return MethodKind(
     45         (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
     46         MethodKindShift);
     47   }
     48 
     49   /// Get the flags that are not included in access control or method
     50   /// properties.
     51   MethodOptions getFlags() const {
     52     return MethodOptions(
     53         unsigned(Attrs) &
     54         ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
     55   }
     56 
     57   /// Is this method virtual.
     58   bool isVirtual() const {
     59     auto MP = getMethodKind();
     60     return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
     61            MP != MethodKind::Static;
     62   }
     63 
     64   /// Does this member introduce a new virtual method.
     65   bool isIntroducedVirtual() const {
     66     auto MP = getMethodKind();
     67     return MP == MethodKind::IntroducingVirtual ||
     68            MP == MethodKind::PureIntroducingVirtual;
     69   }
     70 };
     71 
     72 // Does not correspond to any tag, this is the tail of an LF_POINTER record
     73 // if it represents a member pointer.
     74 class MemberPointerInfo {
     75 public:
     76   MemberPointerInfo() {}
     77 
     78   MemberPointerInfo(TypeIndex ContainingType,
     79                     PointerToMemberRepresentation Representation)
     80       : ContainingType(ContainingType), Representation(Representation) {}
     81 
     82   /// Rewrite member type indices with IndexMap. Returns false if a type index
     83   /// is not in the map.
     84   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
     85 
     86   static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
     87 
     88   TypeIndex getContainingType() const { return ContainingType; }
     89   PointerToMemberRepresentation getRepresentation() const {
     90     return Representation;
     91   }
     92 
     93 private:
     94   struct Layout {
     95     TypeIndex ClassType;
     96     ulittle16_t Representation; // PointerToMemberRepresentation
     97   };
     98 
     99   TypeIndex ContainingType;
    100   PointerToMemberRepresentation Representation;
    101 };
    102 
    103 class TypeRecord {
    104 protected:
    105   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
    106 
    107 public:
    108   TypeRecordKind getKind() const { return Kind; }
    109 
    110 private:
    111   TypeRecordKind Kind;
    112 };
    113 
    114 // LF_MODIFIER
    115 class ModifierRecord : public TypeRecord {
    116 public:
    117   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
    118       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
    119         Modifiers(Modifiers) {}
    120 
    121   /// Rewrite member type indices with IndexMap. Returns false if a type index
    122   /// is not in the map.
    123   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    124 
    125   static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
    126                                              ArrayRef<uint8_t> &Data);
    127 
    128   TypeIndex getModifiedType() const { return ModifiedType; }
    129   ModifierOptions getModifiers() const { return Modifiers; }
    130 
    131 private:
    132   struct Layout {
    133     TypeIndex ModifiedType;
    134     ulittle16_t Modifiers; // ModifierOptions
    135   };
    136 
    137   TypeIndex ModifiedType;
    138   ModifierOptions Modifiers;
    139 };
    140 
    141 // LF_PROCEDURE
    142 class ProcedureRecord : public TypeRecord {
    143 public:
    144   ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
    145                   FunctionOptions Options, uint16_t ParameterCount,
    146                   TypeIndex ArgumentList)
    147       : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
    148         CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
    149         ArgumentList(ArgumentList) {}
    150 
    151   /// Rewrite member type indices with IndexMap. Returns false if a type index
    152   /// is not in the map.
    153   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    154 
    155   static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
    156                                               ArrayRef<uint8_t> &Data);
    157 
    158   static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
    159 
    160   TypeIndex getReturnType() const { return ReturnType; }
    161   CallingConvention getCallConv() const { return CallConv; }
    162   FunctionOptions getOptions() const { return Options; }
    163   uint16_t getParameterCount() const { return ParameterCount; }
    164   TypeIndex getArgumentList() const { return ArgumentList; }
    165 
    166 private:
    167   struct Layout {
    168     TypeIndex ReturnType;
    169     CallingConvention CallConv;
    170     FunctionOptions Options;
    171     ulittle16_t NumParameters;
    172     TypeIndex ArgListType;
    173   };
    174 
    175   TypeIndex ReturnType;
    176   CallingConvention CallConv;
    177   FunctionOptions Options;
    178   uint16_t ParameterCount;
    179   TypeIndex ArgumentList;
    180 };
    181 
    182 // LF_MFUNCTION
    183 class MemberFunctionRecord : public TypeRecord {
    184 public:
    185   MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
    186                        TypeIndex ThisType, CallingConvention CallConv,
    187                        FunctionOptions Options, uint16_t ParameterCount,
    188                        TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
    189       : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
    190         ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
    191         Options(Options), ParameterCount(ParameterCount),
    192         ArgumentList(ArgumentList),
    193         ThisPointerAdjustment(ThisPointerAdjustment) {}
    194 
    195   /// Rewrite member type indices with IndexMap. Returns false if a type index
    196   /// is not in the map.
    197   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    198 
    199   static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
    200                                                    ArrayRef<uint8_t> &Data);
    201 
    202   TypeIndex getReturnType() const { return ReturnType; }
    203   TypeIndex getClassType() const { return ClassType; }
    204   TypeIndex getThisType() const { return ThisType; }
    205   CallingConvention getCallConv() const { return CallConv; }
    206   FunctionOptions getOptions() const { return Options; }
    207   uint16_t getParameterCount() const { return ParameterCount; }
    208   TypeIndex getArgumentList() const { return ArgumentList; }
    209   int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
    210 
    211 private:
    212   struct Layout {
    213     TypeIndex ReturnType;
    214     TypeIndex ClassType;
    215     TypeIndex ThisType;
    216     CallingConvention CallConv;
    217     FunctionOptions Options;
    218     ulittle16_t NumParameters;
    219     TypeIndex ArgListType;
    220     little32_t ThisAdjustment;
    221   };
    222 
    223   TypeIndex ReturnType;
    224   TypeIndex ClassType;
    225   TypeIndex ThisType;
    226   CallingConvention CallConv;
    227   FunctionOptions Options;
    228   uint16_t ParameterCount;
    229   TypeIndex ArgumentList;
    230   int32_t ThisPointerAdjustment;
    231 };
    232 
    233 // LF_MFUNC_ID
    234 class MemberFuncIdRecord : public TypeRecord {
    235 public:
    236   MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
    237                          StringRef Name)
    238       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
    239         FunctionType(FunctionType), Name(Name) {}
    240 
    241   /// Rewrite member type indices with IndexMap. Returns false if a type index
    242   /// is not in the map.
    243   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    244 
    245   static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
    246                                                  ArrayRef<uint8_t> &Data);
    247   TypeIndex getClassType() const { return ClassType; }
    248   TypeIndex getFunctionType() const { return FunctionType; }
    249   StringRef getName() const { return Name; }
    250 
    251 private:
    252   struct Layout {
    253     TypeIndex ClassType;
    254     TypeIndex FunctionType;
    255     // Name: The null-terminated name follows.
    256   };
    257   TypeIndex ClassType;
    258   TypeIndex FunctionType;
    259   StringRef Name;
    260 };
    261 
    262 // LF_ARGLIST, LF_SUBSTR_LIST
    263 class ArgListRecord : public TypeRecord {
    264 public:
    265   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
    266       : TypeRecord(Kind), StringIndices(Indices) {}
    267 
    268   /// Rewrite member type indices with IndexMap. Returns false if a type index
    269   /// is not in the map.
    270   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    271 
    272   static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
    273                                             ArrayRef<uint8_t> &Data);
    274 
    275   ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
    276 
    277   static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
    278 
    279 private:
    280   struct Layout {
    281     ulittle32_t NumArgs; // Number of arguments
    282                          // ArgTypes[]: Type indicies of arguments
    283   };
    284 
    285   std::vector<TypeIndex> StringIndices;
    286 };
    287 
    288 // LF_POINTER
    289 class PointerRecord : public TypeRecord {
    290 public:
    291   static const uint32_t PointerKindShift = 0;
    292   static const uint32_t PointerKindMask = 0x1F;
    293 
    294   static const uint32_t PointerModeShift = 5;
    295   static const uint32_t PointerModeMask = 0x07;
    296 
    297   static const uint32_t PointerSizeShift = 13;
    298   static const uint32_t PointerSizeMask = 0xFF;
    299 
    300   PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
    301                 PointerOptions Options, uint8_t Size)
    302       : PointerRecord(ReferentType, Kind, Mode, Options, Size,
    303                       MemberPointerInfo()) {}
    304 
    305   PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
    306                 PointerOptions Options, uint8_t Size,
    307                 const MemberPointerInfo &Member)
    308       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
    309         PtrKind(Kind), Mode(Mode), Options(Options), Size(Size),
    310         MemberInfo(Member) {}
    311 
    312   /// Rewrite member type indices with IndexMap. Returns false if a type index
    313   /// is not in the map.
    314   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    315 
    316   static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
    317                                             ArrayRef<uint8_t> &Data);
    318 
    319   TypeIndex getReferentType() const { return ReferentType; }
    320   PointerKind getPointerKind() const { return PtrKind; }
    321   PointerMode getMode() const { return Mode; }
    322   PointerOptions getOptions() const { return Options; }
    323   uint8_t getSize() const { return Size; }
    324   MemberPointerInfo getMemberInfo() const { return MemberInfo; }
    325 
    326   bool isPointerToMember() const {
    327     return Mode == PointerMode::PointerToDataMember ||
    328            Mode == PointerMode::PointerToMemberFunction;
    329   }
    330   bool isFlat() const {
    331     return !!(uint32_t(Options) & uint32_t(PointerOptions::Flat32));
    332   }
    333   bool isConst() const {
    334     return !!(uint32_t(Options) & uint32_t(PointerOptions::Const));
    335   }
    336   bool isVolatile() const {
    337     return !!(uint32_t(Options) & uint32_t(PointerOptions::Volatile));
    338   }
    339   bool isUnaligned() const {
    340     return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned));
    341   }
    342 
    343 private:
    344   struct Layout {
    345     TypeIndex PointeeType;
    346     ulittle32_t Attrs; // pointer attributes
    347                        // if pointer to member:
    348                        //   PointerToMemberTail
    349     PointerKind getPtrKind() const {
    350       return PointerKind(Attrs & PointerKindMask);
    351     }
    352     PointerMode getPtrMode() const {
    353       return PointerMode((Attrs >> PointerModeShift) & PointerModeMask);
    354     }
    355     uint8_t getPtrSize() const {
    356       return (Attrs >> PointerSizeShift) & PointerSizeMask;
    357     }
    358     bool isFlat() const { return Attrs & (1 << 8); }
    359     bool isVolatile() const { return Attrs & (1 << 9); }
    360     bool isConst() const { return Attrs & (1 << 10); }
    361     bool isUnaligned() const { return Attrs & (1 << 11); }
    362 
    363     bool isPointerToDataMember() const {
    364       return getPtrMode() == PointerMode::PointerToDataMember;
    365     }
    366     bool isPointerToMemberFunction() const {
    367       return getPtrMode() == PointerMode::PointerToMemberFunction;
    368     }
    369     bool isPointerToMember() const {
    370       return isPointerToMemberFunction() || isPointerToDataMember();
    371     }
    372   };
    373 
    374   TypeIndex ReferentType;
    375   PointerKind PtrKind;
    376   PointerMode Mode;
    377   PointerOptions Options;
    378   uint8_t Size;
    379   MemberPointerInfo MemberInfo;
    380 };
    381 
    382 // LF_NESTTYPE
    383 class NestedTypeRecord : public TypeRecord {
    384 public:
    385   NestedTypeRecord(TypeIndex Type, StringRef Name)
    386       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
    387 
    388   /// Rewrite member type indices with IndexMap. Returns false if a type index
    389   /// is not in the map.
    390   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    391 
    392   static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
    393                                                ArrayRef<uint8_t> &Data);
    394 
    395   TypeIndex getNestedType() const { return Type; }
    396   StringRef getName() const { return Name; }
    397 
    398 private:
    399   struct Layout {
    400     ulittle16_t Pad0; // Should be zero
    401     TypeIndex Type;   // Type index of nested type
    402                       // Name: Null-terminated string
    403   };
    404 
    405   TypeIndex Type;
    406   StringRef Name;
    407 };
    408 
    409 // LF_ARRAY
    410 class ArrayRecord : public TypeRecord {
    411 public:
    412   ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
    413               StringRef Name)
    414       : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
    415         IndexType(IndexType), Size(Size), Name(Name) {}
    416 
    417   /// Rewrite member type indices with IndexMap. Returns false if a type index
    418   /// is not in the map.
    419   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    420 
    421   static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
    422                                           ArrayRef<uint8_t> &Data);
    423 
    424   TypeIndex getElementType() const { return ElementType; }
    425   TypeIndex getIndexType() const { return IndexType; }
    426   uint64_t getSize() const { return Size; }
    427   llvm::StringRef getName() const { return Name; }
    428 
    429 private:
    430   struct Layout {
    431     TypeIndex ElementType;
    432     TypeIndex IndexType;
    433     // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
    434     // Name: The null-terminated name follows.
    435   };
    436 
    437   TypeIndex ElementType;
    438   TypeIndex IndexType;
    439   uint64_t Size;
    440   llvm::StringRef Name;
    441 };
    442 
    443 class TagRecord : public TypeRecord {
    444 protected:
    445   TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
    446             TypeIndex FieldList, StringRef Name, StringRef UniqueName)
    447       : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
    448         FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
    449 
    450 public:
    451   /// Rewrite member type indices with IndexMap. Returns false if a type index
    452   /// is not in the map.
    453   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    454 
    455   static const int HfaKindShift = 11;
    456   static const int HfaKindMask = 0x1800;
    457   static const int WinRTKindShift = 14;
    458   static const int WinRTKindMask = 0xC000;
    459 
    460   uint16_t getMemberCount() const { return MemberCount; }
    461   ClassOptions getOptions() const { return Options; }
    462   TypeIndex getFieldList() const { return FieldList; }
    463   StringRef getName() const { return Name; }
    464   StringRef getUniqueName() const { return UniqueName; }
    465 
    466 private:
    467   uint16_t MemberCount;
    468   ClassOptions Options;
    469   TypeIndex FieldList;
    470   StringRef Name;
    471   StringRef UniqueName;
    472 };
    473 
    474 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
    475 class ClassRecord : public TagRecord {
    476 public:
    477   ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
    478               HfaKind Hfa, WindowsRTClassKind WinRTKind, TypeIndex FieldList,
    479               TypeIndex DerivationList, TypeIndex VTableShape, uint64_t Size,
    480               StringRef Name, StringRef UniqueName)
    481       : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
    482         Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList),
    483         VTableShape(VTableShape), Size(Size) {}
    484 
    485   /// Rewrite member type indices with IndexMap. Returns false if a type index
    486   /// is not in the map.
    487   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    488 
    489   static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
    490                                           ArrayRef<uint8_t> &Data);
    491 
    492   HfaKind getHfa() const { return Hfa; }
    493   WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
    494   TypeIndex getDerivationList() const { return DerivationList; }
    495   TypeIndex getVTableShape() const { return VTableShape; }
    496   uint64_t getSize() const { return Size; }
    497 
    498 private:
    499   struct Layout {
    500     ulittle16_t MemberCount; // Number of members in FieldList.
    501     ulittle16_t Properties;  // ClassOptions bitset
    502     TypeIndex FieldList;     // LF_FIELDLIST: List of all kinds of members
    503     TypeIndex DerivedFrom;   // LF_DERIVED: List of known derived classes
    504     TypeIndex VShape;        // LF_VTSHAPE: Shape of the vftable
    505     // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
    506     // integer.
    507     // Name: The null-terminated name follows.
    508 
    509     bool hasUniqueName() const {
    510       return Properties & uint16_t(ClassOptions::HasUniqueName);
    511     }
    512   };
    513 
    514   HfaKind Hfa;
    515   WindowsRTClassKind WinRTKind;
    516   TypeIndex DerivationList;
    517   TypeIndex VTableShape;
    518   uint64_t Size;
    519 };
    520 
    521 // LF_UNION
    522 struct UnionRecord : public TagRecord {
    523   UnionRecord(uint16_t MemberCount, ClassOptions Options, HfaKind Hfa,
    524               TypeIndex FieldList, uint64_t Size, StringRef Name,
    525               StringRef UniqueName)
    526       : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
    527                   UniqueName),
    528         Hfa(Hfa), Size(Size) {}
    529 
    530   static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
    531                                           ArrayRef<uint8_t> &Data);
    532 
    533   HfaKind getHfa() const { return Hfa; }
    534   uint64_t getSize() const { return Size; }
    535 
    536 private:
    537   struct Layout {
    538     ulittle16_t MemberCount; // Number of members in FieldList.
    539     ulittle16_t Properties;  // ClassOptions bitset
    540     TypeIndex FieldList;     // LF_FIELDLIST: List of all kinds of members
    541     // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
    542     // integer.
    543     // Name: The null-terminated name follows.
    544 
    545     bool hasUniqueName() const {
    546       return Properties & uint16_t(ClassOptions::HasUniqueName);
    547     }
    548   };
    549 
    550   HfaKind Hfa;
    551   uint64_t Size;
    552 };
    553 
    554 // LF_ENUM
    555 class EnumRecord : public TagRecord {
    556 public:
    557   EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
    558              StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
    559       : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
    560                   UniqueName),
    561         UnderlyingType(UnderlyingType) {}
    562 
    563   /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
    564   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    565 
    566   static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
    567                                          ArrayRef<uint8_t> &Data);
    568 
    569   TypeIndex getUnderlyingType() const { return UnderlyingType; }
    570 
    571 private:
    572   struct Layout {
    573     ulittle16_t NumEnumerators; // Number of enumerators
    574     ulittle16_t Properties;
    575     TypeIndex UnderlyingType;
    576     TypeIndex FieldListType;
    577     // Name: The null-terminated name follows.
    578 
    579     bool hasUniqueName() const {
    580       return Properties & uint16_t(ClassOptions::HasUniqueName);
    581     }
    582   };
    583 
    584   TypeIndex UnderlyingType;
    585 };
    586 
    587 // LF_BITFIELD
    588 class BitFieldRecord : public TypeRecord {
    589 public:
    590   BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
    591       : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
    592         BitOffset(BitOffset) {}
    593 
    594   /// Rewrite member type indices with IndexMap. Returns false if a type index
    595   /// is not in the map.
    596   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    597 
    598   static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
    599                                              ArrayRef<uint8_t> &Data);
    600 
    601   TypeIndex getType() const { return Type; }
    602   uint8_t getBitOffset() const { return BitOffset; }
    603   uint8_t getBitSize() const { return BitSize; }
    604 
    605 private:
    606   struct Layout {
    607     TypeIndex Type;
    608     uint8_t BitSize;
    609     uint8_t BitOffset;
    610   };
    611 
    612   TypeIndex Type;
    613   uint8_t BitSize;
    614   uint8_t BitOffset;
    615 };
    616 
    617 // LF_VTSHAPE
    618 class VFTableShapeRecord : public TypeRecord {
    619 public:
    620   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
    621       : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
    622   explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
    623       : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
    624 
    625   /// Rewrite member type indices with IndexMap. Returns false if a type index
    626   /// is not in the map.
    627   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    628 
    629   static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
    630                                                  ArrayRef<uint8_t> &Data);
    631 
    632   ArrayRef<VFTableSlotKind> getSlots() const {
    633     if (!SlotsRef.empty())
    634       return SlotsRef;
    635     return Slots;
    636   }
    637   uint32_t getEntryCount() const { return getSlots().size(); }
    638 
    639 private:
    640   struct Layout {
    641     // Number of vftable entries. Each method may have more than one entry due
    642     // to
    643     // things like covariant return types.
    644     ulittle16_t VFEntryCount;
    645     // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e.
    646   };
    647 
    648 private:
    649   ArrayRef<VFTableSlotKind> SlotsRef;
    650   std::vector<VFTableSlotKind> Slots;
    651 };
    652 
    653 // LF_TYPESERVER2
    654 class TypeServer2Record : public TypeRecord {
    655 public:
    656   TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
    657       : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
    658         Name(Name) {}
    659 
    660   /// Rewrite member type indices with IndexMap. Returns false if a type index
    661   /// is not in the map.
    662   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    663 
    664   static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
    665                                                 ArrayRef<uint8_t> &Data);
    666 
    667   StringRef getGuid() const { return Guid; }
    668 
    669   uint32_t getAge() const { return Age; }
    670 
    671   StringRef getName() const { return Name; }
    672 
    673 private:
    674   struct Layout {
    675     char Guid[16]; // GUID
    676     ulittle32_t Age;
    677     // Name: Name of the PDB as a null-terminated string
    678   };
    679 
    680   StringRef Guid;
    681   uint32_t Age;
    682   StringRef Name;
    683 };
    684 
    685 // LF_STRING_ID
    686 class StringIdRecord : public TypeRecord {
    687 public:
    688   StringIdRecord(TypeIndex Id, StringRef String)
    689       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
    690 
    691   /// Rewrite member type indices with IndexMap. Returns false if a type index
    692   /// is not in the map.
    693   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    694 
    695   static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
    696                                              ArrayRef<uint8_t> &Data);
    697 
    698   TypeIndex getId() const { return Id; }
    699 
    700   StringRef getString() const { return String; }
    701 
    702 private:
    703   struct Layout {
    704     TypeIndex id;
    705     // Name: Name of the PDB as a null-terminated string
    706   };
    707 
    708   TypeIndex Id;
    709   StringRef String;
    710 };
    711 
    712 // LF_FUNC_ID
    713 class FuncIdRecord : public TypeRecord {
    714 public:
    715   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
    716       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
    717         FunctionType(FunctionType), Name(Name) {}
    718 
    719   /// Rewrite member type indices with IndexMap. Returns false if a type index
    720   /// is not in the map.
    721   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    722 
    723   static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
    724                                            ArrayRef<uint8_t> &Data);
    725 
    726   TypeIndex getParentScope() const { return ParentScope; }
    727 
    728   TypeIndex getFunctionType() const { return FunctionType; }
    729 
    730   StringRef getName() const { return Name; }
    731 
    732 private:
    733   struct Layout {
    734     TypeIndex ParentScope;
    735     TypeIndex FunctionType;
    736     // Name: The null-terminated name follows.
    737   };
    738 
    739   TypeIndex ParentScope;
    740   TypeIndex FunctionType;
    741   StringRef Name;
    742 };
    743 
    744 // LF_UDT_SRC_LINE
    745 class UdtSourceLineRecord : public TypeRecord {
    746 public:
    747   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
    748       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
    749         SourceFile(SourceFile), LineNumber(LineNumber) {}
    750 
    751   /// Rewrite member type indices with IndexMap. Returns false if a type index
    752   /// is not in the map.
    753   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    754 
    755   static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
    756                                                   ArrayRef<uint8_t> &Data);
    757 
    758   TypeIndex getUDT() const { return UDT; }
    759   TypeIndex getSourceFile() const { return SourceFile; }
    760   uint32_t getLineNumber() const { return LineNumber; }
    761 
    762 private:
    763   struct Layout {
    764     TypeIndex UDT;        // The user-defined type
    765     TypeIndex SourceFile; // StringID containing the source filename
    766     ulittle32_t LineNumber;
    767   };
    768 
    769   TypeIndex UDT;
    770   TypeIndex SourceFile;
    771   uint32_t LineNumber;
    772 };
    773 
    774 // LF_UDT_MOD_SRC_LINE
    775 class UdtModSourceLineRecord : public TypeRecord {
    776 public:
    777   UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
    778                          uint32_t LineNumber, uint16_t Module)
    779       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
    780         SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
    781 
    782   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    783 
    784   static ErrorOr<UdtModSourceLineRecord> deserialize(TypeRecordKind Kind,
    785                                                      ArrayRef<uint8_t> &Data) {
    786     const Layout *L = nullptr;
    787     CV_DESERIALIZE(Data, L);
    788 
    789     return UdtModSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber,
    790                                   L->Module);
    791   }
    792 
    793   TypeIndex getUDT() const { return UDT; }
    794   TypeIndex getSourceFile() const { return SourceFile; }
    795   uint32_t getLineNumber() const { return LineNumber; }
    796   uint16_t getModule() const { return Module; }
    797 
    798 private:
    799   struct Layout {
    800     TypeIndex UDT;        // The user-defined type
    801     TypeIndex SourceFile; // StringID containing the source filename
    802     ulittle32_t LineNumber;
    803     ulittle16_t Module; // Module that contributes this UDT definition
    804   };
    805 
    806   TypeIndex UDT;
    807   TypeIndex SourceFile;
    808   uint32_t LineNumber;
    809   uint16_t Module;
    810 };
    811 
    812 // LF_BUILDINFO
    813 class BuildInfoRecord : public TypeRecord {
    814 public:
    815   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
    816       : TypeRecord(TypeRecordKind::BuildInfo),
    817         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
    818 
    819   /// Rewrite member type indices with IndexMap. Returns false if a type index
    820   /// is not in the map.
    821   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    822 
    823   static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
    824                                               ArrayRef<uint8_t> &Data);
    825 
    826   ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
    827 
    828 private:
    829   struct Layout {
    830     ulittle16_t NumArgs; // Number of arguments
    831                          // ArgTypes[]: Type indicies of arguments
    832   };
    833   SmallVector<TypeIndex, 4> ArgIndices;
    834 };
    835 
    836 // LF_VFTABLE
    837 class VFTableRecord : public TypeRecord {
    838 public:
    839   VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
    840                 uint32_t VFPtrOffset, StringRef Name,
    841                 ArrayRef<StringRef> Methods)
    842       : TypeRecord(TypeRecordKind::VFTable),
    843         CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
    844         VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {}
    845   VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
    846                 uint32_t VFPtrOffset, StringRef Name,
    847                 const std::vector<StringRef> &Methods)
    848       : TypeRecord(TypeRecordKind::VFTable),
    849         CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
    850         VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {}
    851 
    852   /// Rewrite member type indices with IndexMap. Returns false if a type index
    853   /// is not in the map.
    854   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    855 
    856   static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
    857                                             ArrayRef<uint8_t> &Data);
    858 
    859   TypeIndex getCompleteClass() const { return CompleteClass; }
    860   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
    861   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
    862   StringRef getName() const { return Name; }
    863   ArrayRef<StringRef> getMethodNames() const {
    864     if (!MethodNamesRef.empty())
    865       return MethodNamesRef;
    866     return MethodNames;
    867   }
    868 
    869 private:
    870   struct Layout {
    871     TypeIndex CompleteClass;     // Class that owns this vftable.
    872     TypeIndex OverriddenVFTable; // VFTable that this overrides.
    873     ulittle32_t VFPtrOffset;     // VFPtr offset in CompleteClass
    874     ulittle32_t NamesLen;        // Length of subsequent names array in bytes.
    875     // Names: A sequence of null-terminated strings. First string is vftable
    876     // names.
    877   };
    878 
    879   TypeIndex CompleteClass;
    880   TypeIndex OverriddenVFTable;
    881   ulittle32_t VFPtrOffset;
    882   StringRef Name;
    883   ArrayRef<StringRef> MethodNamesRef;
    884   std::vector<StringRef> MethodNames;
    885 };
    886 
    887 // LF_ONEMETHOD
    888 class OneMethodRecord : public TypeRecord {
    889 public:
    890   OneMethodRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options,
    891                   MemberAccess Access, int32_t VFTableOffset, StringRef Name)
    892       : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Kind(Kind),
    893         Options(Options), Access(Access), VFTableOffset(VFTableOffset),
    894         Name(Name) {}
    895 
    896   /// Rewrite member type indices with IndexMap. Returns false if a type index
    897   /// is not in the map.
    898   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    899 
    900   static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
    901                                               ArrayRef<uint8_t> &Data);
    902 
    903   TypeIndex getType() const { return Type; }
    904   MethodKind getKind() const { return Kind; }
    905   MethodOptions getOptions() const { return Options; }
    906   MemberAccess getAccess() const { return Access; }
    907   int32_t getVFTableOffset() const { return VFTableOffset; }
    908   StringRef getName() const { return Name; }
    909 
    910   bool isIntroducingVirtual() const {
    911     return Kind == MethodKind::IntroducingVirtual ||
    912            Kind == MethodKind::PureIntroducingVirtual;
    913   }
    914 
    915 private:
    916   struct Layout {
    917     MemberAttributes Attrs;
    918     TypeIndex Type;
    919     // If is introduced virtual method:
    920     //   VFTableOffset: int32_t offset in vftable
    921     // Name: Null-terminated string
    922   };
    923 
    924   TypeIndex Type;
    925   MethodKind Kind;
    926   MethodOptions Options;
    927   MemberAccess Access;
    928   int32_t VFTableOffset;
    929   StringRef Name;
    930 };
    931 
    932 // LF_METHODLIST
    933 class MethodOverloadListRecord : public TypeRecord {
    934 public:
    935   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
    936       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
    937 
    938   /// Rewrite member type indices with IndexMap. Returns false if a type index
    939   /// is not in the map.
    940   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    941 
    942   static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
    943                                                        ArrayRef<uint8_t> &Data);
    944 
    945   ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
    946 
    947 private:
    948   struct Layout {
    949     MemberAttributes Attrs;
    950     ulittle16_t Padding;
    951 
    952     TypeIndex Type;
    953     // If is introduced virtual method:
    954     //   VFTableOffset: int32_t offset in vftable
    955   };
    956 
    957   std::vector<OneMethodRecord> Methods;
    958 };
    959 
    960 /// For method overload sets.  LF_METHOD
    961 class OverloadedMethodRecord : public TypeRecord {
    962 public:
    963   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
    964                          StringRef Name)
    965       : TypeRecord(TypeRecordKind::OverloadedMethod),
    966         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
    967 
    968   /// Rewrite member type indices with IndexMap. Returns false if a type index
    969   /// is not in the map.
    970   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
    971 
    972   static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
    973                                                      ArrayRef<uint8_t> &Data);
    974 
    975   uint16_t getNumOverloads() const { return NumOverloads; }
    976   TypeIndex getMethodList() const { return MethodList; }
    977   StringRef getName() const { return Name; }
    978 
    979 private:
    980   struct Layout {
    981     ulittle16_t MethodCount; // Size of overload set
    982     TypeIndex MethList;      // Type index of methods in overload set
    983                              // Name: Null-terminated string
    984   };
    985 
    986   uint16_t NumOverloads;
    987   TypeIndex MethodList;
    988   StringRef Name;
    989 };
    990 
    991 // LF_MEMBER
    992 class DataMemberRecord : public TypeRecord {
    993 public:
    994   DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
    995                    StringRef Name)
    996       : TypeRecord(TypeRecordKind::DataMember), Access(Access), Type(Type),
    997         FieldOffset(Offset), Name(Name) {}
    998 
    999   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1000   /// is not in the map.
   1001   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1002 
   1003   static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
   1004                                                ArrayRef<uint8_t> &Data);
   1005 
   1006   MemberAccess getAccess() const { return Access; }
   1007   TypeIndex getType() const { return Type; }
   1008   uint64_t getFieldOffset() const { return FieldOffset; }
   1009   StringRef getName() const { return Name; }
   1010 
   1011 private:
   1012   struct Layout {
   1013     MemberAttributes Attrs; // Access control attributes, etc
   1014     TypeIndex Type;
   1015     // FieldOffset: LF_NUMERIC encoded byte offset
   1016     // Name: Null-terminated string
   1017   };
   1018 
   1019   MemberAccess Access;
   1020   TypeIndex Type;
   1021   uint64_t FieldOffset;
   1022   StringRef Name;
   1023 };
   1024 
   1025 // LF_STMEMBER
   1026 class StaticDataMemberRecord : public TypeRecord {
   1027 public:
   1028   StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
   1029       : TypeRecord(TypeRecordKind::StaticDataMember), Access(Access),
   1030         Type(Type), Name(Name) {}
   1031 
   1032   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1033   /// is not in the map.
   1034   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1035 
   1036   static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
   1037                                                      ArrayRef<uint8_t> &Data);
   1038 
   1039   MemberAccess getAccess() const { return Access; }
   1040   TypeIndex getType() const { return Type; }
   1041   StringRef getName() const { return Name; }
   1042 
   1043 private:
   1044   struct Layout {
   1045     MemberAttributes Attrs; // Access control attributes, etc
   1046     TypeIndex Type;
   1047     // Name: Null-terminated string
   1048   };
   1049 
   1050   MemberAccess Access;
   1051   TypeIndex Type;
   1052   StringRef Name;
   1053 };
   1054 
   1055 // LF_ENUMERATE
   1056 class EnumeratorRecord : public TypeRecord {
   1057 public:
   1058   EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
   1059       : TypeRecord(TypeRecordKind::Enumerator), Access(Access),
   1060         Value(std::move(Value)), Name(Name) {}
   1061 
   1062   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1063   /// is not in the map.
   1064   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1065 
   1066   static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
   1067                                                ArrayRef<uint8_t> &Data);
   1068 
   1069   MemberAccess getAccess() const { return Access; }
   1070   APSInt getValue() const { return Value; }
   1071   StringRef getName() const { return Name; }
   1072 
   1073 private:
   1074   struct Layout {
   1075     MemberAttributes Attrs; // Access control attributes, etc
   1076                             // EnumValue: LF_NUMERIC encoded enumerator value
   1077                             // Name: Null-terminated string
   1078   };
   1079 
   1080   MemberAccess Access;
   1081   APSInt Value;
   1082   StringRef Name;
   1083 };
   1084 
   1085 // LF_VFUNCTAB
   1086 class VFPtrRecord : public TypeRecord {
   1087 public:
   1088   VFPtrRecord(TypeIndex Type)
   1089       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
   1090 
   1091   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1092   /// is not in the map.
   1093   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1094 
   1095   static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
   1096                                           ArrayRef<uint8_t> &Data);
   1097 
   1098   TypeIndex getType() const { return Type; }
   1099 
   1100 private:
   1101   struct Layout {
   1102     ulittle16_t Pad0;
   1103     TypeIndex Type; // Type of vfptr
   1104   };
   1105   TypeIndex Type;
   1106 };
   1107 
   1108 // LF_BCLASS, LF_BINTERFACE
   1109 class BaseClassRecord : public TypeRecord {
   1110 public:
   1111   BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
   1112       : TypeRecord(TypeRecordKind::BaseClass), Access(Access), Type(Type),
   1113         Offset(Offset) {}
   1114 
   1115   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1116   /// is not in the map.
   1117   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1118 
   1119   static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
   1120                                               ArrayRef<uint8_t> &Data);
   1121 
   1122   MemberAccess getAccess() const { return Access; }
   1123   TypeIndex getBaseType() const { return Type; }
   1124   uint64_t getBaseOffset() const { return Offset; }
   1125 
   1126 private:
   1127   struct Layout {
   1128     MemberAttributes Attrs; // Access control attributes, etc
   1129     TypeIndex BaseType;     // Base class type
   1130     // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.
   1131   };
   1132   MemberAccess Access;
   1133   TypeIndex Type;
   1134   uint64_t Offset;
   1135 };
   1136 
   1137 // LF_VBCLASS, LF_IVBCLASS
   1138 class VirtualBaseClassRecord : public TypeRecord {
   1139 public:
   1140   VirtualBaseClassRecord(MemberAccess Access, TypeIndex BaseType,
   1141                          TypeIndex VBPtrType, uint64_t Offset, uint64_t Index)
   1142       : TypeRecord(TypeRecordKind::VirtualBaseClass), Access(Access),
   1143         BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset),
   1144         VTableIndex(Index) {}
   1145 
   1146   /// Rewrite member type indices with IndexMap. Returns false if a type index
   1147   /// is not in the map.
   1148   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1149 
   1150   static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
   1151                                                      ArrayRef<uint8_t> &Data);
   1152 
   1153   MemberAccess getAccess() const { return Access; }
   1154   TypeIndex getBaseType() const { return BaseType; }
   1155   TypeIndex getVBPtrType() const { return VBPtrType; }
   1156   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
   1157   uint64_t getVTableIndex() const { return VTableIndex; }
   1158 
   1159 private:
   1160   struct Layout {
   1161     MemberAttributes Attrs; // Access control attributes, etc.
   1162     TypeIndex BaseType;     // Base class type
   1163     TypeIndex VBPtrType;    // Virtual base pointer type
   1164     // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC.
   1165     // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC.
   1166   };
   1167   MemberAccess Access;
   1168   TypeIndex BaseType;
   1169   TypeIndex VBPtrType;
   1170   uint64_t VBPtrOffset;
   1171   uint64_t VTableIndex;
   1172 };
   1173 
   1174 /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
   1175 /// together. The first will end in an LF_INDEX record that points to the next.
   1176 class ListContinuationRecord : public TypeRecord {
   1177 public:
   1178   ListContinuationRecord(TypeIndex ContinuationIndex)
   1179       : TypeRecord(TypeRecordKind::ListContinuation),
   1180         ContinuationIndex(ContinuationIndex) {}
   1181 
   1182   TypeIndex getContinuationIndex() const { return ContinuationIndex; }
   1183 
   1184   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
   1185 
   1186   static ErrorOr<ListContinuationRecord> deserialize(TypeRecordKind Kind,
   1187                                                      ArrayRef<uint8_t> &Data);
   1188 
   1189 private:
   1190   struct Layout {
   1191     ulittle16_t Pad0;
   1192     TypeIndex ContinuationIndex;
   1193   };
   1194   TypeIndex ContinuationIndex;
   1195 };
   1196 
   1197 typedef CVRecord<TypeLeafKind> CVType;
   1198 typedef VarStreamArray<CVType> CVTypeArray;
   1199 }
   1200 }
   1201 
   1202 #endif
   1203