LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - TypeRecord.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 202 204 99.0 %
Date: 2017-09-14 15:23:50 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       27254 : 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        8144 :   MemberAttributes() = default;
      55             : 
      56             :   explicit MemberAttributes(MemberAccess Access)
      57        6020 :       : Attrs(static_cast<uint16_t>(Access)) {}
      58             : 
      59         389 :   MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
      60             :     Attrs = static_cast<uint16_t>(Access);
      61          37 :     Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
      62         389 :     Attrs |= static_cast<uint16_t>(Flags);
      63             :   }
      64             : 
      65             :   /// Get the access specifier. Valid for any kind of member.
      66             :   MemberAccess getAccess() const {
      67        6702 :     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        1128 :     return MethodKind(
      73        1128 :         (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
      74        1128 :         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         354 :         unsigned(Attrs) &
      82         354 :         ~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         188 :   MemberPointerInfo() = default;
     105             : 
     106             :   MemberPointerInfo(TypeIndex ContainingType,
     107             :                     PointerToMemberRepresentation Representation)
     108          56 :       : ContainingType(ContainingType), Representation(Representation) {}
     109             : 
     110          24 :   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       22387 :   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
     123             : 
     124             : public:
     125        8374 :   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         387 :   explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     135             :   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
     136          62 :       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
     137         124 :         Modifiers(Modifiers) {}
     138             : 
     139          98 :   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        1432 :   explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     151             :   ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
     152             :                   FunctionOptions Options, uint16_t ParameterCount,
     153             :                   TypeIndex ArgumentList)
     154         150 :       : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
     155             :         CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
     156         300 :         ArgumentList(ArgumentList) {}
     157             : 
     158         291 :   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         291 :   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        3612 :   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          99 :       : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
     182             :         ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
     183             :         Options(Options), ParameterCount(ParameterCount),
     184             :         ArgumentList(ArgumentList),
     185         198 :         ThisPointerAdjustment(ThisPointerAdjustment) {}
     186             : 
     187         358 :   TypeIndex getReturnType() const { return ReturnType; }
     188         358 :   TypeIndex getClassType() const { return ClassType; }
     189         183 :   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         358 :   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           2 :   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         410 :   explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     222             :   MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
     223             :                          StringRef Name)
     224          61 :       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
     225         122 :         FunctionType(FunctionType), Name(Name) {}
     226             : 
     227          42 :   TypeIndex getClassType() const { return ClassType; }
     228          42 :   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        1680 : class ArgListRecord : public TypeRecord {
     238             : public:
     239             :   ArgListRecord() = default;
     240        1905 :   explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     241             : 
     242             :   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
     243         615 :       : TypeRecord(Kind), ArgIndices(Indices) {}
     244             : 
     245         970 :   ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
     246             : 
     247             :   std::vector<TypeIndex> ArgIndices;
     248             : };
     249             : 
     250             : // LF_SUBSTR_LIST
     251         218 : class StringListRecord : public TypeRecord {
     252             : public:
     253             :   StringListRecord() = default;
     254         195 :   explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     255             : 
     256             :   StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
     257         132 :       : TypeRecord(Kind), StringIndices(Indices) {}
     258             : 
     259          80 :   ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
     260             : 
     261             :   std::vector<TypeIndex> StringIndices;
     262             : };
     263             : 
     264             : // LF_POINTER
     265        1604 : 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        2508 :   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         119 :       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
     288         476 :         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          56 :       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
     293         224 :         Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
     294             : 
     295         427 :   TypeIndex getReferentType() const { return ReferentType; }
     296             : 
     297             :   PointerKind getPointerKind() const {
     298         282 :     return static_cast<PointerKind>((Attrs >> PointerKindShift) &
     299         282 :                                     PointerKindMask);
     300             :   }
     301             : 
     302             :   PointerMode getMode() const {
     303        1621 :     return static_cast<PointerMode>((Attrs >> PointerModeShift) &
     304        1621 :                                     PointerModeMask);
     305             :   }
     306             : 
     307             :   PointerOptions getOptions() const {
     308             :     return static_cast<PointerOptions>(Attrs);
     309             :   }
     310             : 
     311             :   uint8_t getSize() const {
     312         218 :     return (Attrs >> PointerSizeShift) & PointerSizeMask;
     313             :   }
     314             : 
     315          48 :   MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
     316             : 
     317             :   bool isPointerToMember() const {
     318        3394 :     return getMode() == PointerMode::PointerToDataMember ||
     319        1110 :            getMode() == PointerMode::PointerToMemberFunction;
     320             :   }
     321             : 
     322         218 :   bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
     323         415 :   bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
     324             : 
     325             :   bool isVolatile() const {
     326         415 :     return !!(Attrs & uint32_t(PointerOptions::Volatile));
     327             :   }
     328             : 
     329             :   bool isUnaligned() const {
     330         415 :     return !!(Attrs & uint32_t(PointerOptions::Unaligned));
     331             :   }
     332             : 
     333             :   TypeIndex ReferentType;
     334             :   uint32_t Attrs;
     335             :   Optional<MemberPointerInfo> MemberInfo;
     336             : 
     337             : private:
     338             :   static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
     339             :                             uint8_t Size) {
     340         175 :     uint32_t A = 0;
     341         175 :     A |= static_cast<uint32_t>(PK);
     342         175 :     A |= static_cast<uint32_t>(PO);
     343         175 :     A |= (static_cast<uint32_t>(PM) << PointerModeShift);
     344         175 :     A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
     345             :     return A;
     346             :   }
     347             : };
     348             : 
     349             : // LF_NESTTYPE
     350             : class NestedTypeRecord : public TypeRecord {
     351             : public:
     352             :   NestedTypeRecord() = default;
     353         828 :   explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     354             :   NestedTypeRecord(TypeIndex Type, StringRef Name)
     355         104 :       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
     356             : 
     357          58 :   TypeIndex getNestedType() const { return Type; }
     358             :   StringRef getName() const { return Name; }
     359             : 
     360             :   TypeIndex Type;
     361             :   StringRef Name;
     362             : };
     363             : 
     364             : // LF_FIELDLIST
     365             : class FieldListRecord : public TypeRecord {
     366             : public:
     367             :   FieldListRecord() = default;
     368        1374 :   explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     369             :   explicit FieldListRecord(ArrayRef<uint8_t> Data)
     370             :       : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
     371             : 
     372             :   ArrayRef<uint8_t> Data;
     373             : };
     374             : 
     375             : // LF_ARRAY
     376             : class ArrayRecord : public TypeRecord {
     377             : public:
     378             :   ArrayRecord() = default;
     379         665 :   explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     380             :   ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
     381             :               StringRef Name)
     382          56 :       : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
     383         112 :         IndexType(IndexType), Size(Size), Name(Name) {}
     384             : 
     385          29 :   TypeIndex getElementType() const { return ElementType; }
     386          29 :   TypeIndex getIndexType() const { return IndexType; }
     387             :   uint64_t getSize() const { return Size; }
     388             :   StringRef getName() const { return Name; }
     389             : 
     390             :   TypeIndex ElementType;
     391             :   TypeIndex IndexType;
     392             :   uint64_t Size;
     393             :   StringRef Name;
     394             : };
     395             : 
     396             : class TagRecord : public TypeRecord {
     397             : protected:
     398         288 :   TagRecord() = default;
     399        5339 :   explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     400             :   TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
     401             :             TypeIndex FieldList, StringRef Name, StringRef UniqueName)
     402         319 :       : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
     403         638 :         FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
     404             : 
     405             : public:
     406             :   static const int HfaKindShift = 11;
     407             :   static const int HfaKindMask = 0x1800;
     408             :   static const int WinRTKindShift = 14;
     409             :   static const int WinRTKindMask = 0xC000;
     410             : 
     411             :   bool hasUniqueName() const {
     412        2722 :     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
     413             :   }
     414             : 
     415             :   bool isNested() const {
     416             :     return (Options & ClassOptions::Nested) != ClassOptions::None;
     417             :   }
     418             : 
     419             :   bool isForwardRef() const {
     420             :     return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
     421             :   }
     422             : 
     423             :   uint16_t getMemberCount() const { return MemberCount; }
     424             :   ClassOptions getOptions() const { return Options; }
     425         349 :   TypeIndex getFieldList() const { return FieldList; }
     426             :   StringRef getName() const { return Name; }
     427             :   StringRef getUniqueName() const { return UniqueName; }
     428             : 
     429             :   uint16_t MemberCount;
     430             :   ClassOptions Options;
     431             :   TypeIndex FieldList;
     432             :   StringRef Name;
     433             :   StringRef UniqueName;
     434             : };
     435             : 
     436             : // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
     437             : class ClassRecord : public TagRecord {
     438             : public:
     439         192 :   ClassRecord() = default;
     440        3140 :   explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
     441             :   ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
     442             :               TypeIndex FieldList, TypeIndex DerivationList,
     443             :               TypeIndex VTableShape, uint64_t Size, StringRef Name,
     444             :               StringRef UniqueName)
     445         221 :       : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
     446         442 :         DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
     447             : 
     448             :   HfaKind getHfa() const {
     449             :     uint16_t Value = static_cast<uint16_t>(Options);
     450             :     Value = (Value & HfaKindMask) >> HfaKindShift;
     451             :     return static_cast<HfaKind>(Value);
     452             :   }
     453             : 
     454             :   WindowsRTClassKind getWinRTKind() const {
     455             :     uint16_t Value = static_cast<uint16_t>(Options);
     456             :     Value = (Value & WinRTKindMask) >> WinRTKindShift;
     457             :     return static_cast<WindowsRTClassKind>(Value);
     458             :   }
     459             : 
     460         285 :   TypeIndex getDerivationList() const { return DerivationList; }
     461         285 :   TypeIndex getVTableShape() const { return VTableShape; }
     462             :   uint64_t getSize() const { return Size; }
     463             : 
     464             :   TypeIndex DerivationList;
     465             :   TypeIndex VTableShape;
     466             :   uint64_t Size;
     467             : };
     468             : 
     469             : // LF_UNION
     470             : struct UnionRecord : public TagRecord {
     471           0 :   UnionRecord() = default;
     472          42 :   explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
     473             :   UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
     474             :               uint64_t Size, StringRef Name, StringRef UniqueName)
     475          50 :       : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
     476             :                   UniqueName),
     477         100 :         Size(Size) {}
     478             : 
     479             :   HfaKind getHfa() const {
     480             :     uint16_t Value = static_cast<uint16_t>(Options);
     481             :     Value = (Value & HfaKindMask) >> HfaKindShift;
     482             :     return static_cast<HfaKind>(Value);
     483             :   }
     484             : 
     485             :   uint64_t getSize() const { return Size; }
     486             : 
     487             :   uint64_t Size;
     488             : };
     489             : 
     490             : // LF_ENUM
     491             : class EnumRecord : public TagRecord {
     492             : public:
     493          72 :   EnumRecord() = default;
     494         786 :   explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
     495             :   EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
     496             :              StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
     497          48 :       : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
     498             :                   UniqueName),
     499          96 :         UnderlyingType(UnderlyingType) {}
     500             : 
     501          72 :   TypeIndex getUnderlyingType() const { return UnderlyingType; }
     502             : 
     503             :   TypeIndex UnderlyingType;
     504             : };
     505             : 
     506             : // LF_BITFIELD
     507             : class BitFieldRecord : public TypeRecord {
     508             : public:
     509             :   BitFieldRecord() = default;
     510          54 :   explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     511             :   BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
     512          50 :       : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
     513         100 :         BitOffset(BitOffset) {}
     514             : 
     515           5 :   TypeIndex getType() const { return Type; }
     516             :   uint8_t getBitOffset() const { return BitOffset; }
     517             :   uint8_t getBitSize() const { return BitSize; }
     518             : 
     519             :   TypeIndex Type;
     520             :   uint8_t BitSize;
     521             :   uint8_t BitOffset;
     522             : };
     523             : 
     524             : // LF_VTSHAPE
     525         168 : class VFTableShapeRecord : public TypeRecord {
     526             : public:
     527             :   VFTableShapeRecord() = default;
     528         312 :   explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     529             :   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
     530          18 :       : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
     531             :   explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
     532             :       : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
     533             : 
     534             :   ArrayRef<VFTableSlotKind> getSlots() const {
     535          39 :     if (!SlotsRef.empty())
     536           6 :       return SlotsRef;
     537          66 :     return Slots;
     538             :   }
     539             : 
     540          30 :   uint32_t getEntryCount() const { return getSlots().size(); }
     541             : 
     542             :   ArrayRef<VFTableSlotKind> SlotsRef;
     543             :   std::vector<VFTableSlotKind> Slots;
     544             : };
     545             : 
     546             : // LF_TYPESERVER2
     547             : class TypeServer2Record : public TypeRecord {
     548             : public:
     549           4 :   TypeServer2Record() = default;
     550          15 :   explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
     551             :   TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
     552             :       : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
     553             :     assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
     554             :     ::memcpy(Guid.Guid, GuidStr.data(), 16);
     555             :   }
     556             : 
     557           1 :   const GUID &getGuid() const { return Guid; }
     558             :   uint32_t getAge() const { return Age; }
     559             :   StringRef getName() const { return Name; }
     560             : 
     561             :   GUID Guid;
     562             :   uint32_t Age;
     563             :   StringRef Name;
     564             : };
     565             : 
     566             : // LF_STRING_ID
     567             : class StringIdRecord : public TypeRecord {
     568             : public:
     569             :   StringIdRecord() = default;
     570        2112 :   explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     571             :   StringIdRecord(TypeIndex Id, StringRef String)
     572         220 :       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
     573             : 
     574         189 :   TypeIndex getId() const { return Id; }
     575             :   StringRef getString() const { return String; }
     576             : 
     577             :   TypeIndex Id;
     578             :   StringRef String;
     579             : };
     580             : 
     581             : // LF_FUNC_ID
     582             : class FuncIdRecord : public TypeRecord {
     583             : public:
     584             :   FuncIdRecord() = default;
     585        1885 :   explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     586             :   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
     587         178 :       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
     588         356 :         FunctionType(FunctionType), Name(Name) {}
     589             : 
     590         201 :   TypeIndex getParentScope() const { return ParentScope; }
     591         201 :   TypeIndex getFunctionType() const { return FunctionType; }
     592             :   StringRef getName() const { return Name; }
     593             : 
     594             :   TypeIndex ParentScope;
     595             :   TypeIndex FunctionType;
     596             :   StringRef Name;
     597             : };
     598             : 
     599             : // LF_UDT_SRC_LINE
     600             : class UdtSourceLineRecord : public TypeRecord {
     601             : public:
     602         102 :   UdtSourceLineRecord() = default;
     603         788 :   explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     604             :   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
     605         108 :       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
     606         216 :         SourceFile(SourceFile), LineNumber(LineNumber) {}
     607             : 
     608         225 :   TypeIndex getUDT() const { return UDT; }
     609         191 :   TypeIndex getSourceFile() const { return SourceFile; }
     610             :   uint32_t getLineNumber() const { return LineNumber; }
     611             : 
     612             :   TypeIndex UDT;
     613             :   TypeIndex SourceFile;
     614             :   uint32_t LineNumber;
     615             : };
     616             : 
     617             : // LF_UDT_MOD_SRC_LINE
     618             : class UdtModSourceLineRecord : public TypeRecord {
     619             : public:
     620          21 :   UdtModSourceLineRecord() = default;
     621         144 :   explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     622             :   UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
     623             :                          uint32_t LineNumber, uint16_t Module)
     624          44 :       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
     625          88 :         SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
     626             : 
     627           7 :   TypeIndex getUDT() const { return UDT; }
     628           0 :   TypeIndex getSourceFile() const { return SourceFile; }
     629             :   uint32_t getLineNumber() const { return LineNumber; }
     630             :   uint16_t getModule() const { return Module; }
     631             : 
     632             :   TypeIndex UDT;
     633             :   TypeIndex SourceFile;
     634             :   uint32_t LineNumber;
     635             :   uint16_t Module;
     636             : };
     637             : 
     638             : // LF_BUILDINFO
     639         220 : class BuildInfoRecord : public TypeRecord {
     640             : public:
     641             :   BuildInfoRecord() = default;
     642         198 :   explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     643             :   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
     644          44 :       : TypeRecord(TypeRecordKind::BuildInfo),
     645         176 :         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
     646             : 
     647          80 :   ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
     648             : 
     649             :   SmallVector<TypeIndex, 4> ArgIndices;
     650             : };
     651             : 
     652             : // LF_VFTABLE
     653         110 : class VFTableRecord : public TypeRecord {
     654             : public:
     655             :   VFTableRecord() = default;
     656          55 :   explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     657          44 :   VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
     658             :                 uint32_t VFPtrOffset, StringRef Name,
     659             :                 ArrayRef<StringRef> Methods)
     660          44 :       : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
     661         132 :         OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
     662          44 :     MethodNames.push_back(Name);
     663         220 :     MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
     664          44 :   }
     665             : 
     666           7 :   TypeIndex getCompleteClass() const { return CompleteClass; }
     667           7 :   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
     668             :   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
     669          22 :   StringRef getName() const { return makeArrayRef(MethodNames).front(); }
     670             : 
     671             :   ArrayRef<StringRef> getMethodNames() const {
     672          21 :     return makeArrayRef(MethodNames).drop_front();
     673             :   }
     674             : 
     675             :   TypeIndex CompleteClass;
     676             :   TypeIndex OverriddenVFTable;
     677             :   uint32_t VFPtrOffset;
     678             :   std::vector<StringRef> MethodNames;
     679             : };
     680             : 
     681             : // LF_ONEMETHOD
     682             : class OneMethodRecord : public TypeRecord {
     683             : public:
     684         844 :   OneMethodRecord() = default;
     685         650 :   explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     686             :   OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
     687             :                   StringRef Name)
     688             :       : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
     689             :         VFTableOffset(VFTableOffset), Name(Name) {}
     690             :   OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
     691             :                   MethodOptions Options, int32_t VFTableOffset, StringRef Name)
     692         389 :       : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
     693        1167 :         Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
     694             : 
     695         182 :   TypeIndex getType() const { return Type; }
     696        2642 :   MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
     697         364 :   MethodOptions getOptions() const { return Attrs.getFlags(); }
     698         364 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     699             :   int32_t getVFTableOffset() const { return VFTableOffset; }
     700             :   StringRef getName() const { return Name; }
     701             : 
     702             :   bool isIntroducingVirtual() const {
     703        1504 :     return getMethodKind() == MethodKind::IntroducingVirtual ||
     704         730 :            getMethodKind() == MethodKind::PureIntroducingVirtual;
     705             :   }
     706             : 
     707             :   TypeIndex Type;
     708             :   MemberAttributes Attrs;
     709             :   int32_t VFTableOffset;
     710             :   StringRef Name;
     711             : };
     712             : 
     713             : // LF_METHODLIST
     714         454 : class MethodOverloadListRecord : public TypeRecord {
     715             : public:
     716             :   MethodOverloadListRecord() = default;
     717         546 :   explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     718             :   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
     719         135 :       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
     720             : 
     721          98 :   ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
     722             : 
     723             :   std::vector<OneMethodRecord> Methods;
     724             : };
     725             : 
     726             : /// For method overload sets.  LF_METHOD
     727             : class OverloadedMethodRecord : public TypeRecord {
     728             : public:
     729             :   OverloadedMethodRecord() = default;
     730         676 :   explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     731             :   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
     732             :                          StringRef Name)
     733          45 :       : TypeRecord(TypeRecordKind::OverloadedMethod),
     734          90 :         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
     735             : 
     736             :   uint16_t getNumOverloads() const { return NumOverloads; }
     737          49 :   TypeIndex getMethodList() const { return MethodList; }
     738             :   StringRef getName() const { return Name; }
     739             : 
     740             :   uint16_t NumOverloads;
     741             :   TypeIndex MethodList;
     742             :   StringRef Name;
     743             : };
     744             : 
     745             : // LF_MEMBER
     746             : class DataMemberRecord : public TypeRecord {
     747             : public:
     748             :   DataMemberRecord() = default;
     749        3690 :   explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     750             :   DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
     751             :                    StringRef Name)
     752             :       : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
     753             :         FieldOffset(Offset), Name(Name) {}
     754             :   DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
     755             :                    StringRef Name)
     756         126 :       : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
     757         378 :         FieldOffset(Offset), Name(Name) {}
     758             : 
     759         554 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     760         277 :   TypeIndex getType() const { return Type; }
     761             :   uint64_t getFieldOffset() const { return FieldOffset; }
     762             :   StringRef getName() const { return Name; }
     763             : 
     764             :   MemberAttributes Attrs;
     765             :   TypeIndex Type;
     766             :   uint64_t FieldOffset;
     767             :   StringRef Name;
     768             : };
     769             : 
     770             : // LF_STMEMBER
     771             : class StaticDataMemberRecord : public TypeRecord {
     772             : public:
     773             :   StaticDataMemberRecord() = default;
     774          45 :   explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     775             :   StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
     776             :       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
     777             :         Name(Name) {}
     778             :   StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
     779          46 :       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
     780         138 :         Name(Name) {}
     781             : 
     782           8 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     783           4 :   TypeIndex getType() const { return Type; }
     784             :   StringRef getName() const { return Name; }
     785             : 
     786             :   MemberAttributes Attrs;
     787             :   TypeIndex Type;
     788             :   StringRef Name;
     789             : };
     790             : 
     791             : // LF_ENUMERATE
     792       26138 : class EnumeratorRecord : public TypeRecord {
     793             : public:
     794             :   EnumeratorRecord() = default;
     795       35025 :   explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     796             :   EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
     797             :       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
     798             :         Value(std::move(Value)), Name(Name) {}
     799             :   EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
     800        5743 :       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
     801       22972 :         Value(std::move(Value)), Name(Name) {}
     802             : 
     803       12072 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     804       12072 :   APSInt getValue() const { return Value; }
     805             :   StringRef getName() const { return Name; }
     806             : 
     807             :   MemberAttributes Attrs;
     808             :   APSInt Value;
     809             :   StringRef Name;
     810             : };
     811             : 
     812             : // LF_VFUNCTAB
     813             : class VFPtrRecord : public TypeRecord {
     814             : public:
     815             :   VFPtrRecord() = default;
     816          48 :   explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     817             :   VFPtrRecord(TypeIndex Type)
     818         104 :       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
     819             : 
     820          11 :   TypeIndex getType() const { return Type; }
     821             : 
     822             :   TypeIndex Type;
     823             : };
     824             : 
     825             : // LF_BCLASS, LF_BINTERFACE
     826             : class BaseClassRecord : public TypeRecord {
     827             : public:
     828             :   BaseClassRecord() = default;
     829         120 :   explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     830             :   BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
     831             :       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
     832             :         Offset(Offset) {}
     833             :   BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
     834          56 :       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
     835         168 :         Offset(Offset) {}
     836             : 
     837          40 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     838          20 :   TypeIndex getBaseType() const { return Type; }
     839             :   uint64_t getBaseOffset() const { return Offset; }
     840             : 
     841             :   MemberAttributes Attrs;
     842             :   TypeIndex Type;
     843             :   uint64_t Offset;
     844             : };
     845             : 
     846             : // LF_VBCLASS, LF_IVBCLASS
     847             : class VirtualBaseClassRecord : public TypeRecord {
     848             : public:
     849             :   VirtualBaseClassRecord() = default;
     850         105 :   explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     851             :   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
     852             :                          TypeIndex BaseType, TypeIndex VBPtrType,
     853             :                          uint64_t Offset, uint64_t Index)
     854             :       : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
     855             :         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
     856             :   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
     857             :                          TypeIndex BaseType, TypeIndex VBPtrType,
     858             :                          uint64_t Offset, uint64_t Index)
     859          49 :       : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
     860         147 :         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
     861             : 
     862          22 :   MemberAccess getAccess() const { return Attrs.getAccess(); }
     863          11 :   TypeIndex getBaseType() const { return BaseType; }
     864          11 :   TypeIndex getVBPtrType() const { return VBPtrType; }
     865             :   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
     866             :   uint64_t getVTableIndex() const { return VTableIndex; }
     867             : 
     868             :   MemberAttributes Attrs;
     869             :   TypeIndex BaseType;
     870             :   TypeIndex VBPtrType;
     871             :   uint64_t VBPtrOffset;
     872             :   uint64_t VTableIndex;
     873             : };
     874             : 
     875             : /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
     876             : /// together. The first will end in an LF_INDEX record that points to the next.
     877             : class ListContinuationRecord : public TypeRecord {
     878             : public:
     879             :   ListContinuationRecord() = default;
     880          12 :   explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
     881             :   ListContinuationRecord(TypeIndex ContinuationIndex)
     882          44 :       : TypeRecord(TypeRecordKind::ListContinuation),
     883          88 :         ContinuationIndex(ContinuationIndex) {}
     884             : 
     885           4 :   TypeIndex getContinuationIndex() const { return ContinuationIndex; }
     886             : 
     887             :   TypeIndex ContinuationIndex;
     888             : };
     889             : 
     890             : } // end namespace codeview
     891             : } // end namespace llvm
     892             : 
     893             : #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H

Generated by: LCOV version 1.13