LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - TypeDeserializer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 41 43 95.3 %
Date: 2018-10-20 13:21:21 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- TypeDeserializer.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_TYPEDESERIALIZER_H
      11             : #define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
      12             : 
      13             : #include "llvm/ADT/ArrayRef.h"
      14             : #include "llvm/ADT/STLExtras.h"
      15             : #include "llvm/DebugInfo/CodeView/CodeView.h"
      16             : #include "llvm/DebugInfo/CodeView/TypeRecord.h"
      17             : #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
      18             : #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
      19             : #include "llvm/Support/BinaryByteStream.h"
      20             : #include "llvm/Support/BinaryStreamReader.h"
      21             : #include "llvm/Support/Error.h"
      22             : #include <cassert>
      23             : #include <cstdint>
      24             : #include <memory>
      25             : 
      26             : namespace llvm {
      27             : namespace codeview {
      28             : 
      29             : class TypeDeserializer : public TypeVisitorCallbacks {
      30             :   struct MappingInfo {
      31             :     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
      32       12007 :         : Stream(RecordData, llvm::support::little), Reader(Stream),
      33       12007 :           Mapping(Reader) {}
      34             : 
      35             :     BinaryByteStream Stream;
      36             :     BinaryStreamReader Reader;
      37             :     TypeRecordMapping Mapping;
      38             :   };
      39             : 
      40             : public:
      41        4412 :   TypeDeserializer() = default;
      42             : 
      43        2646 :   template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
      44        2646 :     Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
      45        2646 :     MappingInfo I(CVT.content());
      46        5292 :     if (auto EC = I.Mapping.visitTypeBegin(CVT))
      47             :       return EC;
      48        5292 :     if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
      49             :       return EC;
      50        5292 :     if (auto EC = I.Mapping.visitTypeEnd(CVT))
      51             :       return EC;
      52             :     return Error::success();
      53             :   }
      54             : 
      55             :   template <typename T>
      56             :   static Expected<T> deserializeAs(ArrayRef<uint8_t> Data) {
      57             :     const RecordPrefix *Prefix =
      58             :         reinterpret_cast<const RecordPrefix *>(Data.data());
      59             :     TypeRecordKind K =
      60             :         static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
      61             :     T Record(K);
      62             :     CVType CVT(static_cast<TypeLeafKind>(K), Data);
      63             :     if (auto EC = deserializeAs<T>(CVT, Record))
      64             :       return std::move(EC);
      65             :     return Record;
      66             :   }
      67             : 
      68        9361 :   Error visitTypeBegin(CVType &Record) override {
      69             :     assert(!Mapping && "Already in a type mapping!");
      70        9361 :     Mapping = llvm::make_unique<MappingInfo>(Record.content());
      71        9361 :     return Mapping->Mapping.visitTypeBegin(Record);
      72             :   }
      73             : 
      74        9361 :   Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
      75        9361 :     return visitTypeBegin(Record);
      76             :   }
      77             : 
      78        9361 :   Error visitTypeEnd(CVType &Record) override {
      79             :     assert(Mapping && "Not in a type mapping!");
      80        9361 :     auto EC = Mapping->Mapping.visitTypeEnd(Record);
      81             :     Mapping.reset();
      82        9361 :     return EC;
      83             :   }
      84             : 
      85             : #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
      86             :   Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
      87             :     return visitKnownRecordImpl<Name##Record>(CVR, Record);                    \
      88             :   }
      89             : #define MEMBER_RECORD(EnumName, EnumVal, Name)
      90             : #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
      91             : #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
      92             : #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
      93             : 
      94             : private:
      95             :   template <typename RecordType>
      96             :   Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
      97        9361 :     return Mapping->Mapping.visitKnownRecord(CVR, Record);
      98             :   }
      99             : 
     100             :   std::unique_ptr<MappingInfo> Mapping;
     101             : };
     102             : 
     103             : class FieldListDeserializer : public TypeVisitorCallbacks {
     104             :   struct MappingInfo {
     105             :     explicit MappingInfo(BinaryStreamReader &R)
     106         903 :         : Reader(R), Mapping(Reader), StartOffset(0) {}
     107             : 
     108             :     BinaryStreamReader &Reader;
     109             :     TypeRecordMapping Mapping;
     110             :     uint32_t StartOffset;
     111             :   };
     112             : 
     113             : public:
     114         903 :   explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
     115             :     CVType FieldList;
     116         903 :     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
     117         903 :     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
     118         903 :   }
     119             : 
     120         903 :   ~FieldListDeserializer() override {
     121             :     CVType FieldList;
     122         903 :     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
     123        1806 :     consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
     124         903 :   }
     125           0 : 
     126             :   Error visitMemberBegin(CVMemberRecord &Record) override {
     127             :     Mapping.StartOffset = Mapping.Reader.getOffset();
     128             :     return Mapping.Mapping.visitMemberBegin(Record);
     129           0 :   }
     130         903 : 
     131             :   Error visitMemberEnd(CVMemberRecord &Record) override {
     132         903 :     if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
     133        1806 :       return EC;
     134         903 :     return Error::success();
     135             :   }
     136        9222 : 
     137        9222 : #define TYPE_RECORD(EnumName, EnumVal, Name)
     138        9222 : #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
     139             :   Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
     140             :     return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
     141        9222 :   }
     142       18444 : #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
     143             : #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
     144             : #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
     145             : 
     146             : private:
     147             :   template <typename RecordType>
     148             :   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
     149             :     if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
     150             :       return EC;
     151             : 
     152             :     uint32_t EndOffset = Mapping.Reader.getOffset();
     153             :     uint32_t RecordLength = EndOffset - Mapping.StartOffset;
     154             :     Mapping.Reader.setOffset(Mapping.StartOffset);
     155             :     if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
     156             :       return EC;
     157             :     assert(Mapping.Reader.getOffset() == EndOffset);
     158        9132 :     return Error::success();
     159       18264 :   }
     160             :   MappingInfo Mapping;
     161             : };
     162        9132 : 
     163        9132 : } // end namespace codeview
     164             : } // end namespace llvm
     165       18264 : 
     166             : #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H

Generated by: LCOV version 1.13