blob: c88c71a6d6f40bc5293486d6061891c27ea2886a [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
30namespace llvm {
31namespace coverage {
32
33class CoverageMappingReader;
34
Andrew Scullcdfcccc2018-10-05 20:58:37 +010035/// Coverage mapping information for a single function.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010036struct CoverageMappingRecord {
37 StringRef FunctionName;
38 uint64_t FunctionHash;
39 ArrayRef<StringRef> Filenames;
40 ArrayRef<CounterExpression> Expressions;
41 ArrayRef<CounterMappingRegion> MappingRegions;
42};
43
Andrew Scullcdfcccc2018-10-05 20:58:37 +010044/// A file format agnostic iterator over coverage mapping data.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010045class CoverageMappingIterator
46 : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
47 CoverageMappingReader *Reader;
48 CoverageMappingRecord Record;
49 coveragemap_error ReadErr;
50
51 void increment();
52
53public:
54 CoverageMappingIterator()
55 : Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {}
56
57 CoverageMappingIterator(CoverageMappingReader *Reader)
58 : Reader(Reader), Record(), ReadErr(coveragemap_error::success) {
59 increment();
60 }
61
62 ~CoverageMappingIterator() {
63 if (ReadErr != coveragemap_error::success)
64 llvm_unreachable("Unexpected error in coverage mapping iterator");
65 }
66
67 CoverageMappingIterator &operator++() {
68 increment();
69 return *this;
70 }
71 bool operator==(const CoverageMappingIterator &RHS) {
72 return Reader == RHS.Reader;
73 }
74 bool operator!=(const CoverageMappingIterator &RHS) {
75 return Reader != RHS.Reader;
76 }
77 Expected<CoverageMappingRecord &> operator*() {
78 if (ReadErr != coveragemap_error::success) {
79 auto E = make_error<CoverageMapError>(ReadErr);
80 ReadErr = coveragemap_error::success;
81 return std::move(E);
82 }
83 return Record;
84 }
85 Expected<CoverageMappingRecord *> operator->() {
86 if (ReadErr != coveragemap_error::success) {
87 auto E = make_error<CoverageMapError>(ReadErr);
88 ReadErr = coveragemap_error::success;
89 return std::move(E);
90 }
91 return &Record;
92 }
93};
94
95class CoverageMappingReader {
96public:
97 virtual ~CoverageMappingReader() = default;
98
99 virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
100 CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
101 CoverageMappingIterator end() { return CoverageMappingIterator(); }
102};
103
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100104/// Base class for the raw coverage mapping and filenames data readers.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100105class RawCoverageReader {
106protected:
107 StringRef Data;
108
109 RawCoverageReader(StringRef Data) : Data(Data) {}
110
111 Error readULEB128(uint64_t &Result);
112 Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
113 Error readSize(uint64_t &Result);
114 Error readString(StringRef &Result);
115};
116
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100117/// Reader for the raw coverage filenames.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100118class RawCoverageFilenamesReader : public RawCoverageReader {
119 std::vector<StringRef> &Filenames;
120
121public:
122 RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
123 : RawCoverageReader(Data), Filenames(Filenames) {}
124 RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
125 RawCoverageFilenamesReader &
126 operator=(const RawCoverageFilenamesReader &) = delete;
127
128 Error read();
129};
130
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100131/// Checks if the given coverage mapping data is exported for
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100132/// an unused function.
133class RawCoverageMappingDummyChecker : public RawCoverageReader {
134public:
135 RawCoverageMappingDummyChecker(StringRef MappingData)
136 : RawCoverageReader(MappingData) {}
137
138 Expected<bool> isDummy();
139};
140
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100141/// Reader for the raw coverage mapping data.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100142class RawCoverageMappingReader : public RawCoverageReader {
143 ArrayRef<StringRef> TranslationUnitFilenames;
144 std::vector<StringRef> &Filenames;
145 std::vector<CounterExpression> &Expressions;
146 std::vector<CounterMappingRegion> &MappingRegions;
147
148public:
149 RawCoverageMappingReader(StringRef MappingData,
150 ArrayRef<StringRef> TranslationUnitFilenames,
151 std::vector<StringRef> &Filenames,
152 std::vector<CounterExpression> &Expressions,
153 std::vector<CounterMappingRegion> &MappingRegions)
154 : RawCoverageReader(MappingData),
155 TranslationUnitFilenames(TranslationUnitFilenames),
156 Filenames(Filenames), Expressions(Expressions),
157 MappingRegions(MappingRegions) {}
158 RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
159 RawCoverageMappingReader &
160 operator=(const RawCoverageMappingReader &) = delete;
161
162 Error read();
163
164private:
165 Error decodeCounter(unsigned Value, Counter &C);
166 Error readCounter(Counter &C);
167 Error
168 readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
169 unsigned InferredFileID, size_t NumFileIDs);
170};
171
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100172/// Reader for the coverage mapping data that is emitted by the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100173/// frontend and stored in an object file.
174class BinaryCoverageReader : public CoverageMappingReader {
175public:
176 struct ProfileMappingRecord {
177 CovMapVersion Version;
178 StringRef FunctionName;
179 uint64_t FunctionHash;
180 StringRef CoverageMapping;
181 size_t FilenamesBegin;
182 size_t FilenamesSize;
183
184 ProfileMappingRecord(CovMapVersion Version, StringRef FunctionName,
185 uint64_t FunctionHash, StringRef CoverageMapping,
186 size_t FilenamesBegin, size_t FilenamesSize)
187 : Version(Version), FunctionName(FunctionName),
188 FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
189 FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
190 };
191
192private:
193 std::vector<StringRef> Filenames;
194 std::vector<ProfileMappingRecord> MappingRecords;
195 InstrProfSymtab ProfileNames;
196 size_t CurrentRecord = 0;
197 std::vector<StringRef> FunctionsFilenames;
198 std::vector<CounterExpression> Expressions;
199 std::vector<CounterMappingRegion> MappingRegions;
200
201 BinaryCoverageReader() = default;
202
203public:
204 BinaryCoverageReader(const BinaryCoverageReader &) = delete;
205 BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete;
206
207 static Expected<std::unique_ptr<BinaryCoverageReader>>
208 create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
209 StringRef Arch);
210
211 Error readNextRecord(CoverageMappingRecord &Record) override;
212};
213
214} // end namespace coverage
215} // end namespace llvm
216
217#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H