cd4469c0666aa2edcbd075fbc4a00fe03acda289
[oota-llvm.git] / include / llvm / ProfileData / CoverageMappingReader.h
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 CoverageMappingReader;
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   CoverageMappingReader *Reader;
45   CoverageMappingRecord Record;
46
47   void increment();
48
49 public:
50   CoverageMappingIterator() : Reader(nullptr) {}
51   CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {
52     increment();
53   }
54
55   CoverageMappingIterator &operator++() {
56     increment();
57     return *this;
58   }
59   bool operator==(const CoverageMappingIterator &RHS) {
60     return Reader == RHS.Reader;
61   }
62   bool operator!=(const CoverageMappingIterator &RHS) {
63     return Reader != RHS.Reader;
64   }
65   CoverageMappingRecord &operator*() { return Record; }
66   CoverageMappingRecord *operator->() { return &Record; }
67 };
68
69 class CoverageMappingReader {
70 public:
71   virtual std::error_code readNextRecord(CoverageMappingRecord &Record) = 0;
72   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
73   CoverageMappingIterator end() { return CoverageMappingIterator(); }
74   virtual ~CoverageMappingReader() {}
75 };
76
77 /// \brief Base class for the raw coverage mapping and filenames data readers.
78 class RawCoverageReader {
79 protected:
80   StringRef Data;
81
82   /// \brief Return the error code.
83   std::error_code error(std::error_code EC) { return EC; }
84
85   /// \brief Clear the current error code and return a successful one.
86   std::error_code success() { return error(instrprof_error::success); }
87
88   RawCoverageReader(StringRef Data) : Data(Data) {}
89
90   std::error_code readULEB128(uint64_t &Result);
91   std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
92   std::error_code readSize(uint64_t &Result);
93   std::error_code readString(StringRef &Result);
94 };
95
96 /// \brief Reader for the raw coverage filenames.
97 class RawCoverageFilenamesReader : public RawCoverageReader {
98   std::vector<StringRef> &Filenames;
99
100   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
101   RawCoverageFilenamesReader &
102   operator=(const RawCoverageFilenamesReader &) = delete;
103
104 public:
105   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
106       : RawCoverageReader(Data), Filenames(Filenames) {}
107
108   std::error_code read();
109 };
110
111 /// \brief Reader for the raw coverage mapping data.
112 class RawCoverageMappingReader : public RawCoverageReader {
113   ArrayRef<StringRef> TranslationUnitFilenames;
114   std::vector<StringRef> &Filenames;
115   std::vector<CounterExpression> &Expressions;
116   std::vector<CounterMappingRegion> &MappingRegions;
117
118   RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
119   RawCoverageMappingReader &
120   operator=(const RawCoverageMappingReader &) = delete;
121
122 public:
123   RawCoverageMappingReader(StringRef MappingData,
124                            ArrayRef<StringRef> TranslationUnitFilenames,
125                            std::vector<StringRef> &Filenames,
126                            std::vector<CounterExpression> &Expressions,
127                            std::vector<CounterMappingRegion> &MappingRegions)
128       : RawCoverageReader(MappingData),
129         TranslationUnitFilenames(TranslationUnitFilenames),
130         Filenames(Filenames), Expressions(Expressions),
131         MappingRegions(MappingRegions) {}
132
133   std::error_code read();
134
135 private:
136   std::error_code decodeCounter(unsigned Value, Counter &C);
137   std::error_code readCounter(Counter &C);
138   std::error_code
139   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
140                              unsigned InferredFileID, size_t NumFileIDs);
141 };
142
143 /// \brief Reader for the coverage mapping data that is emitted by the
144 /// frontend and stored in an object file.
145 class ObjectFileCoverageMappingReader : public CoverageMappingReader {
146 public:
147   struct ProfileMappingRecord {
148     CoverageMappingVersion Version;
149     StringRef FunctionName;
150     uint64_t FunctionHash;
151     StringRef CoverageMapping;
152     size_t FilenamesBegin;
153     size_t FilenamesSize;
154
155     ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName,
156                          uint64_t FunctionHash, StringRef CoverageMapping,
157                          size_t FilenamesBegin, size_t FilenamesSize)
158         : Version(Version), FunctionName(FunctionName),
159           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
160           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
161   };
162
163 private:
164   std::error_code LastError;
165   object::OwningBinary<object::ObjectFile> Object;
166   std::vector<StringRef> Filenames;
167   std::vector<ProfileMappingRecord> MappingRecords;
168   size_t CurrentRecord;
169   std::vector<StringRef> FunctionsFilenames;
170   std::vector<CounterExpression> Expressions;
171   std::vector<CounterMappingRegion> MappingRegions;
172
173   ObjectFileCoverageMappingReader(const ObjectFileCoverageMappingReader &)
174       = delete;
175   ObjectFileCoverageMappingReader &
176   operator=(const ObjectFileCoverageMappingReader &) = delete;
177
178   /// \brief Set the current error_code and return same.
179   std::error_code error(std::error_code EC) {
180     LastError = EC;
181     return EC;
182   }
183
184   /// \brief Clear the current error code and return a successful one.
185   std::error_code success() { return error(instrprof_error::success); }
186
187 public:
188   ObjectFileCoverageMappingReader(std::unique_ptr<MemoryBuffer> &ObjectBuffer);
189
190   std::error_code readHeader();
191   std::error_code readNextRecord(CoverageMappingRecord &Record) override;
192
193   /// \brief Return true if the reader has finished reading the profile data.
194   bool isEOF() { return LastError == instrprof_error::eof; }
195   /// \brief Return true if the reader encountered an error reading profiling
196   /// data.
197   bool hasError() { return LastError && !isEOF(); }
198   /// \brief Get the current error code.
199   std::error_code getError() { return LastError; }
200 };
201
202 } // end namespace coverage
203 } // end namespace llvm
204
205 #endif