//===- 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/Demangle/Demangle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <system_error>
#include <unordered_map>

using namespace llvm;

enum : uint32_t {
  GCOV_ARC_ON_TREE = 1 << 0,
  GCOV_ARC_FALLTHROUGH = 1 << 2,

  GCOV_TAG_FUNCTION = 0x01000000,
  GCOV_TAG_BLOCKS = 0x01410000,
  GCOV_TAG_ARCS = 0x01430000,
  GCOV_TAG_LINES = 0x01450000,
  GCOV_TAG_COUNTER_ARCS = 0x01a10000,
  // GCOV_TAG_OBJECT_SUMMARY superseded GCOV_TAG_PROGRAM_SUMMARY in GCC 9.
  GCOV_TAG_OBJECT_SUMMARY = 0xa1000000,
  GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000,
};

namespace {
struct Summary {
  Summary(StringRef Name) : Name(Name) {}

  StringRef Name;
  uint64_t lines = 0;
  uint64_t linesExec = 0;
  uint64_t branches = 0;
  uint64_t branchesExec = 0;
  uint64_t branchesTaken = 0;
};

struct LineInfo {
  SmallVector<const GCOVBlock *, 1> blocks;
  uint64_t count = 0;
  bool exists = false;
};

struct SourceInfo {
  StringRef filename;
  SmallString<0> displayName;
  std::vector<std::vector<const GCOVFunction *>> startLineToFunctions;
  std::vector<LineInfo> lines;
  bool ignored = false;
  SourceInfo(StringRef filename) : filename(filename) {}
};

class Context {
public:
  Context(const GCOV::Options &Options) : options(Options) {}
  void print(StringRef filename, StringRef gcno, StringRef gcda,
             GCOVFile &file);

private:
  std::string getCoveragePath(StringRef filename, StringRef mainFilename) const;
  void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const;
  void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
                       raw_ostream &OS) const;
  void printSummary(const Summary &summary, raw_ostream &os) const;

