//===- GCOV.cpp - LLVM coverage tool --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// GCOV implements the interface to read and write coverage files that use
// 'gcov' format.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/GCOV.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <system_error>

using namespace llvm;

//===----------------------------------------------------------------------===//
// GCOVFile implementation.

/// readGCNO - Read GCNO buffer.
bool GCOVFile::readGCNO(GCOVBuffer &Buffer) {
  if (!Buffer.readGCNOFormat())
    return false;
  if (!Buffer.readGCOVVersion(Version))
    return false;

  if (!Buffer.readInt(Checksum))
    return false;
  while (true) {
    if (!Buffer.readFunctionTag())
      break;
    auto GFun = make_unique<GCOVFunction>(*this);
    if (!GFun->readGCNO(Buffer, Version))
      return false;
    Functions.push_back(std::move(GFun));
  }

  GCNOInitialized = true;
  return true;
}

/// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be
/// called after readGCNO().
bool GCOVFile::readGCDA(GCOVBuffer &Buffer) {
  assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
  if (!Buffer.readGCDAFormat())
    return false;
  GCOV::GCOVVersion GCDAVersion;
  if (!Buffer.readGCOVVersion(GCDAVersion))
    return false;
  if (Version != GCDAVersion) {
    errs() << "GCOV versions do not match.\n";
    return false;
  }

  uint32_t GCDAChecksum;
  if (!Buffer.readInt(GCDAChecksum))
    return false;
  if (Checksum != GCDAChecksum) {
    errs() << "File checksums do not match: " << Checksum
           << " != " << GCDAChecksum << ".\n";
    return false;
  }
  for (size_t i = 0, e = Functions.size(); i < e; ++i) {
    if (!Buffer.readFunctionTag()) {
      errs() << "Unexpected number of functions.\n";
      return false;
    }
    if (!Functions[i]->readGCDA(Buffer, Version))
      return false;
  }
  if (Buffer.readObjectTag()) {
    uint32_t Length;
    uint32_t Dummy;
    if (!Buffer.readInt(Length))
      return false;
    if (!Buffer.readInt(Dummy))
      return false; // checksum
    if (!Buffer.readInt(Dummy))
      return false; // num
    if (!Buffer.readInt(RunCount))
      return false;
    Buffer.advanceCursor(Length - 3);
  }
  while (Buffer.readProgramTag()) {
    uint32_t Length;
    if (!Buffer.readInt(Length))
      return false;
    Buffer.advanceCursor(Length);
    ++ProgramCount;
  }

  return true;
}

