/* Paths through the code associated with a diagnostic.
   Copyright (C) 2019-2023 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.get ());
    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.get ());
    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.get ());
	    pp_newline (pp);
	  }
	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.get ());
	    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.get (),
			  fndecl, stack_depth);
		else
		  inform (event.get_location (),
			  "%@ %s (depth %i)",
			  &event_id, event_text.get (),
			  stack_depth);
	      }
	    else
	      inform (event.get_location (),
		      "%@ %s", &event_id, event_text.get ());
	  }
      }
      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.get ()));
      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 */
