/* Gcov.c: prepend line execution counts and branch probabilities to a
   source file.
   Copyright (C) 1990-2018 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 <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.  */

struct function_info;
struct block_info;
struct source_info;

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

struct arc_info
{
  /* source and destination blocks.  */
  struct block_info *src;
  struct 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.  */

struct block_location_info
{
  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.  */

struct block_info
{
  /* 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.  */
  struct 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.  */

struct line_info
{
  /* 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 ();
}

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

struct function_info
{
  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 *name;
  char *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;

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

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

  /* Next function.  */
  struct function_info *next;
};

/* 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.  */

struct source_info
{
  /* Default constructor.  */
  source_info ();

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

  /* 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;

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

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

vector<function_info *>
source_info::get_functions_at_location (unsigned line_num) const
{
  vector<function_info *> r;

  for (vector<function_info *>::const_iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      if ((*it)->start_line == line_num && (*it)->src == index)
	r.push_back (*it);
    }

  std::sort (r.begin (), r.end (), function_line_start_cmp ());

  return r;
}

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;

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

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

/* This holds data summary information.  */

static unsigned object_runs;
static unsigned program_count;

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;

/* 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 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 intermediate format used by 'lcov'.  */

static int flag_intermediate_format = 0;

/* Output demangled function names.  */

static int flag_demangled_names = 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;

/* 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;

/* 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 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 *, const char *);
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 char *make_gcov_file_name (const char *, const char *);
static char *mangle_name (const char *, char *);
static void release_structures (void);
extern int main (int, char **);

function_info::function_info (): name (NULL), 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 (), end_line (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 (flag_demangled_names && demangled_name != name)
    free (demangled_name);
  free (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;

/* Enum with types of loop in CFG.  */

enum loop_type
{
  NO_LOOP = 0,
  LOOP = 1,
  NEGATIVE_LOOP = 3
};

/* Loop_type operator that merges two values: A and B.  */

inline loop_type& operator |= (loop_type& a, loop_type b)
{
    return a = static_cast<loop_type> (a | b);
}

/* 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 loop_type
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;

  return cycle_count < 0 ? NEGATIVE_LOOP : LOOP;
}

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

/* 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 loop_type
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)
{
  loop_type result = NO_LOOP;

  /* 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 || !linfo.has_block (w))
	continue;

      path.push_back (arc);
      if (w == start)
	/* Cycle has been found.  */
	result |= handle_cycle (path, count);
      else if (find (blocked.begin (), blocked.end (), w) == blocked.end ())
	result |= circuit (w, path, start, blocked, block_lists, linfo, count);

      path.pop_back ();
    }

  if (result != NO_LOOP)
    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 || !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 result;
}

/* Find cycles for a LINFO.  If HANDLE_NEGATIVE_CYCLES is set and the line
   contains a negative loop, then perform the same function once again.  */

static gcov_type
get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
{
  /* 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.  */

  loop_type result = NO_LOOP;
  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;
      result |= circuit (*it, path, *it, blocked, block_lists, linfo,
			 count);
    }

  /* If we have a negative cycle, repeat the find_cycles routine.  */
  if (result == NEGATIVE_LOOP && handle_negative_cycles)
    count += get_cycles_count (linfo, false);

  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_intermediate_format || argno == argc - 1)
	{
	  generate_results (argv[argno]);
	  release_structures ();
	}
    }

  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, "  -f, --function-summaries        Output summaries for each function\n");
  fnotice (file, "  -h, --help                      Print this help, then exit\n");
  fnotice (file, "  -i, --intermediate-format       Output .gcov file in intermediate text format\n");
  fnotice (file, "  -j, --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, "  -r, --relative-only             Only show data for relative sources\n");
  fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\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, "\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 2018 Free Software Foundation, Inc.\n",
	   _("(C)"));
  fnotice (stdout,
	   _("This is free software; see the source for copying conditions.\n"
	     "There is NO warranty; not even for MERCHANTABILITY or \n"
	     "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' },
  { "intermediate-format",  no_argument,       NULL, 'i' },
  { "human-readable",	    no_argument,       NULL, 'j' },
  { "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' },
  { "unconditional-branches", no_argument,     NULL, 'u' },
  { "display-progress",     no_argument,       NULL, 'd' },
  { "hash-filenames",	    no_argument,       NULL, 'x' },
  { "use-colors",	    no_argument,       NULL, 'k' },
  { 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 = "abcdfhijklmno:prs:uvwx";
  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 'j':
	  flag_human_readable_numbers = 1;
	  break;
	case 'k':
	  flag_use_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':
          flag_intermediate_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 '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 output file F.  */

static void
output_intermediate_line (FILE *f, line_info *line, unsigned line_num)
{
  if (!line->exists)
    return;

  fprintf (f, "lcount:%u,%s,%d\n", line_num,
	   format_gcov (line->count, 0, -1),
	   line->has_unexecuted_block);

  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)
	  {
	    const char *branch_type;
	    /* branch:<line_num>,<branch_coverage_infoype>
	       branch_coverage_infoype
	       : notexec (Branch not executed)
	       : taken (Branch executed and taken)
	       : nottaken (Branch executed, but not taken)
	       */
	    if ((*it)->src->count)
		 branch_type
			= ((*it)->count > 0) ? "taken" : "nottaken";
	    else
	      branch_type = "notexec";
	    fprintf (f, "branch:%d,%s\n", line_num, branch_type);
	  }
      }
}

/* 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 char *
get_gcov_intermediate_filename (const char *file_name)
{
  const char *gcov = ".gcov";
  char *result;
  const char *cptr;

  /* Find the 'basename'.  */
  cptr = lbasename (file_name);

  result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1);
  sprintf (result, "%s%s", cptr, gcov);

  return result;
}

