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: CoverageMappingIterator()51 CoverageMappingIterator() : Reader(nullptr) {} CoverageMappingIterator(CoverageMappingReader * Reader)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; begin()73 CoverageMappingIterator begin() { return CoverageMappingIterator(this); } end()74 CoverageMappingIterator end() { return CoverageMappingIterator(); } ~CoverageMappingReader()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. error(std::error_code EC)84 std::error_code error(std::error_code EC) { return EC; } 85 86 /// \brief Clear the current error code and return a successful one. success()87 std::error_code success() { return error(instrprof_error::success); } 88 RawCoverageReader(StringRef Data)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: RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)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: RawCoverageMappingReader(StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)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 ProfileMappingRecordProfileMappingRecord156 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 BinaryCoverageReader()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