/* Gcov.c: prepend line execution counts and branch probabilities to a
   source file.
   Copyright (C) 1990-2021 Free Software Foundation, Inc.
   Contributed by James E. Wilson of Cygnus Support.
   Mangled by Bob Manson of Cygnus Support.
   Mangled further by Nathan Sidwell <nathan@codesourcery.com>

Gcov is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

Gcov is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Gcov; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* ??? Print a list of the ten blocks with the highest execution counts,
   and list the line numbers corresponding to those blocks.  Also, perhaps
   list the line numbers with the highest execution counts, only printing
   the first if there are several which are all listed in the same block.  */

/* ??? Should have an option to print the number of basic blocks, and the
   percent of them that are covered.  */

/* Need an option to show individual block counts, and show
   probabilities of fall through arcs.  */

#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_VECTOR
#define INCLUDE_STRING
#define INCLUDE_MAP
#define INCLUDE_SET
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "intl.h"
#include "diagnostic.h"
#include "version.h"
#include "demangle.h"
#include "color-macros.h"
#include "pretty-print.h"
#include "json.h"

#include <zlib.h>
#include <getopt.h>

#include "md5.h"

using namespace std;

#define IN_GCOV 1
#include "gcov-io.h"
#include "gcov-io.c"

/* The gcno file is generated by -ftest-coverage option. The gcda file is
   generated by a program compiled with -fprofile-arcs. Their formats
   are documented in gcov-io.h.  */

/* The functions in this file for creating and solution program flow graphs
   are very similar to functions in the gcc source file profile.c.  In
   some places we make use of the knowledge of how profile.c works to
   select particular algorithms here.  */

/* The code validates that the profile information read in corresponds
   to the code currently being compiled.  Rather than checking for
   identical files, the code below compares a checksum on the CFG
   (based on the order of basic blocks and the arcs in the CFG).  If
   the CFG checksum in the gcda file match the CFG checksum in the
   gcno file, the profile data will be used.  */

/* This is the size of the buffer used to read in source file lines.  */

class function_info;
class block_info;
class source_info;

/* Describes an arc between two basic blocks.  */

struct arc_info
{
  /* source and destination blocks.  */
  class block_info *src;
  class block_info *dst;

  /* transition counts.  */
  gcov_type count;
  /* used in cycle search, so that we do not clobber original counts.  */
  gcov_type cs_count;

  unsigned int count_valid : 1;
  unsigned int on_tree : 1;
  unsigned int fake : 1;
  unsigned int fall_through : 1;

  /* Arc to a catch handler.  */
  unsigned int is_throw : 1;

  /* Arc is for a function that abnormally returns.  */
  unsigned int is_call_non_return : 1;

  /* Arc is for catch/setjmp.  */
  unsigned int is_nonlocal_return : 1;

  /* Is an unconditional branch.  */
  unsigned int is_unconditional : 1;

  /* Loop making arc.  */
  unsigned int cycle : 1;

  /* Links to next arc on src and dst lists.  */
  struct arc_info *succ_next;
  struct arc_info *pred_next;
};

/* Describes which locations (lines and files) are associated with
   a basic block.  */

class block_location_info
{
public:
  block_location_info (unsigned _source_file_idx):
    source_file_idx (_source_file_idx)
  {}

  unsigned source_file_idx;
  vector<unsigned> lines;
};

/* Describes a basic block. Contains lists of arcs to successor and
   predecessor blocks.  */

class block_info
{
public:
  /* Constructor.  */
  block_info ();

  /* Chain of exit and entry arcs.  */
  arc_info *succ;
  arc_info *pred;

  /* Number of unprocessed exit and entry arcs.  */
  gcov_type num_succ;
  gcov_type num_pred;

  unsigned id;

  /* Block execution count.  */
  gcov_type count;
  unsigned count_valid : 1;
  unsigned valid_chain : 1;
  unsigned invalid_chain : 1;
  unsigned exceptional : 1;

  /* Block is a call instrumenting site.  */
  unsigned is_call_site : 1; /* Does the call.  */
  unsigned is_call_return : 1; /* Is the return.  */

  /* Block is a landing pad for longjmp or throw.  */
  unsigned is_nonlocal_return : 1;

  vector<block_location_info> locations;

  struct
  {
    /* Single line graph cycle workspace.  Used for all-blocks
       mode.  */
    arc_info *arc;
    unsigned ident;
  } cycle; /* Used in all-blocks mode, after blocks are linked onto
	     lines.  */

  /* Temporary chain for solving graph, and for chaining blocks on one
     line.  */
  class block_info *chain;

};

block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0),
  id (0), count (0), count_valid (0), valid_chain (0), invalid_chain (0),
  exceptional (0), is_call_site (0), is_call_return (0), is_nonlocal_return (0),
  locations (), chain (NULL)
{
  cycle.arc = NULL;
}

/* Describes a single line of source.  Contains a chain of basic blocks
   with code on it.  */

class line_info
{
public:
  /* Default constructor.  */
  line_info ();

  /* Return true when NEEDLE is one of basic blocks the line belongs to.  */
  bool has_block (block_info *needle);

  /* Execution count.  */
  gcov_type count;

  /* Branches from blocks that end on this line.  */
  vector<arc_info *> branches;

  /* blocks which start on this line.  Used in all-blocks mode.  */
  vector<block_info *> blocks;

  unsigned exists : 1;
  unsigned unexceptional : 1;
  unsigned has_unexecuted_block : 1;
};

line_info::line_info (): count (0), branches (), blocks (), exists (false),
  unexceptional (0), has_unexecuted_block (0)
{
}

bool
line_info::has_block (block_info *needle)
{
  return std::find (blocks.begin (), blocks.end (), needle) != blocks.end ();
}

/* Output demangled function names.  */

static int flag_demangled_names = 0;

/* Describes a single function. Contains an array of basic blocks.  */

class function_info
{
public:
  function_info ();
  ~function_info ();

  /* Return true when line N belongs to the function in source file SRC_IDX.
     The line must be defined in body of the function, can't be inlined.  */
  bool group_line_p (unsigned n, unsigned src_idx);

  /* Function filter based on function_info::artificial variable.  */

  static inline bool
  is_artificial (function_info *fn)
  {
    return fn->artificial;
  }

  /* Name of function.  */
  char *m_name;
  char *m_demangled_name;
  unsigned ident;
  unsigned lineno_checksum;
  unsigned cfg_checksum;

  /* The graph contains at least one fake incoming edge.  */
  unsigned has_catch : 1;

  /* True when the function is artificial and does not exist
     in a source file.  */
  unsigned artificial : 1;

  /* True when multiple functions start at a line in a source file.  */
  unsigned is_group : 1;

  /* Array of basic blocks.  Like in GCC, the entry block is
     at blocks[0] and the exit block is at blocks[1].  */
#define ENTRY_BLOCK (0)
#define EXIT_BLOCK (1)
  vector<block_info> blocks;
  unsigned blocks_executed;

  /* Raw arc coverage counts.  */
  vector<gcov_type> counts;

  /* First line number.  */
  unsigned start_line;

  /* First line column.  */
  unsigned start_column;

  /* Last line number.  */
  unsigned end_line;

  /* Last line column.  */
  unsigned end_column;

  /* Index of source file where the function is defined.  */
  unsigned src;

  /* Vector of line information (used only for group functions).  */
  vector<line_info> lines;

  /* Next function.  */
  class function_info *next;

  /*  Get demangled name of a function.  The demangled name
      is converted when it is used for the first time.  */
  char *get_demangled_name ()
  {
    if (m_demangled_name == NULL)
      {
	m_demangled_name = cplus_demangle (m_name, DMGL_PARAMS);
	if (!m_demangled_name)
	  m_demangled_name = m_name;
      }

    return m_demangled_name;
  }

  /* Get name of the function based on flag_demangled_names.  */
  char *get_name ()
  {
    return flag_demangled_names ? get_demangled_name () : m_name;
  }

  /* Return number of basic blocks (without entry and exit block).  */
  unsigned get_block_count ()
  {
    return blocks.size () - 2;
  }
};

/* Function info comparer that will sort functions according to starting
   line.  */

struct function_line_start_cmp
{
  inline bool operator() (const function_info *lhs,
			  const function_info *rhs)
    {
      return (lhs->start_line == rhs->start_line
	      ? lhs->start_column < rhs->start_column
	      : lhs->start_line < rhs->start_line);
    }
};

/* Describes coverage of a file or function.  */

struct coverage_info
{
  int lines;
  int lines_executed;

  int branches;
  int branches_executed;
  int branches_taken;

  int calls;
  int calls_executed;

  char *name;
};

/* Describes a file mentioned in the block graph.  Contains an array
   of line info.  */

class source_info
{
public:
  /* Default constructor.  */
  source_info ();

  vector<function_info *> *get_functions_at_location (unsigned line_num) const;

  /* Register a new function.  */
  void add_function (function_info *fn);

  /* Debug the source file.  */
  void debug ();

  /* Index of the source_info in sources vector.  */
  unsigned index;

  /* Canonical name of source file.  */
  char *name;
  time_t file_time;

  /* Vector of line information.  */
  vector<line_info> lines;

  coverage_info coverage;

  /* Maximum line count in the source file.  */
  unsigned int maximum_count;

  /* Functions in this source file.  These are in ascending line
     number order.  */
  vector<function_info *> functions;

  /* Line number to functions map.  */
  vector<vector<function_info *> *> line_to_function_map;
};

source_info::source_info (): index (0), name (NULL), file_time (),
  lines (), coverage (), maximum_count (0), functions ()
{
}

/* Register a new function.  */
void
source_info::add_function (function_info *fn)
{
  functions.push_back (fn);

  if (fn->start_line >= line_to_function_map.size ())
    line_to_function_map.resize (fn->start_line + 1);

  vector<function_info *> **slot = &line_to_function_map[fn->start_line];
  if (*slot == NULL)
    *slot = new vector<function_info *> ();

  (*slot)->push_back (fn);
}

vector<function_info *> *
source_info::get_functions_at_location (unsigned line_num) const
{
  if (line_num >= line_to_function_map.size ())
    return NULL;

  vector<function_info *> *slot = line_to_function_map[line_num];
  if (slot != NULL)
    std::sort (slot->begin (), slot->end (), function_line_start_cmp ());

  return slot;
}