void GCOVFile::print(raw_ostream &OS) const {
  for (const auto &FPtr : Functions)
    FPtr->print(OS);
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// dump - Dump GCOVFile content to dbgs() for debugging purposes.
LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
#endif

/// collectLineCounts - Collect line counts. This must be used after
/// reading .gcno and .gcda files.
void GCOVFile::collectLineCounts(FileInfo &FI) {
  for (const auto &FPtr : Functions)
    FPtr->collectLineCounts(FI);
  FI.setRunCount(RunCount);
  FI.setProgramCount(ProgramCount);
}

//===----------------------------------------------------------------------===//
// GCOVFunction implementation.

/// readGCNO - Read a function from the GCNO buffer. Return false if an error
/// occurs.
bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
  uint32_t Dummy;
  if (!Buff.readInt(Dummy))
    return false; // Function header length
  if (!Buff.readInt(Ident))
    return false;
  if (!Buff.readInt(Checksum))
    return false;
  if (Version != GCOV::V402) {
    uint32_t CfgChecksum;
    if (!Buff.readInt(CfgChecksum))
      return false;
    if (Parent.getChecksum() != CfgChecksum) {
      errs() << "File checksums do not match: " << Parent.getChecksum()
             << " != " << CfgChecksum << " in (" << Name << ").\n";
      return false;
    }
  }
  if (!Buff.readString(Name))
    return false;
  if (!Buff.readString(Filename))
    return false;
  if (!Buff.readInt(LineNumber))
    return false;

  // read blocks.
  if (!Buff.readBlockTag()) {
    errs() << "Block tag not found.\n";
    return false;
  }
  uint32_t BlockCount;
  if (!Buff.readInt(BlockCount))
    return false;
  for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
    if (!Buff.readInt(Dummy))
      return false; // Block flags;
    Blocks.push_back(make_unique<GCOVBlock>(*this, i));
  }

  // read edges.
  while (Buff.readEdgeTag()) {
    uint32_t EdgeCount;
    if (!Buff.readInt(EdgeCount))
      return false;
    EdgeCount = (EdgeCount - 1) / 2;
    uint32_t BlockNo;
    if (!Buff.readInt(BlockNo))
      return false;
    if (BlockNo >= BlockCount) {
      errs() << "Unexpected block number: " << BlockNo << " (in " << Name
             << ").\n";
      return false;
    }
    for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
      uint32_t Dst;
      if (!Buff.readInt(Dst))
        return false;
      Edges.push_back(make_unique<GCOVEdge>(*Blocks[BlockNo], *Blocks[Dst]));
      GCOVEdge *Edge = Edges.back().get();
      Blocks[BlockNo]->addDstEdge(Edge);
      Blocks[Dst]->addSrcEdge(Edge);
      if (!Buff.readInt(Dummy))
        return false; // Edge flag
    }
  }

  // read line table.
  while (Buff.readLineTag()) {
    uint32_t LineTableLength;
    // Read the length of this line table.
    if (!Buff.readInt(LineTableLength))
      return false;
    uint32_t EndPos = Buff.getCursor() + LineTableLength * 4;
    uint32_t BlockNo;
    // Read the block number this table is associated with.
    if (!Buff.readInt(BlockNo))
      return false;
    if (BlockNo >= BlockCount) {
      errs() << "Unexpected block number: " << BlockNo << " (in " << Name
             << ").\n";
      return false;
    }
    GCOVBlock &Block = *Blocks[BlockNo];
    // Read the word that pads the beginning of the line table. This may be a
    // flag of some sort, but seems to always be zero.
    if (!Buff.readInt(Dummy))
      return false;

    // Line information starts here and continues up until the last word.
    if (Buff.getCursor() != (EndPos - sizeof(uint32_t))) {
      StringRef F;
      // Read the source file name.
      if (!Buff.readString(F))
        return false;
      if (Filename != F) {
        errs() << "Multiple sources for a single basic block: " << Filename
               << " != " << F << " (in " << Name << ").\n";
        return false;
      }
      // Read lines up to, but not including, the null terminator.
      while (Buff.getCursor() < (EndPos - 2 * sizeof(uint32_t))) {
        uint32_t Line;
        if (!Buff.readInt(Line))
          return false;
        // Line 0 means this instruction was injected by the compiler. Skip it.
        if (!Line)
          continue;
        Block.addLine(Line);
      }
      // Read the null terminator.
      if (!Buff.readInt(Dummy))
        return false;
    }
    // The last word is either a flag or padding, it isn't clear which. Skip
    // over it.
    if (!Buff.readInt(Dummy))
      return false;
  }
  return true;
}

/// readGCDA - Read a function from the GCDA buffer. Return false if an error
/// occurs.
bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
  uint32_t HeaderLength;
  if (!Buff.readInt(HeaderLength))
    return false; // Function header length

  uint64_t EndPos = Buff.getCursor() + HeaderLength * sizeof(uint32_t);

  uint32_t GCDAIdent;
  if (!Buff.readInt(GCDAIdent))
    return false;
  if (Ident != GCDAIdent) {
    errs() << "Function identifiers do not match: " << Ident
           << " != " << GCDAIdent << " (in " << Name << ").\n";
    return false;
  }

  uint32_t GCDAChecksum;
  if (!Buff.readInt(GCDAChecksum))
    return false;
  if (Checksum != GCDAChecksum) {
    errs() << "Function checksums do not match: " << Checksum
           << " != " << GCDAChecksum << " (in " << Name << ").\n";
    return false;
  }

  uint32_t CfgChecksum;
  if (Version != GCOV::V402) {
    if (!Buff.readInt(CfgChecksum))
      return false;
    if (Parent.getChecksum() != CfgChecksum) {
      errs() << "File checksums do not match: " << Parent.getChecksum()
             << " != " << CfgChecksum << " (in " << Name << ").\n";
      return false;
    }
  }

  if (Buff.getCursor() < EndPos) {
    StringRef GCDAName;
    if (!Buff.readString(GCDAName))
      return false;
    if (Name != GCDAName) {
      errs() << "Function names do not match: " << Name << " != " << GCDAName
             << ".\n";
      return false;
    }
  }

  if (!Buff.readArcTag()) {
    errs() << "Arc tag not found (in " << Name << ").\n";
    return false;
  }

  uint32_t Count;
  if (!Buff.readInt(Count))
    return false;
  Count /= 2;

  // This for loop adds the counts for each block. A second nested loop is
  // required to combine the edge counts that are contained in the GCDA file.
  for (uint32_t BlockNo = 0; Count > 0; ++BlockNo) {
    // The last block is always reserved for exit block
    if (BlockNo >= Blocks.size()) {
      errs() << "Unexpected number of edges (in " << Name << ").\n";
      return false;
    }
    if (BlockNo == Blocks.size() - 1)
      errs() << "(" << Name << ") has arcs from exit block.\n";
    GCOVBlock &Block = *Blocks[BlockNo];
    for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End;
         ++EdgeNo) {
      if (Count == 0) {
        errs() << "Unexpected number of edges (in " << Name << ").\n";
        return false;
      }
      uint64_t ArcCount;
      if (!Buff.readInt64(ArcCount))
        return false;
      Block.addCount(EdgeNo, ArcCount);
      --Count;
    }
    Block.sortDstEdges();
  }
  return true;
}

