Line data Source code
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 : /// 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 : /// A file format agnostic iterator over coverage mapping data.
45 : class 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 :
53 : public:
54 : CoverageMappingIterator()
55 214 : : Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {}
56 :
57 219 : CoverageMappingIterator(CoverageMappingReader *Reader)
58 219 : : Reader(Reader), Record(), ReadErr(coveragemap_error::success) {
59 219 : increment();
60 219 : }
61 :
62 : ~CoverageMappingIterator() {
63 219 : if (ReadErr != coveragemap_error::success)
64 0 : llvm_unreachable("Unexpected error in coverage mapping iterator");
65 : }
66 :
67 : CoverageMappingIterator &operator++() {
68 495 : increment();
69 : return *this;
70 : }
71 : bool operator==(const CoverageMappingIterator &RHS) {
72 : return Reader == RHS.Reader;
73 : }
74 0 : bool operator!=(const CoverageMappingIterator &RHS) {
75 0 : return Reader != RHS.Reader;
76 : }
77 500 : Expected<CoverageMappingRecord &> operator*() {
78 500 : if (ReadErr != coveragemap_error::success) {
79 : auto E = make_error<CoverageMapError>(ReadErr);
80 1 : ReadErr = coveragemap_error::success;
81 : return std::move(E);
82 : }
83 499 : 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 :
95 : class CoverageMappingReader {
96 : public:
97 0 : virtual ~CoverageMappingReader() = default;
98 :
99 : virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
100 219 : CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
101 0 : CoverageMappingIterator end() { return CoverageMappingIterator(); }
102 : };
103 :
104 : /// Base class for the raw coverage mapping and filenames data readers.
105 : class RawCoverageReader {
106 : protected:
107 : StringRef Data;
108 :
109 285 : 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 :
117 : /// Reader for the raw coverage filenames.
118 : class RawCoverageFilenamesReader : public RawCoverageReader {
119 : std::vector<StringRef> &Filenames;
120 :
121 : public:
122 : RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
123 152 : : RawCoverageReader(Data), Filenames(Filenames) {}
124 : RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
125 : RawCoverageFilenamesReader &
126 : operator=(const RawCoverageFilenamesReader &) = delete;
127 :
128 : Error read();
129 : };
130 :
131 : /// Checks if the given coverage mapping data is exported for
132 : /// an unused function.
133 : class RawCoverageMappingDummyChecker : public RawCoverageReader {
134 : public:
135 : RawCoverageMappingDummyChecker(StringRef MappingData)
136 : : RawCoverageReader(MappingData) {}
137 :
138 : Expected<bool> isDummy();
139 : };
140 :
141 : /// Reader for the raw coverage mapping data.
142 : class RawCoverageMappingReader : public RawCoverageReader {
143 : ArrayRef<StringRef> TranslationUnitFilenames;
144 : std::vector<StringRef> &Filenames;
145 : std::vector<CounterExpression> &Expressions;
146 : std::vector<CounterMappingRegion> &MappingRegions;
147 :
148 : public:
149 : RawCoverageMappingReader(StringRef MappingData,
150 : ArrayRef<StringRef> TranslationUnitFilenames,
151 : std::vector<StringRef> &Filenames,
152 : std::vector<CounterExpression> &Expressions,
153 : std::vector<CounterMappingRegion> &MappingRegions)
154 660 : : RawCoverageReader(MappingData),
155 : TranslationUnitFilenames(TranslationUnitFilenames),
156 : Filenames(Filenames), Expressions(Expressions),
157 660 : MappingRegions(MappingRegions) {}
158 : RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
159 : RawCoverageMappingReader &
160 : operator=(const RawCoverageMappingReader &) = delete;
161 :
162 : Error read();
163 :
164 : private:
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 :
172 : /// Reader for the coverage mapping data that is emitted by the
173 : /// frontend and stored in an object file.
174 : class BinaryCoverageReader : public CoverageMappingReader {
175 : public:
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 376 : : Version(Version), FunctionName(FunctionName),
188 : FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
189 376 : FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
190 : };
191 :
192 : private:
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 324 : BinaryCoverageReader() = default;
202 :
203 : public:
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
|