void source_info::debug ()
{
  fprintf (stderr, "source_info: %s\n", name);
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      fprintf (stderr, "  function_info: %s\n", fn->get_name ());
      for (vector<block_info>::iterator bit = fn->blocks.begin ();
	   bit != fn->blocks.end (); bit++)
	{
	  fprintf (stderr, "    block_info id=%d, count=%" PRId64 " \n",
		   bit->id, bit->count);
	}
    }

  for (unsigned lineno = 1; lineno < lines.size (); ++lineno)
    {
      line_info &line = lines[lineno];
      fprintf (stderr, "  line_info=%d, count=%" PRId64 "\n", lineno, line.count);
    }

  fprintf (stderr, "\n");
}

class name_map
{
public:
  name_map ()
  {
  }

  name_map (char *_name, unsigned _src): name (_name), src (_src)
  {
  }

  bool operator== (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) == 0;
#else
    return strcmp (this->name, rhs.name) == 0;
#endif
  }

  bool operator< (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) < 0;
#else
    return strcmp (this->name, rhs.name) < 0;
#endif
  }

  const char *name;  /* Source file name */
  unsigned src;  /* Source file */
};

/* Vector of all functions.  */
static vector<function_info *> functions;

/* Function ident to function_info * map.  */
static map<unsigned, function_info *> ident_to_fn;

/* Vector of source files.  */
static vector<source_info> sources;

/* Mapping of file names to sources */
static vector<name_map> names;

/* Record all processed files in order to warn about
   a file being read multiple times.  */
static vector<char *> processed_files;

/* This holds data summary information.  */

static unsigned object_runs;

static unsigned total_lines;
static unsigned total_executed;

/* Modification time of graph file.  */

static time_t bbg_file_time;

/* Name of the notes (gcno) output file.  The "bbg" prefix is for
   historical reasons, when the notes file contained only the
   basic block graph notes.  */

static char *bbg_file_name;

/* Stamp of the bbg file */
static unsigned bbg_stamp;

/* Supports has_unexecuted_blocks functionality.  */
static unsigned bbg_supports_has_unexecuted_blocks;

/* Working directory in which a TU was compiled.  */
static const char *bbg_cwd;

/* Name and file pointer of the input file for the count data (gcda).  */

static char *da_file_name;

/* Data file is missing.  */

static int no_data_file;

/* If there is several input files, compute and display results after
   reading all data files.  This way if two or more gcda file refer to
   the same source file (eg inline subprograms in a .h file), the
   counts are added.  */

static int multiple_files = 0;

/* Output branch probabilities.  */

static int flag_branches = 0;

/* Show unconditional branches too.  */
static int flag_unconditional = 0;

/* Output a gcov file if this is true.  This is on by default, and can
   be turned off by the -n option.  */

static int flag_gcov_file = 1;

/* Output to stdout instead to a gcov file.  */

static int flag_use_stdout = 0;

/* Output progress indication if this is true.  This is off by default
   and can be turned on by the -d option.  */

static int flag_display_progress = 0;

/* Output *.gcov file in JSON intermediate format used by consumers.  */

static int flag_json_format = 0;

/* For included files, make the gcov output file name include the name
   of the input source file.  For example, if x.h is included in a.c,
   then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */

static int flag_long_names = 0;

/* For situations when a long name can potentially hit filesystem path limit,
   let's calculate md5sum of the path and append it to a file name.  */

static int flag_hash_filenames = 0;

/* Print verbose informations.  */

static int flag_verbose = 0;

/* Print colored output.  */

static int flag_use_colors = 0;

/* Use perf-like colors to indicate hot lines.  */

static int flag_use_hotness_colors = 0;

/* Output count information for every basic block, not merely those
   that contain line number information.  */

static int flag_all_blocks = 0;

/* Output human readable numbers.  */

static int flag_human_readable_numbers = 0;

/* Output summary info for each function.  */

static int flag_function_summary = 0;

/* Print debugging dumps.  */

static int flag_debug = 0;

/* Object directory file prefix.  This is the directory/file where the
   graph and data files are looked for, if nonzero.  */

static char *object_directory = 0;

/* Source directory prefix.  This is removed from source pathnames
   that match, when generating the output file name.  */

static char *source_prefix = 0;
static size_t source_length = 0;

/* Only show data for sources with relative pathnames.  Absolute ones
   usually indicate a system header file, which although it may
   contain inline functions, is usually uninteresting.  */
static int flag_relative_only = 0;

/* Preserve all pathname components. Needed when object files and
   source files are in subdirectories. '/' is mangled as '#', '.' is
   elided and '..' mangled to '^'.  */

static int flag_preserve_paths = 0;

/* Output the number of times a branch was taken as opposed to the percentage
   of times it was taken.  */

static int flag_counts = 0;

/* Forward declarations.  */
static int process_args (int, char **);
static void print_usage (int) ATTRIBUTE_NORETURN;
static void print_version (void) ATTRIBUTE_NORETURN;
static void process_file (const char *);
static void process_all_functions (void);
static void generate_results (const char *);
static void create_file_names (const char *);
static char *canonicalize_name (const char *);
static unsigned find_source (const char *);
static void read_graph_file (void);
static int read_count_file (void);
static void solve_flow_graph (function_info *);
static void find_exception_blocks (function_info *);
static void add_branch_counts (coverage_info *, const arc_info *);
static void add_line_counts (coverage_info *, function_info *);
static void executed_summary (unsigned, unsigned);
static void function_summary (const coverage_info *);
static void file_summary (const coverage_info *);
static const char *format_gcov (gcov_type, gcov_type, int);
static void accumulate_line_counts (source_info *);
static void output_gcov_file (const char *, source_info *);
static int output_branch_count (FILE *, int, const arc_info *);
static void output_lines (FILE *, const source_info *);
static string make_gcov_file_name (const char *, const char *);
static char *mangle_name (const char *);
static void release_structures (void);
extern int main (int, char **);

function_info::function_info (): m_name (NULL), m_demangled_name (NULL),
  ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0),
  artificial (0), is_group (0),
  blocks (), blocks_executed (0), counts (),
  start_line (0), start_column (0), end_line (0), end_column (0),
  src (0), lines (), next (NULL)
{
}

function_info::~function_info ()
{
  for (int i = blocks.size () - 1; i >= 0; i--)
    {
      arc_info *arc, *arc_n;

      for (arc = blocks[i].succ; arc; arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  free (arc);
	}
    }
  if (m_demangled_name != m_name)
    free (m_demangled_name);
  free (m_name);
}

bool function_info::group_line_p (unsigned n, unsigned src_idx)
{
  return is_group && src == src_idx && start_line <= n && n <= end_line;
}

/* Cycle detection!
   There are a bajillion algorithms that do this.  Boost's function is named
   hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in
   "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
   (url at <http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf>).

   The basic algorithm is simple: effectively, we're finding all simple paths
   in a subgraph (that shrinks every iteration).  Duplicates are filtered by
   "blocking" a path when a node is added to the path (this also prevents non-
   simple paths)--the node is unblocked only when it participates in a cycle.
   */

typedef vector<arc_info *> arc_vector_t;
typedef vector<const block_info *> block_vector_t;

/* Handle cycle identified by EDGES, where the function finds minimum cs_count
   and subtract the value from all counts.  The subtracted value is added
   to COUNT.  Returns type of loop.  */

static void
handle_cycle (const arc_vector_t &edges, int64_t &count)
{
  /* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
     that amount.  */
  int64_t cycle_count = INTTYPE_MAXIMUM (int64_t);
  for (unsigned i = 0; i < edges.size (); i++)
    {
      int64_t ecount = edges[i]->cs_count;
      if (cycle_count > ecount)
	cycle_count = ecount;
    }
  count += cycle_count;
  for (unsigned i = 0; i < edges.size (); i++)
    edges[i]->cs_count -= cycle_count;

  gcc_assert (cycle_count > 0);
}

/* Unblock a block U from BLOCKED.  Apart from that, iterate all blocks
   blocked by U in BLOCK_LISTS.  */

static void
unblock (const block_info *u, block_vector_t &blocked,
	 vector<block_vector_t > &block_lists)
{
  block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
  if (it == blocked.end ())
    return;

  unsigned index = it - blocked.begin ();
  blocked.erase (it);

  block_vector_t to_unblock (block_lists[index]);

  block_lists.erase (block_lists.begin () + index);

  for (block_vector_t::iterator it = to_unblock.begin ();
       it != to_unblock.end (); it++)
    unblock (*it, blocked, block_lists);
}

/* Return true when PATH contains a zero cycle arc count.  */

static bool
path_contains_zero_or_negative_cycle_arc (arc_vector_t &path)
{
  for (unsigned i = 0; i < path.size (); i++)
    if (path[i]->cs_count <= 0)
      return true;
  return false;
}

/* Find circuit going to block V, PATH is provisional seen cycle.
   BLOCKED is vector of blocked vertices, BLOCK_LISTS contains vertices
   blocked by a block.  COUNT is accumulated count of the current LINE.
   Returns what type of loop it contains.  */

static bool
circuit (block_info *v, arc_vector_t &path, block_info *start,
	 block_vector_t &blocked, vector<block_vector_t> &block_lists,
	 line_info &linfo, int64_t &count)
{
  bool loop_found = false;

  /* Add v to the block list.  */
  gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
  blocked.push_back (v);
  block_lists.push_back (block_vector_t ());

  for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
    {
      block_info *w = arc->dst;
      if (w < start
	  || arc->cs_count <= 0
	  || !linfo.has_block (w))
	continue;

      path.push_back (arc);
      if (w == start)
	{
	  /* Cycle has been found.  */
	  handle_cycle (path, count);
	  loop_found = true;
	}
      else if (!path_contains_zero_or_negative_cycle_arc (path)
	       &&  find (blocked.begin (), blocked.end (), w) == blocked.end ())
	loop_found |= circuit (w, path, start, blocked, block_lists, linfo,
			       count);

      path.pop_back ();
    }

  if (loop_found)
    unblock (v, blocked, block_lists);
  else
    for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
      {
	block_info *w = arc->dst;
	if (w < start
	    || arc->cs_count <= 0
	    || !linfo.has_block (w))
	  continue;

	size_t index
	  = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
	gcc_assert (index < blocked.size ());
	block_vector_t &list = block_lists[index];
	if (find (list.begin (), list.end (), v) == list.end ())
	  list.push_back (v);
      }

  return loop_found;
}

