//===- 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 = nullptr;
  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

uint64_t
GCOVBlock::augmentOneCycle(GCOVBlock *src,
                           std::vector<std::pair<GCOVBlock *, size_t>> &stack) {
  GCOVBlock *u;
  size_t i;
  stack.clear();
  stack.emplace_back(src, 0);
  src->incoming = (GCOVArc *)1; // Mark u available for cycle detection
  for (;;) {
    std::tie(u, i) = stack.back();
    if (i == u->succ.size()) {
      u->traversable = false;
      stack.pop_back();
      if (stack.empty())
        break;
      continue;
    }
    ++stack.back().second;
    GCOVArc *succ = u->succ[i];
    // Ignore saturated arcs (cycleCount has been reduced to 0) and visited
    // blocks. Ignore self arcs to guard against bad input (.gcno has no
    // self arcs).
    if (succ->cycleCount == 0 || !succ->dst.traversable || &succ->dst == u)
      continue;
    if (succ->dst.incoming == nullptr) {
      succ->dst.incoming = succ;
      stack.emplace_back(&succ->dst, 0);
      continue;
    }
    uint64_t minCount = succ->cycleCount;
    for (GCOVBlock *v = u;;) {
      minCount = std::min(minCount, v->incoming->cycleCount);
      v = &v->incoming->src;
      if (v == &succ->dst)
        break;
    }
    succ->cycleCount -= minCount;
    for (GCOVBlock *v = u;;) {
      v->incoming->cycleCount -= minCount;
      v = &v->incoming->src;
      if (v == &succ->dst)
        break;
    }
    return minCount;
  }
  return 0;
}

// Get the total execution count of loops among blocks on the same line.
// Assuming a reducible flow graph, the count is the sum of back edge counts.
// Identifying loops is complex, so we simply find cycles and perform cycle
// cancelling iteratively.
uint64_t GCOVBlock::getCyclesCount(const BlockVector &blocks) {
  std::vector<std::pair<GCOVBlock *, size_t>> stack;
  uint64_t count = 0, d;
  for (;;) {
    // Make blocks on the line traversable and try finding a cycle.
    for (auto b : blocks) {
      const_cast<GCOVBlock *>(b)->traversable = true;
      const_cast<GCOVBlock *>(b)->incoming = nullptr;
    }
    d = 0;
    for (auto block : blocks) {
      auto *b = const_cast<GCOVBlock *>(block);
      if (b->traversable && (d = augmentOneCycle(b, stack)) > 0)
        break;
    }
    if (d == 0)
      break;
    count += d;
  }
  // If there is no more loop, all traversable bits should have been cleared.
  // This property is needed by subsequent calls.
  for (auto b : blocks) {
    assert(!b->traversable);
    (void)b;
  }
  return 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;
  }

  count += GCOVBlock::getCyclesCount(line.blocks);
  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);
}
