LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GCOV.h
Go to the documentation of this file.
1 //===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- 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 header provides the interface to read and write coverage files that
11 // use 'gcov' format.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_SUPPORT_GCOV_H
16 #define LLVM_SUPPORT_GCOV_H
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringMap.h"
23 
24 namespace llvm {
25 
26 class GCOVFunction;
27 class GCOVBlock;
28 class FileInfo;
29 
30 namespace GCOV {
31  enum GCOVFormat {
37  };
38 } // end GCOV namespace
39 
40 /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
41 /// read operations.
42 class GCOVBuffer {
43 public:
44  GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
45 
46  /// readGCOVFormat - Read GCOV signature at the beginning of buffer.
48  StringRef Magic = Buffer->getBuffer().slice(0, 12);
49  Cursor = 12;
50  if (Magic == "oncg*404MVLL")
51  return GCOV::GCNO_404;
52  else if (Magic == "oncg*204MVLL")
53  return GCOV::GCNO_402;
54  else if (Magic == "adcg*404MVLL")
55  return GCOV::GCDA_404;
56  else if (Magic == "adcg*204MVLL")
57  return GCOV::GCDA_402;
58 
59  Cursor = 0;
60  return GCOV::InvalidGCOV;
61  }
62 
63  /// readFunctionTag - If cursor points to a function tag then increment the
64  /// cursor and return true otherwise return false.
65  bool readFunctionTag() {
66  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
67  if (Tag.empty() ||
68  Tag[0] != '\0' || Tag[1] != '\0' ||
69  Tag[2] != '\0' || Tag[3] != '\1') {
70  return false;
71  }
72  Cursor += 4;
73  return true;
74  }
75 
76  /// readBlockTag - If cursor points to a block tag then increment the
77  /// cursor and return true otherwise return false.
78  bool readBlockTag() {
79  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
80  if (Tag.empty() ||
81  Tag[0] != '\0' || Tag[1] != '\0' ||
82  Tag[2] != '\x41' || Tag[3] != '\x01') {
83  return false;
84  }
85  Cursor += 4;
86  return true;
87  }
88 
89  /// readEdgeTag - If cursor points to an edge tag then increment the
90  /// cursor and return true otherwise return false.
91  bool readEdgeTag() {
92  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
93  if (Tag.empty() ||
94  Tag[0] != '\0' || Tag[1] != '\0' ||
95  Tag[2] != '\x43' || Tag[3] != '\x01') {
96  return false;
97  }
98  Cursor += 4;
99  return true;
100  }
101 
102  /// readLineTag - If cursor points to a line tag then increment the
103  /// cursor and return true otherwise return false.
104  bool readLineTag() {
105  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
106  if (Tag.empty() ||
107  Tag[0] != '\0' || Tag[1] != '\0' ||
108  Tag[2] != '\x45' || Tag[3] != '\x01') {
109  return false;
110  }
111  Cursor += 4;
112  return true;
113  }
114 
115  /// readArcTag - If cursor points to an gcda arc tag then increment the
116  /// cursor and return true otherwise return false.
117  bool readArcTag() {
118  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
119  if (Tag.empty() ||
120  Tag[0] != '\0' || Tag[1] != '\0' ||
121  Tag[2] != '\xa1' || Tag[3] != '\1') {
122  return false;
123  }
124  Cursor += 4;
125  return true;
126  }
127 
128  /// readObjectTag - If cursor points to an object summary tag then increment
129  /// the cursor and return true otherwise return false.
130  bool readObjectTag() {
131  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
132  if (Tag.empty() ||
133  Tag[0] != '\0' || Tag[1] != '\0' ||
134  Tag[2] != '\0' || Tag[3] != '\xa1') {
135  return false;
136  }
137  Cursor += 4;
138  return true;
139  }
140 
141  /// readProgramTag - If cursor points to a program summary tag then increment
142  /// the cursor and return true otherwise return false.
143  bool readProgramTag() {
144  StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
145  if (Tag.empty() ||
146  Tag[0] != '\0' || Tag[1] != '\0' ||
147  Tag[2] != '\0' || Tag[3] != '\xa3') {
148  return false;
149  }
150  Cursor += 4;
151  return true;
152  }
153 
154  bool readInt(uint32_t &Val) {
155  if (Buffer->getBuffer().size() < Cursor+4) {
156  errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
157  return false;
158  }
159  StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
160  Cursor += 4;
161  Val = *(const uint32_t *)(Str.data());
162  return true;
163  }
164 
165  bool readInt64(uint64_t &Val) {
166  uint32_t Lo, Hi;
167  if (!readInt(Lo) || !readInt(Hi)) return false;
168  Val = ((uint64_t)Hi << 32) | Lo;
169  return true;
170  }
171 
172  bool readString(StringRef &Str) {
173  uint32_t Len;
174  if (!readInt(Len)) return false;
175  Len *= 4;
176  if (Buffer->getBuffer().size() < Cursor+Len) {
177  errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
178  return false;
179  }
180  Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
181  Cursor += Len;
182  return true;
183  }
184 
185  uint64_t getCursor() const { return Cursor; }
186  void advanceCursor(uint32_t n) { Cursor += n*4; }
187 private:
188  MemoryBuffer *Buffer;
189  uint64_t Cursor;
190 };
191 
192 /// GCOVFile - Collects coverage information for one pair of coverage file
193 /// (.gcno and .gcda).
194 class GCOVFile {
195 public:
196  GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
197  ~GCOVFile();
198  bool read(GCOVBuffer &Buffer);
199  void dump();
200  void collectLineCounts(FileInfo &FI);
201 private:
203  uint32_t RunCount;
204  uint32_t ProgramCount;
205 };
206 
207 /// GCOVFunction - Collects function information.
209 public:
210  GCOVFunction() : Ident(0), LineNumber(0) {}
211  ~GCOVFunction();
212  bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
213  StringRef getFilename() const { return Filename; }
214  void dump();
215  void collectLineCounts(FileInfo &FI);
216 private:
217  uint32_t Ident;
218  uint32_t LineNumber;
219  StringRef Name;
220  StringRef Filename;
222 };
223 
224 /// GCOVBlock - Collects block information.
225 class GCOVBlock {
226 public:
227  GCOVBlock(GCOVFunction &P, uint32_t N) :
228  Parent(P), Number(N), Counter(0), Edges(), Lines() {}
229  ~GCOVBlock();
230  void addEdge(uint32_t N) { Edges.push_back(N); }
231  void addLine(uint32_t N) { Lines.push_back(N); }
232  void addCount(uint64_t N) { Counter += N; }
233  size_t getNumEdges() { return Edges.size(); }
234  void dump();
235  void collectLineCounts(FileInfo &FI);
236 private:
237  GCOVFunction &Parent;
238  uint32_t Number;
239  uint64_t Counter;
242 };
243 
245 class FileInfo {
246 public:
247  void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
248  LineInfo[Filename][Line-1] += Count;
249  }
250  void setRunCount(uint32_t Runs) { RunCount = Runs; }
251  void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
252  void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
253 private:
254  StringMap<LineCounts> LineInfo;
255  uint32_t RunCount;
256  uint32_t ProgramCount;
257 };
258 
259 }
260 
261 #endif
void push_back(const T &Elt)
Definition: SmallVector.h:236
GCOVBlock(GCOVFunction &P, uint32_t N)
Definition: GCOV.h:227
raw_ostream & errs()
bool readInt(uint32_t &Val)
Definition: GCOV.h:154
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
void dump()
dump - Dump GCOVBlock content to dbgs() for debugging purposes.
Definition: GCOV.cpp:257
bool read(GCOVBuffer &Buffer)
read - Read GCOV buffer.
Definition: GCOV.cpp:43
bool readLineTag()
Definition: GCOV.h:104
void setProgramCount(uint32_t Programs)
Definition: GCOV.h:251
bool readString(StringRef &Str)
Definition: GCOV.h:172
std::pair< StringRef, StringRef > split(char Separator) const
Definition: StringRef.h:437
void addLine(uint32_t N)
Definition: GCOV.h:231
StringRef getBuffer() const
Definition: MemoryBuffer.h:55
GCOVFormat
Definition: GCOV.h:31
void collectLineCounts(FileInfo &FI)
Definition: GCOV.cpp:233
bool readArcTag()
Definition: GCOV.h:117
const char * data() const
Definition: StringRef.h:107
GCOVBlock - Collects block information.
Definition: GCOV.h:225
bool readInt64(uint64_t &Val)
Definition: GCOV.h:165
void collectLineCounts(FileInfo &FI)
Definition: GCOV.cpp:95
#define P(N)
bool readBlockTag()
Definition: GCOV.h:78
void dump()
dump - Dump GCOVFunction content to dbgs() for debugging purposes.
Definition: GCOV.cpp:224
void addEdge(uint32_t N)
Definition: GCOV.h:230
void advanceCursor(uint32_t n)
Definition: GCOV.h:186
bool readEdgeTag()
Definition: GCOV.h:91
static const char *const Magic
Definition: Archive.cpp:24
~GCOVFunction()
~GCOVFunction - Delete GCOVFunction and its content.
Definition: GCOV.cpp:107
GCOVBuffer(MemoryBuffer *B)
Definition: GCOV.h:44
GCOV::GCOVFormat readGCOVFormat()
readGCOVFormat - Read GCOV signature at the beginning of buffer.
Definition: GCOV.h:47
void addCount(uint64_t N)
Definition: GCOV.h:232
void dump()
dump - Dump GCOVFile content to dbgs() for debugging purposes.
Definition: GCOV.cpp:87
StringRef getFilename() const
Definition: GCOV.h:213
void collectLineCounts(FileInfo &FI)
Definition: GCOV.cpp:250
GCOVFunction - Collects function information.
Definition: GCOV.h:208
#define N
bool readObjectTag()
Definition: GCOV.h:130
DenseMap< uint32_t, uint64_t > LineCounts
Definition: GCOV.h:244
uint64_t getCursor() const
Definition: GCOV.h:185
~GCOVBlock()
~GCOVBlock - Delete GCOVBlock and its content.
Definition: GCOV.cpp:243
size_t getNumEdges()
Definition: GCOV.h:233
bool readProgramTag()
Definition: GCOV.h:143
bool readFunctionTag()
Definition: GCOV.h:65
StringRef slice(size_t Start, size_t End) const
Definition: StringRef.h:421
void setRunCount(uint32_t Runs)
Definition: GCOV.h:250
~GCOVFile()
~GCOVFile - Delete GCOVFile and its content.
Definition: GCOV.cpp:28
bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format)
Definition: GCOV.cpp:113
void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count)
Definition: GCOV.h:247
void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile)
print - Print source files with collected line count information.
Definition: GCOV.cpp:279
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110