/* Find cycles for a LINFO.  */

static gcov_type
get_cycles_count (line_info &linfo)
{
  /* Note that this algorithm works even if blocks aren't in sorted order.
     Each iteration of the circuit detection is completely independent
     (except for reducing counts, but that shouldn't matter anyways).
     Therefore, operating on a permuted order (i.e., non-sorted) only
     has the effect of permuting the output cycles.  */

  bool loop_found = false;
  gcov_type count = 0;
  for (vector<block_info *>::iterator it = linfo.blocks.begin ();
       it != linfo.blocks.end (); it++)
    {
      arc_vector_t path;
      block_vector_t blocked;
      vector<block_vector_t > block_lists;
      loop_found |= circuit (*it, path, *it, blocked, block_lists, linfo,
			     count);
    }

  return count;
}

int
main (int argc, char **argv)
{
  int argno;
  int first_arg;
  const char *p;

  p = argv[0] + strlen (argv[0]);
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
  progname = p;

  xmalloc_set_program_name (progname);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  diagnostic_initialize (global_dc, 0);

  /* Handle response files.  */
  expandargv (&argc, &argv);

  argno = process_args (argc, argv);
  if (optind == argc)
    print_usage (true);

  if (argc - argno > 1)
    multiple_files = 1;

  first_arg = argno;

  for (; argno != argc; argno++)
    {
      if (flag_display_progress)
	printf ("Processing file %d out of %d\n", argno - first_arg + 1,
		argc - first_arg);
      process_file (argv[argno]);

      if (flag_json_format || argno == argc - 1)
	{
	  process_all_functions ();
	  generate_results (argv[argno]);
	  release_structures ();
	}
    }

  if (!flag_use_stdout)
    executed_summary (total_lines, total_executed);

  return 0;
}

/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
   otherwise the output of --help.  */

static void
print_usage (int error_p)
{
  FILE *file = error_p ? stderr : stdout;
  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;

  fnotice (file, "Usage: gcov [OPTION...] SOURCE|OBJ...\n\n");
  fnotice (file, "Print code coverage information.\n\n");
  fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
  fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
                                    rather than percentages\n");
  fnotice (file, "  -d, --display-progress          Display progress information\n");
  fnotice (file, "  -D, --debug			    Display debugging dumps\n");
  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
  fnotice (file, "  -h, --help                      Print this help, then exit\n");
  fnotice (file, "  -j, --json-format               Output JSON intermediate format\n\
                                    into .gcov.json.gz file\n");
  fnotice (file, "  -H, --human-readable            Output human readable numbers\n");
  fnotice (file, "  -k, --use-colors                Emit colored output\n");
  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
                                    source files\n");
  fnotice (file, "  -m, --demangled-names           Output demangled function names\n");
  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
  fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
  fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
  fnotice (file, "  -q, --use-hotness-colors        Emit perf-like colored output for hot lines\n");
  fnotice (file, "  -r, --relative-only             Only show data for relative sources\n");
  fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
  fnotice (file, "  -t, --stdout                    Output to stdout instead of a file\n");
  fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
  fnotice (file, "  -v, --version                   Print version number, then exit\n");
  fnotice (file, "  -w, --verbose                   Print verbose informations\n");
  fnotice (file, "  -x, --hash-filenames            Hash long pathnames\n");
  fnotice (file, "\nObsolete options:\n");
  fnotice (file, "  -i, --json-format               Replaced with -j, --json-format\n");
  fnotice (file, "  -j, --human-readable            Replaced with -H, --human-readable\n");
  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
	   bug_report_url);
  exit (status);
}

/* Print version information and exit.  */

static void
print_version (void)
{
  fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
  fprintf (stdout, "Copyright %s 2021 Free Software Foundation, Inc.\n",
	   _("(C)"));
  fnotice (stdout,
	   _("This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
  exit (SUCCESS_EXIT_CODE);
}

static const struct option options[] =
{
  { "help",                 no_argument,       NULL, 'h' },
  { "version",              no_argument,       NULL, 'v' },
  { "verbose",              no_argument,       NULL, 'w' },
  { "all-blocks",           no_argument,       NULL, 'a' },
  { "branch-probabilities", no_argument,       NULL, 'b' },
  { "branch-counts",        no_argument,       NULL, 'c' },
  { "json-format",	    no_argument,       NULL, 'j' },
  { "human-readable",	    no_argument,       NULL, 'H' },
  { "no-output",            no_argument,       NULL, 'n' },
  { "long-file-names",      no_argument,       NULL, 'l' },
  { "function-summaries",   no_argument,       NULL, 'f' },
  { "demangled-names",      no_argument,       NULL, 'm' },
  { "preserve-paths",       no_argument,       NULL, 'p' },
  { "relative-only",        no_argument,       NULL, 'r' },
  { "object-directory",     required_argument, NULL, 'o' },
  { "object-file",          required_argument, NULL, 'o' },
  { "source-prefix",        required_argument, NULL, 's' },
  { "stdout",		    no_argument,       NULL, 't' },
  { "unconditional-branches", no_argument,     NULL, 'u' },
  { "display-progress",     no_argument,       NULL, 'd' },
  { "hash-filenames",	    no_argument,       NULL, 'x' },
  { "use-colors",	    no_argument,       NULL, 'k' },
  { "use-hotness-colors",   no_argument,       NULL, 'q' },
  { "debug",		    no_argument,       NULL, 'D' },
  { 0, 0, 0, 0 }
};

/* Process args, return index to first non-arg.  */

static int
process_args (int argc, char **argv)
{
  int opt;

  const char *opts = "abcdDfhHijklmno:pqrs:tuvwx";
  while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
    {
      switch (opt)
	{
	case 'a':
	  flag_all_blocks = 1;
	  break;
	case 'b':
	  flag_branches = 1;
	  break;
	case 'c':
	  flag_counts = 1;
	  break;
	case 'f':
	  flag_function_summary = 1;
	  break;
	case 'h':
	  print_usage (false);
	  /* print_usage will exit.  */
	case 'l':
	  flag_long_names = 1;
	  break;
	case 'H':
	  flag_human_readable_numbers = 1;
	  break;
	case 'k':
	  flag_use_colors = 1;
	  break;
	case 'q':
	  flag_use_hotness_colors = 1;
	  break;
	case 'm':
	  flag_demangled_names = 1;
	  break;
	case 'n':
	  flag_gcov_file = 0;
	  break;
	case 'o':
	  object_directory = optarg;
	  break;
	case 's':
	  source_prefix = optarg;
	  source_length = strlen (source_prefix);
	  break;
	case 'r':
	  flag_relative_only = 1;
	  break;
	case 'p':
	  flag_preserve_paths = 1;
	  break;
	case 'u':
	  flag_unconditional = 1;
	  break;
	case 'i':
	case 'j':
	  flag_json_format = 1;
	  flag_gcov_file = 1;
	  break;
	case 'd':
	  flag_display_progress = 1;
	  break;
	case 'x':
	  flag_hash_filenames = 1;
	  break;
	case 'w':
	  flag_verbose = 1;
	  break;
	case 't':
	  flag_use_stdout = 1;
	  break;
	case 'D':
	  flag_debug = 1;
	  break;
	case 'v':
	  print_version ();
	  /* print_version will exit.  */
	default:
	  print_usage (true);
	  /* print_usage will exit.  */
	}
    }

  return optind;
}

/* Output intermediate LINE sitting on LINE_NUM to JSON OBJECT.
   Add FUNCTION_NAME to the LINE.  */

static void
output_intermediate_json_line (json::array *object,
			       line_info *line, unsigned line_num,
			       const char *function_name)
{
  if (!line->exists)
    return;

  json::object *lineo = new json::object ();
  lineo->set ("line_number", new json::integer_number (line_num));
  if (function_name != NULL)
    lineo->set ("function_name", new json::string (function_name));
  lineo->set ("count", new json::integer_number (line->count));
  lineo->set ("unexecuted_block",
	      new json::literal (line->has_unexecuted_block));

  json::array *branches = new json::array ();
  lineo->set ("branches", branches);

  vector<arc_info *>::const_iterator it;
  if (flag_branches)
    for (it = line->branches.begin (); it != line->branches.end ();
	 it++)
      {
	if (!(*it)->is_unconditional && !(*it)->is_call_non_return)
	  {
	    json::object *branch = new json::object ();
	    branch->set ("count", new json::integer_number ((*it)->count));
	    branch->set ("throw", new json::literal ((*it)->is_throw));
	    branch->set ("fallthrough",
			 new json::literal ((*it)->fall_through));
	    branches->append (branch);
	  }
      }

  object->append (lineo);
}

/* Strip filename extension in STR.  */

static string
strip_extention (string str)
{
  string::size_type pos = str.rfind ('.');
  if (pos != string::npos)
    str = str.substr (0, pos);

  return str;
}

/* Calcualte md5sum for INPUT string and return it in hex string format.  */

static string
get_md5sum (const char *input)
{
  md5_ctx ctx;
  char md5sum[16];
  string str;

  md5_init_ctx (&ctx);
  md5_process_bytes (input, strlen (input), &ctx);
  md5_finish_ctx (&ctx, md5sum);

  for (unsigned i = 0; i < 16; i++)
    {
      char b[3];
      sprintf (b, "%02x", (unsigned char)md5sum[i]);
      str += b;
    }

  return str;
}

/* Get the name of the gcov file.  The return value must be free'd.

   It appends the '.gcov' extension to the *basename* of the file.
   The resulting file name will be in PWD.

   e.g.,
   input: foo.da,       output: foo.da.gcov
   input: a/b/foo.cc,   output: foo.cc.gcov  */

static string
get_gcov_intermediate_filename (const char *input_file_name)
{
  string base = basename (input_file_name);
  string str = strip_extention (base);

  if (flag_hash_filenames)
    {
      str += "##";
      str += get_md5sum (input_file_name);
    }
  else if (flag_preserve_paths && base != input_file_name)
    {
      str += "##";
      str += mangle_path (input_file_name);
      str = strip_extention (str);
    }

  str += ".gcov.json.gz";
  return str.c_str ();
}

/* Output the result in JSON intermediate format.
   Source info SRC is dumped into JSON_FILES which is JSON array.  */

static void
output_json_intermediate_file (json::array *json_files, source_info *src)
{
  json::object *root = new json::object ();
  json_files->append (root);

  root->set ("file", new json::string (src->name));

  json::array *functions = new json::array ();
  root->set ("functions", functions);

  std::sort (src->functions.begin (), src->functions.end (),
	     function_line_start_cmp ());
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      json::object *function = new json::object ();
      function->set ("name", new json::string ((*it)->m_name));
      function->set ("demangled_name",
		     new json::string ((*it)->get_demangled_name ()));
      function->set ("start_line",
		     new json::integer_number ((*it)->start_line));
      function->set ("start_column",
		     new json::integer_number ((*it)->start_column));
      function->set ("end_line", new json::integer_number ((*it)->end_line));
      function->set ("end_column",
		     new json::integer_number ((*it)->end_column));
      function->set ("blocks",
		     new json::integer_number ((*it)->get_block_count ()));
      function->set ("blocks_executed",
		     new json::integer_number ((*it)->blocks_executed));
      function->set ("execution_count",
		     new json::integer_number ((*it)->blocks[0].count));

      functions->append (function);
    }

  json::array *lineso = new json::array ();
  root->set ("lines", lineso);

  vector<function_info *> last_non_group_fns;

  for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++)
    {
      vector<function_info *> *fns = src->get_functions_at_location (line_num);

      if (fns != NULL)
	/* Print info for all group functions that begin on the line.  */
	for (vector<function_info *>::iterator it2 = fns->begin ();
	     it2 != fns->end (); it2++)
	  {
	    if (!(*it2)->is_group)
	      last_non_group_fns.push_back (*it2);

	    vector<line_info> &lines = (*it2)->lines;
	    /* The LINES array is allocated only for group functions.  */
	    for (unsigned i = 0; i < lines.size (); i++)
	      {
		line_info *line = &lines[i];
		output_intermediate_json_line (lineso, line, line_num + i,
					       (*it2)->m_name);
	      }
	  }

      /* Follow with lines associated with the source file.  */
      if (line_num < src->lines.size ())
	{
	  unsigned size = last_non_group_fns.size ();
	  function_info *last_fn = size > 0 ? last_non_group_fns[size - 1] : NULL;
	  const char *fname = last_fn ? last_fn->m_name : NULL;
	  output_intermediate_json_line (lineso, &src->lines[line_num], line_num,
					 fname);

	  /* Pop ending function from stack.  */
	  if (last_fn != NULL && last_fn->end_line == line_num)
	    last_non_group_fns.pop_back ();
	}
    }
}

