//===- GCOV.cpp - LLVM coverage tool --------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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/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

//===----------------------------------------------------------------------===//
// 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());
  std::sort(Filenames.begin(), Filenames.end());

  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;
        uint64_t LineCount = 0;
        for (const GCOVBlock *Block : Blocks) {
          if (Options.AllBlocks) {
            // Only take the highest block count for that line.
            uint64_t BlockCount = Block->getCount();
            LineCount = LineCount > BlockCount ? LineCount : BlockCount;
          } else {
            // Sum up all of the block counts.
            LineCount += Block->getCount();
          }

          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;
            }
          }
        }

        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";
  }
}
