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