/* Paths through the code associated with a diagnostic.
   Copyright (C) 2019-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
#include "tree-diagnostic.h"
#include "langhooks.h"
#include "intl.h"
#include "diagnostic-path.h"
#include "json.h"
#include "gcc-rich-location.h"
#include "diagnostic-color.h"
#include "diagnostic-event-id.h"
#include "selftest.h"
#include "selftest-diagnostic.h"

/* Anonymous namespace for path-printing code.  */

namespace {

/* Subclass of range_label for showing a particular event
   when showing a consecutive run of events within a diagnostic_path as
   labelled ranges within one gcc_rich_location.  */

class path_label : public range_label
{
 public:
  path_label (const diagnostic_path *path, unsigned start_idx)
  : m_path (path), m_start_idx (start_idx)
  {}

  label_text get_text (unsigned range_idx) const final override
  {
    unsigned event_idx = m_start_idx + range_idx;
    const diagnostic_event &event = m_path->get_event (event_idx);

    /* Get the description of the event, perhaps with colorization:
       normally, we don't colorize within a range_label, but this
       is special-cased for diagnostic paths.  */
    bool colorize = pp_show_color (global_dc->printer);
    label_text event_text (event.get_desc (colorize));
    gcc_assert (event_text.m_buffer);
    pretty_printer pp;
    pp_show_color (&pp) = pp_show_color (global_dc->printer);
    diagnostic_event_id_t event_id (event_idx);
    pp_printf (&pp, "%@ %s", &event_id, event_text.m_buffer);
    event_text.maybe_free ();
    label_text result = label_text::take (xstrdup (pp_formatted_text (&pp)));
    return result;
  }

 private:
  const diagnostic_path *m_path;
  unsigned m_start_idx;
};

/* Return true if E1 and E2 can be consolidated into the same run of events
   when printing a diagnostic_path.  */

static bool
can_consolidate_events (const diagnostic_event &e1,
			const diagnostic_event &e2,
			bool check_locations)
{
  if (e1.get_fndecl () != e2.get_fndecl ())
    return false;

  if (e1.get_stack_depth () != e2.get_stack_depth ())
    return false;

  if (check_locations)
    {
      location_t loc1 = e1.get_location ();
      location_t loc2 = e2.get_location ();

      if (loc1 < RESERVED_LOCATION_COUNT
	  || loc2 < RESERVED_LOCATION_COUNT)
	return false;

      /* Neither can be macro-based.  */
      if (linemap_location_from_macro_expansion_p (line_table, loc1))
	return false;
      if (linemap_location_from_macro_expansion_p (line_table, loc2))
	return false;
    }

  /* Passed all the tests.  */
  return true;
}

/* A range of consecutive events within a diagnostic_path,
   all with the same fndecl and stack_depth, and which are suitable
   to print with a single call to diagnostic_show_locus.  */
struct event_range
{
  event_range (const diagnostic_path *path, unsigned start_idx,
	       const diagnostic_event &initial_event)
  : m_path (path),
    m_initial_event (initial_event),
    m_fndecl (initial_event.get_fndecl ()),
    m_stack_depth (initial_event.get_stack_depth ()),
    m_start_idx (start_idx), m_end_idx (start_idx),
    m_path_label (path, start_idx),
    m_richloc (initial_event.get_location (), &m_path_label)
  {}

  bool maybe_add_event (const diagnostic_event &new_ev, unsigned idx,
			bool check_rich_locations)
  {
    if (!can_consolidate_events (m_initial_event, new_ev,
				 check_rich_locations))
      return false;
    if (check_rich_locations)
      if (!m_richloc.add_location_if_nearby (new_ev.get_location (),
					     false, &m_path_label))
	return false;
    m_end_idx = idx;
    return true;
  }

  /* Print the events in this range to DC, typically as a single
     call to the printer's diagnostic_show_locus.  */