/* Output the result in intermediate format used by 'lcov'.

The intermediate format contains a single file named 'foo.cc.gcov',
with no source code included.

The default gcov outputs multiple files: 'foo.cc.gcov',
'iostream.gcov', 'ios_base.h.gcov', etc. with source code
included. Instead the intermediate format here outputs only a single
file 'foo.cc.gcov' similar to the above example. */

static void
output_intermediate_file (FILE *gcov_file, source_info *src)
{
  fprintf (gcov_file, "version:%s\n", version_string);
  fprintf (gcov_file, "file:%s\n", src->name);    /* source file name */

  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++)
    {
      /* function:<name>,<line_number>,<execution_count> */
      fprintf (gcov_file, "function:%d,%d,%s,%s\n", (*it)->start_line,
	       (*it)->end_line, format_gcov ((*it)->blocks[0].count, 0, -1),
	       flag_demangled_names ? (*it)->demangled_name : (*it)->name);
    }

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

      /* Print first group functions that begin on the line.  */
      for (vector<function_info *>::iterator it2 = fns.begin ();
	   it2 != fns.end (); it2++)
	{
	  vector<line_info> &lines = (*it2)->lines;
	  for (unsigned i = 0; i < lines.size (); i++)
	    {
	      line_info *line = &lines[i];
	      output_intermediate_line (gcov_file, line, line_num + i);
	    }
	}

      /* Follow with lines associated with the source file.  */
      output_intermediate_line (gcov_file, &src->lines[line_num], line_num);
    }
}

/* 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 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);
  read_graph_file ();
  if (functions.empty ())
    return;

  read_count_file ();

  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->functions.push_back (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)
{
  char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);

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

static void
generate_results (const char *file_name)
{
  FILE *gcov_intermediate_file = NULL;
  char *gcov_intermediate_filename = NULL;

  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 = flag_demangled_names ? fn->demangled_name : fn->name;
      add_line_counts (flag_function_summary ? &coverage : NULL, fn);
      if (flag_function_summary)
	{
	  function_summary (&coverage, "Function");
	  fnotice (stdout, "\n");
	}
    }

  name_map needle;

  if (file_name)
    {
      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);
    }

  if (flag_gcov_file && flag_intermediate_format)
    {
      /* Open the intermediate file.  */
      gcov_intermediate_filename = get_gcov_intermediate_filename (file_name);
      gcov_intermediate_file = fopen (gcov_intermediate_filename, "w");
      if (!gcov_intermediate_file)
	{
	  fnotice (stderr, "Cannot open intermediate output file %s\n",
		   gcov_intermediate_filename);
	  return;
	}
    }

  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);
      function_summary (&src->coverage, "File");
      total_lines += src->coverage.lines;
      total_executed += src->coverage.lines_executed;
      if (flag_gcov_file)
	{
	  if (flag_intermediate_format)
	    /* Output the intermediate format without requiring source
	       files.  This outputs a section to a *single* file.  */
	    output_intermediate_file (gcov_intermediate_file, src);
	  else
	    output_gcov_file (file_name, src);
	  fnotice (stdout, "\n");
	}
    }

  if (flag_gcov_file && flag_intermediate_format)
    {
      /* Now we've finished writing the intermediate file.  */
      fclose (gcov_intermediate_file);
      XDELETEVEC (gcov_intermediate_filename);
    }

  if (!file_name)
    executed_summary (total_lines, total_executed);
}

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

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

	  fn = new function_info ();
	  functions.push_back (fn);
	  fn->name = function_name;
	  if (flag_demangled_names)
	    {
	      fn->demangled_name = cplus_demangle (fn->name, DMGL_PARAMS);
	      if (!fn->demangled_name)
		fn->demangled_name = fn->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->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->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];
	      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;

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

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

      if (tag == GCOV_TAG_PROGRAM_SUMMARY)
	{
	  struct gcov_summary summary;
	  gcov_read_summary (&summary);
	  object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
	  program_count++;
	}
      else if (tag == GCOV_TAG_FUNCTION && !length)
	; /* placeholder  */
      else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
	{
	  unsigned ident;

	  /* Try to find the function in the list.  To speed up the
	     search, first start from the last function found.  */
	  ident = gcov_read_unsigned ();

	  fn = NULL;
	  for (vector<function_info *>::reverse_iterator it
	       = functions.rbegin (); it != functions.rend (); it++)
	    {
	      if ((*it)->ident == ident)
		{
		  fn = *it;
		  break;
		}
	    }

	  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->name);
	      goto cleanup;
	    }
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
	{
	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ()))
	    goto mismatch;

	  for (ix = 0; ix != fn->counts.size (); ix++)
	    fn->counts[ix] += gcov_read_counter ();
	}
      gcov_sync (base, 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->name);
  else
    {
      if (fn->blocks[ENTRY_BLOCK].num_pred)
	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
		 bbg_file_name, fn->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->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->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;
    }
  gcov_type r  = (count + divisor / 2) / divisor;
  sprintf (buffer, "%" PRId64 "%c", r, units[i]);
  return buffer;
}

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

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

  /* Handle invalid values that would result in a misleading value.  */
  if (bottom != 0 && top > bottom && dp >= 0)
    {
      sprintf (buffer, "NAN %%");
      return buffer;
    }

  if (dp >= 0)
    {
      float ratio = bottom ? (float)top / bottom : 0;
      int ix;
      unsigned limit = 100;
      unsigned percent;

      for (ix = dp; ix--; )
	limit *= 10;

      percent = (unsigned) (ratio * limit + (float)0.5);
      if (percent <= 0 && top)
	percent = 1;
      else if (percent >= limit && top != bottom)
	percent = limit - 1;
      ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
      if (dp)
	{
	  dp++;
	  do
	    {
	      buffer[ix+1] = buffer[ix];
	      ix--;
	    }
	  while (dp--);
	  buffer[ix + 1] = '.';
	}
    }
  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 or file.  */

