LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - TypeRecord.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 172 235 73.2 %
Date: 2018-10-20 13:21:21 Functions: 1 97 1.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13