  void print (diagnostic_context *dc)
  {
    location_t initial_loc = m_initial_event.get_location ();

    /* Emit a span indicating the filename (and line/column) if the
       line has changed relative to the last call to
       diagnostic_show_locus.  */
    if (dc->show_caret)
      {
	expanded_location exploc
	  = linemap_client_expand_location_to_spelling_point
	  (initial_loc, LOCATION_ASPECT_CARET);
	if (exploc.file != LOCATION_FILE (dc->last_location))
	  dc->start_span (dc, exploc);
      }

    /* If we have an UNKNOWN_LOCATION (or BUILTINS_LOCATION) as the
       primary location for an event, diagnostic_show_locus won't print
       anything.

       In particular the label for the event won't get printed.
       Fail more gracefully in this case by showing the event
       index and text, at no particular location.  */
    if (get_pure_location (initial_loc) <= BUILTINS_LOCATION)
      {
	for (unsigned i = m_start_idx; i <= m_end_idx; i++)
	  {
	    const diagnostic_event &iter_event = m_path->get_event (i);
	    diagnostic_event_id_t event_id (i);
	    label_text event_text (iter_event.get_desc (true));
	    pretty_printer *pp = dc->printer;
	    pp_printf (pp, " %@: %s", &event_id, event_text.m_buffer);
	    pp_newline (pp);
	    event_text.maybe_free ();
	  }
	return;
      }

    /* Call diagnostic_show_locus to show the events using labels.  */
    diagnostic_show_locus (dc, &m_richloc, DK_DIAGNOSTIC_PATH);

    /* If we have a macro expansion, show the expansion to the user.  */
    if (linemap_location_from_macro_expansion_p (line_table, initial_loc))
      {
	gcc_assert (m_start_idx == m_end_idx);
	maybe_unwind_expanded_macro_loc (dc, initial_loc);
      }
  }

  const diagnostic_path *m_path;
  const diagnostic_event &m_initial_event;
  tree m_fndecl;
  int m_stack_depth;
  unsigned m_start_idx;
  unsigned m_end_idx;
  path_label m_path_label;
  gcc_rich_location m_richloc;
};

/* A struct for grouping together the events in a diagnostic_path into
   ranges of events, partitioned by stack frame (i.e. by fndecl and
   stack depth).  */

struct path_summary
{
  path_summary (const diagnostic_path &path, bool check_rich_locations);

  unsigned get_num_ranges () const { return m_ranges.length (); }

  auto_delete_vec <event_range> m_ranges;
};

/* path_summary's ctor.  */

path_summary::path_summary (const diagnostic_path &path,
			    bool check_rich_locations)
{
  const unsigned num_events = path.num_events ();

  event_range *cur_event_range = NULL;
  for (unsigned idx = 0; idx < num_events; idx++)
    {
      const diagnostic_event &event = path.get_event (idx);
      if (cur_event_range)
	if (cur_event_range->maybe_add_event (event, idx, check_rich_locations))
	  continue;

      cur_event_range = new event_range (&path, idx, event);
      m_ranges.safe_push (cur_event_range);
    }
}

/* Write SPACES to PP.  */

static void
write_indent (pretty_printer *pp, int spaces)
{
  for (int i = 0; i < spaces; i++)
    pp_space (pp);
}

/* Print FNDDECL to PP, quoting it if QUOTED is true.

   We can't use "%qE" here since we can't guarantee the capabilities
   of PP.  */

static void
print_fndecl (pretty_printer *pp, tree fndecl, bool quoted)
{
  const char *n = DECL_NAME (fndecl)
    ? identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2))
    : _("<anonymous>");
  if (quoted)
    pp_printf (pp, "%qs", n);
  else
    pp_string (pp, n);
}

