xref: /minix3/external/bsd/llvm/dist/llvm/include/llvm/ProfileData/CoverageMappingReader.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc //=-- CoverageMappingReader.h - Code coverage mapping reader ------*- C++ -*-=//
2*0a6a1f1dSLionel Sambuc //
3*0a6a1f1dSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc //
5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc //
8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc //
10*0a6a1f1dSLionel Sambuc // This file contains support for reading coverage mapping data for
11*0a6a1f1dSLionel Sambuc // instrumentation based coverage.
12*0a6a1f1dSLionel Sambuc //
13*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
14*0a6a1f1dSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
16*0a6a1f1dSLionel Sambuc #define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H
17*0a6a1f1dSLionel Sambuc 
18*0a6a1f1dSLionel Sambuc #include "llvm/ADT/ArrayRef.h"
19*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringRef.h"
20*0a6a1f1dSLionel Sambuc #include "llvm/Object/ObjectFile.h"
21*0a6a1f1dSLionel Sambuc #include "llvm/ProfileData/CoverageMapping.h"
22*0a6a1f1dSLionel Sambuc #include "llvm/ProfileData/InstrProf.h"
23*0a6a1f1dSLionel Sambuc #include "llvm/Support/FileSystem.h"
24*0a6a1f1dSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
25*0a6a1f1dSLionel Sambuc #include <iterator>
26*0a6a1f1dSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc namespace llvm {
28*0a6a1f1dSLionel Sambuc namespace coverage {
29*0a6a1f1dSLionel Sambuc 
30*0a6a1f1dSLionel Sambuc class ObjectFileCoverageMappingReader;
31*0a6a1f1dSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc /// \brief Coverage mapping information for a single function.
33*0a6a1f1dSLionel Sambuc struct CoverageMappingRecord {
34*0a6a1f1dSLionel Sambuc   StringRef FunctionName;
35*0a6a1f1dSLionel Sambuc   uint64_t FunctionHash;
36*0a6a1f1dSLionel Sambuc   ArrayRef<StringRef> Filenames;
37*0a6a1f1dSLionel Sambuc   ArrayRef<CounterExpression> Expressions;
38*0a6a1f1dSLionel Sambuc   ArrayRef<CounterMappingRegion> MappingRegions;
39*0a6a1f1dSLionel Sambuc };
40*0a6a1f1dSLionel Sambuc 
41*0a6a1f1dSLionel Sambuc /// \brief A file format agnostic iterator over coverage mapping data.
42*0a6a1f1dSLionel Sambuc class CoverageMappingIterator
43*0a6a1f1dSLionel Sambuc     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
44*0a6a1f1dSLionel Sambuc   ObjectFileCoverageMappingReader *Reader;
45*0a6a1f1dSLionel Sambuc   CoverageMappingRecord Record;
46*0a6a1f1dSLionel Sambuc 
47*0a6a1f1dSLionel Sambuc   void increment();
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc public:
CoverageMappingIterator()50*0a6a1f1dSLionel Sambuc   CoverageMappingIterator() : Reader(nullptr) {}
CoverageMappingIterator(ObjectFileCoverageMappingReader * Reader)51*0a6a1f1dSLionel Sambuc   CoverageMappingIterator(ObjectFileCoverageMappingReader *Reader)
52*0a6a1f1dSLionel Sambuc       : Reader(Reader) {
53*0a6a1f1dSLionel Sambuc     increment();
54*0a6a1f1dSLionel Sambuc   }
55*0a6a1f1dSLionel Sambuc 
56*0a6a1f1dSLionel Sambuc   CoverageMappingIterator &operator++() {
57*0a6a1f1dSLionel Sambuc     increment();
58*0a6a1f1dSLionel Sambuc     return *this;
59*0a6a1f1dSLionel Sambuc   }
60*0a6a1f1dSLionel Sambuc   bool operator==(const CoverageMappingIterator &RHS) {
61*0a6a1f1dSLionel Sambuc     return Reader == RHS.Reader;
62*0a6a1f1dSLionel Sambuc   }
63*0a6a1f1dSLionel Sambuc   bool operator!=(const CoverageMappingIterator &RHS) {
64*0a6a1f1dSLionel Sambuc     return Reader != RHS.Reader;
65*0a6a1f1dSLionel Sambuc   }
66*0a6a1f1dSLionel Sambuc   CoverageMappingRecord &operator*() { return Record; }
67*0a6a1f1dSLionel Sambuc   CoverageMappingRecord *operator->() { return &Record; }
68*0a6a1f1dSLionel Sambuc };
69*0a6a1f1dSLionel Sambuc 
70*0a6a1f1dSLionel Sambuc /// \brief Base class for the raw coverage mapping and filenames data readers.
71*0a6a1f1dSLionel Sambuc class RawCoverageReader {
72*0a6a1f1dSLionel Sambuc protected:
73*0a6a1f1dSLionel Sambuc   StringRef Data;
74*0a6a1f1dSLionel Sambuc 
75*0a6a1f1dSLionel Sambuc   /// \brief Return the error code.
error(std::error_code EC)76*0a6a1f1dSLionel Sambuc   std::error_code error(std::error_code EC) { return EC; }
77*0a6a1f1dSLionel Sambuc 
78*0a6a1f1dSLionel Sambuc   /// \brief Clear the current error code and return a successful one.
success()79*0a6a1f1dSLionel Sambuc   std::error_code success() { return error(instrprof_error::success); }
80*0a6a1f1dSLionel Sambuc 
RawCoverageReader(StringRef Data)81*0a6a1f1dSLionel Sambuc   RawCoverageReader(StringRef Data) : Data(Data) {}
82*0a6a1f1dSLionel Sambuc 
83*0a6a1f1dSLionel Sambuc   std::error_code readULEB128(uint64_t &Result);
84*0a6a1f1dSLionel Sambuc   std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
85*0a6a1f1dSLionel Sambuc   std::error_code readSize(uint64_t &Result);
86*0a6a1f1dSLionel Sambuc   std::error_code readString(StringRef &Result);
87*0a6a1f1dSLionel Sambuc };
88*0a6a1f1dSLionel Sambuc 
89*0a6a1f1dSLionel Sambuc /// \brief Reader for the raw coverage filenames.
90*0a6a1f1dSLionel Sambuc class RawCoverageFilenamesReader : public RawCoverageReader {
91*0a6a1f1dSLionel Sambuc   std::vector<StringRef> &Filenames;
92*0a6a1f1dSLionel Sambuc 
93*0a6a1f1dSLionel Sambuc   RawCoverageFilenamesReader(const RawCoverageFilenamesReader &)
94*0a6a1f1dSLionel Sambuc       LLVM_DELETED_FUNCTION;
95*0a6a1f1dSLionel Sambuc   RawCoverageFilenamesReader &
96*0a6a1f1dSLionel Sambuc   operator=(const RawCoverageFilenamesReader &) LLVM_DELETED_FUNCTION;
97*0a6a1f1dSLionel Sambuc 
98*0a6a1f1dSLionel Sambuc public:
RawCoverageFilenamesReader(StringRef Data,std::vector<StringRef> & Filenames)99*0a6a1f1dSLionel Sambuc   RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
100*0a6a1f1dSLionel Sambuc       : RawCoverageReader(Data), Filenames(Filenames) {}
101*0a6a1f1dSLionel Sambuc 
102*0a6a1f1dSLionel Sambuc   std::error_code read();
103*0a6a1f1dSLionel Sambuc };
104*0a6a1f1dSLionel Sambuc 
105*0a6a1f1dSLionel Sambuc /// \brief Reader for the raw coverage mapping data.
106*0a6a1f1dSLionel Sambuc class RawCoverageMappingReader : public RawCoverageReader {
107*0a6a1f1dSLionel Sambuc   StringRef FunctionName;
108*0a6a1f1dSLionel Sambuc   ArrayRef<StringRef> TranslationUnitFilenames;
109*0a6a1f1dSLionel Sambuc   std::vector<StringRef> &Filenames;
110*0a6a1f1dSLionel Sambuc   std::vector<CounterExpression> &Expressions;
111*0a6a1f1dSLionel Sambuc   std::vector<CounterMappingRegion> &MappingRegions;
112*0a6a1f1dSLionel Sambuc 
113*0a6a1f1dSLionel Sambuc   RawCoverageMappingReader(const RawCoverageMappingReader &)
114*0a6a1f1dSLionel Sambuc       LLVM_DELETED_FUNCTION;
115*0a6a1f1dSLionel Sambuc   RawCoverageMappingReader &
116*0a6a1f1dSLionel Sambuc   operator=(const RawCoverageMappingReader &) LLVM_DELETED_FUNCTION;
117*0a6a1f1dSLionel Sambuc 
118*0a6a1f1dSLionel Sambuc public:
RawCoverageMappingReader(StringRef FunctionName,StringRef MappingData,ArrayRef<StringRef> TranslationUnitFilenames,std::vector<StringRef> & Filenames,std::vector<CounterExpression> & Expressions,std::vector<CounterMappingRegion> & MappingRegions)119*0a6a1f1dSLionel Sambuc   RawCoverageMappingReader(StringRef FunctionName, StringRef MappingData,
120*0a6a1f1dSLionel Sambuc                            ArrayRef<StringRef> TranslationUnitFilenames,
121*0a6a1f1dSLionel Sambuc                            std::vector<StringRef> &Filenames,
122*0a6a1f1dSLionel Sambuc                            std::vector<CounterExpression> &Expressions,
123*0a6a1f1dSLionel Sambuc                            std::vector<CounterMappingRegion> &MappingRegions)
124*0a6a1f1dSLionel Sambuc       : RawCoverageReader(MappingData), FunctionName(FunctionName),
125*0a6a1f1dSLionel Sambuc         TranslationUnitFilenames(TranslationUnitFilenames),
126*0a6a1f1dSLionel Sambuc         Filenames(Filenames), Expressions(Expressions),
127*0a6a1f1dSLionel Sambuc         MappingRegions(MappingRegions) {}
128*0a6a1f1dSLionel Sambuc 
129*0a6a1f1dSLionel Sambuc   std::error_code read(CoverageMappingRecord &Record);
130*0a6a1f1dSLionel Sambuc 
131*0a6a1f1dSLionel Sambuc private:
132*0a6a1f1dSLionel Sambuc   std::error_code decodeCounter(unsigned Value, Counter &C);
133*0a6a1f1dSLionel Sambuc   std::error_code readCounter(Counter &C);
134*0a6a1f1dSLionel Sambuc   std::error_code
135*0a6a1f1dSLionel Sambuc   readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
136*0a6a1f1dSLionel Sambuc                              unsigned InferredFileID, size_t NumFileIDs);
137*0a6a1f1dSLionel Sambuc };
138*0a6a1f1dSLionel Sambuc 
139*0a6a1f1dSLionel Sambuc /// \brief Reader for the coverage mapping data that is emitted by the
140*0a6a1f1dSLionel Sambuc /// frontend and stored in an object file.
141*0a6a1f1dSLionel Sambuc class ObjectFileCoverageMappingReader {
142*0a6a1f1dSLionel Sambuc public:
143*0a6a1f1dSLionel Sambuc   struct ProfileMappingRecord {
144*0a6a1f1dSLionel Sambuc     CoverageMappingVersion Version;
145*0a6a1f1dSLionel Sambuc     StringRef FunctionName;
146*0a6a1f1dSLionel Sambuc     uint64_t FunctionHash;
147*0a6a1f1dSLionel Sambuc     StringRef CoverageMapping;
148*0a6a1f1dSLionel Sambuc     size_t FilenamesBegin;
149*0a6a1f1dSLionel Sambuc     size_t FilenamesSize;
150*0a6a1f1dSLionel Sambuc 
ProfileMappingRecordProfileMappingRecord151*0a6a1f1dSLionel Sambuc     ProfileMappingRecord(CoverageMappingVersion Version, StringRef FunctionName,
152*0a6a1f1dSLionel Sambuc                          uint64_t FunctionHash, StringRef CoverageMapping,
153*0a6a1f1dSLionel Sambuc                          size_t FilenamesBegin, size_t FilenamesSize)
154*0a6a1f1dSLionel Sambuc         : Version(Version), FunctionName(FunctionName),
155*0a6a1f1dSLionel Sambuc           FunctionHash(FunctionHash), CoverageMapping(CoverageMapping),
156*0a6a1f1dSLionel Sambuc           FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
157*0a6a1f1dSLionel Sambuc   };
158*0a6a1f1dSLionel Sambuc 
159*0a6a1f1dSLionel Sambuc private:
160*0a6a1f1dSLionel Sambuc   std::error_code LastError;
161*0a6a1f1dSLionel Sambuc   object::OwningBinary<object::ObjectFile> Object;
162*0a6a1f1dSLionel Sambuc   std::vector<StringRef> Filenames;
163*0a6a1f1dSLionel Sambuc   std::vector<ProfileMappingRecord> MappingRecords;
164*0a6a1f1dSLionel Sambuc   size_t CurrentRecord;
165*0a6a1f1dSLionel Sambuc   std::vector<StringRef> FunctionsFilenames;
166*0a6a1f1dSLionel Sambuc   std::vector<CounterExpression> Expressions;
167*0a6a1f1dSLionel Sambuc   std::vector<CounterMappingRegion> MappingRegions;
168*0a6a1f1dSLionel Sambuc 
169*0a6a1f1dSLionel Sambuc   ObjectFileCoverageMappingReader(const ObjectFileCoverageMappingReader &)
170*0a6a1f1dSLionel Sambuc       LLVM_DELETED_FUNCTION;
171*0a6a1f1dSLionel Sambuc   ObjectFileCoverageMappingReader &
172*0a6a1f1dSLionel Sambuc   operator=(const ObjectFileCoverageMappingReader &) LLVM_DELETED_FUNCTION;
173*0a6a1f1dSLionel Sambuc 
174*0a6a1f1dSLionel Sambuc   /// \brief Set the current error_code and return same.
error(std::error_code EC)175*0a6a1f1dSLionel Sambuc   std::error_code error(std::error_code EC) {
176*0a6a1f1dSLionel Sambuc     LastError = EC;
177*0a6a1f1dSLionel Sambuc     return EC;
178*0a6a1f1dSLionel Sambuc   }
179*0a6a1f1dSLionel Sambuc 
180*0a6a1f1dSLionel Sambuc   /// \brief Clear the current error code and return a successful one.
success()181*0a6a1f1dSLionel Sambuc   std::error_code success() { return error(instrprof_error::success); }
182*0a6a1f1dSLionel Sambuc 
183*0a6a1f1dSLionel Sambuc public:
184*0a6a1f1dSLionel Sambuc   ObjectFileCoverageMappingReader(StringRef FileName);
185*0a6a1f1dSLionel Sambuc   ObjectFileCoverageMappingReader(
186*0a6a1f1dSLionel Sambuc       std::unique_ptr<MemoryBuffer> &ObjectBuffer,
187*0a6a1f1dSLionel Sambuc       sys::fs::file_magic Type = sys::fs::file_magic::unknown);
188*0a6a1f1dSLionel Sambuc 
189*0a6a1f1dSLionel Sambuc   std::error_code readHeader();
190*0a6a1f1dSLionel Sambuc   std::error_code readNextRecord(CoverageMappingRecord &Record);
191*0a6a1f1dSLionel Sambuc 
192*0a6a1f1dSLionel Sambuc   /// Iterator over profile data.
begin()193*0a6a1f1dSLionel Sambuc   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
end()194*0a6a1f1dSLionel Sambuc   CoverageMappingIterator end() { return CoverageMappingIterator(); }
195*0a6a1f1dSLionel Sambuc 
196*0a6a1f1dSLionel Sambuc   /// \brief Return true if the reader has finished reading the profile data.
isEOF()197*0a6a1f1dSLionel Sambuc   bool isEOF() { return LastError == instrprof_error::eof; }
198*0a6a1f1dSLionel Sambuc   /// \brief Return true if the reader encountered an error reading profiling
199*0a6a1f1dSLionel Sambuc   /// data.
hasError()200*0a6a1f1dSLionel Sambuc   bool hasError() { return LastError && !isEOF(); }
201*0a6a1f1dSLionel Sambuc   /// \brief Get the current error code.
getError()202*0a6a1f1dSLionel Sambuc   std::error_code getError() { return LastError; }
203*0a6a1f1dSLionel Sambuc };
204*0a6a1f1dSLionel Sambuc 
205*0a6a1f1dSLionel Sambuc } // end namespace coverage
206*0a6a1f1dSLionel Sambuc } // end namespace llvm
207*0a6a1f1dSLionel Sambuc 
208*0a6a1f1dSLionel Sambuc #endif
209