/// getEntryCount - Get the number of times the function was called by
/// retrieving the entry block's count.
uint64_t GCOVFunction::getEntryCount() const {
  return Blocks.front()->getCount();
}

/// getExitCount - Get the number of times the function returned by retrieving
/// the exit block's count.
uint64_t GCOVFunction::getExitCount() const {
  return Blocks.back()->getCount();
}

void GCOVFunction::print(raw_ostream &OS) const {
  OS << "===== " << Name << " (" << Ident << ") @ " << Filename << ":"
     << LineNumber << "\n";
  for (const auto &Block : Blocks)
    Block->print(OS);
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// dump - Dump GCOVFunction content to dbgs() for debugging purposes.
LLVM_DUMP_METHOD void GCOVFunction::dump() const { print(dbgs()); }
#endif

/// collectLineCounts - Collect line counts. This must be used after
/// reading .gcno and .gcda files.
void GCOVFunction::collectLineCounts(FileInfo &FI) {
  // If the line number is zero, this is a function that doesn't actually appear
  // in the source file, so there isn't anything we can do with it.
  if (LineNumber == 0)
    return;

  for (const auto &Block : Blocks)
    Block->collectLineCounts(FI);
  FI.addFunctionLine(Filename, LineNumber, this);
}

//===----------------------------------------------------------------------===//
// GCOVBlock implementation.

/// ~GCOVBlock - Delete GCOVBlock and its content.
GCOVBlock::~GCOVBlock() {
  SrcEdges.clear();
  DstEdges.clear();
  Lines.clear();
}

/// addCount - Add to block counter while storing the edge count. If the
/// destination has no outgoing edges, also update that block's count too.
void GCOVBlock::addCount(size_t DstEdgeNo, uint64_t N) {
  assert(DstEdgeNo < DstEdges.size()); // up to caller to ensure EdgeNo is valid
  DstEdges[DstEdgeNo]->Count = N;
  Counter += N;
  if (!DstEdges[DstEdgeNo]->Dst.getNumDstEdges())
    DstEdges[DstEdgeNo]->Dst.Counter += N;
}

/// sortDstEdges - Sort destination edges by block number, nop if already
/// sorted. This is required for printing branch info in the correct order.
void GCOVBlock::sortDstEdges() {
  if (!DstEdgesAreSorted) {
    SortDstEdgesFunctor SortEdges;
    std::stable_sort(DstEdges.begin(), DstEdges.end(), SortEdges);
  }
}

/// collectLineCounts - Collect line counts. This must be used after
/// reading .gcno and .gcda files.
void GCOVBlock::collectLineCounts(FileInfo &FI) {
  for (uint32_t N : Lines)
    FI.addBlockLine(Parent.getFilename(), N, this);
}

void GCOVBlock::print(raw_ostream &OS) const {
  OS << "Block : " << Number << " Counter : " << Counter << "\n";
  if (!SrcEdges.empty()) {
    OS << "\tSource Edges : ";
    for (const GCOVEdge *Edge : SrcEdges)
      OS << Edge->Src.Number << " (" << Edge->Count << "), ";
    OS << "\n";
  }
  if (!DstEdges.empty()) {
    OS << "\tDestination Edges : ";
    for (const GCOVEdge *Edge : DstEdges)
      OS << Edge->Dst.Number << " (" << Edge->Count << "), ";
    OS << "\n";
  }
  if (!Lines.empty()) {
    OS << "\tLines : ";
    for (uint32_t N : Lines)
      OS << (N) << ",";
    OS << "\n";
  }
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// dump - Dump GCOVBlock content to dbgs() for debugging purposes.
LLVM_DUMP_METHOD void GCOVBlock::dump() const { print(dbgs()); }
#endif

//===----------------------------------------------------------------------===//
// Cycles detection
//
// The algorithm in GCC is based on the algorihtm by Hawick & James:
//   "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
//   http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf.

/// Get the count for the detected cycle.
uint64_t GCOVBlock::getCycleCount(const Edges &Path) {
  uint64_t CycleCount = std::numeric_limits<uint64_t>::max();
  for (auto E : Path) {
    CycleCount = std::min(E->CyclesCount, CycleCount);
  }
  for (auto E : Path) {
    E->CyclesCount -= CycleCount;
  }
  return CycleCount;
}

/// Unblock a vertex previously marked as blocked.
void GCOVBlock::unblock(const GCOVBlock *U, BlockVector &Blocked,
                        BlockVectorLists &BlockLists) {
  auto it = find(Blocked, U);
  if (it == Blocked.end()) {
    return;
  }

  const size_t index = it - Blocked.begin();
  Blocked.erase(it);

  const BlockVector ToUnblock(BlockLists[index]);
  BlockLists.erase(BlockLists.begin() + index);
  for (auto GB : ToUnblock) {
    GCOVBlock::unblock(GB, Blocked, BlockLists);
  }
}

bool GCOVBlock::lookForCircuit(const GCOVBlock *V, const GCOVBlock *Start,
                               Edges &Path, BlockVector &Blocked,
                               BlockVectorLists &BlockLists,
                               const BlockVector &Blocks, uint64_t &Count) {
  Blocked.push_back(V);
  BlockLists.emplace_back(BlockVector());
  bool FoundCircuit = false;

  for (auto E : V->dsts()) {
    const GCOVBlock *W = &E->Dst;
    if (W < Start || find(Blocks, W) == Blocks.end()) {
      continue;
    }

    Path.push_back(E);

    if (W == Start) {
      // We've a cycle.
      Count += GCOVBlock::getCycleCount(Path);
      FoundCircuit = true;
    } else if (find(Blocked, W) == Blocked.end() && // W is not blocked.
               GCOVBlock::lookForCircuit(W, Start, Path, Blocked, BlockLists,
                                         Blocks, Count)) {
      FoundCircuit = true;
    }

    Path.pop_back();
  }

  if (FoundCircuit) {
    GCOVBlock::unblock(V, Blocked, BlockLists);
  } else {
    for (auto E : V->dsts()) {
      const GCOVBlock *W = &E->Dst;
      if (W < Start || find(Blocks, W) == Blocks.end()) {
        continue;
      }
      const size_t index = find(Blocked, W) - Blocked.begin();
      BlockVector &List = BlockLists[index];
      if (find(List, V) == List.end()) {
        List.push_back(V);
      }
    }
  }

  return FoundCircuit;
}

/// Get the count for the list of blocks which lie on the same line.
void GCOVBlock::getCyclesCount(const BlockVector &Blocks, uint64_t &Count) {
  for (auto Block : Blocks) {
    Edges Path;
    BlockVector Blocked;
    BlockVectorLists BlockLists;

    GCOVBlock::lookForCircuit(Block, Block, Path, Blocked, BlockLists, Blocks,
                              Count);
  }
}

/// Get the count for the list of blocks which lie on the same line.
uint64_t GCOVBlock::getLineCount(const BlockVector &Blocks) {
  uint64_t Count = 0;

  for (auto Block : Blocks) {
    if (Block->getNumSrcEdges() == 0) {
      // The block has no predecessors and a non-null counter
      // (can be the case with entry block in functions).
      Count += Block->getCount();
    } else {
      // Add counts from predecessors that are not on the same line.
      for (auto E : Block->srcs()) {
        const GCOVBlock *W = &E->Src;
        if (find(Blocks, W) == Blocks.end()) {
          Count += E->Count;
        }
      }
    }
    for (auto E : Block->dsts()) {
      E->CyclesCount = E->Count;
    }
  }

  GCOVBlock::getCyclesCount(Blocks, Count);

  return Count;
}

//===----------------------------------------------------------------------===//
// FileInfo implementation.

// Safe integer division, returns 0 if numerator is 0.
static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) {
  if (!Numerator)
    return 0;
  return Numerator / Divisor;
}

// This custom division function mimics gcov's branch ouputs:
//   - Round to closest whole number
//   - Only output 0% or 100% if it's exactly that value
static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) {
  if (!Numerator)
    return 0;
  if (Numerator == Divisor)
    return 100;

  uint8_t Res = (Numerator * 100 + Divisor / 2) / Divisor;
  if (Res == 0)
    return 1;
  if (Res == 100)
    return 99;
  return Res;
}