/* Print path_summary PS to DC, giving an overview of the interprocedural
   calls and returns.

   Print the event descriptions in a nested form, printing the event
   descriptions within calls to diagnostic_show_locus, using labels to
   show the events:

   'foo' (events 1-2)
     | NN |
     |    |
     +--> 'bar' (events 3-4)
            | NN |
            |    |
            +--> 'baz' (events 5-6)
                   | NN |
                   |    |
     <------------ +
     |
   'foo' (events 7-8)
     | NN |
     |    |
     +--> 'bar' (events 9-10)
            | NN |
            |    |
            +--> 'baz' (events 11-12)
                   | NN |
                   |    |

   If SHOW_DEPTHS is true, append " (depth N)" to the header of each run
   of events.

   For events with UNKNOWN_LOCATION, print a summary of each the event.  */

void
print_path_summary_as_text (const path_summary *ps, diagnostic_context *dc,
			    bool show_depths)
{
  pretty_printer *pp = dc->printer;

  const int per_frame_indent = 2;

  const char *const line_color = "path";
  const char *start_line_color
    = colorize_start (pp_show_color (pp), line_color);
  const char *end_line_color = colorize_stop (pp_show_color (pp));

  /* Keep track of column numbers of existing '|' characters for
     stack depths we've already printed.  */
  const int EMPTY = -1;
  const int DELETED = -2;
  typedef int_hash <int, EMPTY, DELETED> vbar_hash;
  hash_map <vbar_hash, int> vbar_column_for_depth;

  /* Print the ranges.  */
  const int base_indent = 2;
  int cur_indent = base_indent;
  unsigned i;
  event_range *range;
  FOR_EACH_VEC_ELT (ps->m_ranges, i, range)
    {
      write_indent (pp, cur_indent);
      if (i > 0)
	{
	  const event_range *prev_range = ps->m_ranges[i - 1];
	  if (range->m_stack_depth > prev_range->m_stack_depth)
	    {
	      /* Show pushed stack frame(s).  */
	      const char *push_prefix = "+--> ";
	      pp_string (pp, start_line_color);
	      pp_string (pp, push_prefix);
	      pp_string (pp, end_line_color);
	      cur_indent += strlen (push_prefix);
	    }
	}
      if (range->m_fndecl)
	{
	  print_fndecl (pp, range->m_fndecl, true);
	  pp_string (pp, ": ");
	}
      if (range->m_start_idx == range->m_end_idx)
	pp_printf (pp, "event %i",
		   range->m_start_idx + 1);
      else
	pp_printf (pp, "events %i-%i",
		   range->m_start_idx + 1, range->m_end_idx + 1);
      if (show_depths)
	pp_printf (pp, " (depth %i)", range->m_stack_depth);
      pp_newline (pp);

      /* Print a run of events.  */
      {
	write_indent (pp, cur_indent + per_frame_indent);
	pp_string (pp, start_line_color);
	pp_string (pp, "|");
	pp_string (pp, end_line_color);
	pp_newline (pp);

	char *saved_prefix = pp_take_prefix (pp);
	char *prefix;
	{
	  pretty_printer tmp_pp;
	  write_indent (&tmp_pp, cur_indent + per_frame_indent);
	  pp_string (&tmp_pp, start_line_color);
	  pp_string (&tmp_pp, "|");
	  pp_string (&tmp_pp, end_line_color);
	  prefix = xstrdup (pp_formatted_text (&tmp_pp));
	}
	pp_set_prefix (pp, prefix);
	pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
	range->print (dc);
	pp_set_prefix (pp, saved_prefix);

	write_indent (pp, cur_indent + per_frame_indent);
	pp_string (pp, start_line_color);
	pp_string (pp, "|");
	pp_string (pp, end_line_color);
	pp_newline (pp);
      }

      if (i < ps->m_ranges.length () - 1)
	{
	  const event_range *next_range = ps->m_ranges[i + 1];

	  if (range->m_stack_depth > next_range->m_stack_depth)
	    {
	      if (vbar_column_for_depth.get (next_range->m_stack_depth))
		{
		  /* Show returning from stack frame(s), by printing
		     something like:
		     "                   |\n"
		     "     <------------ +\n"
		     "     |\n".  */
		  int vbar_for_next_frame
		    = *vbar_column_for_depth.get (next_range->m_stack_depth);

		  int indent_for_next_frame
		    = vbar_for_next_frame - per_frame_indent;
		  write_indent (pp, vbar_for_next_frame);
		  pp_string (pp, start_line_color);
		  pp_character (pp, '<');
		  for (int i = indent_for_next_frame + per_frame_indent;
		       i < cur_indent + per_frame_indent - 1; i++)
		    pp_character (pp, '-');
		  pp_character (pp, '+');
		  pp_string (pp, end_line_color);
		  pp_newline (pp);
		  cur_indent = indent_for_next_frame;

		  write_indent (pp, vbar_for_next_frame);
		  pp_string (pp, start_line_color);
		  pp_character (pp, '|');
		  pp_string (pp, end_line_color);
		  pp_newline (pp);
		}
	      else
		{
		  /* Handle disjoint paths (e.g. a callback at some later
		     time).  */
		  cur_indent = base_indent;
		}
	    }
	  else if (range->m_stack_depth < next_range->m_stack_depth)
	    {
	      /* Prepare to show pushed stack frame.  */
	      gcc_assert (range->m_stack_depth != EMPTY);
	      gcc_assert (range->m_stack_depth != DELETED);
	      vbar_column_for_depth.put (range->m_stack_depth,
					 cur_indent + per_frame_indent);
	      cur_indent += per_frame_indent;
	    }

	}
    }
}

} /* end of anonymous namespace for path-printing code.  */

