1 //===- GCOV.cpp - LLVM coverage tool --------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // GCOV implements the interface to read and write coverage files that use
10 // 'gcov' format.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ProfileData/GCOV.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Config/llvm-config.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/Support/MD5.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <algorithm>
24 #include <system_error>
25 
26 using namespace llvm;
27 
28 enum : uint32_t {
29   GCOV_ARC_ON_TREE = 1 << 0,
30   GCOV_ARC_FALLTHROUGH = 1 << 2,
31 
32   GCOV_TAG_FUNCTION = 0x01000000,
33   GCOV_TAG_COUNTER_ARCS = 0x01a10000,
34   // GCOV_TAG_OBJECT_SUMMARY superseded GCOV_TAG_PROGRAM_SUMMARY in GCC 9.
35   GCOV_TAG_OBJECT_SUMMARY = 0xa1000000,
36   GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000,
37 };
38 
39 //===----------------------------------------------------------------------===//
40 // GCOVFile implementation.
41 
42 /// readGCNO - Read GCNO buffer.
43 bool GCOVFile::readGCNO(GCOVBuffer &buf) {
44   if (!buf.readGCNOFormat())
45     return false;
46   if (!buf.readGCOVVersion(Version))
47     return false;
48 
49   if (!buf.readInt(Checksum))
50     return false;
51   if (Version >= GCOV::V900 && !buf.readString(cwd))
52     return false;
53   uint32_t hasUnexecutedBlocks;
54   if (Version >= GCOV::V800 && !buf.readInt(hasUnexecutedBlocks))
55     return false;
56   while (true) {
57     if (!buf.readFunctionTag())
58       break;
59     auto GFun = std::make_unique<GCOVFunction>(*this);
60     if (!GFun->readGCNO(buf, Version))
61       return false;
62     IdentToFunction[GFun->ident] = GFun.get();
63     Functions.push_back(std::move(GFun));
64   }
65 
66   GCNOInitialized = true;
67   return true;
68 }
69 
70 /// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be
71 /// called after readGCNO().
72 bool GCOVFile::readGCDA(GCOVBuffer &buf) {
73   assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
74   if (!buf.readGCDAFormat())
75     return false;
76   GCOV::GCOVVersion GCDAVersion;
77   if (!buf.readGCOVVersion(GCDAVersion))
78     return false;
79   if (Version != GCDAVersion) {
80     errs() << "GCOV versions do not match.\n";
81     return false;
82   }
83 
84   uint32_t GCDAChecksum;
85   if (!buf.readInt(GCDAChecksum))
86     return false;
87   if (Checksum != GCDAChecksum) {
88     errs() << "File checksums do not match: " << Checksum
89            << " != " << GCDAChecksum << ".\n";
90     return false;
91   }
92   uint32_t dummy, tag, length;
93   uint32_t ident;
94   GCOVFunction *fn = nullptr;
95   while (buf.readInt(tag) && tag) {
96     if (!buf.readInt(length))
97       return false;
98     uint32_t cursor = buf.getCursor();
99     if (tag == GCOV_TAG_OBJECT_SUMMARY) {
100       buf.readInt(RunCount);
101       buf.readInt(dummy);
102     } else if (tag == GCOV_TAG_PROGRAM_SUMMARY) {
103       buf.readInt(dummy);
104       buf.readInt(dummy);
105       buf.readInt(RunCount);
106       ++ProgramCount;
107     } else if (tag == GCOV_TAG_FUNCTION) {
108       if (length == 0) // Placeholder
109         continue;
110       // length>3 is to be compatible with some clang --coverage generated
111       // tests. As of GCC 10, GCOV_TAG_FUNCTION_LENGTH has never been larger
112       // than 3.
113       if (length < 3 || !buf.readInt(ident))
114         return false;
115       auto It = IdentToFunction.find(ident);
116       uint32_t linenoChecksum, cfgChecksum;
117       buf.readInt(linenoChecksum);
118       buf.readInt(cfgChecksum);
119       if (Version < GCOV::V407)
120         cfgChecksum = 0;
121       if (It != IdentToFunction.end()) {
122         fn = It->second;
123         if (linenoChecksum != fn->linenoChecksum ||
124             cfgChecksum != fn->cfgChecksum) {
125           errs() << fn->Name
126                  << format(": checksum mismatch, (%u, %u) != (%u, %u)\n",
127                            linenoChecksum, cfgChecksum, fn->linenoChecksum,
128                            fn->cfgChecksum);
129           return false;
130         }
131       }
132     } else if (tag == GCOV_TAG_COUNTER_ARCS && fn) {
133       if (length != 2 * fn->arcs.size()) {
134         errs() << fn->Name
135                << format(
136                       ": GCOV_TAG_COUNTER_ARCS mismatch, got %u, expected %u\n",
137                       length, unsigned(2 * fn->arcs.size()));
138         return false;
139       }
140       for (std::unique_ptr<GCOVArc> &arc : fn->arcs) {
141         if (!buf.readInt64(arc->Count))
142           return false;
143         // FIXME Fix counters
144         arc->src.Counter += arc->Count;
145         if (arc->dst.succ.empty())
146           arc->dst.Counter += arc->Count;
147       }
148     }
149     buf.setCursor(cursor + 4 * length);
150   }
151 
152   return true;
153 }
154 
155 void GCOVFile::print(raw_ostream &OS) const {
156   for (const auto &FPtr : Functions)
157     FPtr->print(OS);
158 }
159 
160 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
161 /// dump - Dump GCOVFile content to dbgs() for debugging purposes.
162 LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
163 #endif
164 
165 /// collectLineCounts - Collect line counts. This must be used after
166 /// reading .gcno and .gcda files.
167 void GCOVFile::collectLineCounts(FileInfo &FI) {
168   for (const auto &FPtr : Functions)
169     FPtr->collectLineCounts(FI);
170   FI.setRunCount(RunCount);
171   FI.setProgramCount(ProgramCount);
172 }
173 
174 //===----------------------------------------------------------------------===//
175 // GCOVFunction implementation.
176 
177 /// readGCNO - Read a function from the GCNO buffer. Return false if an error
178 /// occurs.
179 bool GCOVFunction::readGCNO(GCOVBuffer &buf, GCOV::GCOVVersion Version) {
180   uint32_t Dummy;
181   if (!buf.readInt(Dummy))
182     return false; // Function header length
183   if (!buf.readInt(ident))
184     return false;
185   if (!buf.readInt(linenoChecksum))
186     return false;
187   if (Version >= GCOV::V407 && !buf.readInt(cfgChecksum))
188     return false;
189   if (!buf.readString(Name))
190     return false;
191   if (Version < GCOV::V800) {
192     if (!buf.readString(Filename))
193       return false;
194     if (!buf.readInt(startLine))
195       return false;
196   } else {
197     if (!buf.readInt(Dummy))
198       return false;
199     artificial = Dummy;
200     if (!buf.readString(Filename))
201       return false;
202     if (!buf.readInt(startLine))
203       return false;
204     if (!buf.readInt(startColumn))
205       return false;
206     if (!buf.readInt(endLine))
207       return false;
208     if (Version >= GCOV::V900 && !buf.readInt(endColumn))
209       return false;
210   }
211 
212   // read blocks.
213   if (!buf.readBlockTag()) {
214     errs() << "Block tag not found.\n";
215     return false;
216   }
217   if (Version >= GCOV::V800 && !buf.readInt(Dummy))
218     return false;
219   uint32_t BlockCount;
220   if (!buf.readInt(BlockCount))
221     return false;
222   for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
223     if (Version < GCOV::V800 && !buf.readInt(Dummy))
224       return false; // Block flags;
225     Blocks.push_back(std::make_unique<GCOVBlock>(*this, i));
226   }
227 
228   // read edges.
229   while (buf.readEdgeTag()) {
230     uint32_t EdgeCount;
231     if (!buf.readInt(EdgeCount))
232       return false;
233     EdgeCount = (EdgeCount - 1) / 2;
234     uint32_t BlockNo;
235     if (!buf.readInt(BlockNo))
236       return false;
237     if (BlockNo >= BlockCount) {
238       errs() << "Unexpected block number: " << BlockNo << " (in " << Name
239              << ").\n";
240       return false;
241     }
242     GCOVBlock *src = Blocks[BlockNo].get();
243     for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
244       uint32_t dstNo, flags;
245       if (!buf.readInt(dstNo))
246         return false;
247       if (!buf.readInt(flags))
248         return false;
249       GCOVBlock *dst = Blocks[dstNo].get();
250       auto arc =
251           std::make_unique<GCOVArc>(*src, *dst, flags & GCOV_ARC_FALLTHROUGH);
252       src->addDstEdge(arc.get());
253       dst->addSrcEdge(arc.get());
254       if (flags & GCOV_ARC_ON_TREE)
255         treeArcs.push_back(std::move(arc));
256       else
257         arcs.push_back(std::move(arc));
258     }
259   }
260 
261   // read line table.
262   while (buf.readLineTag()) {
263     uint32_t LineTableLength;
264     // Read the length of this line table.
265     if (!buf.readInt(LineTableLength))
266       return false;
267     uint32_t EndPos = buf.getCursor() + LineTableLength * 4;
268     uint32_t BlockNo;
269     // Read the block number this table is associated with.
270     if (!buf.readInt(BlockNo))
271       return false;
272     if (BlockNo >= BlockCount) {
273       errs() << "Unexpected block number: " << BlockNo << " (in " << Name
274              << ").\n";
275       return false;
276     }
277     GCOVBlock &Block = *Blocks[BlockNo];
278     // Read the word that pads the beginning of the line table. This may be a
279     // flag of some sort, but seems to always be zero.
280     if (!buf.readInt(Dummy))
281       return false;
282 
283     // Line information starts here and continues up until the last word.
284     if (buf.getCursor() != (EndPos - sizeof(uint32_t))) {
285       StringRef F;
286       // Read the source file name.
287       if (!buf.readString(F))
288         return false;
289       if (Filename != F) {
290         // FIXME
291         errs() << "Multiple sources for a single basic block: " << Filename
292                << " != " << F << " (in " << Name << ").\n";
293       }
294       // Read lines up to, but not including, the null terminator.
295       while (buf.getCursor() < (EndPos - 2 * sizeof(uint32_t))) {
296         uint32_t Line;
297         if (!buf.readInt(Line))
298           return false;
299         // Line 0 means this instruction was injected by the compiler. Skip it.
300         if (!Line)
301           continue;
302         Block.addLine(Line);
303       }
304       // Read the null terminator.
305       if (!buf.readInt(Dummy))
306         return false;
307     }
308     // The last word is either a flag or padding, it isn't clear which. Skip
309     // over it.
310     if (!buf.readInt(Dummy))
311       return false;
312   }
313   return true;
314 }
315 
316 /// getEntryCount - Get the number of times the function was called by
317 /// retrieving the entry block's count.
318 uint64_t GCOVFunction::getEntryCount() const {
319   return Blocks.front()->getCount();
320 }
321 
322 /// getExitCount - Get the number of times the function returned by retrieving
323 /// the exit block's count.
324 uint64_t GCOVFunction::getExitCount() const {
325   return Blocks.back()->getCount();
326 }
327 
328 void GCOVFunction::print(raw_ostream &OS) const {
329   OS << "===== " << Name << " (" << ident << ") @ " << Filename << ":"
330      << startLine << "\n";
331   for (const auto &Block : Blocks)
332     Block->print(OS);
333 }
334 
335 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
336 /// dump - Dump GCOVFunction content to dbgs() for debugging purposes.
337 LLVM_DUMP_METHOD void GCOVFunction::dump() const { print(dbgs()); }
338 #endif
339 
340 /// collectLineCounts - Collect line counts. This must be used after
341 /// reading .gcno and .gcda files.
342 void GCOVFunction::collectLineCounts(FileInfo &FI) {
343   // If the line number is zero, this is a function that doesn't actually appear
344   // in the source file, so there isn't anything we can do with it.
345   if (startLine == 0)
346     return;
347 
348   for (const auto &Block : Blocks)
349     Block->collectLineCounts(FI);
350   FI.addFunctionLine(Filename, startLine, this);
351 }
352 
353 //===----------------------------------------------------------------------===//
354 // GCOVBlock implementation.
355 
356 /// collectLineCounts - Collect line counts. This must be used after
357 /// reading .gcno and .gcda files.
358 void GCOVBlock::collectLineCounts(FileInfo &FI) {
359   for (uint32_t N : Lines)
360     FI.addBlockLine(Parent.getFilename(), N, this);
361 }
362 
363 void GCOVBlock::print(raw_ostream &OS) const {
364   OS << "Block : " << Number << " Counter : " << Counter << "\n";
365   if (!pred.empty()) {
366     OS << "\tSource Edges : ";
367     for (const GCOVArc *Edge : pred)
368       OS << Edge->src.Number << " (" << Edge->Count << "), ";
369     OS << "\n";
370   }
371   if (!succ.empty()) {
372     OS << "\tDestination Edges : ";
373     for (const GCOVArc *Edge : succ)
374       OS << Edge->dst.Number << " (" << Edge->Count << "), ";
375     OS << "\n";
376   }
377   if (!Lines.empty()) {
378     OS << "\tLines : ";
379     for (uint32_t N : Lines)
380       OS << (N) << ",";
381     OS << "\n";
382   }
383 }
384 
385 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
386 /// dump - Dump GCOVBlock content to dbgs() for debugging purposes.
387 LLVM_DUMP_METHOD void GCOVBlock::dump() const { print(dbgs()); }
388 #endif
389 
390 //===----------------------------------------------------------------------===//
391 // Cycles detection
392 //
393 // The algorithm in GCC is based on the algorithm by Hawick & James:
394 //   "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
395 //   http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf.
396 
397 /// Get the count for the detected cycle.
398 uint64_t GCOVBlock::getCycleCount(const Edges &Path) {
399   uint64_t CycleCount = std::numeric_limits<uint64_t>::max();
400   for (auto E : Path) {
401     CycleCount = std::min(E->CyclesCount, CycleCount);
402   }
403   for (auto E : Path) {
404     E->CyclesCount -= CycleCount;
405   }
406   return CycleCount;
407 }
408 
409 /// Unblock a vertex previously marked as blocked.
410 void GCOVBlock::unblock(const GCOVBlock *U, BlockVector &Blocked,
411                         BlockVectorLists &BlockLists) {
412   auto it = find(Blocked, U);
413   if (it == Blocked.end()) {
414     return;
415   }
416 
417   const size_t index = it - Blocked.begin();
418   Blocked.erase(it);
419 
420   const BlockVector ToUnblock(BlockLists[index]);
421   BlockLists.erase(BlockLists.begin() + index);
422   for (auto GB : ToUnblock) {
423     GCOVBlock::unblock(GB, Blocked, BlockLists);
424   }
425 }
426 
427 bool GCOVBlock::lookForCircuit(const GCOVBlock *V, const GCOVBlock *Start,
428                                Edges &Path, BlockVector &Blocked,
429                                BlockVectorLists &BlockLists,
430                                const BlockVector &Blocks, uint64_t &Count) {
431   Blocked.push_back(V);
432   BlockLists.emplace_back(BlockVector());
433   bool FoundCircuit = false;
434 
435   for (auto E : V->dsts()) {
436     const GCOVBlock *W = &E->dst;
437     if (W < Start || find(Blocks, W) == Blocks.end()) {
438       continue;
439     }
440 
441     Path.push_back(E);
442 
443     if (W == Start) {
444       // We've a cycle.
445       Count += GCOVBlock::getCycleCount(Path);
446       FoundCircuit = true;
447     } else if (find(Blocked, W) == Blocked.end() && // W is not blocked.
448                GCOVBlock::lookForCircuit(W, Start, Path, Blocked, BlockLists,
449                                          Blocks, Count)) {
450       FoundCircuit = true;
451     }
452 
453     Path.pop_back();
454   }
455 
456   if (FoundCircuit) {
457     GCOVBlock::unblock(V, Blocked, BlockLists);
458   } else {
459     for (auto E : V->dsts()) {
460       const GCOVBlock *W = &E->dst;
461       if (W < Start || find(Blocks, W) == Blocks.end()) {
462         continue;
463       }
464       const size_t index = find(Blocked, W) - Blocked.begin();
465       BlockVector &List = BlockLists[index];
466       if (find(List, V) == List.end()) {
467         List.push_back(V);
468       }
469     }
470   }
471 
472   return FoundCircuit;
473 }
474 
475 /// Get the count for the list of blocks which lie on the same line.
476 void GCOVBlock::getCyclesCount(const BlockVector &Blocks, uint64_t &Count) {
477   for (auto Block : Blocks) {
478     Edges Path;
479     BlockVector Blocked;
480     BlockVectorLists BlockLists;
481 
482     GCOVBlock::lookForCircuit(Block, Block, Path, Blocked, BlockLists, Blocks,
483                               Count);
484   }
485 }
486 
487 /// Get the count for the list of blocks which lie on the same line.
488 uint64_t GCOVBlock::getLineCount(const BlockVector &Blocks) {
489   uint64_t Count = 0;
490 
491   for (auto Block : Blocks) {
492     if (Block->getNumSrcEdges() == 0) {
493       // The block has no predecessors and a non-null counter
494       // (can be the case with entry block in functions).
495       Count += Block->getCount();
496     } else {
497       // Add counts from predecessors that are not on the same line.
498       for (auto E : Block->srcs()) {
499         const GCOVBlock *W = &E->src;
500         if (find(Blocks, W) == Blocks.end()) {
501           Count += E->Count;
502         }
503       }
504     }
505     for (auto E : Block->dsts()) {
506       E->CyclesCount = E->Count;
507     }
508   }
509 
510   GCOVBlock::getCyclesCount(Blocks, Count);
511 
512   return Count;
513 }
514 
515 //===----------------------------------------------------------------------===//
516 // FileInfo implementation.
517 
518 // Safe integer division, returns 0 if numerator is 0.
519 static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) {
520   if (!Numerator)
521     return 0;
522   return Numerator / Divisor;
523 }
524 
525 // This custom division function mimics gcov's branch ouputs:
526 //   - Round to closest whole number
527 //   - Only output 0% or 100% if it's exactly that value
528 static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) {
529   if (!Numerator)
530     return 0;
531   if (Numerator == Divisor)
532     return 100;
533 
534   uint8_t Res = (Numerator * 100 + Divisor / 2) / Divisor;
535   if (Res == 0)
536     return 1;
537   if (Res == 100)
538     return 99;
539   return Res;
540 }
541 
542 namespace {
543 struct formatBranchInfo {
544   formatBranchInfo(const GCOV::Options &Options, uint64_t Count, uint64_t Total)
545       : Options(Options), Count(Count), Total(Total) {}
546 
547   void print(raw_ostream &OS) const {
548     if (!Total)
549       OS << "never executed";
550     else if (Options.BranchCount)
551       OS << "taken " << Count;
552     else
553       OS << "taken " << branchDiv(Count, Total) << "%";
554   }
555 
556   const GCOV::Options &Options;
557   uint64_t Count;
558   uint64_t Total;
559 };
560 
561 static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
562   FBI.print(OS);
563   return OS;
564 }
565 
566 class LineConsumer {
567   std::unique_ptr<MemoryBuffer> Buffer;
568   StringRef Remaining;
569 
570 public:
571   LineConsumer(StringRef Filename) {
572     ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
573         MemoryBuffer::getFileOrSTDIN(Filename);
574     if (std::error_code EC = BufferOrErr.getError()) {
575       errs() << Filename << ": " << EC.message() << "\n";
576       Remaining = "";
577     } else {
578       Buffer = std::move(BufferOrErr.get());
579       Remaining = Buffer->getBuffer();
580     }
581   }
582   bool empty() { return Remaining.empty(); }
583   void printNext(raw_ostream &OS, uint32_t LineNum) {
584     StringRef Line;
585     if (empty())
586       Line = "/*EOF*/";
587     else
588       std::tie(Line, Remaining) = Remaining.split("\n");
589     OS << format("%5u:", LineNum) << Line << "\n";
590   }
591 };
592 } // end anonymous namespace
593 
594 /// Convert a path to a gcov filename. If PreservePaths is true, this
595 /// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
596 static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
597   if (!PreservePaths)
598     return sys::path::filename(Filename).str();
599 
600   // This behaviour is defined by gcov in terms of text replacements, so it's
601   // not likely to do anything useful on filesystems with different textual
602   // conventions.
603   llvm::SmallString<256> Result("");
604   StringRef::iterator I, S, E;
605   for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) {
606     if (*I != '/')
607       continue;
608 
609     if (I - S == 1 && *S == '.') {
610       // ".", the current directory, is skipped.
611     } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') {
612       // "..", the parent directory, is replaced with "^".
613       Result.append("^#");
614     } else {
615       if (S < I)
616         // Leave other components intact,
617         Result.append(S, I);
618       // And separate with "#".
619       Result.push_back('#');
620     }
621     S = I + 1;
622   }
623 
624   if (S < I)
625     Result.append(S, I);
626   return std::string(Result.str());
627 }
628 
629 std::string FileInfo::getCoveragePath(StringRef Filename,
630                                       StringRef MainFilename) {
631   if (Options.NoOutput)
632     // This is probably a bug in gcov, but when -n is specified, paths aren't
633     // mangled at all, and the -l and -p options are ignored. Here, we do the
634     // same.
635     return std::string(Filename);
636 
637   std::string CoveragePath;
638   if (Options.LongFileNames && !Filename.equals(MainFilename))
639     CoveragePath =
640         mangleCoveragePath(MainFilename, Options.PreservePaths) + "##";
641   CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths);
642   if (Options.HashFilenames) {
643     MD5 Hasher;
644     MD5::MD5Result Result;
645     Hasher.update(Filename.str());
646     Hasher.final(Result);
647     CoveragePath += "##" + std::string(Result.digest());
648   }
649   CoveragePath += ".gcov";
650   return CoveragePath;
651 }
652 
653 std::unique_ptr<raw_ostream>
654 FileInfo::openCoveragePath(StringRef CoveragePath) {
655   std::error_code EC;
656   auto OS =
657       std::make_unique<raw_fd_ostream>(CoveragePath, EC, sys::fs::OF_Text);
658   if (EC) {
659     errs() << EC.message() << "\n";
660     return std::make_unique<raw_null_ostream>();
661   }
662   return std::move(OS);
663 }
664 
665 /// print -  Print source files with collected line count information.
666 void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
667                      StringRef GCNOFile, StringRef GCDAFile,
668                      GCOV::GCOVVersion Version) {
669   SmallVector<StringRef, 4> Filenames;
670   for (const auto &LI : LineInfo)
671     Filenames.push_back(LI.first());
672   llvm::sort(Filenames);
673 
674   for (StringRef Filename : Filenames) {
675     auto AllLines = LineConsumer(Filename);
676 
677     std::string CoveragePath = getCoveragePath(Filename, MainFilename);
678     std::unique_ptr<raw_ostream> CovStream;
679     if (Options.NoOutput)
680       CovStream = std::make_unique<raw_null_ostream>();
681     else if (!Options.UseStdout)
682       CovStream = openCoveragePath(CoveragePath);
683     raw_ostream &CovOS =
684         !Options.NoOutput && Options.UseStdout ? llvm::outs() : *CovStream;
685 
686     CovOS << "        -:    0:Source:" << Filename << "\n";
687     CovOS << "        -:    0:Graph:" << GCNOFile << "\n";
688     CovOS << "        -:    0:Data:" << GCDAFile << "\n";
689     CovOS << "        -:    0:Runs:" << RunCount << "\n";
690     if (Version < GCOV::V900)
691       CovOS << "        -:    0:Programs:" << ProgramCount << "\n";
692 
693     const LineData &Line = LineInfo[Filename];
694     GCOVCoverage FileCoverage(Filename);
695     for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
696          ++LineIndex) {
697       if (Options.BranchInfo) {
698         FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
699         if (FuncsIt != Line.Functions.end())
700           printFunctionSummary(CovOS, FuncsIt->second);
701       }
702 
703       BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex);
704       if (BlocksIt == Line.Blocks.end()) {
705         // No basic blocks are on this line. Not an executable line of code.
706         CovOS << "        -:";
707         AllLines.printNext(CovOS, LineIndex + 1);
708       } else {
709         const BlockVector &Blocks = BlocksIt->second;
710 
711         // Add up the block counts to form line counts.
712         DenseMap<const GCOVFunction *, bool> LineExecs;
713         for (const GCOVBlock *Block : Blocks) {
714           if (Options.FuncCoverage) {
715             // This is a slightly convoluted way to most accurately gather line
716             // statistics for functions. Basically what is happening is that we
717             // don't want to count a single line with multiple blocks more than
718             // once. However, we also don't simply want to give the total line
719             // count to every function that starts on the line. Thus, what is
720             // happening here are two things:
721             // 1) Ensure that the number of logical lines is only incremented
722             //    once per function.
723             // 2) If there are multiple blocks on the same line, ensure that the
724             //    number of lines executed is incremented as long as at least
725             //    one of the blocks are executed.
726             const GCOVFunction *Function = &Block->getParent();
727             if (FuncCoverages.find(Function) == FuncCoverages.end()) {
728               std::pair<const GCOVFunction *, GCOVCoverage> KeyValue(
729                   Function, GCOVCoverage(Function->getName()));
730               FuncCoverages.insert(KeyValue);
731             }
732             GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
733 
734             if (LineExecs.find(Function) == LineExecs.end()) {
735               if (Block->getCount()) {
736                 ++FuncCoverage.LinesExec;
737                 LineExecs[Function] = true;
738               } else {
739                 LineExecs[Function] = false;
740               }
741               ++FuncCoverage.LogicalLines;
742             } else if (!LineExecs[Function] && Block->getCount()) {
743               ++FuncCoverage.LinesExec;
744               LineExecs[Function] = true;
745             }
746           }
747         }
748 
749         const uint64_t LineCount = GCOVBlock::getLineCount(Blocks);
750         if (LineCount == 0)
751           CovOS << "    #####:";
752         else {
753           CovOS << format("%9" PRIu64 ":", LineCount);
754           ++FileCoverage.LinesExec;
755         }
756         ++FileCoverage.LogicalLines;
757 
758         AllLines.printNext(CovOS, LineIndex + 1);
759 
760         uint32_t BlockNo = 0;
761         uint32_t EdgeNo = 0;
762         for (const GCOVBlock *Block : Blocks) {
763           // Only print block and branch information at the end of the block.
764           if (Block->getLastLine() != LineIndex + 1)
765             continue;
766           if (Options.AllBlocks)
767             printBlockInfo(CovOS, *Block, LineIndex, BlockNo);
768           if (Options.BranchInfo) {
769             size_t NumEdges = Block->getNumDstEdges();
770             if (NumEdges > 1)
771               printBranchInfo(CovOS, *Block, FileCoverage, EdgeNo);
772             else if (Options.UncondBranch && NumEdges == 1)
773               printUncondBranchInfo(CovOS, EdgeNo, Block->succ[0]->Count);
774           }
775         }
776       }
777     }
778     FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage));
779   }
780 
781   if (!Options.UseStdout) {
782     // FIXME: There is no way to detect calls given current instrumentation.
783     if (Options.FuncCoverage)
784       printFuncCoverage(InfoOS);
785     printFileCoverage(InfoOS);
786   }
787 }
788 
789 /// printFunctionSummary - Print function and block summary.
790 void FileInfo::printFunctionSummary(raw_ostream &OS,
791                                     const FunctionVector &Funcs) const {
792   for (const GCOVFunction *Func : Funcs) {
793     uint64_t EntryCount = Func->getEntryCount();
794     uint32_t BlocksExec = 0;
795     for (const GCOVBlock &Block : Func->blocks())
796       if (Block.getNumDstEdges() && Block.getCount())
797         ++BlocksExec;
798 
799     OS << "function " << Func->getName() << " called " << EntryCount
800        << " returned " << safeDiv(Func->getExitCount() * 100, EntryCount)
801        << "% blocks executed "
802        << safeDiv(BlocksExec * 100, Func->getNumBlocks() - 1) << "%\n";
803   }
804 }
805 
806 /// printBlockInfo - Output counts for each block.
807 void FileInfo::printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
808                               uint32_t LineIndex, uint32_t &BlockNo) const {
809   if (Block.getCount() == 0)
810     OS << "    $$$$$:";
811   else
812     OS << format("%9" PRIu64 ":", Block.getCount());
813   OS << format("%5u-block %2u\n", LineIndex + 1, BlockNo++);
814 }
815 
816 /// printBranchInfo - Print conditional branch probabilities.
817 void FileInfo::printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
818                                GCOVCoverage &Coverage, uint32_t &EdgeNo) {
819   SmallVector<uint64_t, 16> BranchCounts;
820   uint64_t TotalCounts = 0;
821   for (const GCOVArc *Edge : Block.dsts()) {
822     BranchCounts.push_back(Edge->Count);
823     TotalCounts += Edge->Count;
824     if (Block.getCount())
825       ++Coverage.BranchesExec;
826     if (Edge->Count)
827       ++Coverage.BranchesTaken;
828     ++Coverage.Branches;
829 
830     if (Options.FuncCoverage) {
831       const GCOVFunction *Function = &Block.getParent();
832       GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
833       if (Block.getCount())
834         ++FuncCoverage.BranchesExec;
835       if (Edge->Count)
836         ++FuncCoverage.BranchesTaken;
837       ++FuncCoverage.Branches;
838     }
839   }
840 
841   for (uint64_t N : BranchCounts)
842     OS << format("branch %2u ", EdgeNo++)
843        << formatBranchInfo(Options, N, TotalCounts) << "\n";
844 }
845 
846 /// printUncondBranchInfo - Print unconditional branch probabilities.
847 void FileInfo::printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo,
848                                      uint64_t Count) const {
849   OS << format("unconditional %2u ", EdgeNo++)
850      << formatBranchInfo(Options, Count, Count) << "\n";
851 }
852 
853 // printCoverage - Print generic coverage info used by both printFuncCoverage
854 // and printFileCoverage.
855 void FileInfo::printCoverage(raw_ostream &OS,
856                              const GCOVCoverage &Coverage) const {
857   OS << format("Lines executed:%.2f%% of %u\n",
858                double(Coverage.LinesExec) * 100 / Coverage.LogicalLines,
859                Coverage.LogicalLines);
860   if (Options.BranchInfo) {
861     if (Coverage.Branches) {
862       OS << format("Branches executed:%.2f%% of %u\n",
863                    double(Coverage.BranchesExec) * 100 / Coverage.Branches,
864                    Coverage.Branches);
865       OS << format("Taken at least once:%.2f%% of %u\n",
866                    double(Coverage.BranchesTaken) * 100 / Coverage.Branches,
867                    Coverage.Branches);
868     } else {
869       OS << "No branches\n";
870     }
871     OS << "No calls\n"; // to be consistent with gcov
872   }
873 }
874 
875 // printFuncCoverage - Print per-function coverage info.
876 void FileInfo::printFuncCoverage(raw_ostream &OS) const {
877   for (const auto &FC : FuncCoverages) {
878     const GCOVCoverage &Coverage = FC.second;
879     OS << "Function '" << Coverage.Name << "'\n";
880     printCoverage(OS, Coverage);
881     OS << "\n";
882   }
883 }
884 
885 // printFileCoverage - Print per-file coverage info.
886 void FileInfo::printFileCoverage(raw_ostream &OS) const {
887   for (const auto &FC : FileCoverages) {
888     const std::string &Filename = FC.first;
889     const GCOVCoverage &Coverage = FC.second;
890     OS << "File '" << Coverage.Name << "'\n";
891     printCoverage(OS, Coverage);
892     if (!Options.NoOutput)
893       OS << Coverage.Name << ":creating '" << Filename << "'\n";
894     OS << "\n";
895   }
896 }
897