/* Function start pair.  */
struct function_start
{
  unsigned source_file_idx;
  unsigned start_line;
};

/* Traits class for function start hash maps below.  */

struct function_start_pair_hash : typed_noop_remove <function_start>
{
  typedef function_start value_type;
  typedef function_start compare_type;

  static hashval_t
  hash (const function_start &ref)
  {
    inchash::hash hstate (0);
    hstate.add_int (ref.source_file_idx);
    hstate.add_int (ref.start_line);
    return hstate.end ();
  }

  static bool
  equal (const function_start &ref1, const function_start &ref2)
  {
    return (ref1.source_file_idx == ref2.source_file_idx
	    && ref1.start_line == ref2.start_line);
  }

  static void
  mark_deleted (function_start &ref)
  {
    ref.start_line = ~1U;
  }

  static const bool empty_zero_p = false;

  static void
  mark_empty (function_start &ref)
  {
    ref.start_line = ~2U;
  }

  static bool
  is_deleted (const function_start &ref)
  {
    return ref.start_line == ~1U;
  }

  static bool
  is_empty (const function_start &ref)
  {
    return ref.start_line == ~2U;
  }
};

/* Process a single input file.  */

static void
process_file (const char *file_name)
{
  create_file_names (file_name);

  for (unsigned i = 0; i < processed_files.size (); i++)
    if (strcmp (da_file_name, processed_files[i]) == 0)
      {
	fnotice (stderr, "'%s' file is already processed\n",
		 file_name);
	return;
      }

  processed_files.push_back (xstrdup (da_file_name));

  read_graph_file ();
  read_count_file ();
}

/* Process all functions in all files.  */

static void
process_all_functions (void)
{
  hash_map<function_start_pair_hash, function_info *> fn_map;

  /* Identify group functions.  */
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    if (!(*it)->artificial)
      {
	function_start needle;
	needle.source_file_idx = (*it)->src;
	needle.start_line = (*it)->start_line;

	function_info **slot = fn_map.get (needle);
	if (slot)
	  {
	    (*slot)->is_group = 1;
	    (*it)->is_group = 1;
	  }
	else
	  fn_map.put (needle, *it);
      }

  /* Remove all artificial function.  */
  functions.erase (remove_if (functions.begin (), functions.end (),
			      function_info::is_artificial), functions.end ());

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      unsigned src = fn->src;

      if (!fn->counts.empty () || no_data_file)
	{
	  source_info *s = &sources[src];
	  s->add_function (fn);

	  /* Mark last line in files touched by function.  */
	  for (unsigned block_no = 0; block_no != fn->blocks.size ();
	       block_no++)
	    {
	      block_info *block = &fn->blocks[block_no];
	      for (unsigned i = 0; i < block->locations.size (); i++)
		{
		  /* Sort lines of locations.  */
		  sort (block->locations[i].lines.begin (),
			block->locations[i].lines.end ());

		  if (!block->locations[i].lines.empty ())
		    {
		      s = &sources[block->locations[i].source_file_idx];
		      unsigned last_line
			= block->locations[i].lines.back ();

		      /* Record new lines for the function.  */
		      if (last_line >= s->lines.size ())
			{
			  s = &sources[block->locations[i].source_file_idx];
			  unsigned last_line
			    = block->locations[i].lines.back ();

			  /* Record new lines for the function.  */
			  if (last_line >= s->lines.size ())
			    {
			      /* Record new lines for a source file.  */
			      s->lines.resize (last_line + 1);
			    }
			}
		    }
		}
	    }

	  /* Allocate lines for group function, following start_line
	     and end_line information of the function.  */
	  if (fn->is_group)
	    fn->lines.resize (fn->end_line - fn->start_line + 1);

	  solve_flow_graph (fn);
	  if (fn->has_catch)
	    find_exception_blocks (fn);
	}
      else
	{
	  /* The function was not in the executable -- some other
	     instance must have been selected.  */
	}
    }
}

static void
output_gcov_file (const char *file_name, source_info *src)
{
  string gcov_file_name_str
    = make_gcov_file_name (file_name, src->coverage.name);
  const char *gcov_file_name = gcov_file_name_str.c_str ();

  if (src->coverage.lines)
    {
      FILE *gcov_file = fopen (gcov_file_name, "w");
      if (gcov_file)
	{
	  fnotice (stdout, "Creating '%s'\n", gcov_file_name);
	  output_lines (gcov_file, src);
	  if (ferror (gcov_file))
	    fnotice (stderr, "Error writing output file '%s'\n",
		     gcov_file_name);
	  fclose (gcov_file);
	}
      else
	fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
    }
  else
    {
      unlink (gcov_file_name);
      fnotice (stdout, "Removing '%s'\n", gcov_file_name);
    }
}

static void
generate_results (const char *file_name)
{
  string gcov_intermediate_filename;

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      coverage_info coverage;

      memset (&coverage, 0, sizeof (coverage));
      coverage.name = fn->get_name ();
      add_line_counts (flag_function_summary ? &coverage : NULL, fn);
      if (flag_function_summary)
	{
	  function_summary (&coverage);
	  fnotice (stdout, "\n");
	}
    }

  name_map needle;
  needle.name = file_name;
  vector<name_map>::iterator it
    = std::find (names.begin (), names.end (), needle);
  if (it != names.end ())
    file_name = sources[it->src].coverage.name;
  else
    file_name = canonicalize_name (file_name);

  gcov_intermediate_filename = get_gcov_intermediate_filename (file_name);

  json::object *root = new json::object ();
  root->set ("format_version", new json::string ("1"));
  root->set ("gcc_version", new json::string (version_string));

  if (bbg_cwd != NULL)
    root->set ("current_working_directory", new json::string (bbg_cwd));
  root->set ("data_file", new json::string (file_name));

  json::array *json_files = new json::array ();
  root->set ("files", json_files);

  for (vector<source_info>::iterator it = sources.begin ();
       it != sources.end (); it++)
    {
      source_info *src = &(*it);
      if (flag_relative_only)
	{
	  /* Ignore this source, if it is an absolute path (after
	     source prefix removal).  */
	  char first = src->coverage.name[0];

#if HAVE_DOS_BASED_FILE_SYSTEM
	  if (first && src->coverage.name[1] == ':')
	    first = src->coverage.name[2];
#endif
	  if (IS_DIR_SEPARATOR (first))
	    continue;
	}

      accumulate_line_counts (src);
      if (flag_debug)
	src->debug ();

      if (!flag_use_stdout)
	file_summary (&src->coverage);
      total_lines += src->coverage.lines;
      total_executed += src->coverage.lines_executed;
      if (flag_gcov_file)
	{
	  if (flag_json_format)
	    {
	      output_json_intermediate_file (json_files, src);
	      if (!flag_use_stdout)
		fnotice (stdout, "\n");
	    }
	  else
	    {
	      if (flag_use_stdout)
		{
		  if (src->coverage.lines)
		    output_lines (stdout, src);
		}
	      else
		{
		  output_gcov_file (file_name, src);
		  fnotice (stdout, "\n");
		}
	    }
	}
    }

  if (flag_gcov_file && flag_json_format)
    {
      if (flag_use_stdout)
	{
	  root->dump (stdout);
	  printf ("\n");
	}
      else
	{
	  pretty_printer pp;
	  root->print (&pp);
	  pp_formatted_text (&pp);

	  fnotice (stdout, "Creating '%s'\n",
		   gcov_intermediate_filename.c_str ());
	  gzFile output = gzopen (gcov_intermediate_filename.c_str (), "w");
	  if (output == NULL)
	    {
	      fnotice (stderr, "Cannot open JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return;
	    }

	  if (gzputs (output, pp_formatted_text (&pp)) == EOF
	      || gzclose (output))
	    {
	      fnotice (stderr, "Error writing JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return;
	    }
	}
    }
}

/* Release all memory used.  */

static void
release_structures (void)
{
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    delete (*it);

  sources.resize (0);
  names.resize (0);
  functions.resize (0);
  ident_to_fn.clear ();
}

/* Generate the names of the graph and data files.  If OBJECT_DIRECTORY
   is not specified, these are named from FILE_NAME sans extension.  If
   OBJECT_DIRECTORY is specified and is a directory, the files are in that
   directory, but named from the basename of the FILE_NAME, sans extension.
   Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
   and the data files are named from that.  */

static void
create_file_names (const char *file_name)
{
  char *cptr;
  char *name;
  int length = strlen (file_name);
  int base;

  /* Free previous file names.  */
  free (bbg_file_name);
  free (da_file_name);
  da_file_name = bbg_file_name = NULL;
  bbg_file_time = 0;
  bbg_stamp = 0;

  if (object_directory && object_directory[0])
    {
      struct stat status;

      length += strlen (object_directory) + 2;
      name = XNEWVEC (char, length);
      name[0] = 0;

      base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
      strcat (name, object_directory);
      if (base && (!IS_DIR_SEPARATOR (name[strlen (name) - 1])))
	strcat (name, "/");
    }
  else
    {
      name = XNEWVEC (char, length + 1);
      strcpy (name, file_name);
      base = 0;
    }

  if (base)
    {
      /* Append source file name.  */
      const char *cptr = lbasename (file_name);
      strcat (name, cptr ? cptr : file_name);
    }

  /* Remove the extension.  */
  cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
  if (cptr)
    *cptr = 0;

  length = strlen (name);

  bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
  strcpy (bbg_file_name, name);
  strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);

  da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
  strcpy (da_file_name, name);
  strcpy (da_file_name + length, GCOV_DATA_SUFFIX);

  free (name);
  return;
}