  void collectFunction(GCOVFunction &f, Summary &summary);
  void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line,
                         size_t lineNum) const;
  void collectSource(SourceInfo &si, Summary &summary) const;
  void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno,
                      StringRef gcda, raw_ostream &os) const;
  void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const;

  const GCOV::Options &options;
  std::vector<SourceInfo> sources;
};
} // namespace

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

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

  Checksum = buf.getWord();
  if (Version >= GCOV::V900)
    cwd = buf.getString();
  if (Version >= GCOV::V800)
    buf.getWord(); // hasUnexecutedBlocks

  uint32_t tag, length;
  GCOVFunction *fn;
  while ((tag = buf.getWord())) {
    if (!buf.readInt(length))
      return false;
    if (tag == GCOV_TAG_FUNCTION) {
      functions.push_back(std::make_unique<GCOVFunction>(*this));
      fn = functions.back().get();
      fn->ident = buf.getWord();
      fn->linenoChecksum = buf.getWord();
      if (Version >= GCOV::V407)
        fn->cfgChecksum = buf.getWord();
      buf.readString(fn->Name);
      StringRef filename;
      if (Version < GCOV::V800) {
        filename = buf.getString();
        fn->startLine = buf.getWord();
      } else {
        fn->artificial = buf.getWord();
        filename = buf.getString();
        fn->startLine = buf.getWord();
        fn->startColumn = buf.getWord();
        fn->endLine = buf.getWord();
        if (Version >= GCOV::V900)
          fn->endColumn = buf.getWord();
      }
      auto r = filenameToIdx.try_emplace(filename, filenameToIdx.size());
      if (r.second)
        filenames.emplace_back(filename);
      fn->srcIdx = r.first->second;
      IdentToFunction[fn->ident] = fn;
    } else if (tag == GCOV_TAG_BLOCKS && fn) {
      if (Version < GCOV::V800) {
        for (uint32_t i = 0; i != length; ++i) {
          buf.getWord(); // Ignored block flags
          fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
        }
      } else {
        uint32_t num = buf.getWord();
        for (uint32_t i = 0; i != num; ++i)
          fn->blocks.push_back(std::make_unique<GCOVBlock>(i));
      }
    } else if (tag == GCOV_TAG_ARCS && fn) {
      uint32_t srcNo = buf.getWord();
      if (srcNo >= fn->blocks.size()) {
        errs() << "unexpected block number: " << srcNo << " (in "
               << fn->blocks.size() << ")\n";
        return false;
      }
      GCOVBlock *src = fn->blocks[srcNo].get();
      for (uint32_t i = 0, e = (length - 1) / 2; i != e; ++i) {
        uint32_t dstNo = buf.getWord(), flags = buf.getWord();
        GCOVBlock *dst = fn->blocks[dstNo].get();
        auto arc = std::make_unique<GCOVArc>(*src, *dst, flags);
        src->addDstEdge(arc.get());
        dst->addSrcEdge(arc.get());
        if (arc->onTree())
          fn->treeArcs.push_back(std::move(arc));
        else
          fn->arcs.push_back(std::move(arc));
      }
    } else if (tag == GCOV_TAG_LINES && fn) {
      uint32_t srcNo = buf.getWord();
      if (srcNo >= fn->blocks.size()) {
        errs() << "unexpected block number: " << srcNo << " (in "
               << fn->blocks.size() << ")\n";
        return false;
      }
      GCOVBlock &Block = *fn->blocks[srcNo];
      for (;;) {
        uint32_t line = buf.getWord();
        if (line)
          Block.addLine(line);
        else {
          StringRef filename = buf.getString();
          if (filename.empty())
            break;
          // TODO Unhandled
        }
      }
    }
  }

  GCNOInitialized = true;
  return true;
}

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

  uint32_t GCDAChecksum;
  if (!buf.readInt(GCDAChecksum))
    return false;
  if (Checksum != GCDAChecksum) {
    errs() << "File checksums do not match: " << Checksum
           << " != " << GCDAChecksum << ".\n";
    return false;
  }
  uint32_t dummy, tag, length;
  uint32_t ident;
  GCOVFunction *fn = nullptr;
  while ((tag = buf.getWord())) {
    if (!buf.readInt(length))
      return false;
    uint32_t pos = buf.cursor.tell();
    if (tag == GCOV_TAG_OBJECT_SUMMARY) {
      buf.readInt(RunCount);
      buf.readInt(dummy);
      // clang<11 uses a fake 4.2 format which sets length to 9.
      if (length == 9)
        buf.readInt(RunCount);
    } else if (tag == GCOV_TAG_PROGRAM_SUMMARY) {
      // clang<11 uses a fake 4.2 format which sets length to 0.
      if (length > 0) {
        buf.readInt(dummy);
        buf.readInt(dummy);
        buf.readInt(RunCount);
      }
      ++ProgramCount;
    } else if (tag == GCOV_TAG_FUNCTION) {
      if (length == 0) // Placeholder
        continue;
      // As of GCC 10, GCOV_TAG_FUNCTION_LENGTH has never been larger than 3.
      // However, clang<11 uses a fake 4.2 format which may set length larger
      // than 3.
      if (length < 2 || !buf.readInt(ident))
        return false;
      auto It = IdentToFunction.find(ident);
      uint32_t linenoChecksum, cfgChecksum = 0;
      buf.readInt(linenoChecksum);
      if (Version >= GCOV::V407)
        buf.readInt(cfgChecksum);
      if (It != IdentToFunction.end()) {
        fn = It->second;
        if (linenoChecksum != fn->linenoChecksum ||
            cfgChecksum != fn->cfgChecksum) {
          errs() << fn->Name
                 << format(": checksum mismatch, (%u, %u) != (%u, %u)\n",
                           linenoChecksum, cfgChecksum, fn->linenoChecksum,
                           fn->cfgChecksum);
          return false;
        }
      }
    } else if (tag == GCOV_TAG_COUNTER_ARCS && fn) {
      if (length != 2 * fn->arcs.size()) {
        errs() << fn->Name
               << format(
                      ": GCOV_TAG_COUNTER_ARCS mismatch, got %u, expected %u\n",
                      length, unsigned(2 * fn->arcs.size()));
        return false;
      }
      for (std::unique_ptr<GCOVArc> &arc : fn->arcs) {
        if (!buf.readInt64(arc->count))
          return false;
        arc->src.count += arc->count;
      }

      if (fn->blocks.size() >= 2) {
        GCOVBlock &src = *fn->blocks[0];
        GCOVBlock &sink =
            Version < GCOV::V408 ? *fn->blocks.back() : *fn->blocks[1];
        auto arc = std::make_unique<GCOVArc>(sink, src, GCOV_ARC_ON_TREE);
        sink.addDstEdge(arc.get());
        src.addSrcEdge(arc.get());
        fn->treeArcs.push_back(std::move(arc));

        for (GCOVBlock &block : fn->blocksRange())
          fn->propagateCounts(block, nullptr);
        for (size_t i = fn->treeArcs.size() - 1; i; --i)
          fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count;
      }
    }
    pos += 4 * length;
    if (pos < buf.cursor.tell())
      return false;
    buf.de.skip(buf.cursor, pos - buf.cursor.tell());
  }

  return true;
}

