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