/* Find or create a source file structure for FILE_NAME. Copies
   FILE_NAME on creation */

static unsigned
find_source (const char *file_name)
{
  char *canon;
  unsigned idx;
  struct stat status;

  if (!file_name)
    file_name = "<unknown>";

  name_map needle;
  needle.name = file_name;

  vector<name_map>::iterator it = std::find (names.begin (), names.end (),
					     needle);
  if (it != names.end ())
    {
      idx = it->src;
      goto check_date;
    }

  /* Not found, try the canonical name. */
  canon = canonicalize_name (file_name);
  needle.name = canon;
  it = std::find (names.begin (), names.end (), needle);
  if (it == names.end ())
    {
      /* Not found with canonical name, create a new source.  */
      source_info *src;

      idx = sources.size ();
      needle = name_map (canon, idx);
      names.push_back (needle);

      sources.push_back (source_info ());
      src = &sources.back ();
      src->name = canon;
      src->coverage.name = src->name;
      src->index = idx;
      if (source_length
#if HAVE_DOS_BASED_FILE_SYSTEM
	  /* You lose if separators don't match exactly in the
	     prefix.  */
	  && !strncasecmp (source_prefix, src->coverage.name, source_length)
#else
	  && !strncmp (source_prefix, src->coverage.name, source_length)
#endif
	  && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
	src->coverage.name += source_length + 1;
      if (!stat (src->name, &status))
	src->file_time = status.st_mtime;
    }
  else
    idx = it->src;

  needle.name = file_name;
  if (std::find (names.begin (), names.end (), needle) == names.end ())
    {
      /* Append the non-canonical name.  */
      names.push_back (name_map (xstrdup (file_name), idx));
    }

  /* Resort the name map.  */
  std::sort (names.begin (), names.end ());

 check_date:
  if (sources[idx].file_time > bbg_file_time)
    {
      static int info_emitted;

      fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
	       file_name, bbg_file_name);
      if (!info_emitted)
	{
	  fnotice (stderr,
		   "(the message is displayed only once per source file)\n");
	  info_emitted = 1;
	}
      sources[idx].file_time = 0;
    }

  return idx;
}

/* Read the notes file.  Save functions to FUNCTIONS global vector.  */

static void
read_graph_file (void)
{
  unsigned version;
  unsigned current_tag = 0;
  unsigned tag;

  if (!gcov_open (bbg_file_name, 1))
    {
      fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
      return;
    }
  bbg_file_time = gcov_time ();
  if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
    {
      fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
      gcov_close ();
      return;
    }

  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
	       bbg_file_name, v, e);
    }
  bbg_stamp = gcov_read_unsigned ();
  /* Read checksum.  */
  gcov_read_unsigned ();
  bbg_cwd = xstrdup (gcov_read_string ());
  bbg_supports_has_unexecuted_blocks = gcov_read_unsigned ();

  function_info *fn = NULL;
  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      gcov_position_t base = gcov_position ();

      if (tag == GCOV_TAG_FUNCTION)
	{
	  char *function_name;
	  unsigned ident;
	  unsigned lineno_checksum, cfg_checksum;

	  ident = gcov_read_unsigned ();
	  lineno_checksum = gcov_read_unsigned ();
	  cfg_checksum = gcov_read_unsigned ();
	  function_name = xstrdup (gcov_read_string ());
	  unsigned artificial = gcov_read_unsigned ();
	  unsigned src_idx = find_source (gcov_read_string ());
	  unsigned start_line = gcov_read_unsigned ();
	  unsigned start_column = gcov_read_unsigned ();
	  unsigned end_line = gcov_read_unsigned ();
	  unsigned end_column = gcov_read_unsigned ();

	  fn = new function_info ();
	  functions.push_back (fn);
	  ident_to_fn[ident] = fn;

	  fn->m_name = function_name;
	  fn->ident = ident;
	  fn->lineno_checksum = lineno_checksum;
	  fn->cfg_checksum = cfg_checksum;
	  fn->src = src_idx;
	  fn->start_line = start_line;
	  fn->start_column = start_column;
	  fn->end_line = end_line;
	  fn->end_column = end_column;
	  fn->artificial = artificial;

	  current_tag = tag;
	}
      else if (fn && tag == GCOV_TAG_BLOCKS)
	{
	  if (!fn->blocks.empty ())
	    fnotice (stderr, "%s:already seen blocks for '%s'\n",
		     bbg_file_name, fn->get_name ());
	  else
	    fn->blocks.resize (gcov_read_unsigned ());
	}
      else if (fn && tag == GCOV_TAG_ARCS)
	{
	  unsigned src = gcov_read_unsigned ();
	  fn->blocks[src].id = src;
	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
	  block_info *src_blk = &fn->blocks[src];
	  unsigned mark_catches = 0;
	  struct arc_info *arc;

	  if (src >= fn->blocks.size () || fn->blocks[src].succ)
	    goto corrupt;

	  while (num_dests--)
	    {
	      unsigned dest = gcov_read_unsigned ();
	      unsigned flags = gcov_read_unsigned ();

	      if (dest >= fn->blocks.size ())
		goto corrupt;
	      arc = XCNEW (arc_info);

	      arc->dst = &fn->blocks[dest];
	      /* Set id in order to find EXIT_BLOCK.  */
	      arc->dst->id = dest;
	      arc->src = src_blk;

	      arc->count = 0;
	      arc->count_valid = 0;
	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
	      arc->fake = !!(flags & GCOV_ARC_FAKE);
	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);

	      arc->succ_next = src_blk->succ;
	      src_blk->succ = arc;
	      src_blk->num_succ++;

	      arc->pred_next = fn->blocks[dest].pred;
	      fn->blocks[dest].pred = arc;
	      fn->blocks[dest].num_pred++;

	      if (arc->fake)
		{
		  if (src)
		    {
		      /* Exceptional exit from this function, the
			 source block must be a call.  */
		      fn->blocks[src].is_call_site = 1;
		      arc->is_call_non_return = 1;
		      mark_catches = 1;
		    }
		  else
		    {
		      /* Non-local return from a callee of this
			 function.  The destination block is a setjmp.  */
		      arc->is_nonlocal_return = 1;
		      fn->blocks[dest].is_nonlocal_return = 1;
		    }
		}

	      if (!arc->on_tree)
		fn->counts.push_back (0);
	    }

	  if (mark_catches)
	    {
	      /* We have a fake exit from this block.  The other
		 non-fall through exits must be to catch handlers.
		 Mark them as catch arcs.  */

	      for (arc = src_blk->succ; arc; arc = arc->succ_next)
		if (!arc->fake && !arc->fall_through)
		  {
		    arc->is_throw = 1;
		    fn->has_catch = 1;
		  }
	    }
	}
      else if (fn && tag == GCOV_TAG_LINES)
	{
	  unsigned blockno = gcov_read_unsigned ();
	  block_info *block = &fn->blocks[blockno];

	  if (blockno >= fn->blocks.size ())
	    goto corrupt;

	  while (true)
	    {
	      unsigned lineno = gcov_read_unsigned ();

	      if (lineno)
		block->locations.back ().lines.push_back (lineno);
	      else
		{
		  const char *file_name = gcov_read_string ();

		  if (!file_name)
		    break;
		  block->locations.push_back (block_location_info
					      (find_source (file_name)));
		}
	    }
	}
      else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
	{
	  fn = NULL;
	  current_tag = 0;
	}
      gcov_sync (base, length);
      if (gcov_is_error ())
	{
	corrupt:;
	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
	  break;
	}
    }
  gcov_close ();

  if (functions.empty ())
    fnotice (stderr, "%s:no functions found\n", bbg_file_name);
}

/* Reads profiles from the count file and attach to each
   function. Return nonzero if fatal error.  */

static int
read_count_file (void)
{
  unsigned ix;
  unsigned version;
  unsigned tag;
  function_info *fn = NULL;
  int error = 0;
  map<unsigned, function_info *>::iterator it;

  if (!gcov_open (da_file_name, 1))
    {
      fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
	       da_file_name);
      no_data_file = 1;
      return 0;
    }
  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
    {
      fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
    cleanup:;
      gcov_close ();
      return 1;
    }
  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
	       da_file_name, v, e);
    }
  tag = gcov_read_unsigned ();
  if (tag != bbg_stamp)
    {
      fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
      goto cleanup;
    }

  /* Read checksum.  */
  gcov_read_unsigned ();

  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      int read_length = (int)length;
      unsigned long base = gcov_position ();

      if (tag == GCOV_TAG_OBJECT_SUMMARY)
	{
	  struct gcov_summary summary;
	  gcov_read_summary (&summary);
	  object_runs = summary.runs;
	}
      else if (tag == GCOV_TAG_FUNCTION && !length)
	; /* placeholder  */
      else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
	{
	  unsigned ident;
	  ident = gcov_read_unsigned ();
	  fn = NULL;
	  it = ident_to_fn.find (ident);
	  if (it != ident_to_fn.end ())
	    fn = it->second;

	  if (!fn)
	    ;
	  else if (gcov_read_unsigned () != fn->lineno_checksum
		   || gcov_read_unsigned () != fn->cfg_checksum)
	    {
	    mismatch:;
	      fnotice (stderr, "%s:profile mismatch for '%s'\n",
		       da_file_name, fn->get_name ());
	      goto cleanup;
	    }
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
	{
	  length = abs (read_length);
	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ()))
	    goto mismatch;

	  if (read_length > 0)
	    for (ix = 0; ix != fn->counts.size (); ix++)
	      fn->counts[ix] += gcov_read_counter ();
	}
      if (read_length < 0)
	read_length = 0;
      gcov_sync (base, read_length);
      if ((error = gcov_is_error ()))
	{
	  fnotice (stderr,
		   error < 0
		   ? N_("%s:overflowed\n")
		   : N_("%s:corrupted\n"),
		   da_file_name);
	  goto cleanup;
	}
    }

  gcov_close ();
  return 0;
}