namespace {
struct formatBranchInfo {
  formatBranchInfo(const GCOV::Options &Options, uint64_t Count, uint64_t Total)
      : Options(Options), Count(Count), Total(Total) {}

  void print(raw_ostream &OS) const {
    if (!Total)
      OS << "never executed";
    else if (Options.BranchCount)
      OS << "taken " << Count;
    else
      OS << "taken " << branchDiv(Count, Total) << "%";
  }

  const GCOV::Options &Options;
  uint64_t Count;
  uint64_t Total;
};

static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
  FBI.print(OS);
  return OS;
}

class LineConsumer {
  std::unique_ptr<MemoryBuffer> Buffer;
  StringRef Remaining;

public:
  LineConsumer(StringRef Filename) {
    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
        MemoryBuffer::getFileOrSTDIN(Filename);
    if (std::error_code EC = BufferOrErr.getError()) {
      errs() << Filename << ": " << EC.message() << "\n";
      Remaining = "";
    } else {
      Buffer = std::move(BufferOrErr.get());
      Remaining = Buffer->getBuffer();
    }
  }
  bool empty() { return Remaining.empty(); }
  void printNext(raw_ostream &OS, uint32_t LineNum) {
    StringRef Line;
    if (empty())
      Line = "/*EOF*/";
    else
      std::tie(Line, Remaining) = Remaining.split("\n");
    OS << format("%5u:", LineNum) << Line << "\n";
  }
};
} // end anonymous namespace

