CoverageMappingReader.h revision 327952
1321369Sdim//===- CoverageMappingReader.h - Code coverage mapping reader ---*- C++ -*-===// 2303231Sdim// 3303231Sdim// The LLVM Compiler Infrastructure 4303231Sdim// 5303231Sdim// This file is distributed under the University of Illinois Open Source 6303231Sdim// License. See LICENSE.TXT for details. 7303231Sdim// 8303231Sdim//===----------------------------------------------------------------------===// 9303231Sdim// 10303231Sdim// This file contains support for reading coverage mapping data for 11303231Sdim// instrumentation based coverage. 12303231Sdim// 13303231Sdim//===----------------------------------------------------------------------===// 14303231Sdim 15321369Sdim#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H 16321369Sdim#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H 17303231Sdim 18303231Sdim#include "llvm/ADT/ArrayRef.h" 19303231Sdim#include "llvm/ADT/StringRef.h" 20303231Sdim#include "llvm/ProfileData/Coverage/CoverageMapping.h" 21303231Sdim#include "llvm/ProfileData/InstrProf.h" 22321369Sdim#include "llvm/Support/Error.h" 23303231Sdim#include "llvm/Support/MemoryBuffer.h" 24321369Sdim#include <cstddef> 25321369Sdim#include <cstdint> 26303231Sdim#include <iterator> 27321369Sdim#include <memory> 28321369Sdim#include <vector> 29303231Sdim 30303231Sdimnamespace llvm { 31303231Sdimnamespace coverage { 32303231Sdim 33303231Sdimclass CoverageMappingReader; 34303231Sdim 35303231Sdim/// \brief Coverage mapping information for a single function. 36303231Sdimstruct CoverageMappingRecord { 37303231Sdim StringRef FunctionName; 38303231Sdim uint64_t FunctionHash; 39303231Sdim ArrayRef<StringRef> Filenames; 40303231Sdim ArrayRef<CounterExpression> Expressions; 41303231Sdim ArrayRef<CounterMappingRegion> MappingRegions; 42303231Sdim}; 43303231Sdim 44303231Sdim/// \brief A file format agnostic iterator over coverage mapping data. 45303231Sdimclass CoverageMappingIterator 46303231Sdim : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> { 47327952Sdim CoverageMappingReader *Reader; 48303231Sdim CoverageMappingRecord Record; 49327952Sdim coveragemap_error ReadErr; 50303231Sdim 51303231Sdim void increment(); 52303231Sdim 53303231Sdimpublic: 54327952Sdim CoverageMappingIterator() 55327952Sdim : Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {} 56321369Sdim 57327952Sdim CoverageMappingIterator(CoverageMappingReader *Reader) 58327952Sdim : Reader(Reader), Record(), ReadErr(coveragemap_error::success) { 59303231Sdim increment(); 60303231Sdim } 61303231Sdim 62327952Sdim ~CoverageMappingIterator() { 63327952Sdim if (ReadErr != coveragemap_error::success) 64327952Sdim llvm_unreachable("Unexpected error in coverage mapping iterator"); 65327952Sdim } 66327952Sdim 67303231Sdim CoverageMappingIterator &operator++() { 68303231Sdim increment(); 69303231Sdim return *this; 70303231Sdim } 71303231Sdim bool operator==(const CoverageMappingIterator &RHS) { 72303231Sdim return Reader == RHS.Reader; 73303231Sdim } 74303231Sdim bool operator!=(const CoverageMappingIterator &RHS) { 75303231Sdim return Reader != RHS.Reader; 76303231Sdim } 77327952Sdim Expected<CoverageMappingRecord &> operator*() { 78327952Sdim if (ReadErr != coveragemap_error::success) { 79327952Sdim auto E = make_error<CoverageMapError>(ReadErr); 80327952Sdim ReadErr = coveragemap_error::success; 81327952Sdim return std::move(E); 82327952Sdim } 83327952Sdim return Record; 84327952Sdim } 85327952Sdim Expected<CoverageMappingRecord *> operator->() { 86327952Sdim if (ReadErr != coveragemap_error::success) { 87327952Sdim auto E = make_error<CoverageMapError>(ReadErr); 88327952Sdim ReadErr = coveragemap_error::success; 89327952Sdim return std::move(E); 90327952Sdim } 91327952Sdim return &Record; 92327952Sdim } 93303231Sdim}; 94303231Sdim 95303231Sdimclass CoverageMappingReader { 96303231Sdimpublic: 97321369Sdim virtual ~CoverageMappingReader() = default; 98321369Sdim 99303231Sdim virtual Error readNextRecord(CoverageMappingRecord &Record) = 0; 100303231Sdim CoverageMappingIterator begin() { return CoverageMappingIterator(this); } 101303231Sdim CoverageMappingIterator end() { return CoverageMappingIterator(); } 102303231Sdim}; 103303231Sdim 104303231Sdim/// \brief Base class for the raw coverage mapping and filenames data readers. 105303231Sdimclass RawCoverageReader { 106303231Sdimprotected: 107303231Sdim StringRef Data; 108303231Sdim 109303231Sdim RawCoverageReader(StringRef Data) : Data(Data) {} 110303231Sdim 111303231Sdim Error readULEB128(uint64_t &Result); 112303231Sdim Error readIntMax(uint64_t &Result, uint64_t MaxPlus1); 113303231Sdim Error readSize(uint64_t &Result); 114303231Sdim Error readString(StringRef &Result); 115303231Sdim}; 116303231Sdim 117303231Sdim/// \brief Reader for the raw coverage filenames. 118303231Sdimclass RawCoverageFilenamesReader : public RawCoverageReader { 119303231Sdim std::vector<StringRef> &Filenames; 120303231Sdim 121321369Sdimpublic: 122321369Sdim RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames) 123321369Sdim : RawCoverageReader(Data), Filenames(Filenames) {} 124303231Sdim RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; 125303231Sdim RawCoverageFilenamesReader & 126303231Sdim operator=(const RawCoverageFilenamesReader &) = delete; 127303231Sdim 128303231Sdim Error read(); 129303231Sdim}; 130303231Sdim 131303231Sdim/// \brief Checks if the given coverage mapping data is exported for 132303231Sdim/// an unused function. 133303231Sdimclass RawCoverageMappingDummyChecker : public RawCoverageReader { 134303231Sdimpublic: 135303231Sdim RawCoverageMappingDummyChecker(StringRef MappingData) 136303231Sdim : RawCoverageReader(MappingData) {} 137303231Sdim 138303231Sdim Expected<bool> isDummy(); 139303231Sdim}; 140303231Sdim 141303231Sdim/// \brief Reader for the raw coverage mapping data. 142303231Sdimclass RawCoverageMappingReader : public RawCoverageReader { 143303231Sdim ArrayRef<StringRef> TranslationUnitFilenames; 144303231Sdim std::vector<StringRef> &Filenames; 145303231Sdim std::vector<CounterExpression> &Expressions; 146303231Sdim std::vector<CounterMappingRegion> &MappingRegions; 147303231Sdim 148303231Sdimpublic: 149303231Sdim RawCoverageMappingReader(StringRef MappingData, 150303231Sdim ArrayRef<StringRef> TranslationUnitFilenames, 151303231Sdim std::vector<StringRef> &Filenames, 152303231Sdim std::vector<CounterExpression> &Expressions, 153303231Sdim std::vector<CounterMappingRegion> &MappingRegions) 154303231Sdim : RawCoverageReader(MappingData), 155303231Sdim TranslationUnitFilenames(TranslationUnitFilenames), 156303231Sdim Filenames(Filenames), Expressions(Expressions), 157303231Sdim MappingRegions(MappingRegions) {} 158321369Sdim RawCoverageMappingReader(const RawCoverageMappingReader &) = delete; 159321369Sdim RawCoverageMappingReader & 160321369Sdim operator=(const RawCoverageMappingReader &) = delete; 161303231Sdim 162303231Sdim Error read(); 163303231Sdim 164303231Sdimprivate: 165303231Sdim Error decodeCounter(unsigned Value, Counter &C); 166303231Sdim Error readCounter(Counter &C); 167303231Sdim Error 168303231Sdim readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions, 169303231Sdim unsigned InferredFileID, size_t NumFileIDs); 170303231Sdim}; 171303231Sdim 172303231Sdim/// \brief Reader for the coverage mapping data that is emitted by the 173303231Sdim/// frontend and stored in an object file. 174303231Sdimclass BinaryCoverageReader : public CoverageMappingReader { 175303231Sdimpublic: 176303231Sdim struct ProfileMappingRecord { 177303231Sdim CovMapVersion Version; 178303231Sdim StringRef FunctionName; 179303231Sdim uint64_t FunctionHash; 180303231Sdim StringRef CoverageMapping; 181303231Sdim size_t FilenamesBegin; 182303231Sdim size_t FilenamesSize; 183303231Sdim 184303231Sdim ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName, 185303231Sdim uint64_t FunctionHash, StringRef CoverageMapping, 186303231Sdim size_t FilenamesBegin, size_t FilenamesSize) 187303231Sdim : Version(Version), FunctionName(FunctionName), 188303231Sdim FunctionHash(FunctionHash), CoverageMapping(CoverageMapping), 189303231Sdim FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {} 190303231Sdim }; 191303231Sdim 192303231Sdimprivate: 193303231Sdim std::vector<StringRef> Filenames; 194303231Sdim std::vector<ProfileMappingRecord> MappingRecords; 195303231Sdim InstrProfSymtab ProfileNames; 196321369Sdim size_t CurrentRecord = 0; 197303231Sdim std::vector<StringRef> FunctionsFilenames; 198303231Sdim std::vector<CounterExpression> Expressions; 199303231Sdim std::vector<CounterMappingRegion> MappingRegions; 200303231Sdim 201321369Sdim BinaryCoverageReader() = default; 202321369Sdim 203321369Sdimpublic: 204303231Sdim BinaryCoverageReader(const BinaryCoverageReader &) = delete; 205303231Sdim BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; 206303231Sdim 207303231Sdim static Expected<std::unique_ptr<BinaryCoverageReader>> 208303231Sdim create(std::unique_ptr<MemoryBuffer> &ObjectBuffer, 209303231Sdim StringRef Arch); 210303231Sdim 211303231Sdim Error readNextRecord(CoverageMappingRecord &Record) override; 212303231Sdim}; 213303231Sdim 214303231Sdim} // end namespace coverage 215303231Sdim} // end namespace llvm 216303231Sdim 217321369Sdim#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H 218