LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - TypeDeserializer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 47 53 88.7 %
Date: 2017-09-14 15:23:50 Functions: 38 43 88.4 %
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        2310 : class TypeDeserializer : public TypeVisitorCallbacks {
      30       19988 :   struct MappingInfo {
      31             :     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
      32        4997 :         : Stream(RecordData, llvm::support::little), Reader(Stream),
      33       14991 :           Mapping(Reader) {}
      34             : 
      35             :     BinaryByteStream Stream;
      36             :     BinaryStreamReader Reader;
      37             :     TypeRecordMapping Mapping;
      38             :   };
      39             : 
      40             : public:
      41        4620 :   TypeDeserializer() = default;
      42             : 
      43         601 :   template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
      44         601 :     Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
      45        1202 :     MappingInfo I(CVT.content());
      46        1803 :     if (auto EC = I.Mapping.visitTypeBegin(CVT))
      47           0 :       return EC;
      48        1803 :     if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
      49           0 :       return EC;
      50        1803 :     if (auto EC = I.Mapping.visitTypeEnd(CVT))
      51           0 :       return EC;
      52        1803 :     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        4396 :   Error visitTypeBegin(CVType &Record) override {
      69             :     assert(!Mapping && "Already in a type mapping!");
      70        4396 :     Mapping = llvm::make_unique<MappingInfo>(Record.content());
      71        8792 :     return Mapping->Mapping.visitTypeBegin(Record);
      72             :   }
      73             : 
      74        4378 :   Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
      75        4378 :     return visitTypeBegin(Record);
      76             :   }
      77             : 
      78        4396 :   Error visitTypeEnd(CVType &Record) override {
      79             :     assert(Mapping && "Not in a type mapping!");
      80        8792 :     auto EC = Mapping->Mapping.visitTypeEnd(Record);
      81        8792 :     Mapping.reset();
      82        4396 :     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        8792 :     return Mapping->Mapping.visitKnownRecord(CVR, Record);
      98             :   }
      99             : 
     100             :   std::unique_ptr<MappingInfo> Mapping;
     101             : };
     102             : 
     103             : class FieldListDeserializer : public TypeVisitorCallbacks {
     104         696 :   struct MappingInfo {
     105             :     explicit MappingInfo(BinaryStreamReader &R)
     106         696 :         : Reader(R), Mapping(Reader), StartOffset(0) {}
     107             : 
     108             :     BinaryStreamReader &Reader;
     109             :     TypeRecordMapping Mapping;
     110             :     uint32_t StartOffset;
     111             :   };
     112             : 
     113             : public:
     114         696 :   explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
     115         696 :     CVType FieldList;
     116         348 :     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
     117         696 :     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
     118         348 :   }
     119             : 
     120        1044 :   ~FieldListDeserializer() override {
     121         696 :     CVType FieldList;
     122         348 :     FieldList.Type = TypeLeafKind::LF_FIELDLIST;
     123         696 :     consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
     124         348 :   }
     125             : 
     126        7444 :   Error visitMemberBegin(CVMemberRecord &Record) override {
     127        7444 :     Mapping.StartOffset = Mapping.Reader.getOffset();
     128        7444 :     return Mapping.Mapping.visitMemberBegin(Record);
     129             :   }
     130             : 
     131        7444 :   Error visitMemberEnd(CVMemberRecord &Record) override {
     132       22332 :     if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
     133           0 :       return EC;
     134       22332 :     return Error::success();
     135             :   }
     136             : 
     137             : #define TYPE_RECORD(EnumName, EnumVal, Name)
     138             : #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
     139             :   Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
     140             :     return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
     141             :   }
     142             : #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        7444 :   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
     149       22332 :     if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
     150           0 :       return EC;
     151             : 
     152        7444 :     uint32_t EndOffset = Mapping.Reader.getOffset();
     153        7444 :     uint32_t RecordLength = EndOffset - Mapping.StartOffset;
     154       14888 :     Mapping.Reader.setOffset(Mapping.StartOffset);
     155       22332 :     if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
     156           0 :       return EC;
     157             :     assert(Mapping.Reader.getOffset() == EndOffset);
     158       22332 :     return Error::success();
     159             :   }
     160             :   MappingInfo Mapping;
     161             : };
     162             : 
     163             : } // end namespace codeview
     164             : } // end namespace llvm
     165             : 
     166             : #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H

Generated by: LCOV version 1.13