/// Convert a path to a gcov filename. If PreservePaths is true, this
/// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
  if (!PreservePaths)
    return sys::path::filename(Filename).str();

  // This behaviour is defined by gcov in terms of text replacements, so it's
  // not likely to do anything useful on filesystems with different textual
  // conventions.
  llvm::SmallString<256> Result("");
  StringRef::iterator I, S, E;
  for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) {
    if (*I != '/')
      continue;

    if (I - S == 1 && *S == '.') {
      // ".", the current directory, is skipped.
    } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') {
      // "..", the parent directory, is replaced with "^".
      Result.append("^#");
    } else {
      if (S < I)
        // Leave other components intact,
        Result.append(S, I);
      // And separate with "#".
      Result.push_back('#');
    }
    S = I + 1;
  }

  if (S < I)
    Result.append(S, I);
  return Result.str();
}

std::string FileInfo::getCoveragePath(StringRef Filename,
                                      StringRef MainFilename) {
  if (Options.NoOutput)
    // This is probably a bug in gcov, but when -n is specified, paths aren't
    // mangled at all, and the -l and -p options are ignored. Here, we do the
    // same.
    return Filename;

  std::string CoveragePath;
  if (Options.LongFileNames && !Filename.equals(MainFilename))
    CoveragePath =
        mangleCoveragePath(MainFilename, Options.PreservePaths) + "##";
  CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov";
  return CoveragePath;
}

std::unique_ptr<raw_ostream>
FileInfo::openCoveragePath(StringRef CoveragePath) {
  if (Options.NoOutput)
    return llvm::make_unique<raw_null_ostream>();

  std::error_code EC;
  auto OS =
      llvm::make_unique<raw_fd_ostream>(CoveragePath, EC, sys::fs::F_Text);
  if (EC) {
    errs() << EC.message() << "\n";
    return llvm::make_unique<raw_null_ostream>();
  }
  return std::move(OS);
}