/* Solve the flow graph. Propagate counts from the instrumented arcs
   to the blocks and the uninstrumented arcs.  */

static void
solve_flow_graph (function_info *fn)
{
  unsigned ix;
  arc_info *arc;
  gcov_type *count_ptr = &fn->counts.front ();
  block_info *blk;
  block_info *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
  block_info *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */

  /* The arcs were built in reverse order.  Fix that now.  */
  for (ix = fn->blocks.size (); ix--;)
    {
      arc_info *arc_p, *arc_n;

      for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  arc->succ_next = arc_p;
	}
      fn->blocks[ix].succ = arc_p;

      for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->pred_next;
	  arc->pred_next = arc_p;
	}
      fn->blocks[ix].pred = arc_p;
    }

  if (fn->blocks.size () < 2)
    fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
	     bbg_file_name, fn->get_name ());
  else
    {
      if (fn->blocks[ENTRY_BLOCK].num_pred)
	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* We can't deduce the entry block counts from the lack of
	   predecessors.  */
	fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;

      if (fn->blocks[EXIT_BLOCK].num_succ)
	fnotice (stderr, "%s:'%s' has arcs from exit block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* Likewise, we can't deduce exit block counts from the lack
	   of its successors.  */
	fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
    }

  /* Propagate the measured counts, this must be done in the same
     order as the code in profile.c  */
  for (unsigned i = 0; i < fn->blocks.size (); i++)
    {
      blk = &fn->blocks[i];
      block_info const *prev_dst = NULL;
      int out_of_order = 0;
      int non_fake_succ = 0;

      for (arc = blk->succ; arc; arc = arc->succ_next)
	{
	  if (!arc->fake)
	    non_fake_succ++;

	  if (!arc->on_tree)
	    {
	      if (count_ptr)
		arc->count = *count_ptr++;
	      arc->count_valid = 1;
	      blk->num_succ--;
	      arc->dst->num_pred--;
	    }
	  if (prev_dst && prev_dst > arc->dst)
	    out_of_order = 1;
	  prev_dst = arc->dst;
	}
      if (non_fake_succ == 1)
	{
	  /* If there is only one non-fake exit, it is an
	     unconditional branch.  */
	  for (arc = blk->succ; arc; arc = arc->succ_next)
	    if (!arc->fake)
	      {
		arc->is_unconditional = 1;
		/* If this block is instrumenting a call, it might be
		   an artificial block. It is not artificial if it has
		   a non-fallthrough exit, or the destination of this
		   arc has more than one entry.  Mark the destination
		   block as a return site, if none of those conditions
		   hold.  */
		if (blk->is_call_site && arc->fall_through
		    && arc->dst->pred == arc && !arc->pred_next)
		  arc->dst->is_call_return = 1;
	      }
	}

      /* Sort the successor arcs into ascending dst order. profile.c
	 normally produces arcs in the right order, but sometimes with
	 one or two out of order.  We're not using a particularly
	 smart sort.  */
      if (out_of_order)
	{
	  arc_info *start = blk->succ;
	  unsigned changes = 1;

	  while (changes)
	    {
	      arc_info *arc, *arc_p, *arc_n;

	      changes = 0;
	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
		{
		  if (arc->dst > arc_n->dst)
		    {
		      changes = 1;
		      if (arc_p)
			arc_p->succ_next = arc_n;
		      else
			start = arc_n;
		      arc->succ_next = arc_n->succ_next;
		      arc_n->succ_next = arc;
		      arc_p = arc_n;
		    }
		  else
		    {
		      arc_p = arc;
		      arc = arc_n;
		    }
		}
	    }
	  blk->succ = start;
	}

      /* Place it on the invalid chain, it will be ignored if that's
	 wrong.  */
      blk->invalid_chain = 1;
      blk->chain = invalid_blocks;
      invalid_blocks = blk;
    }

  while (invalid_blocks || valid_blocks)
    {
      while ((blk = invalid_blocks))
	{
	  gcov_type total = 0;
	  const arc_info *arc;

	  invalid_blocks = blk->chain;
	  blk->invalid_chain = 0;
	  if (!blk->num_succ)
	    for (arc = blk->succ; arc; arc = arc->succ_next)
	      total += arc->count;
	  else if (!blk->num_pred)
	    for (arc = blk->pred; arc; arc = arc->pred_next)
	      total += arc->count;
	  else
	    continue;

	  blk->count = total;
	  blk->count_valid = 1;
	  blk->chain = valid_blocks;
	  blk->valid_chain = 1;
	  valid_blocks = blk;
	}
      while ((blk = valid_blocks))
	{
	  gcov_type total;
	  arc_info *arc, *inv_arc;

	  valid_blocks = blk->chain;
	  blk->valid_chain = 0;
	  if (blk->num_succ == 1)
	    {
	      block_info *dst;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->succ; arc; arc = arc->succ_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      dst = inv_arc->dst;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_succ--;
	      dst->num_pred--;
	      if (dst->count_valid)
		{
		  if (dst->num_pred == 1 && !dst->valid_chain)
		    {
		      dst->chain = valid_blocks;
		      dst->valid_chain = 1;
		      valid_blocks = dst;
		    }
		}
	      else
		{
		  if (!dst->num_pred && !dst->invalid_chain)
		    {
		      dst->chain = invalid_blocks;
		      dst->invalid_chain = 1;
		      invalid_blocks = dst;
		    }
		}
	    }
	  if (blk->num_pred == 1)
	    {
	      block_info *src;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->pred; arc; arc = arc->pred_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      src = inv_arc->src;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_pred--;
	      src->num_succ--;
	      if (src->count_valid)
		{
		  if (src->num_succ == 1 && !src->valid_chain)
		    {
		      src->chain = valid_blocks;
		      src->valid_chain = 1;
		      valid_blocks = src;
		    }
		}
	      else
		{
		  if (!src->num_succ && !src->invalid_chain)
		    {
		      src->chain = invalid_blocks;
		      src->invalid_chain = 1;
		      invalid_blocks = src;
		    }
		}
	    }
	}
    }

  /* If the graph has been correctly solved, every block will have a
     valid count.  */
  for (unsigned i = 0; ix < fn->blocks.size (); i++)
    if (!fn->blocks[i].count_valid)
      {
	fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
		 bbg_file_name, fn->get_name ());
	break;
      }
}

/* Mark all the blocks only reachable via an incoming catch.  */

static void
find_exception_blocks (function_info *fn)
{
  unsigned ix;
  block_info **queue = XALLOCAVEC (block_info *, fn->blocks.size ());

  /* First mark all blocks as exceptional.  */
  for (ix = fn->blocks.size (); ix--;)
    fn->blocks[ix].exceptional = 1;

  /* Now mark all the blocks reachable via non-fake edges */
  queue[0] = &fn->blocks[0];
  queue[0]->exceptional = 0;
  for (ix = 1; ix;)
    {
      block_info *block = queue[--ix];
      const arc_info *arc;

      for (arc = block->succ; arc; arc = arc->succ_next)
	if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
	  {
	    arc->dst->exceptional = 0;
	    queue[ix++] = arc->dst;
	  }
    }
}


/* Increment totals in COVERAGE according to arc ARC.  */

static void
add_branch_counts (coverage_info *coverage, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      coverage->calls++;
      if (arc->src->count)
	coverage->calls_executed++;
    }
  else if (!arc->is_unconditional)
    {
      coverage->branches++;
      if (arc->src->count)
	coverage->branches_executed++;
      if (arc->count)
	coverage->branches_taken++;
    }
}

/* Format COUNT, if flag_human_readable_numbers is set, return it human
   readable format.  */

static char const *
format_count (gcov_type count)
{
  static char buffer[64];
  const char *units = " kMGTPEZY";

  if (count < 1000 || !flag_human_readable_numbers)
    {
      sprintf (buffer, "%" PRId64, count);
      return buffer;
    }

  unsigned i;
  gcov_type divisor = 1;
  for (i = 0; units[i+1]; i++, divisor *= 1000)
    {
      if (count + divisor / 2 < 1000 * divisor)
	break;
    }
  float r = 1.0f * count / divisor;
  sprintf (buffer, "%.1f%c", r, units[i]);
  return buffer;
}

/* Format a GCOV_TYPE integer as either a percent ratio, or absolute
   count.  If DECIMAL_PLACES >= 0, format TOP/BOTTOM * 100 to DECIMAL_PLACES.
   If DECIMAL_PLACES is zero, no decimal point is printed. Only print 100% when
   TOP==BOTTOM and only print 0% when TOP=0.  If DECIMAL_PLACES < 0, then simply
   format TOP.  Return pointer to a static string.  */

static char const *
format_gcov (gcov_type top, gcov_type bottom, int decimal_places)
{
  static char buffer[20];

  if (decimal_places >= 0)
    {
      float ratio = bottom ? 100.0f * top / bottom: 0;

      /* Round up to 1% if there's a small non-zero value.  */
      if (ratio > 0.0f && ratio < 0.5f && decimal_places == 0)
	ratio = 1.0f;
      sprintf (buffer, "%.*f%%", decimal_places, ratio);
    }
  else
    return format_count (top);

  return buffer;
}

/* Summary of execution */