void GCOVFile::print(raw_ostream &OS) const {
  for (const GCOVFunction &f : *this)
    f.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

bool GCOVArc::onTree() const { return flags & GCOV_ARC_ON_TREE; }

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

StringRef GCOVFunction::getName(bool demangle) const {
  if (!demangle)
    return Name;
  if (demangled.empty()) {
    do {
      if (Name.startswith("_Z")) {
        int status = 0;
        // Name is guaranteed to be NUL-terminated.
        char *res = itaniumDemangle(Name.data(), nullptr, nullptr, &status);
        if (status == 0) {
          demangled = res;
          free(res);
          break;
        }
      }
      demangled = Name;
    } while (0);
  }
  return demangled;
}
StringRef GCOVFunction::getFilename() const { return file.filenames[srcIdx]; }

/// 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();
}

GCOVBlock &GCOVFunction::getExitBlock() const {
  return file.getVersion() < GCOV::V408 ? *blocks.back() : *blocks[1];
}

// For each basic block, the sum of incoming edge counts equals the sum of
// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a
// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be
// uniquely identified.
uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) {
  // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise
  // this prevents infinite recursion.
  if (!visited.insert(&v).second)
    return 0;

  uint64_t excess = 0;
  for (GCOVArc *e : v.srcs())
    if (e != pred)
      excess += e->onTree() ? propagateCounts(e->src, e) : e->count;
  for (GCOVArc *e : v.dsts())
    if (e != pred)
      excess -= e->onTree() ? propagateCounts(e->dst, e) : e->count;
  if (int64_t(excess) < 0)
    excess = -excess;
  if (pred)
    pred->count = excess;
  return excess;
}

void GCOVFunction::print(raw_ostream &OS) const {
  OS << "===== " << Name << " (" << ident << ") @ " << getFilename() << ":"
     << startLine << "\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.

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

void GCOVBlock::print(raw_ostream &OS) const {
  OS << "Block : " << number << " Counter : " << count << "\n";
  if (!pred.empty()) {
    OS << "\tSource Edges : ";
    for (const GCOVArc *Edge : pred)
      OS << Edge->src.number << " (" << Edge->count << "), ";
    OS << "\n";
  }
  if (!succ.empty()) {
    OS << "\tDestination Edges : ";
    for (const GCOVArc *Edge : succ) {
      if (Edge->flags & GCOV_ARC_ON_TREE)
        OS << '*';
      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 algorithm 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->cycleCount, CycleCount);
  }
  for (auto E : Path) {
    E->cycleCount -= 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);
  }
}

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

