LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - CodeViewRecordIO.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 48 59 81.4 %
Date: 2017-09-14 15:23:50 Functions: 28 32 87.5 %
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       24816 : class CodeViewRecordIO {
      31             :   uint32_t getCurrentOffset() const {
      32       35445 :     return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
      33             :   }
      34             : 
      35             : public:
      36       13516 :   explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
      37       11300 :   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      135241 :   bool isWriting() const { return !isReading(); }
      46             : 
      47             :   uint32_t maxFieldLength() const;
      48             : 
      49         330 :   template <typename T> Error mapObject(T &Value) {
      50         330 :     if (isWriting())
      51           0 :       return Writer->writeObject(Value);
      52             : 
      53             :     const T *ValuePtr;
      54         990 :     if (auto EC = Reader->readObject(ValuePtr))
      55           0 :       return EC;
      56         330 :     Value = *ValuePtr;
      57         990 :     return Error::success();
      58             :   }
      59             : 
      60       29442 :   template <typename T> Error mapInteger(T &Value) {
      61       29442 :     if (isWriting())
      62       10595 :       return Writer->writeInteger(Value);
      63             : 
      64       18847 :     return Reader->readInteger(Value);
      65             :   }
      66             : 
      67        4631 :   template <typename T> Error mapEnum(T &Value) {
      68        4631 :     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        4631 :     if (isWriting())
      74        1104 :       X = static_cast<U>(Value);
      75             : 
      76       13893 :     if (auto EC = mapInteger(X))
      77           0 :       return EC;
      78        4631 :     if (isReading())
      79        3527 :       Value = static_cast<T>(X);
      80       13893 :     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         933 :   Error mapVectorN(T &Items, const ElementMapper &Mapper) {
      93             :     SizeType Size;
      94         933 :     if (isWriting()) {
      95         582 :       Size = static_cast<SizeType>(Items.size());
      96         873 :       if (auto EC = Writer->writeInteger(Size))
      97           0 :         return EC;
      98             : 
      99        1456 :       for (auto &X : Items) {
     100        1264 :         if (auto EC = Mapper(*this, X))
     101           0 :           return EC;
     102             :       }
     103             :     } else {
     104        1926 :       if (auto EC = Reader->readInteger(Size))
     105           0 :         return EC;
     106        1594 :       for (SizeType I = 0; I < Size; ++I) {
     107         952 :         typename T::value_type Item;
     108        3808 :         if (auto EC = Mapper(*this, Item))
     109           0 :           return EC;
     110         952 :         Items.push_back(Item);
     111             :       }
     112             :     }
     113             : 
     114        2799 :     return Error::success();
     115             :   }
     116             : 
     117             :   template <typename T, typename ElementMapper>
     118         314 :   Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
     119         314 :     if (isWriting()) {
     120         166 :       for (auto &Item : Items) {
     121         188 :         if (auto EC = Mapper(*this, Item))
     122           0 :           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        1766 :       while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
     128        1249 :         if (auto EC = Mapper(*this, Field))
     129           0 :           return EC;
     130         407 :         Items.push_back(Field);
     131             :       }
     132             :     }
     133         942 :     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      183606 :   struct RecordLimit {
     147             :     uint32_t BeginOffset;
     148             :     Optional<uint32_t> MaxLength;
     149             : 
     150             :     Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
     151       18872 :       if (!MaxLength.hasValue())
     152             :         return None;
     153             :       assert(CurrentOffset >= BeginOffset);
     154             : 
     155       12727 :       uint32_t BytesUsed = CurrentOffset - BeginOffset;
     156       25454 :       if (BytesUsed >= *MaxLength)
     157           0 :         return 0;
     158       38181 :       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