/* Print PATH to CONTEXT, according to CONTEXT's path_format.  */

void
default_tree_diagnostic_path_printer (diagnostic_context *context,
				      const diagnostic_path *path)
{
  gcc_assert (path);

  const unsigned num_events = path->num_events ();

  switch (context->path_format)
    {
    case DPF_NONE:
      /* Do nothing.  */
      return;

    case DPF_SEPARATE_EVENTS:
      {
	/* A note per event.  */
	for (unsigned i = 0; i < num_events; i++)
	  {
	    const diagnostic_event &event = path->get_event (i);
	    label_text event_text (event.get_desc (false));
	    gcc_assert (event_text.m_buffer);
	    diagnostic_event_id_t event_id (i);
	    if (context->show_path_depths)
	      {
		int stack_depth = event.get_stack_depth ();
		tree fndecl = event.get_fndecl ();
		/* -fdiagnostics-path-format=separate-events doesn't print
		   fndecl information, so with -fdiagnostics-show-path-depths
		   print the fndecls too, if any.  */
		if (fndecl)
		  inform (event.get_location (),
			  "%@ %s (fndecl %qD, depth %i)",
			  &event_id, event_text.m_buffer,
			  fndecl, stack_depth);
		else
		  inform (event.get_location (),
			  "%@ %s (depth %i)",
			  &event_id, event_text.m_buffer,
			  stack_depth);
	      }
	    else
	      inform (event.get_location (),
		      "%@ %s", &event_id, event_text.m_buffer);
	    event_text.maybe_free ();
	  }
      }
      break;

    case DPF_INLINE_EVENTS:
      {
	/* Consolidate related events.  */
	path_summary summary (*path, true);
	char *saved_prefix = pp_take_prefix (context->printer);
	pp_set_prefix (context->printer, NULL);
	print_path_summary_as_text (&summary, context,
				    context->show_path_depths);
	pp_flush (context->printer);
	pp_set_prefix (context->printer, saved_prefix);
      }
    }
}

/* This has to be here, rather than diagnostic-format-json.cc,
   since diagnostic-format-json.o is within OBJS-libcommon and thus
   doesn't have access to trees (for m_fndecl).  */