// Format dividend/divisor as a percentage. Return 1 if the result is greater
// than 0% and less than 1%.
static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor) {
  if (!dividend || !divisor)
    return 0;
  dividend *= 100;
  return dividend < divisor ? 1 : dividend / 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() = default;
  LineConsumer(StringRef Filename) {
    // Open source files without requiring a NUL terminator. The concurrent
    // modification may nullify the NUL terminator condition.
    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
        MemoryBuffer::getFileOrSTDIN(Filename, -1,
                                     /*RequiresNullTerminator=*/false);
    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 std::string(Result.str());
}

std::string Context::getCoveragePath(StringRef filename,
                                     StringRef mainFilename) const {
  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 std::string(filename);

  std::string CoveragePath;
  if (options.LongFileNames && !filename.equals(mainFilename))
    CoveragePath =
        mangleCoveragePath(mainFilename, options.PreservePaths) + "##";
  CoveragePath += mangleCoveragePath(filename, options.PreservePaths);
  if (options.HashFilenames) {
    MD5 Hasher;
    MD5::MD5Result Result;
    Hasher.update(filename.str());
    Hasher.final(Result);
    CoveragePath += "##" + std::string(Result.digest());
  }
  CoveragePath += ".gcov";
  return CoveragePath;
}

void Context::collectFunction(GCOVFunction &f, Summary &summary) {
  SourceInfo &si = sources[f.srcIdx];
  if (f.startLine >= si.startLineToFunctions.size())
    si.startLineToFunctions.resize(f.startLine + 1);
  si.startLineToFunctions[f.startLine].push_back(&f);
  for (const GCOVBlock &b : f.blocksRange()) {
    if (b.lines.empty())
      continue;
    uint32_t maxLineNum = *std::max_element(b.lines.begin(), b.lines.end());
    if (maxLineNum >= si.lines.size())
      si.lines.resize(maxLineNum + 1);
    for (uint32_t lineNum : b.lines) {
      LineInfo &line = si.lines[lineNum];
      if (!line.exists)
        ++summary.lines;
      if (line.count == 0 && b.count)
        ++summary.linesExec;
      line.exists = true;
      line.count += b.count;
      line.blocks.push_back(&b);
    }
  }
}

void Context::collectSourceLine(SourceInfo &si, Summary *summary,
                                LineInfo &line, size_t lineNum) const {
  uint64_t count = 0;
  for (const GCOVBlock *b : line.blocks) {
    if (b->number == 0) {
      // For nonstandard control flows, arcs into the exit block may be
      // duplicately counted (fork) or not be counted (abnormal exit), and thus
      // the (exit,entry) counter may be inaccurate. Count the entry block with
      // the outgoing arcs.
      for (const GCOVArc *arc : b->succ)
        count += arc->count;
    } else {
      // Add counts from predecessors that are not on the same line.
      for (const GCOVArc *arc : b->pred)
        if (!llvm::is_contained(line.blocks, &arc->src))
          count += arc->count;
    }
    for (GCOVArc *arc : b->succ)
      arc->cycleCount = arc->count;
  }

  GCOVBlock::getCyclesCount(line.blocks, count);
  line.count = count;
  if (line.exists) {
    ++summary->lines;
    if (line.count != 0)
      ++summary->linesExec;
  }

  if (options.BranchInfo)
    for (const GCOVBlock *b : line.blocks) {
      if (b->getLastLine() != lineNum)
        continue;
      int branches = 0, execBranches = 0, takenBranches = 0;
      for (const GCOVArc *arc : b->succ) {
        ++branches;
        if (count != 0)
          ++execBranches;
        if (arc->count != 0)
          ++takenBranches;
      }
      if (branches > 1) {
        summary->branches += branches;
        summary->branchesExec += execBranches;
        summary->branchesTaken += takenBranches;
      }
    }
}

void Context::collectSource(SourceInfo &si, Summary &summary) const {
  size_t lineNum = 0;
  for (LineInfo &line : si.lines) {
    collectSourceLine(si, &summary, line, lineNum);
    ++lineNum;
  }
}

void Context::annotateSource(SourceInfo &si, const GCOVFile &file,
                             StringRef gcno, StringRef gcda,
                             raw_ostream &os) const {
  auto source =
      options.Intermediate ? LineConsumer() : LineConsumer(si.filename);

  os << "        -:    0:Source:" << si.displayName << '\n';
  os << "        -:    0:Graph:" << gcno << '\n';
  os << "        -:    0:Data:" << gcda << '\n';
  os << "        -:    0:Runs:" << file.RunCount << '\n';
  if (file.Version < GCOV::V900)
    os << "        -:    0:Programs:" << file.ProgramCount << '\n';

  for (size_t lineNum = 1; !source.empty(); ++lineNum) {
    if (lineNum >= si.lines.size()) {
      os << "        -:";
      source.printNext(os, lineNum);
      continue;
    }

    const LineInfo &line = si.lines[lineNum];
    if (options.BranchInfo && lineNum < si.startLineToFunctions.size())
      for (const auto *f : si.startLineToFunctions[lineNum])
        printFunctionDetails(*f, os);
    if (!line.exists)
      os << "        -:";
    else if (line.count == 0)
      os << "    #####:";
    else
      os << format("%9" PRIu64 ":", line.count);
    source.printNext(os, lineNum);

    uint32_t blockIdx = 0, edgeIdx = 0;
    for (const GCOVBlock *b : line.blocks) {
      if (b->getLastLine() != lineNum)
        continue;
      if (options.AllBlocks) {
        if (b->getCount() == 0)
          os << "    $$$$$:";
        else
          os << format("%9" PRIu64 ":", b->count);
        os << format("%5u-block %2u\n", lineNum, blockIdx++);
      }
      if (options.BranchInfo) {
        size_t NumEdges = b->succ.size();
        if (NumEdges > 1)
          printBranchInfo(*b, edgeIdx, os);
        else if (options.UncondBranch && NumEdges == 1) {
          uint64_t count = b->succ[0]->count;
          os << format("unconditional %2u ", edgeIdx++)
             << formatBranchInfo(options, count, count) << '\n';
        }
      }
    }
  }
}

void Context::printSourceToIntermediate(const SourceInfo &si,
                                        raw_ostream &os) const {
  os << "file:" << si.filename << '\n';
  for (const auto &fs : si.startLineToFunctions)
    for (const GCOVFunction *f : fs)
      os << "function:" << f->startLine << ',' << f->getEntryCount() << ','
         << f->getName(options.Demangle) << '\n';
  for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) {
    const LineInfo &line = si.lines[lineNum];
    if (line.blocks.empty())
      continue;
    // GCC 8 (r254259) added third third field for Ada:
    // lcount:<line>,<count>,<has_unexecuted_blocks>
    // We don't need the third field.
    os << "lcount:" << lineNum << ',' << line.count << '\n';

    if (!options.BranchInfo)
      continue;
    for (const GCOVBlock *b : line.blocks) {
      if (b->succ.size() < 2 || b->getLastLine() != lineNum)
        continue;
      for (const GCOVArc *arc : b->succ) {
        const char *type =
            b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec";
        os << "branch:" << lineNum << ',' << type << '\n';
      }
    }
  }
}

