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