json::value *
default_tree_make_json_for_path (diagnostic_context *context,
				 const diagnostic_path *path)
{
  json::array *path_array = new json::array ();
  for (unsigned i = 0; i < path->num_events (); i++)
    {
      const diagnostic_event &event = path->get_event (i);

      json::object *event_obj = new json::object ();
      if (event.get_location ())
	event_obj->set ("location",
			json_from_expanded_location (context,
						     event.get_location ()));
      label_text event_text (event.get_desc (false));
      event_obj->set ("description", new json::string (event_text.m_buffer));
      event_text.maybe_free ();
      if (tree fndecl = event.get_fndecl ())
	{
	  const char *function
	    = identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2));
	  event_obj->set ("function", new json::string (function));
	}
      event_obj->set ("depth",
		      new json::integer_number (event.get_stack_depth ()));
      path_array->append (event_obj);
    }
  return path_array;
}

#if CHECKING_P

/* Disable warnings about missing quoting in GCC diagnostics for the print
   calls in the tests below.  */
#if __GNUC__ >= 10
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wformat-diag"
#endif

namespace selftest {

/* A subclass of simple_diagnostic_path that adds member functions
   for adding test events.  */

class test_diagnostic_path : public simple_diagnostic_path
{
 public:
  test_diagnostic_path (pretty_printer *event_pp)
  : simple_diagnostic_path (event_pp)
  {
  }

  void add_entry (tree fndecl, int stack_depth)
  {
    add_event (UNKNOWN_LOCATION, fndecl, stack_depth,
	       "entering %qE", fndecl);
  }

  void add_return (tree fndecl, int stack_depth)
  {
    add_event (UNKNOWN_LOCATION, fndecl, stack_depth,
	       "returning to %qE", fndecl);
  }

  void add_call (tree caller, int caller_stack_depth, tree callee)
  {
    add_event (UNKNOWN_LOCATION, caller, caller_stack_depth,
	       "calling %qE", callee);
    add_entry (callee, caller_stack_depth + 1);
  }
};

/* Verify that empty paths are handled gracefully.  */

static void
test_empty_path (pretty_printer *event_pp)
{
  test_diagnostic_path path (event_pp);
  ASSERT_FALSE (path.interprocedural_p ());

  path_summary summary (path, false);
  ASSERT_EQ (summary.get_num_ranges (), 0);

  test_diagnostic_context dc;
  print_path_summary_as_text (&summary, &dc, true);
  ASSERT_STREQ ("",
		pp_formatted_text (dc.printer));
}

/* Verify that print_path_summary works on a purely intraprocedural path.  */

static void
test_intraprocedural_path (pretty_printer *event_pp)
{
  tree fntype_void_void
    = build_function_type_array (void_type_node, 0, NULL);
  tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);

  test_diagnostic_path path (event_pp);
  path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
  path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");

  ASSERT_FALSE (path.interprocedural_p ());

  path_summary summary (path, false);
  ASSERT_EQ (summary.get_num_ranges (), 1);

  test_diagnostic_context dc;
  print_path_summary_as_text (&summary, &dc, true);
  ASSERT_STREQ ("  `foo': events 1-2 (depth 0)\n"
		"    |\n"
		"    | (1): first `free'\n"
		"    | (2): double `free'\n"
		"    |\n",
		pp_formatted_text (dc.printer));
}

/* Verify that print_path_summary works on an interprocedural path.  */

