LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - TypeRecord.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 176 178 98.9 %
Date: 2018-07-13 00:08:38 Functions: 5 5 100.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       10849 :   MemberAttributes() = default;
      55             : 
      56             :   explicit MemberAttributes(MemberAccess Access)
      57        6067 :       : Attrs(static_cast<uint16_t>(Access)) {}
      58             : 
      59         445 :   MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
      60             :     Attrs = static_cast<uint16_t>(Access);
      61          61 :     Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
      62         445 :     Attrs |= static_cast<uint16_t>(Flags);
      63             :   }
      64             : 
      65             :   /// Get the access specifier. Valid for any kind of member.
      66             :   MemberAccess getAccess() const {
      67        7688 :     return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
      68             :   }
      69             : 
      70             :   /// Indicates if a method is defined with friend, virtual, static, etc.
      71             :   MethodKind getMethodKind() const {
      72        2800 :     return MethodKind(
      73        2800 :         (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
      74        2800 :         MethodKindShift);
      75             :   }
      76             : 
      77             :   /// Get the flags that are not included in access control or method
      78             :   /// properties.
      79             :   MethodOptions getFlags() const {
      80             :     return MethodOptions(
      81         828 :         unsigned(Attrs) &
      82         396 :         ~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          64 :       : ContainingType(ContainingType), Representation(Representation) {}
     109             : 
     110          31 :   TypeIndex getContainingType() const { return ContainingType; }
     111             :   PointerToMemberRepresentation getRepresentation() const {
     112             :     return Representation;
     113             :   }
     114             : 
     115             :   TypeIndex ContainingType;
     116             :   PointerToMemberRepresentation Representation;
     117             : };
     118             : 
     119             : class TypeRecord {
     120             : protected:
     121             :   TypeRecord() = default;
     122       31798 :   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
     123             : 
     124             : public:
     125       10164 :   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         246 :   explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     135             :   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
     136          74 :       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
     137          74 :         Modifiers(Modifiers) {}
     138             : 
     139         149 :   TypeIndex getModifiedType() const { return ModifiedType; }
     140             :   ModifierOptions getModifiers() const { return Modifiers; }
     141             : 
     142             :   TypeIndex ModifiedType;
     143             :   ModifierOptions Modifiers;
     144             : };
     145             : 
     146             : // LF_PROCEDURE
     147             : class ProcedureRecord : public TypeRecord {
     148             : public:
     149             :   ProcedureRecord() = default;
     150         482 :   explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     151             :   ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
     152             :                   FunctionOptions Options, uint16_t ParameterCount,
     153             :                   TypeIndex ArgumentList)
     154         193 :       : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
     155             :         CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
     156         193 :         ArgumentList(ArgumentList) {}
     157             : 
     158         380 :   TypeIndex getReturnType() const { return ReturnType; }
     159             :   CallingConvention getCallConv() const { return CallConv; }
     160             :   FunctionOptions getOptions() const { return Options; }
     161             :   uint16_t getParameterCount() const { return ParameterCount; }
     162         380 :   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        1709 :   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         136 :       : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
     182             :         ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
     183             :         Options(Options), ParameterCount(ParameterCount),
     184             :         ArgumentList(ArgumentList),
     185         136 :         ThisPointerAdjustment(ThisPointerAdjustment) {}
     186             : 
     187         804 :   TypeIndex getReturnType() const { return ReturnType; }
     188         804 :   TypeIndex getClassType() const { return ClassType; }
     189         403 :   TypeIndex getThisType() const { return ThisType; }
     190             :   CallingConvention getCallConv() const { return CallConv; }
     191             :   FunctionOptions getOptions() const { return Options; }
     192             :   uint16_t getParameterCount() const { return ParameterCount; }
     193         804 :   TypeIndex getArgumentList() const { return ArgumentList; }
     194             :   int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
     195             : 
     196             :   TypeIndex ReturnType;
     197             :   TypeIndex ClassType;
     198             :   TypeIndex ThisType;
     199             :   CallingConvention CallConv;
     200             :   FunctionOptions Options;
     201             :   uint16_t ParameterCount;
     202             :   TypeIndex ArgumentList;
     203             :   int32_t ThisPointerAdjustment;
     204             : };
     205             : 
     206             : // LF_LABEL
     207             : class LabelRecord : public TypeRecord {
     208             : public:
     209             :   LabelRecord() = default;
     210           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          90 :       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
     225          90 :         FunctionType(FunctionType), Name(Name) {}
     226             : 
     227          65 :   TypeIndex getClassType() const { return ClassType; }
     228          65 :   TypeIndex getFunctionType() const { return FunctionType; }
     229             :   StringRef getName() const { return Name; }
     230             : 
     231             :   TypeIndex ClassType;
     232             :   TypeIndex FunctionType;
     233             :   StringRef Name;
     234             : };
     235             : 
     236             : // LF_ARGLIST
     237         281 : class ArgListRecord : public TypeRecord {
     238             : public:
     239             :   ArgListRecord() = default;
     240         969 :   explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     241             : 
     242             :   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
     243         281 :       : 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          48 : class StringListRecord : public TypeRecord {
     252             : public:
     253             :   StringListRecord() = default;
     254          81 :   explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     255             : 
     256             :   StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
     257          48 :       : TypeRecord(Kind), StringIndices(Indices) {}
     258             : 
     259             :   ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
     260             : 
     261             :   std::vector<TypeIndex> StringIndices;
     262             : };
     263             : 
     264             : // LF_POINTER
     265          96 : 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        1534 :   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         173 :       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
     288         298 :         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          64 :       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
     293          80 :         Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
     294             : 
     295         805 :   TypeIndex getReferentType() const { return ReferentType; }
     296             : 
     297             :   PointerKind getPointerKind() const {
     298         622 :     return static_cast<PointerKind>((Attrs >> PointerKindShift) &
     299         622 :                                     PointerKindMask);
     300             :   }
     301             : 
     302             :   PointerMode getMode() const {
     303        3337 :     return static_cast<PointerMode>((Attrs >> PointerModeShift) &
     304        3337 :                                     PointerModeMask);
     305             :   }
     306             : 
     307             :   PointerOptions getOptions() const {
     308             :     return static_cast<PointerOptions>(Attrs);
     309             :   }
     310             : 
     311             :   uint8_t getSize() const {
     312         402 :     return (Attrs >> PointerSizeShift) & PointerSizeMask;
     313             :   }
     314             : 
     315          31 :   MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
     316             : 
     317             :   bool isPointerToMember() const {
     318        4654 :     return getMode() == PointerMode::PointerToDataMember ||
     319             :            getMode() == PointerMode::PointerToMemberFunction;
     320             :   }
     321             : 
     322         402 :   bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
     323         790 :   bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
     324             : 
     325             :   bool isVolatile() const {
     326         790 :     return !!(Attrs & uint32_t(PointerOptions::Volatile));
     327             :   }
     328             : 
     329             :   bool isUnaligned() const {
     330         790 :     return !!(Attrs & uint32_t(PointerOptions::Unaligned));
     331             :   }
     332             : 
     333             :   bool isRestrict() const {
     334         790 :     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         137 :     A |= static_cast<uint32_t>(PK);
     351         132 :     A |= static_cast<uint32_t>(PO);
     352         136 :     A |= (static_cast<uint32_t>(PM) << PointerModeShift);
     353         141 :     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         286 :   explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     363             :   NestedTypeRecord(TypeIndex Type, StringRef Name)
     364         116 :       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
     365             : 
     366          69 :   TypeIndex getNestedType() const { return Type; }
     367             :   StringRef getName() const { return Name; }
     368             : 
     369             :   TypeIndex Type;
     370             :   StringRef Name;
     371             : };
     372             : 
     373             : // LF_FIELDLIST
     374             : class FieldListRecord : public TypeRecord {
     375             : public:
     376             :   FieldListRecord() = default;
     377         959 :   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         161 :   explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     389             :   ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
     390             :               StringRef Name)
     391          64 :       : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
     392          64 :         IndexType(IndexType), Size(Size), Name(Name) {}
     393             : 
     394          37 :   TypeIndex getElementType() const { return ElementType; }
     395          37 :   TypeIndex getIndexType() const { return IndexType; }
     396             :   uint64_t getSize() const { return Size; }
     397             :   StringRef getName() const { return Name; }
     398             : 
     399             :   TypeIndex ElementType;
     400             :   TypeIndex IndexType;
     401             :   uint64_t Size;
     402             :   StringRef Name;
     403             : };
     404             : 
     405             : class TagRecord : public TypeRecord {
     406             : protected:
     407             :   TagRecord() = default;
     408        2742 :   explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     409             :   TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
     410             :             TypeIndex FieldList, StringRef Name, StringRef UniqueName)
     411         382 :       : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
     412         382 :         FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
     413             : 
     414             : public:
     415             :   static const int HfaKindShift = 11;
     416             :   static const int HfaKindMask = 0x1800;
     417             :   static const int WinRTKindShift = 14;
     418             :   static const int WinRTKindMask = 0xC000;
     419             : 
     420             :   bool hasUniqueName() const {
     421        2752 :     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
     422             :   }
     423             : 
     424             :   bool isNested() const {
     425             :     return (Options & ClassOptions::Nested) != ClassOptions::None;
     426             :   }
     427             : 
     428             :   bool isForwardRef() const {
     429             :     return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
     430             :   }
     431             : 
     432             :   uint16_t getMemberCount() const { return MemberCount; }
     433             :   ClassOptions getOptions() const { return Options; }
     434         686 :   TypeIndex getFieldList() const { return FieldList; }
     435             :   StringRef getName() const { return Name; }
     436             :   StringRef getUniqueName() const { return UniqueName; }
     437             : 
     438             :   uint16_t MemberCount;
     439             :   ClassOptions Options;
     440             :   TypeIndex FieldList;
     441             :   StringRef Name;
     442             :   StringRef UniqueName;
     443             : };
     444             : 
     445             : // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
     446             : class ClassRecord : public TagRecord {
     447             : public:
     448             :   ClassRecord() = default;
     449        2370 :   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         273 :       : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
     455         273 :         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         610 :   TypeIndex getDerivationList() const { return DerivationList; }
     470         610 :   TypeIndex getVTableShape() const { return VTableShape; }
     471             :   uint64_t getSize() const { return Size; }
     472             : 
     473             :   TypeIndex DerivationList;
     474             :   TypeIndex VTableShape;
     475             :   uint64_t Size;
     476             : };
     477             : 
     478             : // LF_UNION
     479             : struct UnionRecord : public TagRecord {
     480             :   UnionRecord() = default;
     481          26 :   explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
     482             :   UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
     483             :               uint64_t Size, StringRef Name, StringRef UniqueName)
     484          57 :       : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
     485             :                   UniqueName),
     486          57 :         Size(Size) {}
     487             : 
     488             :   HfaKind getHfa() const {
     489             :     uint16_t Value = static_cast<uint16_t>(Options);
     490             :     Value = (Value & HfaKindMask) >> HfaKindShift;
     491             :     return static_cast<HfaKind>(Value);
     492             :   }
     493             : 
     494             :   uint64_t getSize() const { return Size; }
     495             : 
     496             :   uint64_t Size;
     497             : };
     498             : 
     499             : // LF_ENUM
     500             : class EnumRecord : public TagRecord {
     501             : public:
     502             :   EnumRecord() = default;
     503         142 :   explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
     504             :   EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
     505             :              StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
     506          52 :       : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
     507             :                   UniqueName),
     508          52 :         UnderlyingType(UnderlyingType) {}
     509             : 
     510          81 :   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          56 :       : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
     522          56 :         BitOffset(BitOffset) {}
     523             : 
     524           7 :   TypeIndex getType() const { return Type; }
     525             :   uint8_t getBitOffset() const { return BitOffset; }
     526             :   uint8_t getBitSize() const { return BitSize; }
     527             : 
     528             :   TypeIndex Type;
     529             :   uint8_t BitSize;
     530             :   uint8_t BitOffset;
     531             : };
     532             : 
     533             : // LF_VTSHAPE
     534         105 : class VFTableShapeRecord : public TypeRecord {
     535             : public:
     536             :   VFTableShapeRecord() = default;
     537          93 :   explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     538             :   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
     539          18 :       : 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           7 :   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           5 :   const GUID &getGuid() const { return Guid; }
     567             :   uint32_t getAge() const { return Age; }
     568             :   StringRef getName() const { return Name; }
     569             : 
     570             :   GUID Guid;
     571             :   uint32_t Age;
     572             :   StringRef Name;
     573             : };
     574             : 
     575             : // LF_STRING_ID
     576             : class StringIdRecord : public TypeRecord {
     577             : public:
     578             :   StringIdRecord() = default;
     579         707 :   explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     580             :   StringIdRecord(TypeIndex Id, StringRef String)
     581         286 :       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
     582             : 
     583         250 :   TypeIndex getId() const { return Id; }
     584             :   StringRef getString() const { return String; }
     585             : 
     586             :   TypeIndex Id;
     587             :   StringRef String;
     588             : };
     589             : 
     590             : // LF_FUNC_ID
     591             : class FuncIdRecord : public TypeRecord {
     592             : public:
     593             :   FuncIdRecord() = default;
     594         489 :   explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     595             :   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
     596         230 :       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
     597         230 :         FunctionType(FunctionType), Name(Name) {}
     598             : 
     599         258 :   TypeIndex getParentScope() const { return ParentScope; }
     600         258 :   TypeIndex getFunctionType() const { return FunctionType; }
     601             :   StringRef getName() const { return Name; }
     602             : 
     603             :   TypeIndex ParentScope;
     604             :   TypeIndex FunctionType;
     605             :   StringRef Name;
     606             : };
     607             : 
     608             : // LF_UDT_SRC_LINE
     609             : class UdtSourceLineRecord : public TypeRecord {
     610             : public:
     611             :   UdtSourceLineRecord() = default;
     612         898 :   explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     613             :   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
     614         141 :       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
     615         141 :         SourceFile(SourceFile), LineNumber(LineNumber) {}
     616             : 
     617         442 :   TypeIndex getUDT() const { return UDT; }
     618         369 :   TypeIndex getSourceFile() const { return SourceFile; }
     619             :   uint32_t getLineNumber() const { return LineNumber; }
     620             : 
     621             :   TypeIndex UDT;
     622             :   TypeIndex SourceFile;
     623             :   uint32_t LineNumber;
     624             : };
     625             : 
     626             : // LF_UDT_MOD_SRC_LINE
     627             : class UdtModSourceLineRecord : public TypeRecord {
     628             : public:
     629             :   UdtModSourceLineRecord() = default;
     630          36 :   explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     631             :   UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
     632             :                          uint32_t LineNumber, uint16_t Module)
     633          48 :       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
     634          48 :         SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
     635             : 
     636           7 :   TypeIndex getUDT() const { return UDT; }
     637           0 :   TypeIndex getSourceFile() const { return SourceFile; }
     638             :   uint32_t getLineNumber() const { return LineNumber; }
     639             :   uint16_t getModule() const { return Module; }
     640             : 
     641             :   TypeIndex UDT;
     642             :   TypeIndex SourceFile;
     643             :   uint32_t LineNumber;
     644             :   uint16_t Module;
     645             : };
     646             : 
     647             : // LF_BUILDINFO
     648          48 : class BuildInfoRecord : public TypeRecord {
     649             : public:
     650             :   BuildInfoRecord() = default;
     651          83 :   explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     652             :   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
     653          48 :       : TypeRecord(TypeRecordKind::BuildInfo),
     654             :         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
     655             : 
     656             :   ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
     657             : 
     658             :   SmallVector<TypeIndex, 4> ArgIndices;
     659             : };
     660             : 
     661             : // LF_VFTABLE
     662          96 : class VFTableRecord : public TypeRecord {
     663             : public:
     664             :   VFTableRecord() = default;
     665          15 :   explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     666          48 :   VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
     667             :                 uint32_t VFPtrOffset, StringRef Name,
     668             :                 ArrayRef<StringRef> Methods)
     669          48 :       : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
     670          48 :         OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
     671          48 :     MethodNames.push_back(Name);
     672             :     MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
     673          48 :   }
     674             : 
     675           7 :   TypeIndex getCompleteClass() const { return CompleteClass; }
     676           7 :   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
     677             :   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
     678          11 :   StringRef getName() const { return makeArrayRef(MethodNames).front(); }
     679             : 
     680             :   ArrayRef<StringRef> getMethodNames() const {
     681             :     return makeArrayRef(MethodNames).drop_front();
     682             :   }
     683             : 
     684             :   TypeIndex CompleteClass;
     685             :   TypeIndex OverriddenVFTable;
     686             :   uint32_t VFPtrOffset;
     687             :   std::vector<StringRef> MethodNames;
     688             : };
     689             : 
     690             : // LF_ONEMETHOD
     691             : class OneMethodRecord : public TypeRecord {
     692             : public:
     693             :   OneMethodRecord() = default;
     694         638 :   explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     695             :   OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
     696             :                   StringRef Name)
     697             :       : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
     698             :         VFTableOffset(VFTableOffset), Name(Name) {}
     699             :   OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
     700             :                   MethodOptions Options, int32_t VFTableOffset, StringRef Name)
     701         445 :       : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
     702         890 :         Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
     703             : 
     704         396 :   TypeIndex getType() const { return Type; }
     705             :   MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
     706             :   MethodOptions getOptions() const { return Attrs.getFlags(); }
     707             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     708             :   int32_t getVFTableOffset() const { return VFTableOffset; }
     709             :   StringRef getName() const { return Name; }
     710             : 
     711             :   bool isIntroducingVirtual() const {
     712        1788 :     return getMethodKind() == MethodKind::IntroducingVirtual ||
     713             :            getMethodKind() == MethodKind::PureIntroducingVirtual;
     714             :   }
     715             : 
     716             :   TypeIndex Type;
     717             :   MemberAttributes Attrs;
     718             :   int32_t VFTableOffset;
     719             :   StringRef Name;
     720             : };
     721             : 
     722             : // LF_METHODLIST
     723          48 : class MethodOverloadListRecord : public TypeRecord {
     724             : public:
     725             :   MethodOverloadListRecord() = default;
     726         398 :   explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     727             :   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
     728          49 :       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
     729             : 
     730             :   ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
     731             : 
     732             :   std::vector<OneMethodRecord> Methods;
     733             : };
     734             : 
     735             : /// For method overload sets.  LF_METHOD
     736             : class OverloadedMethodRecord : public TypeRecord {
     737             : public:
     738             :   OverloadedMethodRecord() = default;
     739         385 :   explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     740             :   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
     741             :                          StringRef Name)
     742          49 :       : TypeRecord(TypeRecordKind::OverloadedMethod),
     743          49 :         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
     744             : 
     745             :   uint16_t getNumOverloads() const { return NumOverloads; }
     746          87 :   TypeIndex getMethodList() const { return MethodList; }
     747             :   StringRef getName() const { return Name; }
     748             : 
     749             :   uint16_t NumOverloads;
     750             :   TypeIndex MethodList;
     751             :   StringRef Name;
     752             : };
     753             : 
     754             : // LF_MEMBER
     755             : class DataMemberRecord : public TypeRecord {
     756             : public:
     757             :   DataMemberRecord() = default;
     758        1910 :   explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     759             :   DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
     760             :                    StringRef Name)
     761             :       : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
     762             :         FieldOffset(Offset), Name(Name) {}
     763             :   DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
     764             :                    StringRef Name)
     765         150 :       : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
     766         150 :         FieldOffset(Offset), Name(Name) {}
     767             : 
     768             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     769         504 :   TypeIndex getType() const { return Type; }
     770             :   uint64_t getFieldOffset() const { return FieldOffset; }
     771             :   StringRef getName() const { return Name; }
     772             : 
     773             :   MemberAttributes Attrs;
     774             :   TypeIndex Type;
     775             :   uint64_t FieldOffset;
     776             :   StringRef Name;
     777             : };
     778             : 
     779             : // LF_STMEMBER
     780             : class StaticDataMemberRecord : public TypeRecord {
     781             : public:
     782             :   StaticDataMemberRecord() = default;
     783         195 :   explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     784             :   StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
     785             :       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
     786             :         Name(Name) {}
     787             :   StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
     788          51 :       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
     789          51 :         Name(Name) {}
     790             : 
     791             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     792          42 :   TypeIndex getType() const { return Type; }
     793             :   StringRef getName() const { return Name; }
     794             : 
     795             :   MemberAttributes Attrs;
     796             :   TypeIndex Type;
     797             :   StringRef Name;
     798             : };
     799             : 
     800             : // LF_ENUMERATE
     801         856 : class EnumeratorRecord : public TypeRecord {
     802             : public:
     803             :   EnumeratorRecord() = default;
     804        7524 :   explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     805             :   EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
     806             :       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
     807             :         Value(std::move(Value)), Name(Name) {}
     808             :   EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
     809        5747 :       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
     810        5747 :         Value(std::move(Value)), Name(Name) {}
     811             : 
     812             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     813             :   APSInt getValue() const { return Value; }
     814             :   StringRef getName() const { return Name; }
     815             : 
     816             :   MemberAttributes Attrs;
     817             :   APSInt Value;
     818             :   StringRef Name;
     819             : };
     820             : 
     821             : // LF_VFUNCTAB
     822             : class VFPtrRecord : public TypeRecord {
     823             : public:
     824             :   VFPtrRecord() = default;
     825           4 :   explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     826             :   VFPtrRecord(TypeIndex Type)
     827         122 :       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
     828             : 
     829          16 :   TypeIndex getType() const { return Type; }
     830             : 
     831             :   TypeIndex Type;
     832             : };
     833             : 
     834             : // LF_BCLASS, LF_BINTERFACE
     835             : class BaseClassRecord : public TypeRecord {
     836             : public:
     837             :   BaseClassRecord() = default;
     838          32 :   explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     839             :   BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
     840             :       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
     841             :         Offset(Offset) {}
     842             :   BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
     843          62 :       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
     844          62 :         Offset(Offset) {}
     845             : 
     846             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     847          20 :   TypeIndex getBaseType() const { return Type; }
     848             :   uint64_t getBaseOffset() const { return Offset; }
     849             : 
     850             :   MemberAttributes Attrs;
     851             :   TypeIndex Type;
     852             :   uint64_t Offset;
     853             : };
     854             : 
     855             : // LF_VBCLASS, LF_IVBCLASS
     856             : class VirtualBaseClassRecord : public TypeRecord {
     857             : public:
     858             :   VirtualBaseClassRecord() = default;
     859          25 :   explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     860             :   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
     861             :                          TypeIndex BaseType, TypeIndex VBPtrType,
     862             :                          uint64_t Offset, uint64_t Index)
     863             :       : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
     864             :         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
     865             :   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
     866             :                          TypeIndex BaseType, TypeIndex VBPtrType,
     867             :                          uint64_t Offset, uint64_t Index)
     868          57 :       : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
     869          57 :         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
     870             : 
     871             :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     872          15 :   TypeIndex getBaseType() const { return BaseType; }
     873          15 :   TypeIndex getVBPtrType() const { return VBPtrType; }
     874             :   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
     875             :   uint64_t getVTableIndex() const { return VTableIndex; }
     876             : 
     877             :   MemberAttributes Attrs;
     878             :   TypeIndex BaseType;
     879             :   TypeIndex VBPtrType;
     880             :   uint64_t VBPtrOffset;
     881             :   uint64_t VTableIndex;
     882             : };
     883             : 
     884             : /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
     885             : /// together. The first will end in an LF_INDEX record that points to the next.
     886             : class ListContinuationRecord : public TypeRecord {
     887             : public:
     888             :   ListContinuationRecord() = default;
     889           0 :   explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     890             :   ListContinuationRecord(TypeIndex ContinuationIndex)
     891          48 :       : TypeRecord(TypeRecordKind::ListContinuation),
     892          48 :         ContinuationIndex(ContinuationIndex) {}
     893             : 
     894           4 :   TypeIndex getContinuationIndex() const { return ContinuationIndex; }
     895             : 
     896             :   TypeIndex ContinuationIndex;
     897             : };
     898             : 
     899             : // LF_PRECOMP
     900             : class PrecompRecord : public TypeRecord {
     901             : public:
     902             :   PrecompRecord() = default;
     903           5 :   explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     904             : 
     905             :   uint32_t getStartTypeIndex() const { return StartTypeIndex; }
     906             :   uint32_t getTypesCount() const { return TypesCount; }
     907             :   uint32_t getSignature() const { return Signature; }
     908             :   StringRef getPrecompFilePath() const { return PrecompFilePath; }
     909             : 
     910             :   uint32_t StartTypeIndex;
     911             :   uint32_t TypesCount;
     912             :   uint32_t Signature;
     913             :   StringRef PrecompFilePath;
     914             : };
     915             : 
     916             : // LF_ENDPRECOMP
     917             : class EndPrecompRecord : public TypeRecord {
     918             : public:
     919             :   EndPrecompRecord() = default;
     920           5 :   explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     921             : 
     922             :   uint32_t getSignature() const { return Signature; }
     923             : 
     924             :   uint32_t Signature;
     925             : };
     926             : } // end namespace codeview
     927             : } // end namespace llvm
     928             : 
     929             : #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H

Generated by: LCOV version 1.13