void Context::print(StringRef filename, StringRef gcno, StringRef gcda,
                    GCOVFile &file) {
  for (StringRef filename : file.filenames) {
    sources.emplace_back(filename);
    SourceInfo &si = sources.back();
    si.displayName = si.filename;
    if (!options.SourcePrefix.empty() &&
        sys::path::replace_path_prefix(si.displayName, options.SourcePrefix,
                                       "") &&
        !si.displayName.empty()) {
      // TODO replace_path_prefix may strip the prefix even if the remaining
      // part does not start with a separator.
      if (sys::path::is_separator(si.displayName[0]))
        si.displayName.erase(si.displayName.begin());
      else
        si.displayName = si.filename;
    }
    if (options.RelativeOnly && sys::path::is_absolute(si.displayName))
      si.ignored = true;
  }

  raw_ostream &os = llvm::outs();
  for (GCOVFunction &f : make_pointee_range(file.functions)) {
    Summary summary(f.getName(options.Demangle));
    collectFunction(f, summary);
    if (options.FuncCoverage && !options.UseStdout) {
      os << "Function '" << summary.Name << "'\n";
      printSummary(summary, os);
      os << '\n';
    }
  }

  for (SourceInfo &si : sources) {
    if (si.ignored)
      continue;
    Summary summary(si.displayName);
    collectSource(si, summary);

    // Print file summary unless -t is specified.
    std::string gcovName = getCoveragePath(si.filename, filename);
    if (!options.UseStdout) {
      os << "File '" << summary.Name << "'\n";
      printSummary(summary, os);
      if (!options.NoOutput && !options.Intermediate)
        os << "Creating '" << gcovName << "'\n";
      os << '\n';
    }

    if (options.NoOutput || options.Intermediate)
      continue;
    Optional<raw_fd_ostream> os;
    if (!options.UseStdout) {
      std::error_code ec;
      os.emplace(gcovName, ec, sys::fs::OF_Text);
      if (ec) {
        errs() << ec.message() << '\n';
        continue;
      }
    }
    annotateSource(si, file, gcno, gcda,
                   options.UseStdout ? llvm::outs() : *os);
  }

  if (options.Intermediate && !options.NoOutput) {
    // gcov 7.* unexpectedly create multiple .gcov files, which was fixed in 8.0
    // (PR GCC/82702). We create just one file.
    std::string outputPath(sys::path::filename(filename));
    std::error_code ec;
    raw_fd_ostream os(outputPath + ".gcov", ec, sys::fs::OF_Text);
    if (ec) {
      errs() << ec.message() << '\n';
      return;
    }

    for (const SourceInfo &si : sources)
      printSourceToIntermediate(si, os);
  }
}