static void
test_interprocedural_path_1 (pretty_printer *event_pp)
{
  /* Build fndecls.  The types aren't quite right, but that
     doesn't matter for the purposes of this test.  */
  tree fntype_void_void
    = build_function_type_array (void_type_node, 0, NULL);
  tree fndecl_test = build_fn_decl ("test", fntype_void_void);
  tree fndecl_make_boxed_int
    = build_fn_decl ("make_boxed_int", fntype_void_void);
  tree fndecl_wrapped_malloc
    = build_fn_decl ("wrapped_malloc", fntype_void_void);
  tree fndecl_free_boxed_int
    = build_fn_decl ("free_boxed_int", fntype_void_void);
  tree fndecl_wrapped_free
    = build_fn_decl ("wrapped_free", fntype_void_void);

  test_diagnostic_path path (event_pp);
  path.add_entry (fndecl_test, 0);
  path.add_call (fndecl_test, 0, fndecl_make_boxed_int);
  path.add_call (fndecl_make_boxed_int, 1, fndecl_wrapped_malloc);
  path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_malloc, 2, "calling malloc");
  path.add_return (fndecl_test, 0);
  path.add_call (fndecl_test, 0, fndecl_free_boxed_int);
  path.add_call (fndecl_free_boxed_int, 1, fndecl_wrapped_free);
  path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_free, 2, "calling free");
  path.add_return (fndecl_test, 0);
  path.add_call (fndecl_test, 0, fndecl_free_boxed_int);
  path.add_call (fndecl_free_boxed_int, 1, fndecl_wrapped_free);
  path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_free, 2, "calling free");
  ASSERT_EQ (path.num_events (), 18);

  ASSERT_TRUE (path.interprocedural_p ());

  path_summary summary (path, false);
  ASSERT_EQ (summary.get_num_ranges (), 9);

  test_diagnostic_context dc;
  print_path_summary_as_text (&summary, &dc, true);
  ASSERT_STREQ
    ("  `test': events 1-2 (depth 0)\n"
     "    |\n"
     "    | (1): entering `test'\n"
     "    | (2): calling `make_boxed_int'\n"
     "    |\n"
     "    +--> `make_boxed_int': events 3-4 (depth 1)\n"
     "           |\n"
     "           | (3): entering `make_boxed_int'\n"
     "           | (4): calling `wrapped_malloc'\n"
     "           |\n"
     "           +--> `wrapped_malloc': events 5-6 (depth 2)\n"
     "                  |\n"
     "                  | (5): entering `wrapped_malloc'\n"
     "                  | (6): calling malloc\n"
     "                  |\n"
     "    <-------------+\n"
     "    |\n"
     "  `test': events 7-8 (depth 0)\n"
     "    |\n"
     "    | (7): returning to `test'\n"
     "    | (8): calling `free_boxed_int'\n"
     "    |\n"
     "    +--> `free_boxed_int': events 9-10 (depth 1)\n"
     "           |\n"
     "           | (9): entering `free_boxed_int'\n"
     "           | (10): calling `wrapped_free'\n"
     "           |\n"
     "           +--> `wrapped_free': events 11-12 (depth 2)\n"
     "                  |\n"
     "                  | (11): entering `wrapped_free'\n"
     "                  | (12): calling free\n"
     "                  |\n"
     "    <-------------+\n"
     "    |\n"
     "  `test': events 13-14 (depth 0)\n"
     "    |\n"
     "    | (13): returning to `test'\n"
     "    | (14): calling `free_boxed_int'\n"
     "    |\n"
     "    +--> `free_boxed_int': events 15-16 (depth 1)\n"
     "           |\n"
     "           | (15): entering `free_boxed_int'\n"
     "           | (16): calling `wrapped_free'\n"
     "           |\n"
     "           +--> `wrapped_free': events 17-18 (depth 2)\n"
     "                  |\n"
     "                  | (17): entering `wrapped_free'\n"
     "                  | (18): calling free\n"
     "                  |\n",
     pp_formatted_text (dc.printer));
}

/* Example where we pop the stack to an intermediate frame, rather than the
   initial one.  */

