LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - CodeViewRecordIO.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 43 44 97.7 %
Date: 2018-05-20 00:06:23 Functions: 29 32 90.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- CodeViewRecordIO.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_CODEVIEWRECORDIO_H
      11             : #define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
      12             : 
      13             : #include "llvm/ADT/APSInt.h"
      14             : #include "llvm/ADT/None.h"
      15             : #include "llvm/ADT/Optional.h"
      16             : #include "llvm/ADT/SmallVector.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
      19             : #include "llvm/DebugInfo/CodeView/TypeRecord.h"
      20             : #include "llvm/Support/BinaryStreamReader.h"
      21             : #include "llvm/Support/BinaryStreamWriter.h"
      22             : #include "llvm/Support/Error.h"
      23             : #include <cassert>
      24             : #include <cstdint>
      25             : #include <type_traits>
      26             : 
      27             : namespace llvm {
      28             : namespace codeview {
      29             : 
      30             : class CodeViewRecordIO {
      31             :   uint32_t getCurrentOffset() const {
      32       50597 :     return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
      33             :   }
      34             : 
      35             : public:
      36       12790 :   explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
      37        7488 :   explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
      38             : 
      39             :   Error beginRecord(Optional<uint32_t> MaxLength);
      40             :   Error endRecord();
      41             : 
      42             :   Error mapInteger(TypeIndex &TypeInd);
      43             : 
      44             :   bool isReading() const { return Reader != nullptr; }
      45      198288 :   bool isWriting() const { return !isReading(); }
      46             : 
      47             :   uint32_t maxFieldLength() const;
      48             : 
      49         550 :   template <typename T> Error mapObject(T &Value) {
      50         550 :     if (isWriting())
      51          18 :       return Writer->writeObject(Value);
      52             : 
      53             :     const T *ValuePtr;
      54        1064 :     if (auto EC = Reader->readObject(ValuePtr))
      55             :       return EC;
      56         532 :     Value = *ValuePtr;
      57             :     return Error::success();
      58             :   }
      59             : 
      60       43954 :   template <typename T> Error mapInteger(T &Value) {
      61       43954 :     if (isWriting())
      62       13673 :       return Writer->writeInteger(Value);
      63             : 
      64       30281 :     return Reader->readInteger(Value);
      65             :   }
      66             : 
      67        8928 :   template <typename T> Error mapEnum(T &Value) {
      68        8928 :     if (sizeof(Value) > maxFieldLength())
      69           0 :       return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
      70             : 
      71             :     using U = typename std::underlying_type<T>::type;
      72             :     U X;
      73        8928 :     if (isWriting())
      74        1803 :       X = static_cast<U>(Value);
      75             : 
      76       17856 :     if (auto EC = mapInteger(X))
      77             :       return EC;
      78        8928 :     if (isReading())
      79        7125 :       Value = static_cast<T>(X);
      80             :     return Error::success();
      81             :   }
      82             : 
      83             :   Error mapEncodedInteger(int64_t &Value);
      84             :   Error mapEncodedInteger(uint64_t &Value);
      85             :   Error mapEncodedInteger(APSInt &Value);
      86             :   Error mapStringZ(StringRef &Value);
      87             :   Error mapGuid(GUID &Guid);
      88             : 
      89             :   Error mapStringZVectorZ(std::vector<StringRef> &Value);
      90             : 
      91             :   template <typename SizeType, typename T, typename ElementMapper>
      92        1330 :   Error mapVectorN(T &Items, const ElementMapper &Mapper) {
      93             :     SizeType Size;
      94        1330 :     if (isWriting()) {
      95         834 :       Size = static_cast<SizeType>(Items.size());
      96         864 :       if (auto EC = Writer->writeInteger(Size))
      97             :         return EC;
      98             : 
      99        1111 :       for (auto &X : Items) {
     100         533 :         if (auto EC = Mapper(*this, X))
     101             :           return EC;
     102             :       }
     103             :     } else {
     104        1796 :       if (auto EC = Reader->readInteger(Size))
     105             :         return EC;
     106        4020 :       for (SizeType I = 0; I < Size; ++I) {
     107             :         typename T::value_type Item;
     108        1561 :         if (auto EC = Mapper(*this, Item))
     109             :           return EC;
     110        1561 :         Items.push_back(Item);
     111             :       }
     112             :     }
     113             : 
     114             :     return Error::success();
     115             :   }
     116             : 
     117             :   template <typename T, typename ElementMapper>
     118         582 :   Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
     119         582 :     if (isWriting()) {
     120         199 :       for (auto &Item : Items) {
     121         258 :         if (auto EC = Mapper(*this, Item))
     122             :           return EC;
     123             :       }
     124             :     } else {
     125          11 :       typename T::value_type Field;
     126             :       // Stop when we run out of bytes or we hit record padding bytes.
     127        3418 :       while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
     128        1584 :         if (auto EC = Mapper(*this, Field))
     129             :           return EC;
     130         806 :         Items.push_back(Field);
     131             :       }
     132             :     }
     133             :     return Error::success();
     134             :   }
     135             : 
     136             :   Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
     137             :   Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
     138             : 
     139             :   Error padToAlignment(uint32_t Align);
     140             :   Error skipPadding();
     141             : 
     142             : private:
     143             :   Error writeEncodedSignedInteger(const int64_t &Value);
     144             :   Error writeEncodedUnsignedInteger(const uint64_t &Value);
     145             : 
     146       70512 :   struct RecordLimit {
     147             :     uint32_t BeginOffset;
     148             :     Optional<uint32_t> MaxLength;
     149             : 
     150             :     Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
     151       25205 :       if (!MaxLength.hasValue())
     152             :         return None;
     153             :       assert(CurrentOffset >= BeginOffset);
     154             : 
     155       18629 :       uint32_t BytesUsed = CurrentOffset - BeginOffset;
     156       18629 :       if (BytesUsed >= *MaxLength)
     157             :         return 0;
     158       18629 :       return *MaxLength - BytesUsed;
     159             :     }
     160             :   };
     161             : 
     162             :   SmallVector<RecordLimit, 2> Limits;
     163             : 
     164             :   BinaryStreamReader *Reader = nullptr;
     165             :   BinaryStreamWriter *Writer = nullptr;
     166             : };
     167             : 
     168             : } // end namespace codeview
     169             : } // end namespace llvm
     170             : 
     171             : #endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H

Generated by: LCOV version 1.13