void Context::printFunctionDetails(const GCOVFunction &f,
                                   raw_ostream &os) const {
  const uint64_t entryCount = f.getEntryCount();
  uint32_t blocksExec = 0;
  const GCOVBlock &exitBlock = f.getExitBlock();
  uint64_t exitCount = 0;
  for (const GCOVArc *arc : exitBlock.pred)
    exitCount += arc->count;
  for (const GCOVBlock &b : f.blocksRange())
    if (b.number != 0 && &b != &exitBlock && b.getCount())
      ++blocksExec;

  os << "function " << f.getName(options.Demangle) << " called " << entryCount
     << " returned " << formatPercentage(exitCount, entryCount)
     << "% blocks executed "
     << formatPercentage(blocksExec, f.blocks.size() - 2) << "%\n";
}

/// printBranchInfo - Print conditional branch probabilities.
void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
                              raw_ostream &os) const {
  uint64_t total = 0;
  for (const GCOVArc *arc : Block.dsts())
    total += arc->count;
  for (const GCOVArc *arc : Block.dsts())
    os << format("branch %2u ", edgeIdx++)
       << formatBranchInfo(options, arc->count, total) << '\n';
}

void Context::printSummary(const Summary &summary, raw_ostream &os) const {
  os << format("Lines executed:%.2f%% of %" PRIu64 "\n",
               double(summary.linesExec) * 100 / summary.lines, summary.lines);
  if (options.BranchInfo) {
    if (summary.branches == 0) {
      os << "No branches\n";
    } else {
      os << format("Branches executed:%.2f%% of %" PRIu64 "\n",
                   double(summary.branchesExec) * 100 / summary.branches,
                   summary.branches);
      os << format("Taken at least once:%.2f%% of %" PRIu64 "\n",
                   double(summary.branchesTaken) * 100 / summary.branches,
                   summary.branches);
    }
    os << "No calls\n";
  }
}

void llvm::gcovOneInput(const GCOV::Options &options, StringRef filename,
                        StringRef gcno, StringRef gcda, GCOVFile &file) {
  Context fi(options);
  fi.print(filename, gcno, gcda, file);
}