static void
executed_summary (unsigned lines, unsigned executed)
{
  if (lines)
    fnotice (stdout, "Lines executed:%s of %d\n",
	     format_gcov (executed, lines, 2), lines);
  else
    fnotice (stdout, "No executable lines\n");
}

/* Output summary info for a function.  */

static void
function_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "Function", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);
}

/* Output summary info for a file.  */

static void
file_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "File", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);

  if (flag_branches)
    {
      if (coverage->branches)
	{
	  fnotice (stdout, "Branches executed:%s of %d\n",
		   format_gcov (coverage->branches_executed,
				coverage->branches, 2),
		   coverage->branches);
	  fnotice (stdout, "Taken at least once:%s of %d\n",
		   format_gcov (coverage->branches_taken,
				coverage->branches, 2),
		   coverage->branches);
	}
      else
	fnotice (stdout, "No branches\n");
      if (coverage->calls)
	fnotice (stdout, "Calls executed:%s of %d\n",
		 format_gcov (coverage->calls_executed, coverage->calls, 2),
		 coverage->calls);
      else
	fnotice (stdout, "No calls\n");
    }
}

/* Canonicalize the filename NAME by canonicalizing directory
   separators, eliding . components and resolving .. components
   appropriately.  Always returns a unique string.  */

static char *
canonicalize_name (const char *name)
{
  /* The canonical name cannot be longer than the incoming name.  */
  char *result = XNEWVEC (char, strlen (name) + 1);
  const char *base = name, *probe;
  char *ptr = result;
  char *dd_base;
  int slash = 0;

#if HAVE_DOS_BASED_FILE_SYSTEM
  if (base[0] && base[1] == ':')
    {
      result[0] = base[0];
      result[1] = ':';
      base += 2;
      ptr += 2;
    }
#endif
  for (dd_base = ptr; *base; base = probe)
    {
      size_t len;

      for (probe = base; *probe; probe++)
	if (IS_DIR_SEPARATOR (*probe))
	  break;

      len = probe - base;
      if (len == 1 && base[0] == '.')
	/* Elide a '.' directory */
	;
      else if (len == 2 && base[0] == '.' && base[1] == '.')
	{
	  /* '..', we can only elide it and the previous directory, if
	     we're not a symlink.  */
	  struct stat ATTRIBUTE_UNUSED buf;

	  *ptr = 0;
	  if (dd_base == ptr
#if defined (S_ISLNK)
	      /* S_ISLNK is not POSIX.1-1996.  */
	      || stat (result, &buf) || S_ISLNK (buf.st_mode)
#endif
		)
	    {
	      /* Cannot elide, or unreadable or a symlink.  */
	      dd_base = ptr + 2 + slash;
	      goto regular;
	    }
	  while (ptr != dd_base && *ptr != '/')
	    ptr--;
	  slash = ptr != result;
	}
      else
	{
	regular:
	  /* Regular pathname component.  */
	  if (slash)
	    *ptr++ = '/';
	  memcpy (ptr, base, len);
	  ptr += len;
	  slash = 1;
	}

      for (; IS_DIR_SEPARATOR (*probe); probe++)
	continue;
    }
  *ptr = 0;

  return result;
}

/* Generate an output file name. INPUT_NAME is the canonicalized main
   input file and SRC_NAME is the canonicalized file name.
   LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
   long_output_names we prepend the processed name of the input file
   to each output name (except when the current source file is the
   input file, so you don't get a double concatenation). The two
   components are separated by '##'.  With preserve_paths we create a
   filename from all path components of the source file, replacing '/'
   with '#', and .. with '^', without it we simply take the basename
   component.  (Remember, the canonicalized name will already have
   elided '.' components and converted \\ separators.)  */

static string
make_gcov_file_name (const char *input_name, const char *src_name)
{
  string str;

  /* When hashing filenames, we shorten them by only using the filename
     component and appending a hash of the full (mangled) pathname.  */
  if (flag_hash_filenames)
    str = (string (mangle_name (src_name)) + "##"
	   + get_md5sum (src_name) + ".gcov");
  else
    {
      if (flag_long_names && input_name && strcmp (src_name, input_name) != 0)
	{
	  str += mangle_name (input_name);
	  str += "##";
	}

      str += mangle_name (src_name);
      str += ".gcov";
    }

  return str;
}

/* Mangle BASE name, copy it at the beginning of PTR buffer and
   return address of the \0 character of the buffer.  */

static char *
mangle_name (char const *base)
{
  /* Generate the source filename part.  */
  if (!flag_preserve_paths)
    return xstrdup (lbasename (base));
  else
    return mangle_path (base);
}

/* Scan through the bb_data for each line in the block, increment
   the line number execution count indicated by the execution count of
   the appropriate basic block.  */

static void
add_line_counts (coverage_info *coverage, function_info *fn)
{
  bool has_any_line = false;
  /* Scan each basic block.  */
  for (unsigned ix = 0; ix != fn->blocks.size (); ix++)
    {
      line_info *line = NULL;
      block_info *block = &fn->blocks[ix];
      if (block->count && ix && ix + 1 != fn->blocks.size ())
	fn->blocks_executed++;
      for (unsigned i = 0; i < block->locations.size (); i++)
	{
	  unsigned src_idx = block->locations[i].source_file_idx;
	  vector<unsigned> &lines = block->locations[i].lines;

	  block->cycle.arc = NULL;
	  block->cycle.ident = ~0U;

	  for (unsigned j = 0; j < lines.size (); j++)
	    {
	      unsigned ln = lines[j];

	      /* Line belongs to a function that is in a group.  */
	      if (fn->group_line_p (ln, src_idx))
		{
		  gcc_assert (lines[j] - fn->start_line < fn->lines.size ());
		  line = &(fn->lines[lines[j] - fn->start_line]);
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	      else
		{
		  gcc_assert (ln < sources[src_idx].lines.size ());
		  line = &(sources[src_idx].lines[ln]);
		  if (coverage)
		    {
		      if (!line->exists)
			coverage->lines++;
		      if (!line->count && block->count)
			coverage->lines_executed++;
		    }
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	    }

	  has_any_line = true;

	  if (!ix || ix + 1 == fn->blocks.size ())
	    /* Entry or exit block.  */;
	  else if (line != NULL)
	    {
	      line->blocks.push_back (block);

	      if (flag_branches)
		{
		  arc_info *arc;

		  for (arc = block->succ; arc; arc = arc->succ_next)
		    line->branches.push_back (arc);
		}
	    }
	}
    }

  if (!has_any_line)
    fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name,
	     fn->get_name ());
}

/* Accumulate info for LINE that belongs to SRC source file.  If ADD_COVERAGE
   is set to true, update source file summary.  */

static void accumulate_line_info (line_info *line, source_info *src,
				  bool add_coverage)
{
  if (add_coverage)
    for (vector<arc_info *>::iterator it = line->branches.begin ();
	 it != line->branches.end (); it++)
      add_branch_counts (&src->coverage, *it);

  if (!line->blocks.empty ())
    {
      /* The user expects the line count to be the number of times
	 a line has been executed.  Simply summing the block count
	 will give an artificially high number.  The Right Thing
	 is to sum the entry counts to the graph of blocks on this
	 line, then find the elementary cycles of the local graph
	 and add the transition counts of those cycles.  */
      gcov_type count = 0;

      /* Cycle detection.  */
      for (vector<block_info *>::iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  for (arc_info *arc = (*it)->pred; arc; arc = arc->pred_next)
	    if (!line->has_block (arc->src))
	      count += arc->count;
	  for (arc_info *arc = (*it)->succ; arc; arc = arc->succ_next)
	    arc->cs_count = arc->count;
	}

      /* Now, add the count of loops entirely on this line.  */
      count += get_cycles_count (*line);
      line->count = count;

      if (line->count > src->maximum_count)
	src->maximum_count = line->count;
    }

  if (line->exists && add_coverage)
    {
      src->coverage.lines++;
      if (line->count)
	src->coverage.lines_executed++;
    }
}

/* Accumulate the line counts of a file.  */

static void
accumulate_line_counts (source_info *src)
{
  /* First work on group functions.  */
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      function_info *fn = *it;

      if (fn->src != src->index || !fn->is_group)
	continue;

      for (vector<line_info>::iterator it2 = fn->lines.begin ();
	   it2 != fn->lines.end (); it2++)
	  {
	    line_info *line = &(*it2);
	    accumulate_line_info (line, src, false);
	  }
    }

  /* Work on global lines that line in source file SRC.  */
  for (vector<line_info>::iterator it = src->lines.begin ();
       it != src->lines.end (); it++)
    accumulate_line_info (&(*it), src, true);

  /* If not using intermediate mode, sum lines of group functions and
     add them to lines that live in a source file.  */
  if (!flag_json_format)
    for (vector<function_info *>::iterator it = src->functions.begin ();
	 it != src->functions.end (); it++)
      {
	function_info *fn = *it;

	if (fn->src != src->index || !fn->is_group)
	  continue;

	for (unsigned i = 0; i < fn->lines.size (); i++)
	  {
	    line_info *fn_line = &fn->lines[i];
	    if (fn_line->exists)
	      {
		unsigned ln = fn->start_line + i;
		line_info *src_line = &src->lines[ln];

		if (!src_line->exists)
		  src->coverage.lines++;
		if (!src_line->count && fn_line->count)
		  src->coverage.lines_executed++;

		src_line->count += fn_line->count;
		src_line->exists = 1;

		if (fn_line->has_unexecuted_block)
		  src_line->has_unexecuted_block = 1;

		if (fn_line->unexceptional)
		  src_line->unexceptional = 1;
	      }
	  }
      }
}

/* Output information about ARC number IX.  Returns nonzero if
   anything is output.  */

static int
output_branch_count (FILE *gcov_file, int ix, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      if (arc->src->count)
	{
	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
		   format_gcov (arc->src->count - arc->count,
				arc->src->count, -flag_counts));
	}
      else
	fnotice (gcov_file, "call   %2d never executed\n", ix);
    }
  else if (!arc->is_unconditional)
    {
      if (arc->src->count)
	fnotice (gcov_file, "branch %2d taken %s%s", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts),
		 arc->fall_through ? " (fallthrough)"
		 : arc->is_throw ? " (throw)" : "");
      else
	fnotice (gcov_file, "branch %2d never executed", ix);

      if (flag_verbose)
	fnotice (gcov_file, " (BB %d)", arc->dst->id);

      fnotice (gcov_file, "\n");
    }
  else if (flag_unconditional && !arc->dst->is_call_return)
    {
      if (arc->src->count)
	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts));
      else
	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
    }
  else
    return 0;
  return 1;
}