/// print -  Print source files with collected line count information.
void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
                     StringRef GCNOFile, StringRef GCDAFile) {
  SmallVector<StringRef, 4> Filenames;
  for (const auto &LI : LineInfo)
    Filenames.push_back(LI.first());
  llvm::sort(Filenames);

  for (StringRef Filename : Filenames) {
    auto AllLines = LineConsumer(Filename);

    std::string CoveragePath = getCoveragePath(Filename, MainFilename);
    std::unique_ptr<raw_ostream> CovStream = openCoveragePath(CoveragePath);
    raw_ostream &CovOS = *CovStream;

    CovOS << "        -:    0:Source:" << Filename << "\n";
    CovOS << "        -:    0:Graph:" << GCNOFile << "\n";
    CovOS << "        -:    0:Data:" << GCDAFile << "\n";
    CovOS << "        -:    0:Runs:" << RunCount << "\n";
    CovOS << "        -:    0:Programs:" << ProgramCount << "\n";

    const LineData &Line = LineInfo[Filename];
    GCOVCoverage FileCoverage(Filename);
    for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
         ++LineIndex) {
      if (Options.BranchInfo) {
        FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
        if (FuncsIt != Line.Functions.end())
          printFunctionSummary(CovOS, FuncsIt->second);
      }

      BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex);
      if (BlocksIt == Line.Blocks.end()) {
        // No basic blocks are on this line. Not an executable line of code.
        CovOS << "        -:";
        AllLines.printNext(CovOS, LineIndex + 1);
      } else {
        const BlockVector &Blocks = BlocksIt->second;

        // Add up the block counts to form line counts.
        DenseMap<const GCOVFunction *, bool> LineExecs;
        for (const GCOVBlock *Block : Blocks) {
          if (Options.FuncCoverage) {
            // This is a slightly convoluted way to most accurately gather line
            // statistics for functions. Basically what is happening is that we
            // don't want to count a single line with multiple blocks more than
            // once. However, we also don't simply want to give the total line
            // count to every function that starts on the line. Thus, what is
            // happening here are two things:
            // 1) Ensure that the number of logical lines is only incremented
            //    once per function.
            // 2) If there are multiple blocks on the same line, ensure that the
            //    number of lines executed is incremented as long as at least
            //    one of the blocks are executed.
            const GCOVFunction *Function = &Block->getParent();
            if (FuncCoverages.find(Function) == FuncCoverages.end()) {
              std::pair<const GCOVFunction *, GCOVCoverage> KeyValue(
                  Function, GCOVCoverage(Function->getName()));
              FuncCoverages.insert(KeyValue);
            }
            GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;

            if (LineExecs.find(Function) == LineExecs.end()) {
              if (Block->getCount()) {
                ++FuncCoverage.LinesExec;
                LineExecs[Function] = true;
              } else {
                LineExecs[Function] = false;
              }
              ++FuncCoverage.LogicalLines;
            } else if (!LineExecs[Function] && Block->getCount()) {
              ++FuncCoverage.LinesExec;
              LineExecs[Function] = true;
            }
          }
        }

        const uint64_t LineCount = GCOVBlock::getLineCount(Blocks);
        if (LineCount == 0)
          CovOS << "    #####:";
        else {
          CovOS << format("%9" PRIu64 ":", LineCount);
          ++FileCoverage.LinesExec;
        }
        ++FileCoverage.LogicalLines;

        AllLines.printNext(CovOS, LineIndex + 1);

        uint32_t BlockNo = 0;
        uint32_t EdgeNo = 0;
        for (const GCOVBlock *Block : Blocks) {
          // Only print block and branch information at the end of the block.
          if (Block->getLastLine() != LineIndex + 1)
            continue;
          if (Options.AllBlocks)
            printBlockInfo(CovOS, *Block, LineIndex, BlockNo);
          if (Options.BranchInfo) {
            size_t NumEdges = Block->getNumDstEdges();
            if (NumEdges > 1)
              printBranchInfo(CovOS, *Block, FileCoverage, EdgeNo);
            else if (Options.UncondBranch && NumEdges == 1)
              printUncondBranchInfo(CovOS, EdgeNo,
                                    (*Block->dst_begin())->Count);
          }
        }
      }
    }
    FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage));
  }

  // FIXME: There is no way to detect calls given current instrumentation.
  if (Options.FuncCoverage)
    printFuncCoverage(InfoOS);
  printFileCoverage(InfoOS);
}

