GCOV.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===- GCOV.cpp - LLVM coverage tool --------------------------------------===//
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                     The LLVM Compiler Infrastructure
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is distributed under the University of Illinois Open Source
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// License. See LICENSE.TXT for details.
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===//
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// GCOV implements the interface to read and write coverage files that use
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 'gcov' format.
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===//
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "llvm/Support/GCOV.h"
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "llvm/ADT/STLExtras.h"
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "llvm/Support/Debug.h"
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Format.h"
20#include "llvm/Support/MemoryObject.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/system_error.h"
23#include <algorithm>
24using namespace llvm;
25
26//===----------------------------------------------------------------------===//
27// GCOVFile implementation.
28
29/// ~GCOVFile - Delete GCOVFile and its content.
30GCOVFile::~GCOVFile() {
31  DeleteContainerPointers(Functions);
32}
33
34/// readGCNO - Read GCNO buffer.
35bool GCOVFile::readGCNO(GCOVBuffer &Buffer) {
36  if (!Buffer.readGCNOFormat()) return false;
37  if (!Buffer.readGCOVVersion(Version)) return false;
38
39  if (!Buffer.readInt(Checksum)) return false;
40  while (true) {
41    if (!Buffer.readFunctionTag()) break;
42    GCOVFunction *GFun = new GCOVFunction(*this);
43    if (!GFun->readGCNO(Buffer, Version))
44      return false;
45    Functions.push_back(GFun);
46  }
47
48  GCNOInitialized = true;
49  return true;
50}
51
52/// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be
53/// called after readGCNO().
54bool GCOVFile::readGCDA(GCOVBuffer &Buffer) {
55  assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
56  if (!Buffer.readGCDAFormat()) return false;
57  GCOV::GCOVVersion GCDAVersion;
58  if (!Buffer.readGCOVVersion(GCDAVersion)) return false;
59  if (Version != GCDAVersion) {
60    errs() << "GCOV versions do not match.\n";
61    return false;
62  }
63
64  uint32_t GCDAChecksum;
65  if (!Buffer.readInt(GCDAChecksum)) return false;
66  if (Checksum != GCDAChecksum) {
67    errs() << "File checksums do not match: " << Checksum << " != "
68           << GCDAChecksum << ".\n";
69    return false;
70  }
71  for (size_t i = 0, e = Functions.size(); i < e; ++i) {
72    if (!Buffer.readFunctionTag()) {
73      errs() << "Unexpected number of functions.\n";
74      return false;
75    }
76    if (!Functions[i]->readGCDA(Buffer, Version))
77      return false;
78  }
79  if (Buffer.readObjectTag()) {
80    uint32_t Length;
81    uint32_t Dummy;
82    if (!Buffer.readInt(Length)) return false;
83    if (!Buffer.readInt(Dummy)) return false; // checksum
84    if (!Buffer.readInt(Dummy)) return false; // num
85    if (!Buffer.readInt(RunCount)) return false;
86    Buffer.advanceCursor(Length-3);
87  }
88  while (Buffer.readProgramTag()) {
89    uint32_t Length;
90    if (!Buffer.readInt(Length)) return false;
91    Buffer.advanceCursor(Length);
92    ++ProgramCount;
93  }
94
95  return true;
96}
97
98/// dump - Dump GCOVFile content to dbgs() for debugging purposes.
99void GCOVFile::dump() const {
100  for (SmallVectorImpl<GCOVFunction *>::const_iterator I = Functions.begin(),
101         E = Functions.end(); I != E; ++I)
102    (*I)->dump();
103}
104
105/// collectLineCounts - Collect line counts. This must be used after
106/// reading .gcno and .gcda files.
107void GCOVFile::collectLineCounts(FileInfo &FI) {
108  for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(),
109         E = Functions.end(); I != E; ++I)
110    (*I)->collectLineCounts(FI);
111  FI.setRunCount(RunCount);
112  FI.setProgramCount(ProgramCount);
113}
114
115//===----------------------------------------------------------------------===//
116// GCOVFunction implementation.
117
118/// ~GCOVFunction - Delete GCOVFunction and its content.
119GCOVFunction::~GCOVFunction() {
120  DeleteContainerPointers(Blocks);
121  DeleteContainerPointers(Edges);
122}
123
124/// readGCNO - Read a function from the GCNO buffer. Return false if an error
125/// occurs.
126bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
127  uint32_t Dummy;
128  if (!Buff.readInt(Dummy)) return false; // Function header length
129  if (!Buff.readInt(Ident)) return false;
130  if (!Buff.readInt(Checksum)) return false;
131  if (Version != GCOV::V402) {
132    uint32_t CfgChecksum;
133    if (!Buff.readInt(CfgChecksum)) return false;
134    if (Parent.getChecksum() != CfgChecksum) {
135      errs() << "File checksums do not match: " << Parent.getChecksum()
136             << " != " << CfgChecksum << " in (" << Name << ").\n";
137      return false;
138    }
139  }
140  if (!Buff.readString(Name)) return false;
141  if (!Buff.readString(Filename)) return false;
142  if (!Buff.readInt(LineNumber)) return false;
143
144  // read blocks.
145  if (!Buff.readBlockTag()) {
146    errs() << "Block tag not found.\n";
147    return false;
148  }
149  uint32_t BlockCount;
150  if (!Buff.readInt(BlockCount)) return false;
151  for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
152    if (!Buff.readInt(Dummy)) return false; // Block flags;
153    Blocks.push_back(new GCOVBlock(*this, i));
154  }
155
156  // read edges.
157  while (Buff.readEdgeTag()) {
158    uint32_t EdgeCount;
159    if (!Buff.readInt(EdgeCount)) return false;
160    EdgeCount = (EdgeCount - 1) / 2;
161    uint32_t BlockNo;
162    if (!Buff.readInt(BlockNo)) return false;
163    if (BlockNo >= BlockCount) {
164      errs() << "Unexpected block number: " << BlockNo << " (in " << Name
165             << ").\n";
166      return false;
167    }
168    for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
169      uint32_t Dst;
170      if (!Buff.readInt(Dst)) return false;
171      GCOVEdge *Edge = new GCOVEdge(Blocks[BlockNo], Blocks[Dst]);
172      Edges.push_back(Edge);
173      Blocks[BlockNo]->addDstEdge(Edge);
174      Blocks[Dst]->addSrcEdge(Edge);
175      if (!Buff.readInt(Dummy)) return false; // Edge flag
176    }
177  }
178
179  // read line table.
180  while (Buff.readLineTag()) {
181    uint32_t LineTableLength;
182    if (!Buff.readInt(LineTableLength)) return false;
183    uint32_t EndPos = Buff.getCursor() + LineTableLength*4;
184    uint32_t BlockNo;
185    if (!Buff.readInt(BlockNo)) return false;
186    if (BlockNo >= BlockCount) {
187      errs() << "Unexpected block number: " << BlockNo << " (in " << Name
188             << ").\n";
189      return false;
190    }
191    GCOVBlock *Block = Blocks[BlockNo];
192    if (!Buff.readInt(Dummy)) return false; // flag
193    while (Buff.getCursor() != (EndPos - 4)) {
194      StringRef F;
195      if (!Buff.readString(F)) return false;
196      if (Filename != F) {
197        errs() << "Multiple sources for a single basic block: " << Filename
198               << " != " << F << " (in " << Name << ").\n";
199        return false;
200      }
201      if (Buff.getCursor() == (EndPos - 4)) break;
202      while (true) {
203        uint32_t Line;
204        if (!Buff.readInt(Line)) return false;
205        if (!Line) break;
206        Block->addLine(Line);
207      }
208    }
209    if (!Buff.readInt(Dummy)) return false; // flag
210  }
211  return true;
212}
213
214/// readGCDA - Read a function from the GCDA buffer. Return false if an error
215/// occurs.
216bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
217  uint32_t Dummy;
218  if (!Buff.readInt(Dummy)) return false; // Function header length
219
220  uint32_t GCDAIdent;
221  if (!Buff.readInt(GCDAIdent)) return false;
222  if (Ident != GCDAIdent) {
223    errs() << "Function identifiers do not match: " << Ident << " != "
224           << GCDAIdent << " (in " << Name << ").\n";
225    return false;
226  }
227
228  uint32_t GCDAChecksum;
229  if (!Buff.readInt(GCDAChecksum)) return false;
230  if (Checksum != GCDAChecksum) {
231    errs() << "Function checksums do not match: " << Checksum << " != "
232           << GCDAChecksum << " (in " << Name << ").\n";
233    return false;
234  }
235
236  uint32_t CfgChecksum;
237  if (Version != GCOV::V402) {
238    if (!Buff.readInt(CfgChecksum)) return false;
239    if (Parent.getChecksum() != CfgChecksum) {
240      errs() << "File checksums do not match: " << Parent.getChecksum()
241             << " != " << CfgChecksum << " (in " << Name << ").\n";
242      return false;
243    }
244  }
245
246  StringRef GCDAName;
247  if (!Buff.readString(GCDAName)) return false;
248  if (Name != GCDAName) {
249    errs() << "Function names do not match: " << Name << " != " << GCDAName
250           << ".\n";
251    return false;
252  }
253
254  if (!Buff.readArcTag()) {
255    errs() << "Arc tag not found (in " << Name << ").\n";
256    return false;
257  }
258
259  uint32_t Count;
260  if (!Buff.readInt(Count)) return false;
261  Count /= 2;
262
263  // This for loop adds the counts for each block. A second nested loop is
264  // required to combine the edge counts that are contained in the GCDA file.
265  for (uint32_t BlockNo = 0; Count > 0; ++BlockNo) {
266    // The last block is always reserved for exit block
267    if (BlockNo >= Blocks.size()-1) {
268      errs() << "Unexpected number of edges (in " << Name << ").\n";
269      return false;
270    }
271    GCOVBlock &Block = *Blocks[BlockNo];
272    for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End;
273           ++EdgeNo) {
274      if (Count == 0) {
275        errs() << "Unexpected number of edges (in " << Name << ").\n";
276        return false;
277      }
278      uint64_t ArcCount;
279      if (!Buff.readInt64(ArcCount)) return false;
280      Block.addCount(EdgeNo, ArcCount);
281      --Count;
282    }
283    Block.sortDstEdges();
284  }
285  return true;
286}
287
288/// getEntryCount - Get the number of times the function was called by
289/// retrieving the entry block's count.
290uint64_t GCOVFunction::getEntryCount() const {
291  return Blocks.front()->getCount();
292}
293
294/// getExitCount - Get the number of times the function returned by retrieving
295/// the exit block's count.
296uint64_t GCOVFunction::getExitCount() const {
297  return Blocks.back()->getCount();
298}
299
300/// dump - Dump GCOVFunction content to dbgs() for debugging purposes.
301void GCOVFunction::dump() const {
302  dbgs() <<  "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n";
303  for (SmallVectorImpl<GCOVBlock *>::const_iterator I = Blocks.begin(),
304         E = Blocks.end(); I != E; ++I)
305    (*I)->dump();
306}
307
308/// collectLineCounts - Collect line counts. This must be used after
309/// reading .gcno and .gcda files.
310void GCOVFunction::collectLineCounts(FileInfo &FI) {
311  // If the line number is zero, this is a function that doesn't actually appear
312  // in the source file, so there isn't anything we can do with it.
313  if (LineNumber == 0)
314    return;
315
316  for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(),
317         E = Blocks.end(); I != E; ++I)
318    (*I)->collectLineCounts(FI);
319  FI.addFunctionLine(Filename, LineNumber, this);
320}
321
322//===----------------------------------------------------------------------===//
323// GCOVBlock implementation.
324
325/// ~GCOVBlock - Delete GCOVBlock and its content.
326GCOVBlock::~GCOVBlock() {
327  SrcEdges.clear();
328  DstEdges.clear();
329  Lines.clear();
330}
331
332/// addCount - Add to block counter while storing the edge count. If the
333/// destination has no outgoing edges, also update that block's count too.
334void GCOVBlock::addCount(size_t DstEdgeNo, uint64_t N) {
335  assert(DstEdgeNo < DstEdges.size()); // up to caller to ensure EdgeNo is valid
336  DstEdges[DstEdgeNo]->Count = N;
337  Counter += N;
338  if (!DstEdges[DstEdgeNo]->Dst->getNumDstEdges())
339    DstEdges[DstEdgeNo]->Dst->Counter += N;
340}
341
342/// sortDstEdges - Sort destination edges by block number, nop if already
343/// sorted. This is required for printing branch info in the correct order.
344void GCOVBlock::sortDstEdges() {
345  if (!DstEdgesAreSorted) {
346    SortDstEdgesFunctor SortEdges;
347    std::stable_sort(DstEdges.begin(), DstEdges.end(), SortEdges);
348  }
349}
350
351/// collectLineCounts - Collect line counts. This must be used after
352/// reading .gcno and .gcda files.
353void GCOVBlock::collectLineCounts(FileInfo &FI) {
354  for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(),
355         E = Lines.end(); I != E; ++I)
356    FI.addBlockLine(Parent.getFilename(), *I, this);
357}
358
359/// dump - Dump GCOVBlock content to dbgs() for debugging purposes.
360void GCOVBlock::dump() const {
361  dbgs() << "Block : " << Number << " Counter : " << Counter << "\n";
362  if (!SrcEdges.empty()) {
363    dbgs() << "\tSource Edges : ";
364    for (EdgeIterator I = SrcEdges.begin(), E = SrcEdges.end(); I != E; ++I) {
365      const GCOVEdge *Edge = *I;
366      dbgs() << Edge->Src->Number << " (" << Edge->Count << "), ";
367    }
368    dbgs() << "\n";
369  }
370  if (!DstEdges.empty()) {
371    dbgs() << "\tDestination Edges : ";
372    for (EdgeIterator I = DstEdges.begin(), E = DstEdges.end(); I != E; ++I) {
373      const GCOVEdge *Edge = *I;
374      dbgs() << Edge->Dst->Number << " (" << Edge->Count << "), ";
375    }
376    dbgs() << "\n";
377  }
378  if (!Lines.empty()) {
379    dbgs() << "\tLines : ";
380    for (SmallVectorImpl<uint32_t>::const_iterator I = Lines.begin(),
381           E = Lines.end(); I != E; ++I)
382      dbgs() << (*I) << ",";
383    dbgs() << "\n";
384  }
385}
386
387//===----------------------------------------------------------------------===//
388// FileInfo implementation.
389
390// Safe integer division, returns 0 if numerator is 0.
391static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) {
392  if (!Numerator)
393    return 0;
394  return Numerator/Divisor;
395}
396
397// This custom division function mimics gcov's branch ouputs:
398//   - Round to closest whole number
399//   - Only output 0% or 100% if it's exactly that value
400static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) {
401  if (!Numerator)
402    return 0;
403  if (Numerator == Divisor)
404    return 100;
405
406  uint8_t Res = (Numerator*100+Divisor/2) / Divisor;
407  if (Res == 0)
408    return 1;
409  if (Res == 100)
410    return 99;
411  return Res;
412}
413
414struct formatBranchInfo {
415  formatBranchInfo(const GCOVOptions &Options, uint64_t Count,
416                   uint64_t Total) :
417    Options(Options), Count(Count), Total(Total) {}
418
419  void print(raw_ostream &OS) const {
420    if (!Total)
421      OS << "never executed";
422    else if (Options.BranchCount)
423      OS << "taken " << Count;
424    else
425      OS << "taken " << branchDiv(Count, Total) << "%";
426  }
427
428  const GCOVOptions &Options;
429  uint64_t Count;
430  uint64_t Total;
431};
432
433static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
434  FBI.print(OS);
435  return OS;
436}
437
438/// Convert a path to a gcov filename. If PreservePaths is true, this
439/// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
440static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
441  if (!PreservePaths)
442    return (sys::path::filename(Filename) + ".gcov").str();
443
444  // This behaviour is defined by gcov in terms of text replacements, so it's
445  // not likely to do anything useful on filesystems with different textual
446  // conventions.
447  llvm::SmallString<256> Result("");
448  StringRef::iterator I, S, E;
449  for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) {
450    if (*I != '/')
451      continue;
452
453    if (I - S == 1 && *S == '.') {
454      // ".", the current directory, is skipped.
455    } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') {
456      // "..", the parent directory, is replaced with "^".
457      Result.append("^#");
458    } else {
459      if (S < I)
460        // Leave other components intact,
461        Result.append(S, I);
462      // And separate with "#".
463      Result.push_back('#');
464    }
465    S = I + 1;
466  }
467
468  if (S < I)
469    Result.append(S, I);
470  Result.append(".gcov");
471  return Result.str();
472}
473
474/// print -  Print source files with collected line count information.
475void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) {
476  for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
477         E = LineInfo.end(); I != E; ++I) {
478    StringRef Filename = I->first();
479    std::unique_ptr<MemoryBuffer> Buff;
480    if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
481      errs() << Filename << ": " << ec.message() << "\n";
482      return;
483    }
484    StringRef AllLines = Buff->getBuffer();
485
486    std::string CoveragePath = mangleCoveragePath(Filename,
487                                                  Options.PreservePaths);
488    std::string ErrorInfo;
489    raw_fd_ostream OS(CoveragePath.c_str(), ErrorInfo, sys::fs::F_Text);
490    if (!ErrorInfo.empty())
491      errs() << ErrorInfo << "\n";
492
493    OS << "        -:    0:Source:" << Filename << "\n";
494    OS << "        -:    0:Graph:" << GCNOFile << "\n";
495    OS << "        -:    0:Data:" << GCDAFile << "\n";
496    OS << "        -:    0:Runs:" << RunCount << "\n";
497    OS << "        -:    0:Programs:" << ProgramCount << "\n";
498
499    const LineData &Line = I->second;
500    GCOVCoverage FileCoverage(Filename);
501    for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
502      if (Options.BranchInfo) {
503        FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
504        if (FuncsIt != Line.Functions.end())
505          printFunctionSummary(OS, FuncsIt->second);
506      }
507
508      BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex);
509      if (BlocksIt == Line.Blocks.end()) {
510        // No basic blocks are on this line. Not an executable line of code.
511        OS << "        -:";
512        std::pair<StringRef, StringRef> P = AllLines.split('\n');
513        OS << format("%5u:", LineIndex+1) << P.first << "\n";
514        AllLines = P.second;
515      } else {
516        const BlockVector &Blocks = BlocksIt->second;
517
518        // Add up the block counts to form line counts.
519        DenseMap<const GCOVFunction *, bool> LineExecs;
520        uint64_t LineCount = 0;
521        for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
522               I != E; ++I) {
523          const GCOVBlock *Block = *I;
524          if (Options.AllBlocks) {
525            // Only take the highest block count for that line.
526            uint64_t BlockCount = Block->getCount();
527            LineCount = LineCount > BlockCount ? LineCount : BlockCount;
528          } else {
529            // Sum up all of the block counts.
530            LineCount += Block->getCount();
531          }
532
533          if (Options.FuncCoverage) {
534            // This is a slightly convoluted way to most accurately gather line
535            // statistics for functions. Basically what is happening is that we
536            // don't want to count a single line with multiple blocks more than
537            // once. However, we also don't simply want to give the total line
538            // count to every function that starts on the line. Thus, what is
539            // happening here are two things:
540            // 1) Ensure that the number of logical lines is only incremented
541            //    once per function.
542            // 2) If there are multiple blocks on the same line, ensure that the
543            //    number of lines executed is incremented as long as at least
544            //    one of the blocks are executed.
545            const GCOVFunction *Function = &Block->getParent();
546            if (FuncCoverages.find(Function) == FuncCoverages.end()) {
547              std::pair<const GCOVFunction *, GCOVCoverage>
548                KeyValue(Function, GCOVCoverage(Function->getName()));
549              FuncCoverages.insert(KeyValue);
550            }
551            GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
552
553            if (LineExecs.find(Function) == LineExecs.end()) {
554              if (Block->getCount()) {
555                ++FuncCoverage.LinesExec;
556                LineExecs[Function] = true;
557              } else {
558                LineExecs[Function] = false;
559              }
560              ++FuncCoverage.LogicalLines;
561            } else if (!LineExecs[Function] && Block->getCount()) {
562              ++FuncCoverage.LinesExec;
563              LineExecs[Function] = true;
564            }
565          }
566        }
567
568        if (LineCount == 0)
569          OS << "    #####:";
570        else {
571          OS << format("%9" PRIu64 ":", LineCount);
572          ++FileCoverage.LinesExec;
573        }
574        ++FileCoverage.LogicalLines;
575
576        std::pair<StringRef, StringRef> P = AllLines.split('\n');
577        OS << format("%5u:", LineIndex+1) << P.first << "\n";
578        AllLines = P.second;
579
580        uint32_t BlockNo = 0;
581        uint32_t EdgeNo = 0;
582        for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
583               I != E; ++I) {
584          const GCOVBlock *Block = *I;
585
586          // Only print block and branch information at the end of the block.
587          if (Block->getLastLine() != LineIndex+1)
588            continue;
589          if (Options.AllBlocks)
590            printBlockInfo(OS, *Block, LineIndex, BlockNo);
591          if (Options.BranchInfo) {
592            size_t NumEdges = Block->getNumDstEdges();
593            if (NumEdges > 1)
594              printBranchInfo(OS, *Block, FileCoverage, EdgeNo);
595            else if (Options.UncondBranch && NumEdges == 1)
596              printUncondBranchInfo(OS, EdgeNo, (*Block->dst_begin())->Count);
597          }
598        }
599      }
600    }
601    FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage));
602  }
603
604  // FIXME: There is no way to detect calls given current instrumentation.
605  if (Options.FuncCoverage)
606    printFuncCoverage();
607  printFileCoverage();
608}
609
610/// printFunctionSummary - Print function and block summary.
611void FileInfo::printFunctionSummary(raw_fd_ostream &OS,
612                                    const FunctionVector &Funcs) const {
613  for (FunctionVector::const_iterator I = Funcs.begin(), E = Funcs.end();
614         I != E; ++I) {
615    const GCOVFunction *Func = *I;
616    uint64_t EntryCount = Func->getEntryCount();
617    uint32_t BlocksExec = 0;
618    for (GCOVFunction::BlockIterator I = Func->block_begin(),
619           E = Func->block_end(); I != E; ++I) {
620      const GCOVBlock *Block = *I;
621      if (Block->getNumDstEdges() && Block->getCount())
622          ++BlocksExec;
623    }
624
625    OS << "function " << Func->getName() << " called " << EntryCount
626       << " returned " << safeDiv(Func->getExitCount()*100, EntryCount)
627       << "% blocks executed "
628       << safeDiv(BlocksExec*100, Func->getNumBlocks()-1) << "%\n";
629  }
630}
631
632/// printBlockInfo - Output counts for each block.
633void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
634                              uint32_t LineIndex, uint32_t &BlockNo) const {
635  if (Block.getCount() == 0)
636    OS << "    $$$$$:";
637  else
638    OS << format("%9" PRIu64 ":", Block.getCount());
639  OS << format("%5u-block %2u\n", LineIndex+1, BlockNo++);
640}
641
642/// printBranchInfo - Print conditional branch probabilities.
643void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
644                               GCOVCoverage &Coverage, uint32_t &EdgeNo) {
645  SmallVector<uint64_t, 16> BranchCounts;
646  uint64_t TotalCounts = 0;
647  for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end();
648         I != E; ++I) {
649    const GCOVEdge *Edge = *I;
650    BranchCounts.push_back(Edge->Count);
651    TotalCounts += Edge->Count;
652    if (Block.getCount()) ++Coverage.BranchesExec;
653    if (Edge->Count) ++Coverage.BranchesTaken;
654    ++Coverage.Branches;
655
656    if (Options.FuncCoverage) {
657      const GCOVFunction *Function = &Block.getParent();
658      GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
659      if (Block.getCount()) ++FuncCoverage.BranchesExec;
660      if (Edge->Count) ++FuncCoverage.BranchesTaken;
661      ++FuncCoverage.Branches;
662    }
663  }
664
665  for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(),
666         E = BranchCounts.end(); I != E; ++I) {
667    OS << format("branch %2u ", EdgeNo++)
668       << formatBranchInfo(Options, *I, TotalCounts) << "\n";
669  }
670}
671
672/// printUncondBranchInfo - Print unconditional branch probabilities.
673void FileInfo::printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
674                                     uint64_t Count) const {
675  OS << format("unconditional %2u ", EdgeNo++)
676     << formatBranchInfo(Options, Count, Count) << "\n";
677}
678
679// printCoverage - Print generic coverage info used by both printFuncCoverage
680// and printFileCoverage.
681void FileInfo::printCoverage(const GCOVCoverage &Coverage) const {
682  outs() << format("Lines executed:%.2f%% of %u\n",
683                   double(Coverage.LinesExec)*100/Coverage.LogicalLines,
684                   Coverage.LogicalLines);
685  if (Options.BranchInfo) {
686    if (Coverage.Branches) {
687      outs() << format("Branches executed:%.2f%% of %u\n",
688                       double(Coverage.BranchesExec)*100/Coverage.Branches,
689                       Coverage.Branches);
690      outs() << format("Taken at least once:%.2f%% of %u\n",
691                       double(Coverage.BranchesTaken)*100/Coverage.Branches,
692                       Coverage.Branches);
693    } else {
694      outs() << "No branches\n";
695    }
696    outs() << "No calls\n"; // to be consistent with gcov
697  }
698}
699
700// printFuncCoverage - Print per-function coverage info.
701void FileInfo::printFuncCoverage() const {
702  for (FuncCoverageMap::const_iterator I = FuncCoverages.begin(),
703                                       E = FuncCoverages.end(); I != E; ++I) {
704    const GCOVCoverage &Coverage = I->second;
705    outs() << "Function '" << Coverage.Name << "'\n";
706    printCoverage(Coverage);
707    outs() << "\n";
708  }
709}
710
711// printFileCoverage - Print per-file coverage info.
712void FileInfo::printFileCoverage() const {
713  for (FileCoverageList::const_iterator I = FileCoverages.begin(),
714                                        E = FileCoverages.end(); I != E; ++I) {
715    const std::string &Filename = I->first;
716    const GCOVCoverage &Coverage = I->second;
717    outs() << "File '" << Coverage.Name << "'\n";
718    printCoverage(Coverage);
719    outs() << Coverage.Name << ":creating '" << Filename << "'\n\n";
720  }
721}
722