LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GCOV.cpp
Go to the documentation of this file.
1 //===- GCOVr.cpp - LLVM coverage tool -------------------------------------===//
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 // GCOV implements the interface to read and write coverage files that use
11 // 'gcov' format.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/GCOV.h"
17 #include "llvm/ADT/OwningPtr.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Support/Format.h"
22 using namespace llvm;
23 
24 //===----------------------------------------------------------------------===//
25 // GCOVFile implementation.
26 
27 /// ~GCOVFile - Delete GCOVFile and its content.
29  DeleteContainerPointers(Functions);
30 }
31 
32 /// isGCDAFile - Return true if Format identifies a .gcda file.
33 static bool isGCDAFile(GCOV::GCOVFormat Format) {
34  return Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404;
35 }
36 
37 /// isGCNOFile - Return true if Format identifies a .gcno file.
38 static bool isGCNOFile(GCOV::GCOVFormat Format) {
39  return Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404;
40 }
41 
42 /// read - Read GCOV buffer.
43 bool GCOVFile::read(GCOVBuffer &Buffer) {
44  GCOV::GCOVFormat Format = Buffer.readGCOVFormat();
45  if (Format == GCOV::InvalidGCOV)
46  return false;
47 
48  if (isGCNOFile(Format)) {
49  while (true) {
50  if (!Buffer.readFunctionTag()) break;
51  GCOVFunction *GFun = new GCOVFunction();
52  if (!GFun->read(Buffer, Format))
53  return false;
54  Functions.push_back(GFun);
55  }
56  }
57  else if (isGCDAFile(Format)) {
58  for (size_t i = 0, e = Functions.size(); i < e; ++i) {
59  if (!Buffer.readFunctionTag()) {
60  errs() << "Unexpected number of functions.\n";
61  return false;
62  }
63  if (!Functions[i]->read(Buffer, Format))
64  return false;
65  }
66  if (Buffer.readObjectTag()) {
67  uint32_t Length;
68  uint32_t Dummy;
69  if (!Buffer.readInt(Length)) return false;
70  if (!Buffer.readInt(Dummy)) return false; // checksum
71  if (!Buffer.readInt(Dummy)) return false; // num
72  if (!Buffer.readInt(RunCount)) return false;;
73  Buffer.advanceCursor(Length-3);
74  }
75  while (Buffer.readProgramTag()) {
76  uint32_t Length;
77  if (!Buffer.readInt(Length)) return false;
78  Buffer.advanceCursor(Length);
79  ++ProgramCount;
80  }
81  }
82 
83  return true;
84 }
85 
86 /// dump - Dump GCOVFile content to dbgs() for debugging purposes.
88  for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(),
89  E = Functions.end(); I != E; ++I)
90  (*I)->dump();
91 }
92 
93 /// collectLineCounts - Collect line counts. This must be used after
94 /// reading .gcno and .gcda files.
96  for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(),
97  E = Functions.end(); I != E; ++I)
98  (*I)->collectLineCounts(FI);
99  FI.setRunCount(RunCount);
100  FI.setProgramCount(ProgramCount);
101 }
102 
103 //===----------------------------------------------------------------------===//
104 // GCOVFunction implementation.
105 
106 /// ~GCOVFunction - Delete GCOVFunction and its content.
108  DeleteContainerPointers(Blocks);
109 }
110 
111 /// read - Read a function from the buffer. Return false if buffer cursor
112 /// does not point to a function tag.
114  uint32_t Dummy;
115  if (!Buff.readInt(Dummy)) return false; // Function header length
116  if (!Buff.readInt(Ident)) return false;
117  if (!Buff.readInt(Dummy)) return false; // Checksum #1
118  if (Format != GCOV::GCNO_402 && Format != GCOV::GCDA_402)
119  if (!Buff.readInt(Dummy)) return false; // Checksum #2
120 
121  if (!Buff.readString(Name)) return false;
122 
123  if (Format == GCOV::GCNO_402 || Format == GCOV::GCNO_404)
124  if (!Buff.readString(Filename)) return false;
125 
126  if (Format == GCOV::GCDA_402 || Format == GCOV::GCDA_404) {
127  if (!Buff.readArcTag()) {
128  errs() << "Arc tag not found.\n";
129  return false;
130  }
131  uint32_t Count;
132  if (!Buff.readInt(Count)) return false;
133  Count /= 2;
134 
135  // This for loop adds the counts for each block. A second nested loop is
136  // required to combine the edge counts that are contained in the GCDA file.
137  for (uint32_t Line = 0; Count > 0; ++Line) {
138  if (Line >= Blocks.size()) {
139  errs() << "Unexpected number of edges.\n";
140  return false;
141  }
142  GCOVBlock &Block = *Blocks[Line];
143  for (size_t Edge = 0, End = Block.getNumEdges(); Edge < End; ++Edge) {
144  if (Count == 0) {
145  errs() << "Unexpected number of edges.\n";
146  return false;
147  }
148  uint64_t ArcCount;
149  if (!Buff.readInt64(ArcCount)) return false;
150  Block.addCount(ArcCount);
151  --Count;
152  }
153  }
154  return true;
155  }
156 
157  if (!Buff.readInt(LineNumber)) return false;
158 
159  // read blocks.
160  if (!Buff.readBlockTag()) {
161  errs() << "Block tag not found.\n";
162  return false;
163  }
164  uint32_t BlockCount;
165  if (!Buff.readInt(BlockCount)) return false;
166  for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
167  if (!Buff.readInt(Dummy)) return false; // Block flags;
168  Blocks.push_back(new GCOVBlock(*this, i));
169  }
170 
171  // read edges.
172  while (Buff.readEdgeTag()) {
173  uint32_t EdgeCount;
174  if (!Buff.readInt(EdgeCount)) return false;
175  EdgeCount = (EdgeCount - 1) / 2;
176  uint32_t BlockNo;
177  if (!Buff.readInt(BlockNo)) return false;
178  if (BlockNo >= BlockCount) {
179  errs() << "Unexpected block number.\n";
180  return false;
181  }
182  for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
183  uint32_t Dst;
184  if (!Buff.readInt(Dst)) return false;
185  Blocks[BlockNo]->addEdge(Dst);
186  if (!Buff.readInt(Dummy)) return false; // Edge flag
187  }
188  }
189 
190  // read line table.
191  while (Buff.readLineTag()) {
192  uint32_t LineTableLength;
193  if (!Buff.readInt(LineTableLength)) return false;
194  uint32_t EndPos = Buff.getCursor() + LineTableLength*4;
195  uint32_t BlockNo;
196  if (!Buff.readInt(BlockNo)) return false;
197  if (BlockNo >= BlockCount) {
198  errs() << "Unexpected block number.\n";
199  return false;
200  }
201  GCOVBlock *Block = Blocks[BlockNo];
202  if (!Buff.readInt(Dummy)) return false; // flag
203  while (Buff.getCursor() != (EndPos - 4)) {
204  StringRef F;
205  if (!Buff.readString(F)) return false;
206  if (F != Filename) {
207  errs() << "Multiple sources for a single basic block.\n";
208  return false;
209  }
210  if (Buff.getCursor() == (EndPos - 4)) break;
211  while (true) {
212  uint32_t Line;
213  if (!Buff.readInt(Line)) return false;
214  if (!Line) break;
215  Block->addLine(Line);
216  }
217  }
218  if (!Buff.readInt(Dummy)) return false; // flag
219  }
220  return true;
221 }
222 
223 /// dump - Dump GCOVFunction content to dbgs() for debugging purposes.
225  dbgs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n";
226  for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(),
227  E = Blocks.end(); I != E; ++I)
228  (*I)->dump();
229 }
230 
231 /// collectLineCounts - Collect line counts. This must be used after
232 /// reading .gcno and .gcda files.
234  for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(),
235  E = Blocks.end(); I != E; ++I)
236  (*I)->collectLineCounts(FI);
237 }
238 
239 //===----------------------------------------------------------------------===//
240 // GCOVBlock implementation.
241 
242 /// ~GCOVBlock - Delete GCOVBlock and its content.
244  Edges.clear();
245  Lines.clear();
246 }
247 
248 /// collectLineCounts - Collect line counts. This must be used after
249 /// reading .gcno and .gcda files.
252  E = Lines.end(); I != E; ++I)
253  FI.addLineCount(Parent.getFilename(), *I, Counter);
254 }
255 
256 /// dump - Dump GCOVBlock content to dbgs() for debugging purposes.
258  dbgs() << "Block : " << Number << " Counter : " << Counter << "\n";
259  if (!Edges.empty()) {
260  dbgs() << "\tEdges : ";
261  for (SmallVectorImpl<uint32_t>::iterator I = Edges.begin(), E = Edges.end();
262  I != E; ++I)
263  dbgs() << (*I) << ",";
264  dbgs() << "\n";
265  }
266  if (!Lines.empty()) {
267  dbgs() << "\tLines : ";
269  E = Lines.end(); I != E; ++I)
270  dbgs() << (*I) << ",";
271  dbgs() << "\n";
272  }
273 }
274 
275 //===----------------------------------------------------------------------===//
276 // FileInfo implementation.
277 
278 /// print - Print source files with collected line count information.
280  StringRef gcdaFile) {
281  for (StringMap<LineCounts>::iterator I = LineInfo.begin(), E = LineInfo.end();
282  I != E; ++I) {
283  StringRef Filename = I->first();
284  OS << " -: 0:Source:" << Filename << "\n";
285  OS << " -: 0:Graph:" << gcnoFile << "\n";
286  OS << " -: 0:Data:" << gcdaFile << "\n";
287  OS << " -: 0:Runs:" << RunCount << "\n";
288  OS << " -: 0:Programs:" << ProgramCount << "\n";
289  LineCounts &L = LineInfo[Filename];
291  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
292  errs() << Filename << ": " << ec.message() << "\n";
293  return;
294  }
295  StringRef AllLines = Buff->getBuffer();
296  uint32_t i = 0;
297  while (!AllLines.empty()) {
298  if (L.find(i) != L.end()) {
299  if (L[i] == 0)
300  OS << " #####:";
301  else
302  OS << format("%9" PRIu64 ":", L[i]);
303  } else {
304  OS << " -:";
305  }
306  std::pair<StringRef, StringRef> P = AllLines.split('\n');
307  if (AllLines != P.first)
308  OS << format("%5u:", i+1) << P.first;
309  OS << "\n";
310  AllLines = P.second;
311  ++i;
312  }
313  }
314 }
void DeleteContainerPointers(Container &C)
Definition: STLExtras.h:315
raw_ostream & errs()
bool readInt(uint32_t &Val)
Definition: GCOV.h:154
void dump()
dump - Dump GCOVBlock content to dbgs() for debugging purposes.
Definition: GCOV.cpp:257
static bool isGCDAFile(GCOV::GCOVFormat Format)
isGCDAFile - Return true if Format identifies a .gcda file.
Definition: GCOV.cpp:33
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
F(f)
static bool isGCNOFile(GCOV::GCOVFormat Format)
isGCNOFile - Return true if Format identifies a .gcno file.
Definition: GCOV.cpp:38
void collectLineCounts(FileInfo &FI)
Definition: GCOV.cpp:233
format_object1< T > format(const char *Fmt, const T &Val)
Definition: Format.h:180
bool readArcTag()
Definition: GCOV.h:117
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
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
static error_code getFileOrSTDIN(StringRef Filename, OwningPtr< MemoryBuffer > &result, int64_t FileSize=-1)
#define P(N)
bool readBlockTag()
Definition: GCOV.h:78
void dump()
dump - Dump GCOVFunction content to dbgs() for debugging purposes.
Definition: GCOV.cpp:224
iterator end()
Definition: DenseMap.h:57
void advanceCursor(uint32_t n)
Definition: GCOV.h:186
bool readEdgeTag()
Definition: GCOV.h:91
~GCOVFunction()
~GCOVFunction - Delete GCOVFunction and its content.
Definition: GCOV.cpp:107
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
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Definition: Debug.cpp:101
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 I(x, y, z)
Definition: MD5.cpp:54
bool readObjectTag()
Definition: GCOV.h:130
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
void setRunCount(uint32_t Runs)
Definition: GCOV.h:250
iterator find(const KeyT &Val)
Definition: DenseMap.h:108
~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