Home | History | Annotate | Download | only in Coverage
      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/Coverage/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 Error 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   RawCoverageReader(StringRef Data) : Data(Data) {}
     84 
     85   Error readULEB128(uint64_t &Result);
     86   Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
     87   Error readSize(uint64_t &Result);
     88   Error readString(StringRef &Result);
     89 };
     90 
     91 /// \brief Reader for the raw coverage filenames.
     92 class RawCoverageFilenamesReader : public RawCoverageReader {
     93   std::vector<StringRef> &Filenames;
     94 
     95   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
     96   RawCoverageFilenamesReader &
     97   operator=(const RawCoverageFilenamesReader &) = delete;
     98 
     99 public:
    100   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
    101       : RawCoverageReader(Data), Filenames(Filenames) {}
    102 
    103   Error read();
    104 };
    105 
    106 /// \brief Checks if the given coverage mapping data is exported for
    107 /// an unused function.
    108 class RawCoverageMappingDummyChecker : public RawCoverageReader {
    109 public:
    110   RawCoverageMappingDummyChecker(StringRef MappingData)
    111       : RawCoverageReader(MappingData) {}
    112 
    113   Expected<bool> isDummy();
    114 };
    115 
    116 /// \brief Reader for the raw coverage mapping data.
    117 class RawCoverageMappingReader : public RawCoverageReader {
    118   ArrayRef<StringRef> TranslationUnitFilenames;
    119   std::vector<StringRef> &Filenames;
    120   std::vector<CounterExpression> &Expressions;
    121   std::vector<CounterMappingRegion> &MappingRegions;
    122 
    123   RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
    124   RawCoverageMappingReader &
    125   operator=(const RawCoverageMappingReader &) = delete;
    126 
    127 public:
    128   RawCoverageMappingReader(StringRef MappingData,
    129                            ArrayRef<StringRef> TranslationUnitFilenames,
    130                            std::vector<StringRef> &Filenames,
    131                            std::vector<CounterExpression> &Expressions,
    132                            std::vector<CounterMappingRegion> &MappingRegions)
    133       : RawCoverageReader(MappingData),
    134         TranslationUnitFilenames(TranslationUnitFilenames),
    135         Filenames(Filenames), Expressions(Expressions),
    136         MappingRegions(MappingRegions) {}
    137 
    138   Error read();
    139 
    140 private:
    141   Error decodeCounter(unsigned Value, Counter &C);
    142   Error readCounter(Counter &C);
    143   Error
    144   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
    145                              unsigned InferredFileID, size_t NumFileIDs);
    146 };
    147 
    148 /// \brief Reader for the coverage mapping data that is emitted by the
    149 /// frontend and stored in an object file.
    150 class BinaryCoverageReader : public CoverageMappingReader {
    151 public:
    152   struct ProfileMappingRecord {
    153     CovMapVersion Version;
    154     StringRef FunctionName;
    155     uint64_t FunctionHash;
    156     StringRef CoverageMapping;
    157     size_t FilenamesBegin;
    158     size_t FilenamesSize;
    159 
    160     ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName,
    161                          uint64_t FunctionHash, StringRef CoverageMapping,
    162                          size_t FilenamesBegin, size_t FilenamesSize)
    163         : Version(Version), FunctionName(FunctionName),
    164           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
    165           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
    166   };
    167 
    168 private:
    169   std::vector<StringRef> Filenames;
    170   std::vector<ProfileMappingRecord> MappingRecords;
    171   InstrProfSymtab ProfileNames;
    172   size_t CurrentRecord;
    173   std::vector<StringRef> FunctionsFilenames;
    174   std::vector<CounterExpression> Expressions;
    175   std::vector<CounterMappingRegion> MappingRegions;
    176 
    177   BinaryCoverageReader(const BinaryCoverageReader &) = delete;
    178   BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
    179 
    180   BinaryCoverageReader() : CurrentRecord(0) {}
    181 
    182 public:
    183   static Expected<std::unique_ptr<BinaryCoverageReader>>
    184   create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
    185          StringRef Arch);
    186 
    187   Error readNextRecord(CoverageMappingRecord &Record) override;
    188 };
    189 
    190 } // end namespace coverage
    191 } // end namespace llvm
    192 
    193 #endif
    194