Home | History | Annotate | Download | only in ProfileData
      1 //=-- CoverageMappingReader.h - Code coverage mapping reader ------*- 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 // This file contains support for reading coverage mapping data for
     11 // instrumentation based coverage.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
     16 #define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
     17 
     18 #include "llvm/ADT/ArrayRef.h"
     19 #include "llvm/ADT/StringRef.h"
     20 #include "llvm/ADT/Triple.h"
     21 #include "llvm/Object/ObjectFile.h"
     22 #include "llvm/ProfileData/CoverageMapping.h"
     23 #include "llvm/ProfileData/InstrProf.h"
     24 #include "llvm/Support/FileSystem.h"
     25 #include "llvm/Support/MemoryBuffer.h"
     26 #include <iterator>
     27 
     28 namespace llvm {
     29 namespace coverage {
     30 
     31 class CoverageMappingReader;
     32 
     33 /// \brief Coverage mapping information for a single function.
     34 struct CoverageMappingRecord {
     35   StringRef FunctionName;
     36   uint64_t FunctionHash;
     37   ArrayRef<StringRef> Filenames;
     38   ArrayRef<CounterExpression> Expressions;
     39   ArrayRef<CounterMappingRegion> MappingRegions;
     40 };
     41 
     42 /// \brief A file format agnostic iterator over coverage mapping data.
     43 class CoverageMappingIterator
     44     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
     45   CoverageMappingReader *Reader;
     46   CoverageMappingRecord Record;
     47 
     48   void increment();
     49 
     50 public:
     51   CoverageMappingIterator() : Reader(nullptr) {}
     52   CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {
     53     increment();
     54   }
     55 
     56   CoverageMappingIterator &operator++() {
     57     increment();
     58     return *this;
     59   }
     60   bool operator==(const CoverageMappingIterator &RHS) {
     61     return Reader == RHS.Reader;
     62   }
     63   bool operator!=(const CoverageMappingIterator &RHS) {
     64     return Reader != RHS.Reader;
     65   }
     66   CoverageMappingRecord &operator*() { return Record; }
     67   CoverageMappingRecord *operator->() { return &Record; }
     68 };
     69 
     70 class CoverageMappingReader {
     71 public:
     72   virtual std::error_code readNextRecord(CoverageMappingRecord &Record) = 0;
     73   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
     74   CoverageMappingIterator end() { return CoverageMappingIterator(); }
     75   virtual ~CoverageMappingReader() {}
     76 };
     77 
     78 /// \brief Base class for the raw coverage mapping and filenames data readers.
     79 class RawCoverageReader {
     80 protected:
     81   StringRef Data;
     82 
     83   /// \brief Return the error code.
     84   std::error_code error(std::error_code EC) { return EC; }
     85 
     86   /// \brief Clear the current error code and return a successful one.
     87   std::error_code success() { return error(instrprof_error::success); }
     88 
     89   RawCoverageReader(StringRef Data) : Data(Data) {}
     90 
     91   std::error_code readULEB128(uint64_t &Result);
     92   std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
     93   std::error_code readSize(uint64_t &Result);
     94   std::error_code readString(StringRef &Result);
     95 };
     96 
     97 /// \brief Reader for the raw coverage filenames.
     98 class RawCoverageFilenamesReader : public RawCoverageReader {
     99   std::vector<StringRef> &Filenames;
    100 
    101   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
    102   RawCoverageFilenamesReader &
    103   operator=(const RawCoverageFilenamesReader &) = delete;
    104 
    105 public:
    106   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
    107       : RawCoverageReader(Data), Filenames(Filenames) {}
    108 
    109   std::error_code read();
    110 };
    111 
    112 /// \brief Reader for the raw coverage mapping data.
    113 class RawCoverageMappingReader : public RawCoverageReader {
    114   ArrayRef<StringRef> TranslationUnitFilenames;
    115   std::vector<StringRef> &Filenames;
    116   std::vector<CounterExpression> &Expressions;
    117   std::vector<CounterMappingRegion> &MappingRegions;
    118 
    119   RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
    120   RawCoverageMappingReader &
    121   operator=(const RawCoverageMappingReader &) = delete;
    122 
    123 public:
    124   RawCoverageMappingReader(StringRef MappingData,
    125                            ArrayRef<StringRef> TranslationUnitFilenames,
    126                            std::vector<StringRef> &Filenames,
    127                            std::vector<CounterExpression> &Expressions,
    128                            std::vector<CounterMappingRegion> &MappingRegions)
    129       : RawCoverageReader(MappingData),
    130         TranslationUnitFilenames(TranslationUnitFilenames),
    131         Filenames(Filenames), Expressions(Expressions),
    132         MappingRegions(MappingRegions) {}
    133 
    134   std::error_code read();
    135 
    136 private:
    137   std::error_code decodeCounter(unsigned Value, Counter &C);
    138   std::error_code readCounter(Counter &C);
    139   std::error_code
    140   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
    141                              unsigned InferredFileID, size_t NumFileIDs);
    142 };
    143 
    144 /// \brief Reader for the coverage mapping data that is emitted by the
    145 /// frontend and stored in an object file.
    146 class BinaryCoverageReader : public CoverageMappingReader {
    147 public:
    148   struct ProfileMappingRecord {
    149     CoverageMappingVersion Version;
    150     StringRef FunctionName;
    151     uint64_t FunctionHash;
    152     StringRef CoverageMapping;
    153     size_t FilenamesBegin;
    154     size_t FilenamesSize;
    155 
    156     ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName,
    157                          uint64_t FunctionHash, StringRef CoverageMapping,
    158                          size_t FilenamesBegin, size_t FilenamesSize)
    159         : Version(Version), FunctionName(FunctionName),
    160           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
    161           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
    162   };
    163 
    164 private:
    165   std::vector<StringRef> Filenames;
    166   std::vector<ProfileMappingRecord> MappingRecords;
    167   size_t CurrentRecord;
    168   std::vector<StringRef> FunctionsFilenames;
    169   std::vector<CounterExpression> Expressions;
    170   std::vector<CounterMappingRegion> MappingRegions;
    171 
    172   BinaryCoverageReader(const BinaryCoverageReader &) = delete;
    173   BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
    174 
    175   BinaryCoverageReader() : CurrentRecord(0) {}
    176 
    177 public:
    178   static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
    179   create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
    180          Triple::ArchType Arch = Triple::ArchType::UnknownArch);
    181 
    182   std::error_code readNextRecord(CoverageMappingRecord &Record) override;
    183 };
    184 
    185 } // end namespace coverage
    186 } // end namespace llvm
    187 
    188 #endif
    189