LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - CodeViewRecordIO.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 133 194 68.6 %
Date: 2018-10-20 13:21:21 Functions: 22 31 71.0 %
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       57375 :     return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
      33             :   }
      34             : 
      35             : public:
      36        3549 :   explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
      37        9344 :   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           0 :   bool isReading() const { return Reader != nullptr; }
      45      175294 :   bool isWriting() const { return !isReading(); }
      46             : 
      47             :   uint32_t maxFieldLength() const;
      48             : 
      49         177 :   template <typename T> Error mapObject(T &Value) {
      50         177 :     if (isWriting())
      51          30 :       return Writer->writeObject(Value);
      52             : 
      53             :     const T *ValuePtr;
      54         294 :     if (auto EC = Reader->readObject(ValuePtr))
      55             :       return EC;
      56         147 :     Value = *ValuePtr;
      57             :     return Error::success();
      58             :   }
      59           7 : 
      60       37264 :   template <typename T> Error mapInteger(T &Value) {
      61       37257 :     if (isWriting())
      62       10089 :       return Writer->writeInteger(Value);
      63             : 
      64       27182 :     return Reader->readInteger(Value);
      65             :   }
      66        5125 : 
      67        5118 :   template <typename T> Error mapEnum(T &Value) {
      68         989 :     if (sizeof(Value) > maxFieldLength())
      69          16 :       return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
      70        4145 : 
      71           4 :     using U = typename std::underlying_type<T>::type;
      72        2743 :     U X;
      73        2743 :     if (isWriting())
      74         557 :       X = static_cast<U>(Value);
      75             : 
      76        2222 :     if (auto EC = mapInteger(X))
      77             :       return EC;
      78        1797 :     if (isReading())
      79        1951 :       Value = static_cast<T>(X);
      80         414 :     return Error::success();
      81          26 :   }
      82        1537 : 
      83             :   Error mapEncodedInteger(int64_t &Value);
      84       27855 :   Error mapEncodedInteger(uint64_t &Value);
      85       27599 :   Error mapEncodedInteger(APSInt &Value);
      86        8435 :   Error mapStringZ(StringRef &Value);
      87             :   Error mapGuid(GUID &Guid);
      88       19292 : 
      89             :   Error mapStringZVectorZ(std::vector<StringRef> &Value);
      90       12712 : 
      91       21585 :   template <typename SizeType, typename T, typename ElementMapper>
      92       13629 :   Error mapVectorN(T &Items, const ElementMapper &Mapper) {
      93             :     SizeType Size;
      94        7956 :     if (isWriting()) {
      95             :       Size = static_cast<SizeType>(Items.size());
      96         177 :       if (auto EC = Writer->writeInteger(Size))
      97        9050 :         return EC;
      98        1434 : 
      99             :       for (auto &X : Items) {
     100       17919 :         if (auto EC = Mapper(*this, X))
     101             :           return EC;
     102        9864 :       }
     103        8434 :     } else {
     104         599 :       if (auto EC = Reader->readInteger(Size))
     105             :         return EC;
     106         393 :       for (SizeType I = 0; I < Size; ++I) {
     107           1 :         typename T::value_type Item;
     108        6737 :         if (auto EC = Mapper(*this, Item))
     109        6737 :           return EC;
     110        2307 :         Items.push_back(Item);
     111             :       }
     112        4431 :     }
     113           0 : 
     114        4807 :     return Error::success();
     115        4809 :   }
     116        1846 : 
     117           1 :   template <typename T, typename ElementMapper>
     118        2962 :   Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
     119             :     if (isWriting()) {
     120             :       for (auto &Item : Items) {
     121        5360 :         if (auto EC = Mapper(*this, Item))
     122        5360 :           return EC;
     123             :       }
     124             :     } else {
     125             :       typename T::value_type Field;
     126             :       // Stop when we run out of bytes or we hit record padding bytes.
     127        5360 :       while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
     128        1028 :         if (auto EC = Mapper(*this, Field))
     129             :           return EC;
     130       10720 :         Items.push_back(Field);
     131             :       }
     132        5360 :     }
     133        4332 :     return Error::success();
     134             :   }
     135             : 
     136         349 :   Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
     137         349 :   Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
     138             : 
     139             :   Error padToAlignment(uint32_t Align);
     140             :   Error skipPadding();
     141             : 
     142         349 : private:
     143          73 :   Error writeEncodedSignedInteger(const int64_t &Value);
     144             :   Error writeEncodedUnsignedInteger(const uint64_t &Value);
     145         698 : 
     146       42736 :   struct RecordLimit {
     147         349 :     uint32_t BeginOffset;
     148         276 :     Optional<uint32_t> MaxLength;
     149             : 
     150             :     Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
     151       30795 :       if (!MaxLength.hasValue())
     152        2950 :         return None;
     153             :       assert(CurrentOffset >= BeginOffset);
     154             : 
     155       21242 :       uint32_t BytesUsed = CurrentOffset - BeginOffset;
     156       21242 :       if (BytesUsed >= *MaxLength)
     157        2950 :         return 0;
     158       21938 :       return *MaxLength - BytesUsed;
     159             :     }
     160        5900 :   };
     161             : 
     162        2950 :   SmallVector<RecordLimit, 2> Limits;
     163        2254 : 
     164             :   BinaryStreamReader *Reader = nullptr;
     165             :   BinaryStreamWriter *Writer = nullptr;
     166        2547 : };
     167        2547 : 
     168             : } // end namespace codeview
     169             : } // end namespace llvm
     170             : 
     171             : #endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H

Generated by: LCOV version 1.13