static const char *
read_line (FILE *file)
{
  static char *string;
  static size_t string_len;
  size_t pos = 0;
  char *ptr;

  if (!string_len)
    {
      string_len = 200;
      string = XNEWVEC (char, string_len);
    }

  while ((ptr = fgets (string + pos, string_len - pos, file)))
    {
      size_t len = strlen (string + pos);

      if (len && string[pos + len - 1] == '\n')
	{
	  string[pos + len - 1] = 0;
	  return string;
	}
      pos += len;
      /* If the file contains NUL characters or an incomplete
	 last line, which can happen more than once in one run,
	 we have to avoid doubling the STRING_LEN unnecessarily.  */
      if (pos > string_len / 2)
	{
	  string_len *= 2;
	  string = XRESIZEVEC (char, string, string_len);
	}
    }

  return pos ? string : NULL;
}

/* Pad string S with spaces from left to have total width equal to 9.  */

static void
pad_count_string (string &s)
{
  if (s.size () < 9)
    s.insert (0, 9 - s.size (), ' ');
}

/* Print GCOV line beginning to F stream.  If EXISTS is set to true, the
   line exists in source file.  UNEXCEPTIONAL indicated that it's not in
   an exceptional statement.  The output is printed for LINE_NUM of given
   COUNT of executions.  EXCEPTIONAL_STRING and UNEXCEPTIONAL_STRING are
   used to indicate non-executed blocks.  */

static void
output_line_beginning (FILE *f, bool exists, bool unexceptional,
		       bool has_unexecuted_block,
		       gcov_type count, unsigned line_num,
		       const char *exceptional_string,
		       const char *unexceptional_string,
		       unsigned int maximum_count)
{
  string s;
  if (exists)
    {
      if (count > 0)
	{
	  s = format_gcov (count, 0, -1);
	  if (has_unexecuted_block
	      && bbg_supports_has_unexecuted_blocks)
	    {
	      if (flag_use_colors)
		{
		  pad_count_string (s);
		  s.insert (0, SGR_SEQ (COLOR_BG_MAGENTA
					COLOR_SEPARATOR COLOR_FG_WHITE));
		  s += SGR_RESET;
		}
	      else
		s += "*";
	    }
	  pad_count_string (s);
	}
      else
	{
	  if (flag_use_colors)
	    {
	      s = "0";
	      pad_count_string (s);
	      if (unexceptional)
		s.insert (0, SGR_SEQ (COLOR_BG_RED
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      else
		s.insert (0, SGR_SEQ (COLOR_BG_CYAN
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      s += SGR_RESET;
	    }
	  else
	    {
	      s = unexceptional ? unexceptional_string : exceptional_string;
	      pad_count_string (s);
	    }
	}
    }
  else
    {
      s = "-";
      pad_count_string (s);
    }

  /* Format line number in output.  */
  char buffer[16];
  sprintf (buffer, "%5u", line_num);
  string linestr (buffer);

  if (flag_use_hotness_colors && maximum_count)
    {
      if (count * 2 > maximum_count) /* > 50%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_RED));
      else if (count * 5 > maximum_count) /* > 20%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_YELLOW));
      else if (count * 10 > maximum_count) /* > 10%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_GREEN));
      linestr += SGR_RESET;
    }

  fprintf (f, "%s:%s", s.c_str (), linestr.c_str ());
}

static void
print_source_line (FILE *f, const vector<const char *> &source_lines,
		   unsigned line)
{
  gcc_assert (line >= 1);
  gcc_assert (line <= source_lines.size ());

  fprintf (f, ":%s\n", source_lines[line - 1]);
}

/* Output line details for LINE and print it to F file.  LINE lives on
   LINE_NUM.  */

static void
output_line_details (FILE *f, const line_info *line, unsigned line_num)
{
  if (flag_all_blocks)
    {
      arc_info *arc;
      int ix, jx;

      ix = jx = 0;
      for (vector<block_info *>::const_iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  if (!(*it)->is_call_return)
	    {
	      output_line_beginning (f, line->exists,
				     (*it)->exceptional, false,
				     (*it)->count, line_num,
				     "%%%%%", "$$$$$", 0);
	      fprintf (f, "-block %2d", ix++);
	      if (flag_verbose)
		fprintf (f, " (BB %u)", (*it)->id);
	      fprintf (f, "\n");
	    }
	  if (flag_branches)
	    for (arc = (*it)->succ; arc; arc = arc->succ_next)
	      jx += output_branch_count (f, jx, arc);
	}
    }
  else if (flag_branches)
    {
      int ix;

      ix = 0;
      for (vector<arc_info *>::const_iterator it = line->branches.begin ();
	   it != line->branches.end (); it++)
	ix += output_branch_count (f, ix, (*it));
    }
}

/* Output detail statistics about function FN to file F.  */

static void
output_function_details (FILE *f, function_info *fn)
{
  if (!flag_branches)
    return;

  arc_info *arc = fn->blocks[EXIT_BLOCK].pred;
  gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
  gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;

  for (; arc; arc = arc->pred_next)
    if (arc->fake)
      return_count -= arc->count;

  fprintf (f, "function %s", fn->get_name ());
  fprintf (f, " called %s",
	   format_gcov (called_count, 0, -1));
  fprintf (f, " returned %s",
	   format_gcov (return_count, called_count, 0));
  fprintf (f, " blocks executed %s",
	   format_gcov (fn->blocks_executed, fn->get_block_count (), 0));
  fprintf (f, "\n");
}

/* Read in the source file one line at a time, and output that line to
   the gcov file preceded by its execution count and other
   information.  */

static void
output_lines (FILE *gcov_file, const source_info *src)
{
#define  DEFAULT_LINE_START "        -:    0:"
#define FN_SEPARATOR "------------------\n"

  FILE *source_file;
  const char *retval;

  /* Print colorization legend.  */
  if (flag_use_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: profile count: " \
	     SGR_SEQ (COLOR_BG_CYAN) "zero coverage (exceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_RED) "zero coverage (unexceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_MAGENTA) "unexecuted block" SGR_RESET "\n");

  if (flag_use_hotness_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: line numbers: hotness: " \
	     SGR_SEQ (COLOR_BG_RED) "> 50%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_YELLOW) "> 20%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_GREEN) "> 10%" SGR_RESET "\n");

  fprintf (gcov_file, DEFAULT_LINE_START "Source:%s\n", src->coverage.name);
  if (!multiple_files)
    {
      fprintf (gcov_file, DEFAULT_LINE_START "Graph:%s\n", bbg_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Data:%s\n",
	       no_data_file ? "-" : da_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Runs:%u\n", object_runs);
    }

  source_file = fopen (src->name, "r");
  if (!source_file)
    fnotice (stderr, "Cannot open source file %s\n", src->name);
  else if (src->file_time == 0)
    fprintf (gcov_file, DEFAULT_LINE_START "Source is newer than graph\n");

  vector<const char *> source_lines;
  if (source_file)
    while ((retval = read_line (source_file)) != NULL)
      source_lines.push_back (xstrdup (retval));

  unsigned line_start_group = 0;
  vector<function_info *> *fns;

  for (unsigned line_num = 1; line_num <= source_lines.size (); line_num++)
    {
      if (line_num >= src->lines.size ())
	{
	  fprintf (gcov_file, "%9s:%5u", "-", line_num);
	  print_source_line (gcov_file, source_lines, line_num);
	  continue;
	}

      const line_info *line = &src->lines[line_num];

      if (line_start_group == 0)
	{
	  fns = src->get_functions_at_location (line_num);
	  if (fns != NULL && fns->size () > 1)
	    {
	      /* It's possible to have functions that partially overlap,
		 thus take the maximum end_line of functions starting
		 at LINE_NUM.  */
	      for (unsigned i = 0; i < fns->size (); i++)
		if ((*fns)[i]->end_line > line_start_group)
		  line_start_group = (*fns)[i]->end_line;
	    }
	  else if (fns != NULL && fns->size () == 1)
	    {
	      function_info *fn = (*fns)[0];
	      output_function_details (gcov_file, fn);
	    }
	}

      /* For lines which don't exist in the .bb file, print '-' before
	 the source line.  For lines which exist but were never
	 executed, print '#####' or '=====' before the source line.
	 Otherwise, print the execution count before the source line.
	 There are 16 spaces of indentation added before the source
	 line so that tabs won't be messed up.  */
      output_line_beginning (gcov_file, line->exists, line->unexceptional,
			     line->has_unexecuted_block, line->count,
			     line_num, "=====", "#####", src->maximum_count);

      print_source_line (gcov_file, source_lines, line_num);
      output_line_details (gcov_file, line, line_num);

      if (line_start_group == line_num)
	{
	  for (vector<function_info *>::iterator it = fns->begin ();
	       it != fns->end (); it++)
	    {
	      function_info *fn = *it;
	      vector<line_info> &lines = fn->lines;

	      fprintf (gcov_file, FN_SEPARATOR);

	      string fn_name = fn->get_name ();
	      if (flag_use_colors)
		{
		  fn_name.insert (0, SGR_SEQ (COLOR_FG_CYAN));
		  fn_name += SGR_RESET;
		}

	      fprintf (gcov_file, "%s:\n", fn_name.c_str ());

	      output_function_details (gcov_file, fn);

	      /* Print all lines covered by the function.  */
	      for (unsigned i = 0; i < lines.size (); i++)
		{
		  line_info *line = &lines[i];
		  unsigned l = fn->start_line + i;

		  /* For lines which don't exist in the .bb file, print '-'
		     before the source line.  For lines which exist but
		     were never executed, print '#####' or '=====' before
		     the source line.  Otherwise, print the execution count
		     before the source line.
		     There are 16 spaces of indentation added before the source
		     line so that tabs won't be messed up.  */
		  output_line_beginning (gcov_file, line->exists,
					 line->unexceptional,
					 line->has_unexecuted_block,
					 line->count,
					 l, "=====", "#####",
					 src->maximum_count);

		  print_source_line (gcov_file, source_lines, l);
		  output_line_details (gcov_file, line, l);
		}
	    }

	  fprintf (gcov_file, FN_SEPARATOR);
	  line_start_group = 0;
	}
    }

  if (source_file)
    fclose (source_file);
}
