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/Object/ObjectFile.h" 21 #include "llvm/ProfileData/CoverageMapping.h" 22 #include "llvm/ProfileData/InstrProf.h" 23 #include "llvm/Support/FileSystem.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include <iterator> 26 27 namespace llvm { 28 namespace coverage { 29 30 class ObjectFileCoverageMappingReader; 31 32 /// \brief Coverage mapping information for a single function. 33 struct CoverageMappingRecord { 34 StringRef FunctionName; 35 uint64_t FunctionHash; 36 ArrayRef<StringRef> Filenames; 37 ArrayRef<CounterExpression> Expressions; 38 ArrayRef<CounterMappingRegion> MappingRegions; 39 }; 40 41 /// \brief A file format agnostic iterator over coverage mapping data. 42 class CoverageMappingIterator 43 : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> { 44 ObjectFileCoverageMappingReader *Reader; 45 CoverageMappingRecord Record; 46 47 void increment(); 48 49 public: CoverageMappingIterator()50 CoverageMappingIterator() : Reader(nullptr) {} CoverageMappingIterator(ObjectFileCoverageMappingReader * Reader)51 CoverageMappingIterator(ObjectFileCoverageMappingReader *Reader) 52 : 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 /// \brief Base class for the raw coverage mapping and filenames data readers. 71 class RawCoverageReader { 72 protected: 73 StringRef Data; 74 75 /// \brief Return the error code. error(std::error_code EC)76 std::error_code error(std::error_code EC) { return EC; } 77 78 /// \brief Clear the current error code and return a successful one. success()79 std::error_code success() { return error(instrprof_error::success); } 80 RawCoverageReader(StringRef Data)81 RawCoverageReader(StringRef Data) : Data(Data) {} 82 83 std::error_code readULEB128(uint64_t &Result); 84 std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1); 85 std::error_code readSize(uint64_t &Result); 86 std::error_code readString(StringRef &Result); 87 }; 88 89 /// \brief Reader for the raw coverage filenames. 90 class RawCoverageFilenamesReader : public RawCoverageReader { 91 std::vector<StringRef> &Filenames; 92 93 RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) 94 LLVM_DELETED_FUNCTION; 95 RawCoverageFilenamesReader & 96 operator=(const RawCoverageFilenamesReader &) LLVM_DELETED_FUNCTION; 97 98 public: RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)99 RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames) 100 : RawCoverageReader(Data), Filenames(Filenames) {} 101 102 std::error_code read(); 103 }; 104 105 /// \brief Reader for the raw coverage mapping data. 106 class RawCoverageMappingReader : public RawCoverageReader { 107 StringRef FunctionName; 108 ArrayRef<StringRef> TranslationUnitFilenames; 109 std::vector<StringRef> &Filenames; 110 std::vector<CounterExpression> &Expressions; 111 std::vector<CounterMappingRegion> &MappingRegions; 112 113 RawCoverageMappingReader(const RawCoverageMappingReader &) 114 LLVM_DELETED_FUNCTION; 115 RawCoverageMappingReader & 116 operator=(const RawCoverageMappingReader &) LLVM_DELETED_FUNCTION; 117 118 public: RawCoverageMappingReader(StringRef FunctionName,StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)119 RawCoverageMappingReader(StringRef FunctionName, StringRef MappingData, 120 ArrayRef<StringRef> TranslationUnitFilenames, 121 std::vector<StringRef> &Filenames, 122 std::vector<CounterExpression> &Expressions, 123 std::vector<CounterMappingRegion> &MappingRegions) 124 : RawCoverageReader(MappingData), FunctionName(FunctionName), 125 TranslationUnitFilenames(TranslationUnitFilenames), 126 Filenames(Filenames), Expressions(Expressions), 127 MappingRegions(MappingRegions) {} 128 129 std::error_code read(CoverageMappingRecord &Record); 130 131 private: 132 std::error_code decodeCounter(unsigned Value, Counter &C); 133 std::error_code readCounter(Counter &C); 134 std::error_code 135 readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions, 136 unsigned InferredFileID, size_t NumFileIDs); 137 }; 138 139 /// \brief Reader for the coverage mapping data that is emitted by the 140 /// frontend and stored in an object file. 141 class ObjectFileCoverageMappingReader { 142 public: 143 struct ProfileMappingRecord { 144 CoverageMappingVersion Version; 145 StringRef FunctionName; 146 uint64_t FunctionHash; 147 StringRef CoverageMapping; 148 size_t FilenamesBegin; 149 size_t FilenamesSize; 150 ProfileMappingRecordProfileMappingRecord151 ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName, 152 uint64_t FunctionHash, StringRef CoverageMapping, 153 size_t FilenamesBegin, size_t FilenamesSize) 154 : Version(Version), FunctionName(FunctionName), 155 FunctionHash(FunctionHash), CoverageMapping(CoverageMapping), 156 FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} 157 }; 158 159 private: 160 std::error_code LastError; 161 object::OwningBinary<object::ObjectFile> Object; 162 std::vector<StringRef> Filenames; 163 std::vector<ProfileMappingRecord> MappingRecords; 164 size_t CurrentRecord; 165 std::vector<StringRef> FunctionsFilenames; 166 std::vector<CounterExpression> Expressions; 167 std::vector<CounterMappingRegion> MappingRegions; 168 169 ObjectFileCoverageMappingReader(const ObjectFileCoverageMappingReader &) 170 LLVM_DELETED_FUNCTION; 171 ObjectFileCoverageMappingReader & 172 operator=(const ObjectFileCoverageMappingReader &) LLVM_DELETED_FUNCTION; 173 174 /// \brief Set the current error_code and return same. error(std::error_code EC)175 std::error_code error(std::error_code EC) { 176 LastError = EC; 177 return EC; 178 } 179 180 /// \brief Clear the current error code and return a successful one. success()181 std::error_code success() { return error(instrprof_error::success); } 182 183 public: 184 ObjectFileCoverageMappingReader(StringRef FileName); 185 ObjectFileCoverageMappingReader( 186 std::unique_ptr<MemoryBuffer> &ObjectBuffer, 187 sys::fs::file_magic Type = sys::fs::file_magic::unknown); 188 189 std::error_code readHeader(); 190 std::error_code readNextRecord(CoverageMappingRecord &Record); 191 192 /// Iterator over profile data. begin()193 CoverageMappingIterator begin() { return CoverageMappingIterator(this); } end()194 CoverageMappingIterator end() { return CoverageMappingIterator(); } 195 196 /// \brief Return true if the reader has finished reading the profile data. isEOF()197 bool isEOF() { return LastError == instrprof_error::eof; } 198 /// \brief Return true if the reader encountered an error reading profiling 199 /// data. hasError()200 bool hasError() { return LastError && !isEOF(); } 201 /// \brief Get the current error code. getError()202 std::error_code getError() { return LastError; } 203 }; 204 205 } // end namespace coverage 206 } // end namespace llvm 207 208 #endif 209