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