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