/// printFunctionSummary - Print function and block summary.
void FileInfo::printFunctionSummary(raw_ostream &OS,
                                    const FunctionVector &Funcs) const {
  for (const GCOVFunction *Func : Funcs) {
    uint64_t EntryCount = Func->getEntryCount();
    uint32_t BlocksExec = 0;
    for (const GCOVBlock &Block : Func->blocks())
      if (Block.getNumDstEdges() && Block.getCount())
        ++BlocksExec;

    OS << "function " << Func->getName() << " called " << EntryCount
       << " returned " << safeDiv(Func->getExitCount() * 100, EntryCount)
       << "% blocks executed "
       << safeDiv(BlocksExec * 100, Func->getNumBlocks() - 1) << "%\n";
  }
}

/// printBlockInfo - Output counts for each block.
void FileInfo::printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
                              uint32_t LineIndex, uint32_t &BlockNo) const {
  if (Block.getCount() == 0)
    OS << "    $$$$$:";
  else
    OS << format("%9" PRIu64 ":", Block.getCount());
  OS << format("%5u-block %2u\n", LineIndex + 1, BlockNo++);
}

/// printBranchInfo - Print conditional branch probabilities.
void FileInfo::printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
                               GCOVCoverage &Coverage, uint32_t &EdgeNo) {
  SmallVector<uint64_t, 16> BranchCounts;
  uint64_t TotalCounts = 0;
  for (const GCOVEdge *Edge : Block.dsts()) {
    BranchCounts.push_back(Edge->Count);
    TotalCounts += Edge->Count;
    if (Block.getCount())
      ++Coverage.BranchesExec;
    if (Edge->Count)
      ++Coverage.BranchesTaken;
    ++Coverage.Branches;

    if (Options.FuncCoverage) {
      const GCOVFunction *Function = &Block.getParent();
      GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
      if (Block.getCount())
        ++FuncCoverage.BranchesExec;
      if (Edge->Count)
        ++FuncCoverage.BranchesTaken;
      ++FuncCoverage.Branches;
    }
  }

  for (uint64_t N : BranchCounts)
    OS << format("branch %2u ", EdgeNo++)
       << formatBranchInfo(Options, N, TotalCounts) << "\n";
}

/// printUncondBranchInfo - Print unconditional branch probabilities.
void FileInfo::printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo,
                                     uint64_t Count) const {
  OS << format("unconditional %2u ", EdgeNo++)
     << formatBranchInfo(Options, Count, Count) << "\n";
}

// printCoverage - Print generic coverage info used by both printFuncCoverage
// and printFileCoverage.
void FileInfo::printCoverage(raw_ostream &OS,
                             const GCOVCoverage &Coverage) const {
  OS << format("Lines executed:%.2f%% of %u\n",
               double(Coverage.LinesExec) * 100 / Coverage.LogicalLines,
               Coverage.LogicalLines);
  if (Options.BranchInfo) {
    if (Coverage.Branches) {
      OS << format("Branches executed:%.2f%% of %u\n",
                   double(Coverage.BranchesExec) * 100 / Coverage.Branches,
                   Coverage.Branches);
      OS << format("Taken at least once:%.2f%% of %u\n",
                   double(Coverage.BranchesTaken) * 100 / Coverage.Branches,
                   Coverage.Branches);
    } else {
      OS << "No branches\n";
    }
    OS << "No calls\n"; // to be consistent with gcov
  }
}

// printFuncCoverage - Print per-function coverage info.
void FileInfo::printFuncCoverage(raw_ostream &OS) const {
  for (const auto &FC : FuncCoverages) {
    const GCOVCoverage &Coverage = FC.second;
    OS << "Function '" << Coverage.Name << "'\n";
    printCoverage(OS, Coverage);
    OS << "\n";
  }
}

// printFileCoverage - Print per-file coverage info.
void FileInfo::printFileCoverage(raw_ostream &OS) const {
  for (const auto &FC : FileCoverages) {
    const std::string &Filename = FC.first;
    const GCOVCoverage &Coverage = FC.second;
    OS << "File '" << Coverage.Name << "'\n";
    printCoverage(OS, Coverage);
    if (!Options.NoOutput)
      OS << Coverage.Name << ":creating '" << Filename << "'\n";
    OS << "\n";
  }
}