static void
function_summary (const coverage_info *coverage, const char *title)
{
  fnotice (stdout, "%s '%s'\n", title, 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;
}

/* Print hex representation of 16 bytes from SUM and write it to BUFFER.  */

static void
md5sum_to_hex (const char *sum, char *buffer)
{
  for (unsigned i = 0; i < 16; i++)
    sprintf (buffer + (2 * i), "%02x", (unsigned char)sum[i]);
}

/* 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 char *
make_gcov_file_name (const char *input_name, const char *src_name)
{
  char *ptr;
  char *result;

  if (flag_long_names && input_name && strcmp (src_name, input_name))
    {
      /* Generate the input filename part.  */
      result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);

      ptr = result;
      ptr = mangle_name (input_name, ptr);
      ptr[0] = ptr[1] = '#';
      ptr += 2;
    }
  else
    {
      result = XNEWVEC (char, strlen (src_name) + 10);
      ptr = result;
    }

  ptr = mangle_name (src_name, ptr);
  strcpy (ptr, ".gcov");

  /* 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)
    {
      md5_ctx ctx;
      char md5sum[16];
      char md5sum_hex[33];

      md5_init_ctx (&ctx);
      md5_process_bytes (src_name, strlen (src_name), &ctx);
      md5_finish_ctx (&ctx, md5sum);
      md5sum_to_hex (md5sum, md5sum_hex);
      free (result);

      result = XNEWVEC (char, strlen (src_name) + 50);
      ptr = result;
      ptr = mangle_name (src_name, ptr);
      ptr[0] = ptr[1] = '#';
      ptr += 2;
      memcpy (ptr, md5sum_hex, 32);
      ptr += 32;
      strcpy (ptr, ".gcov");
    }

  return result;
}

static char *
mangle_name (char const *base, char *ptr)
{
  size_t len;

  /* Generate the source filename part.  */
  if (!flag_preserve_paths)
    {
      base = lbasename (base);
      len = strlen (base);
      memcpy (ptr, base, len);
      ptr += len;
    }
  else
    {
      /* Convert '/' to '#', convert '..' to '^',
	 convert ':' to '~' on DOS based file system.  */
      const char *probe;

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

	  for (probe = base; *probe; probe++)
	    if (*probe == '/')
	      break;
	  len = probe - base;
	  if (len == 2 && base[0] == '.' && base[1] == '.')
	    *ptr++ = '^';
	  else
	    {
	      memcpy (ptr, base, len);
	      ptr += len;
	    }
	  if (*probe)
	    {
	      *ptr++ = '#';
	      probe++;
	    }
	}
    }

  return ptr;
}

/* 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->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->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_intermediate_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)
{
  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);
    }

  fprintf (f, "%s:%5u", s.c_str (), line_num);
}

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,
				     "%%%%%", "$$$$$");
	      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, const 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",
	   flag_demangled_names ? fn->demangled_name : fn->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->blocks.size () - 2,
			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;

  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);
    }
  fprintf (gcov_file, DEFAULT_LINE_START "Programs:%u\n", program_count);

  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.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.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, "=====", "#####");

      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
		= flag_demangled_names ? fn->demangled_name : fn->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, "=====", "#####");

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