static void
test_interprocedural_path_2 (pretty_printer *event_pp)
{
  /* Build fndecls.  The types aren't quite right, but that
     doesn't matter for the purposes of this test.  */
  tree fntype_void_void
    = build_function_type_array (void_type_node, 0, NULL);
  tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
  tree fndecl_bar = build_fn_decl ("bar", fntype_void_void);
  tree fndecl_baz = build_fn_decl ("baz", fntype_void_void);

  test_diagnostic_path path (event_pp);
  path.add_entry (fndecl_foo, 0);
  path.add_call (fndecl_foo, 0, fndecl_bar);
  path.add_call (fndecl_bar, 1, fndecl_baz);
  path.add_return (fndecl_bar, 1);
  path.add_call (fndecl_bar, 1, fndecl_baz);
  ASSERT_EQ (path.num_events (), 8);

  ASSERT_TRUE (path.interprocedural_p ());

  path_summary summary (path, false);
  ASSERT_EQ (summary.get_num_ranges (), 5);

  test_diagnostic_context dc;
  print_path_summary_as_text (&summary, &dc, true);
  ASSERT_STREQ
    ("  `foo': events 1-2 (depth 0)\n"
     "    |\n"
     "    | (1): entering `foo'\n"
     "    | (2): calling `bar'\n"
     "    |\n"
     "    +--> `bar': events 3-4 (depth 1)\n"
     "           |\n"
     "           | (3): entering `bar'\n"
     "           | (4): calling `baz'\n"
     "           |\n"
     "           +--> `baz': event 5 (depth 2)\n"
     "                  |\n"
     "                  | (5): entering `baz'\n"
     "                  |\n"
     "           <------+\n"
     "           |\n"
     "         `bar': events 6-7 (depth 1)\n"
     "           |\n"
     "           | (6): returning to `bar'\n"
     "           | (7): calling `baz'\n"
     "           |\n"
     "           +--> `baz': event 8 (depth 2)\n"
     "                  |\n"
     "                  | (8): entering `baz'\n"
     "                  |\n",
     pp_formatted_text (dc.printer));
}

/* Verify that print_path_summary is sane in the face of a recursive
   diagnostic_path.  */

static void
test_recursion (pretty_printer *event_pp)
{
  tree fntype_void_void
    = build_function_type_array (void_type_node, 0, NULL);
  tree fndecl_factorial = build_fn_decl ("factorial", fntype_void_void);

 test_diagnostic_path path (event_pp);
  path.add_entry (fndecl_factorial, 0);
  for (int depth = 0; depth < 3; depth++)
    path.add_call (fndecl_factorial, depth, fndecl_factorial);
  ASSERT_EQ (path.num_events (), 7);

  ASSERT_TRUE (path.interprocedural_p ());

  path_summary summary (path, false);
  ASSERT_EQ (summary.get_num_ranges (), 4);

  test_diagnostic_context dc;
  print_path_summary_as_text (&summary, &dc, true);
  ASSERT_STREQ
    ("  `factorial': events 1-2 (depth 0)\n"
     "    |\n"
     "    | (1): entering `factorial'\n"
     "    | (2): calling `factorial'\n"
     "    |\n"
     "    +--> `factorial': events 3-4 (depth 1)\n"
     "           |\n"
     "           | (3): entering `factorial'\n"
     "           | (4): calling `factorial'\n"
     "           |\n"
     "           +--> `factorial': events 5-6 (depth 2)\n"
     "                  |\n"
     "                  | (5): entering `factorial'\n"
     "                  | (6): calling `factorial'\n"
     "                  |\n"
     "                  +--> `factorial': event 7 (depth 3)\n"
     "                         |\n"
     "                         | (7): entering `factorial'\n"
     "                         |\n",
     pp_formatted_text (dc.printer));
}

/* Run all of the selftests within this file.  */

void
tree_diagnostic_path_cc_tests ()
{
  auto_fix_quotes fix_quotes;
  pretty_printer *event_pp = global_dc->printer->clone ();
  pp_show_color (event_pp) = 0;
  test_empty_path (event_pp);
  test_intraprocedural_path (event_pp);
  test_interprocedural_path_1 (event_pp);
  test_interprocedural_path_2 (event_pp);
  test_recursion (event_pp);
  delete event_pp;
}

} // namespace selftest

#if __GNUC__ >= 10
#  pragma GCC diagnostic pop
#endif

#endif /* #if CHECKING_P */
