From cc003784addd6560edc205b1ff00da73fcb9e333 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 24 Jun 2019 15:04:57 -0400
Subject: [PATCH 39/63] FIXME: simplify and consolidate diagnostic_path
 printing

---
 gcc/common.opt                                     |  15 +-
 gcc/diagnostic-path.h                              |   4 +-
 gcc/diagnostic.c                                   |   2 +-
 gcc/diagnostic.h                                   |  24 +-
 gcc/opts.c                                         |   4 +-
 .../gcc.dg/plugin/diagnostic-path-format-default.c | 140 +++++++
 .../plugin/diagnostic-path-format-inline-events.c  | 140 +++++++
 .../gcc.dg/plugin/diagnostic-path-format-none.c    |  43 +++
 .../diagnostic-path-format-separate-events.c       |  44 +++
 .../diagnostic-path-summary-format-default.c       | 140 -------
 ...iagnostic-path-summary-format-event-summaries.c |  74 ----
 .../diagnostic-path-summary-format-inline-events.c | 140 -------
 .../plugin/diagnostic-path-summary-format-none.c   |  43 ---
 .../plugin/diagnostic-path-summary-format-simple.c |  66 ----
 .../gcc.dg/plugin/diagnostic-test-paths-1.c        |   2 +-
 .../gcc.dg/plugin/diagnostic-test-paths-2.c        |  31 +-
 gcc/testsuite/gcc.dg/plugin/plugin.exp             |   9 +-
 gcc/toplev.c                                       |   4 +-
 gcc/tree-diagnostic.c                              | 414 +++++++++------------
 19 files changed, 583 insertions(+), 756 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events.c
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-none.c
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-separate-events.c
 delete mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-default.c
 delete mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-event-summaries.c
 delete mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-inline-events.c
 delete mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-none.c
 delete mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-simple.c

diff --git a/gcc/common.opt b/gcc/common.opt
index ed12144..0613746 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1397,24 +1397,21 @@ fdiagnostics-show-metadata
 Common Var(flag_diagnostics_show_metadata) Init(1)
 FIXME; TODO: add to docs
 
-fdiagnostics-path-summary-format=
-Common Joined RejectNegative Var(flag_diagnostics_path_summary_format) Enum(diagnostic_path_summary_format) Init(DPSF_INLINE_EVENTS)
+fdiagnostics-path-format=
+Common Joined RejectNegative Var(flag_diagnostics_path_format) Enum(diagnostic_path_format) Init(DPF_INLINE_EVENTS)
 FIXME; TODO: docs
 
 Enum
-Name(diagnostic_path_summary_format) Type(int)
+Name(diagnostic_path_format) Type(int)
 
 EnumValue
-Enum(diagnostic_path_summary_format) String(none) Value(DPSF_NONE)
+Enum(diagnostic_path_format) String(none) Value(DPF_NONE)
 
 EnumValue
-Enum(diagnostic_path_summary_format) String(simple) Value(DPSF_SIMPLE)
+Enum(diagnostic_path_format) String(separate-events) Value(DPF_SEPARATE_EVENTS)
 
 EnumValue
-Enum(diagnostic_path_summary_format) String(event-summaries) Value(DPSF_EVENT_SUMMARIES)
-
-EnumValue
-Enum(diagnostic_path_summary_format) String(inline-events) Value(DPSF_INLINE_EVENTS)
+Enum(diagnostic_path_format) String(inline-events) Value(DPF_INLINE_EVENTS)
 
 fdiagnostics-show-path-depths
 Common Var(flag_diagnostics_show_path_depths) Init(0)
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h
index b337feb..353437d 100644
--- a/gcc/diagnostic-path.h
+++ b/gcc/diagnostic-path.h
@@ -74,7 +74,7 @@ class diagnostic_event
   virtual int get_stack_depth () const = 0;
 
   /* Get a localized (and possibly colorized) description of this event.  */
-  virtual label_text get_desc () const = 0;
+  virtual label_text get_desc (bool can_colorize) const = 0;
 };
 
 /* Abstract base class for getting at a sequence of events.  */
@@ -103,7 +103,7 @@ class simple_diagnostic_event : public diagnostic_event
   location_t get_location () const FINAL OVERRIDE { return m_loc; }
   tree get_fndecl () const FINAL OVERRIDE { return m_fndecl; }
   int get_stack_depth () const FINAL OVERRIDE { return m_depth; }
-  label_text get_desc () const FINAL OVERRIDE
+  label_text get_desc (bool) const FINAL OVERRIDE
   {
     return label_text::borrow (m_desc);
   }
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 0468325..e3c59de 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -179,7 +179,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
   for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
     context->caret_chars[i] = '^';
   context->show_metadata = false;
-  context->path_summary_format = DPSF_NONE;
+  context->path_format = DPF_NONE;
   context->show_path_depths = false;
   context->show_option_requested = false;
   context->abort_on_error = false;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 3734ba2..557e02d 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -35,20 +35,20 @@ enum diagnostics_output_format
   DIAGNOSTICS_OUTPUT_FORMAT_JSON
 };
 
-/* FIXME.  */
-enum diagnostic_path_summary_format
+/* An enum for controlling how diagnostic_paths should be printed.  */
+enum diagnostic_path_format
 {
-  /* FIXME.  */
-  DPSF_NONE,
+  /* Don't print diagnostic_paths.  */
+  DPF_NONE,
 
-  /* FIXME.  */
-  DPSF_SIMPLE,
+  /* Print diagnostic_paths by emitting a separate "note" for every event
+     in the path.  */
+  DPF_SEPARATE_EVENTS,
 
-  /* FIXME.  */
-  DPSF_EVENT_SUMMARIES,
-
-  /* FIXME.  */
-  DPSF_INLINE_EVENTS
+  /* Print diagnostic_paths by consolidating events together where they
+     are close enough, and emitting a "note" for every such consolidated
+     group.  */
+  DPF_INLINE_EVENTS
 };
 
 /* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
@@ -150,7 +150,7 @@ struct diagnostic_context
   bool show_metadata;
 
   /* FIXME.  */
-  enum diagnostic_path_summary_format path_summary_format;
+  enum diagnostic_path_format path_format;
 
   /* FIXME.  */
   bool show_path_depths;
diff --git a/gcc/opts.c b/gcc/opts.c
index ec63e17..737174a 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2408,8 +2408,8 @@ common_handle_option (struct gcc_options *opts,
       dc->show_metadata = value;
       break;
 
-    case OPT_fdiagnostics_path_summary_format_:
-      dc->path_summary_format = (enum diagnostic_path_summary_format)value;
+    case OPT_fdiagnostics_path_format_:
+      dc->path_format = (enum diagnostic_path_format)value;
       break;
 
     case OPT_fdiagnostics_show_path_depths:
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c
new file mode 100644
index 0000000..d68f856
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c
@@ -0,0 +1,140 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#include <stdlib.h>
+
+void *wrapped_malloc (size_t size)
+{
+  return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+  /* { dg-begin-multiline-output "" }
+  'test': events 1-2
+     |
+     | {
+     | ^
+     | |
+     | (1) entering 'test'
+     |   boxed_int *obj = make_boxed_int (i);
+     |                    ~~~~~~~~~~~~~~~~~~
+     |                    |
+     |                    (2) calling 'make_boxed_int'
+     |
+     +--> 'make_boxed_int': events 3-4
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (3) entering 'make_boxed_int'
+                  |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+                  |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                  |                                    |
+                  |                                    (4) calling 'wrapped_malloc'
+                  |
+                  +--> 'wrapped_malloc': events 5-6
+                               |
+                               | {
+                               | ^
+                               | |
+                               | (5) entering 'wrapped_malloc'
+                               |   return malloc (size);
+                               |          ~~~~~~~~~~~~~
+                               |          |
+                               |          (6) calling 'malloc'
+                               |
+     <-------------------------+
+     |
+  'test': event 7
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (7) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 8-9
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (8) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (9) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 10-11
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (10) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (11) calling 'free'
+                              |
+     <------------------------+
+     |
+  'test': event 12
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (12) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 13-14
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (13) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (14) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 15-16
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (15) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (16) calling 'free'
+                              |
+     { dg-end-multiline-output "" } */
+}
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+  result->i = i;
+  return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  wrapped_free (bi);
+}
+
+void test (int i)
+{
+  boxed_int *obj = make_boxed_int (i);
+
+  free_boxed_int (obj);
+
+  free_boxed_int (obj);
+}
+
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events.c
new file mode 100644
index 0000000..a457283
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events.c
@@ -0,0 +1,140 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-path-format=inline-events" } */
+
+#include <stdlib.h>
+
+void *wrapped_malloc (size_t size)
+{
+  return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+  /* { dg-begin-multiline-output "" }
+  'test': events 1-2
+     |
+     | {
+     | ^
+     | |
+     | (1) entering 'test'
+     |   boxed_int *obj = make_boxed_int (i);
+     |                    ~~~~~~~~~~~~~~~~~~
+     |                    |
+     |                    (2) calling 'make_boxed_int'
+     |
+     +--> 'make_boxed_int': events 3-4
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (3) entering 'make_boxed_int'
+                  |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+                  |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                  |                                    |
+                  |                                    (4) calling 'wrapped_malloc'
+                  |
+                  +--> 'wrapped_malloc': events 5-6
+                               |
+                               | {
+                               | ^
+                               | |
+                               | (5) entering 'wrapped_malloc'
+                               |   return malloc (size);
+                               |          ~~~~~~~~~~~~~
+                               |          |
+                               |          (6) calling 'malloc'
+                               |
+     <-------------------------+
+     |
+  'test': event 7
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (7) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 8-9
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (8) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (9) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 10-11
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (10) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (11) calling 'free'
+                              |
+     <------------------------+
+     |
+  'test': event 12
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (12) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 13-14
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (13) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (14) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 15-16
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (15) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (16) calling 'free'
+                              |
+     { dg-end-multiline-output "" } */
+}
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+  result->i = i;
+  return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  wrapped_free (bi);
+}
+
+void test (int i)
+{
+  boxed_int *obj = make_boxed_int (i);
+
+  free_boxed_int (obj);
+
+  free_boxed_int (obj);
+}
+
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-none.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-none.c
new file mode 100644
index 0000000..0a29f67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-none.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-path-format=none" } */
+
+#include <stdlib.h>
+
+void *wrapped_malloc (size_t size)
+{
+  return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+}
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+  result->i = i;
+  return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  wrapped_free (bi);
+}
+
+void test (int i)
+{
+  boxed_int *obj = make_boxed_int (i);
+
+  free_boxed_int (obj);
+
+  free_boxed_int (obj);
+}
+
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-separate-events.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-separate-events.c
new file mode 100644
index 0000000..dcb72c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-separate-events.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-path-format=separate-events" } */
+
+#include <stdlib.h>
+
+void *wrapped_malloc (size_t size)
+{
+  return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+}
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+  result->i = i;
+  return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  wrapped_free (bi);
+}
+
+void test (int i)
+{ /* { dg-message "\\(1\\) entering 'test'" } */
+  boxed_int *obj = make_boxed_int (i); /* { dg-message "\\(2\\) calling 'make_boxed_int'" } */
+  /* etc */
+
+  free_boxed_int (obj);
+
+  free_boxed_int (obj);
+}
+
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-default.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-default.c
deleted file mode 100644
index d68f856..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-default.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
-  return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
-  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
-  /* { dg-begin-multiline-output "" }
-  'test': events 1-2
-     |
-     | {
-     | ^
-     | |
-     | (1) entering 'test'
-     |   boxed_int *obj = make_boxed_int (i);
-     |                    ~~~~~~~~~~~~~~~~~~
-     |                    |
-     |                    (2) calling 'make_boxed_int'
-     |
-     +--> 'make_boxed_int': events 3-4
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (3) entering 'make_boxed_int'
-                  |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-                  |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  |                                    |
-                  |                                    (4) calling 'wrapped_malloc'
-                  |
-                  +--> 'wrapped_malloc': events 5-6
-                               |
-                               | {
-                               | ^
-                               | |
-                               | (5) entering 'wrapped_malloc'
-                               |   return malloc (size);
-                               |          ~~~~~~~~~~~~~
-                               |          |
-                               |          (6) calling 'malloc'
-                               |
-     <-------------------------+
-     |
-  'test': event 7
-     |
-     |   free_boxed_int (obj);
-     |   ^~~~~~~~~~~~~~~~~~~~
-     |   |
-     |   (7) calling 'free_boxed_int'
-     |
-     +--> 'free_boxed_int': events 8-9
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (8) entering 'free_boxed_int'
-                  |   wrapped_free (bi);
-                  |   ~~~~~~~~~~~~~~~~~
-                  |   |
-                  |   (9) calling 'wrapped_free'
-                  |
-                  +--> 'wrapped_free': events 10-11
-                              |
-                              | {
-                              | ^
-                              | |
-                              | (10) entering 'wrapped_free'
-                              |   free (ptr);
-                              |   ~~~~~~~~~~
-                              |   |
-                              |   (11) calling 'free'
-                              |
-     <------------------------+
-     |
-  'test': event 12
-     |
-     |   free_boxed_int (obj);
-     |   ^~~~~~~~~~~~~~~~~~~~
-     |   |
-     |   (12) calling 'free_boxed_int'
-     |
-     +--> 'free_boxed_int': events 13-14
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (13) entering 'free_boxed_int'
-                  |   wrapped_free (bi);
-                  |   ~~~~~~~~~~~~~~~~~
-                  |   |
-                  |   (14) calling 'wrapped_free'
-                  |
-                  +--> 'wrapped_free': events 15-16
-                              |
-                              | {
-                              | ^
-                              | |
-                              | (15) entering 'wrapped_free'
-                              |   free (ptr);
-                              |   ~~~~~~~~~~
-                              |   |
-                              |   (16) calling 'free'
-                              |
-     { dg-end-multiline-output "" } */
-}
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-  result->i = i;
-  return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  wrapped_free (bi);
-}
-
-void test (int i)
-{
-  boxed_int *obj = make_boxed_int (i);
-
-  free_boxed_int (obj);
-
-  free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-event-summaries.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-event-summaries.c
deleted file mode 100644
index 903c405..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-event-summaries.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-path-summary-format=event-summaries" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
-  return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
-  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
-  /* { dg-begin-multiline-output "" }
-  'test': events 1-2
-     | (1): entering 'test'
-     | (2): calling 'make_boxed_int'
-     +--> 'make_boxed_int': events 3-4
-                  | (3): entering 'make_boxed_int'
-                  | (4): calling 'wrapped_malloc'
-                  +--> 'wrapped_malloc': events 5-6
-                               | (5): entering 'wrapped_malloc'
-                               | (6): calling 'malloc'
-     <-------------------------+
-     |
-  'test': event 7
-     | (7): calling 'free_boxed_int'
-     +--> 'free_boxed_int': events 8-9
-                  | (8): entering 'free_boxed_int'
-                  | (9): calling 'wrapped_free'
-                  +--> 'wrapped_free': events 10-11
-                              | (10): entering 'wrapped_free'
-                              | (11): calling 'free'
-     <------------------------+
-     |
-  'test': event 12
-     | (12): calling 'free_boxed_int'
-     +--> 'free_boxed_int': events 13-14
-                  | (13): entering 'free_boxed_int'
-                  | (14): calling 'wrapped_free'
-                  +--> 'wrapped_free': events 15-16
-                              | (15): entering 'wrapped_free'
-                              | (16): calling 'free'
-     { dg-end-multiline-output "" } */
-}
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-  result->i = i;
-  return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  wrapped_free (bi);
-}
-
-void test (int i)
-{
-  boxed_int *obj = make_boxed_int (i);
-
-  free_boxed_int (obj);
-
-  free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-inline-events.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-inline-events.c
deleted file mode 100644
index c111e11..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-inline-events.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-path-summary-format=inline-events" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
-  return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
-  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
-  /* { dg-begin-multiline-output "" }
-  'test': events 1-2
-     |
-     | {
-     | ^
-     | |
-     | (1) entering 'test'
-     |   boxed_int *obj = make_boxed_int (i);
-     |                    ~~~~~~~~~~~~~~~~~~
-     |                    |
-     |                    (2) calling 'make_boxed_int'
-     |
-     +--> 'make_boxed_int': events 3-4
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (3) entering 'make_boxed_int'
-                  |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-                  |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  |                                    |
-                  |                                    (4) calling 'wrapped_malloc'
-                  |
-                  +--> 'wrapped_malloc': events 5-6
-                               |
-                               | {
-                               | ^
-                               | |
-                               | (5) entering 'wrapped_malloc'
-                               |   return malloc (size);
-                               |          ~~~~~~~~~~~~~
-                               |          |
-                               |          (6) calling 'malloc'
-                               |
-     <-------------------------+
-     |
-  'test': event 7
-     |
-     |   free_boxed_int (obj);
-     |   ^~~~~~~~~~~~~~~~~~~~
-     |   |
-     |   (7) calling 'free_boxed_int'
-     |
-     +--> 'free_boxed_int': events 8-9
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (8) entering 'free_boxed_int'
-                  |   wrapped_free (bi);
-                  |   ~~~~~~~~~~~~~~~~~
-                  |   |
-                  |   (9) calling 'wrapped_free'
-                  |
-                  +--> 'wrapped_free': events 10-11
-                              |
-                              | {
-                              | ^
-                              | |
-                              | (10) entering 'wrapped_free'
-                              |   free (ptr);
-                              |   ~~~~~~~~~~
-                              |   |
-                              |   (11) calling 'free'
-                              |
-     <------------------------+
-     |
-  'test': event 12
-     |
-     |   free_boxed_int (obj);
-     |   ^~~~~~~~~~~~~~~~~~~~
-     |   |
-     |   (12) calling 'free_boxed_int'
-     |
-     +--> 'free_boxed_int': events 13-14
-                  |
-                  | {
-                  | ^
-                  | |
-                  | (13) entering 'free_boxed_int'
-                  |   wrapped_free (bi);
-                  |   ~~~~~~~~~~~~~~~~~
-                  |   |
-                  |   (14) calling 'wrapped_free'
-                  |
-                  +--> 'wrapped_free': events 15-16
-                              |
-                              | {
-                              | ^
-                              | |
-                              | (15) entering 'wrapped_free'
-                              |   free (ptr);
-                              |   ~~~~~~~~~~
-                              |   |
-                              |   (16) calling 'free'
-                              |
-     { dg-end-multiline-output "" } */
-}
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-  result->i = i;
-  return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  wrapped_free (bi);
-}
-
-void test (int i)
-{
-  boxed_int *obj = make_boxed_int (i);
-
-  free_boxed_int (obj);
-
-  free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-none.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-none.c
deleted file mode 100644
index 2efdd74..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-none.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-path-summary-format=none" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
-  return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
-  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
-}
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-  result->i = i;
-  return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  wrapped_free (bi);
-}
-
-void test (int i)
-{
-  boxed_int *obj = make_boxed_int (i);
-
-  free_boxed_int (obj);
-
-  free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-simple.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-simple.c
deleted file mode 100644
index 097eb55..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-summary-format-simple.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-show-path-depths -fdiagnostics-path-summary-format=simple" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
-  return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
-  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
-  /* { dg-begin-multiline-output "" }
-  'test': events 1-2 (depth 0)
-     |
-     +--> 'make_boxed_int': events 3-4 (depth 1)
-                  |
-                  +--> 'wrapped_malloc': events 5-6 (depth 2)
-                               |
-     <-------------------------+
-     |
-  'test': event 7 (depth 0)
-     |
-     +--> 'free_boxed_int': events 8-9 (depth 1)
-                  |
-                  +--> 'wrapped_free': events 10-11 (depth 2)
-                              |
-     <------------------------+
-     |
-  'test': event 12 (depth 0)
-     |
-     +--> 'free_boxed_int': events 13-14 (depth 1)
-                  |
-                  +--> 'wrapped_free': events 15-16 (depth 2)
-     { dg-end-multiline-output "" } */
-}
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-  result->i = i;
-  return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  wrapped_free (bi);
-}
-
-void test (int i)
-{
-  boxed_int *obj = make_boxed_int (i);
-
-  free_boxed_int (obj);
-
-  free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-1.c
index 9b63760..66c2c66c 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fdiagnostics-path-format=separate-events" } */
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
index b42f37e..124f5a4 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
@@ -36,20 +36,23 @@ make_a_list_of_random_ints_badly(PyObject *self,
    29 |     PyList_Append(list, item);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      { dg-end-multiline-output "" } */
-
-  /* { dg-message "\\(1\\) when 'PyList_New' fails, returning NULL" "" { target *-*-* } PyList_New } */
   /* { dg-begin-multiline-output "" }
-   25 |   list = PyList_New(0);
-      |          ^~~~~~~~~~~~~
-   26 | 
-   27 |   for (i = 0; i < count; i++) {
-      |   ~~~     
-      |   |
-      |   (2) when 'i < count'
-   28 |     item = PyLong_FromLong(random());
-   29 |     PyList_Append(list, item);
-      |     ~~~~~~~~~~~~~~~~~~~~~~~~~
-      |     |
-      |     (3) when calling 'PyList_Append', passing NULL as argument 1
+  'make_a_list_of_random_ints_badly': events 1-3
+                   |
+                   |   25 |   list = PyList_New(0);
+                   |      |          ^~~~~~~~~~~~~
+                   |      |          |
+                   |      |          (1) when 'PyList_New' fails, returning NULL
+                   |   26 | 
+                   |   27 |   for (i = 0; i < count; i++) {
+                   |      |   ~~~     
+                   |      |   |
+                   |      |   (2) when 'i < count'
+                   |   28 |     item = PyLong_FromLong(random());
+                   |   29 |     PyList_Append(list, item);
+                   |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+                   |      |     |
+                   |      |     (3) when calling 'PyList_Append', passing NULL as argument 1
+                   |
      { dg-end-multiline-output "" } */
 }
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 60065e6..0f69459 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -60,11 +60,10 @@ set plugin_test_list [list \
 	  diagnostic-test-paths-1.c \
 	  diagnostic-test-paths-2.c \
 	  diagnostic-test-paths-3.c \
-	  diagnostic-path-summary-format-default.c \
-	  diagnostic-path-summary-format-none.c \
-	  diagnostic-path-summary-format-simple.c \
-	  diagnostic-path-summary-format-event-summaries.c \
-	  diagnostic-path-summary-format-inline-events.c } \
+	  diagnostic-path-format-default.c \
+	  diagnostic-path-format-none.c \
+	  diagnostic-path-format-separate-events.c \
+	  diagnostic-path-format-inline-events.c } \
 ]
 
 foreach plugin_test $plugin_test_list {
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e996829..f168bc7 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1123,8 +1123,8 @@ general_init (const char *argv0, bool init_signals)
     = global_options_init.x_flag_diagnostics_nn_line_numbers;
   global_dc->show_metadata
     = global_options_init.x_flag_diagnostics_show_metadata;
-  global_dc->path_summary_format
-    = (enum diagnostic_path_summary_format)global_options_init.x_flag_diagnostics_path_summary_format;
+  global_dc->path_format
+    = (enum diagnostic_path_format)global_options_init.x_flag_diagnostics_path_format;
   global_dc->show_path_depths
     = global_options_init.x_flag_diagnostics_show_path_depths;
   global_dc->show_option_requested
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 2106ed2..bcc435a 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -326,7 +326,9 @@ class path_label : public range_label
     unsigned event_idx = m_start_idx + range_idx;
     const diagnostic_event &event = m_path->get_event (event_idx);
 
-    label_text event_text (event.get_desc ());
+    /* Get the description of the event without colorization: we
+       shouldn't colorize within a range_label.  */
+    label_text event_text (event.get_desc (false));
     gcc_assert (event_text.m_buffer);
     label_text result
       = label_text::take (xasprintf ("(%i) %s", event_idx + 1,
@@ -384,7 +386,7 @@ can_consolidate_events (const diagnostic_event &e1,
 
    For use by print_path_summary.  */
 
-struct interprocedural_path_summary
+struct path_summary
 {
   /* A range of consecutive events within a diagnostic_path,
      all with the same fndecl and stack_depth.  */
@@ -399,15 +401,14 @@ struct interprocedural_path_summary
     int m_start_idx;
     int m_end_idx;
   };
-  interprocedural_path_summary (const diagnostic_path &path);
+  path_summary (const diagnostic_path &path);
 
   auto_vec <event_range> m_ranges;
 };
 
-/* interprocedural_path_summary's ctor.  */
+/* path_summary's ctor.  */
 
-interprocedural_path_summary::
-interprocedural_path_summary (const diagnostic_path &path)
+path_summary::path_summary (const diagnostic_path &path)
 {
   const unsigned num_events = path.num_events ();
 
@@ -466,27 +467,63 @@ print_fndecl (pretty_printer *pp, tree fndecl, bool quoted)
 /* Print SUMMARY to PP, giving an overview of the interprocedural
    calls and returns.
 
-   For example:
+   If SHOW_EVENT_SUMMARIES is true, then print the event descriptions
+   in a nested form.
 
    'foo' (events 1-2)
-     |
+     | (1) desc 1
+     | (2) desc 2
      +--> 'bar' (events 3-4)
-            |
+            | (3) desc 3
+            | (4) desc 4
             +--> 'baz' (events 5-6)
-                   |
+                   | (5) desc 5
+                   | (6) desc 6
      <------------ +
      |
    'foo' (events 7-8)
+     | (7) desc 7
+     | (8) desc 8
+     +--> 'bar' (events 9-10)
+            | (9) desc 9
+            | (10) desc 10
+            +--> 'baz' (events 11-12)
+                   | (11) desc 11
+                   | (12) desc 12
+
+   If SHOW_EVENT_SUMMARIES is false, then print 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)
-            |
-            +--> 'baz' (events 11-12).  */
+            | NN |
+            |    |
+            +--> 'baz' (events 11-12)
+                   | NN |
+                   |    |
+
+   SHOW_EVENT_SUMMARIES==true is currently only available via selftests.  */
 
 static void
 print_path_summary (pretty_printer *pp,
-		    const interprocedural_path_summary& summary,
-		    const diagnostic_path *path, bool show_depths,
-		    enum diagnostic_path_summary_format summary_format)
+		    const path_summary& summary,
+		    const diagnostic_path *path,
+		    bool show_depths,
+		    bool show_events_summaries)
 {
   auto_vec<int> name_lengths;
 
@@ -495,7 +532,7 @@ print_path_summary (pretty_printer *pp,
     pretty_printer *tmp_pp = pp->clone ();
     pp_show_color (tmp_pp) = 0;
     int i;
-    interprocedural_path_summary::event_range *range;
+    path_summary::event_range *range;
     FOR_EACH_VEC_ELT (summary.m_ranges, i, range)
       {
 	print_fndecl (tmp_pp, range->m_fndecl, false);
@@ -525,13 +562,13 @@ print_path_summary (pretty_printer *pp,
   const int base_indent = 2;
   int cur_indent = base_indent;
   unsigned i;
-  interprocedural_path_summary::event_range *range;
+  path_summary::event_range *range;
   FOR_EACH_VEC_ELT (summary.m_ranges, i, range)
     {
       write_indent (pp, cur_indent);
       if (i > 0)
 	{
-	  const interprocedural_path_summary::event_range *prev_range
+	  const path_summary::event_range *prev_range
 	    = &summary.m_ranges[i - 1];
 	  if (range->m_stack_depth > prev_range->m_stack_depth)
 	    {
@@ -556,80 +593,61 @@ print_path_summary (pretty_printer *pp,
 
       int midpoint = name_lengths[i] / 2;
 
-      switch (summary_format)
+      if (show_events_summaries)
 	{
-	default:
-	case DPSF_NONE:
-	  gcc_unreachable ();
-
-	case DPSF_SIMPLE:
-	  break;
-	case DPSF_EVENT_SUMMARIES:
-	  {
-	    for (int event_idx = range->m_start_idx;
-		 event_idx <= range->m_end_idx; event_idx++)
-	      {
-		write_indent (pp, cur_indent + midpoint);
-		label_text event_desc = path->get_event (event_idx).get_desc ();
-		pp_string (pp, start_line_color);
-		pp_string (pp, "|");
-		pp_string (pp, end_line_color);
-		pp_printf (pp, " (%i): %s",
-			   event_idx + 1, event_desc.m_buffer);
-		event_desc.maybe_free ();
-		pp_newline (pp);
-	      }
-	  }
-	  break;
-	case DPSF_INLINE_EVENTS:
-	  {
-	    write_indent (pp, cur_indent + midpoint);
-	    pp_string (pp, start_line_color);
-	    pp_string (pp, "|");
-	    pp_string (pp, end_line_color);
-	    /* No newline here, as diagnostic_show_locus adds a leading
-	       newline.  */
-
-	    char *saved_prefix = pp_take_prefix (pp);
-	    char *prefix;
+	  for (int event_idx = range->m_start_idx;
+	       event_idx <= range->m_end_idx; event_idx++)
 	    {
-	      pretty_printer tmp_pp;
-	      write_indent (&tmp_pp, cur_indent + midpoint);
-	      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));
+	      write_indent (pp, cur_indent + midpoint);
+	      label_text event_desc
+		= path->get_event (event_idx).get_desc (true);
+	      pp_string (pp, start_line_color);
+	      pp_string (pp, "|");
+	      pp_string (pp, end_line_color);
+	      pp_printf (pp, " (%i): %s",
+			 event_idx + 1, event_desc.m_buffer);
+	      event_desc.maybe_free ();
+	      pp_newline (pp);
 	    }
-	    pp_set_prefix (pp, prefix);
-	    pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
-	    print_event_range (pp, path,
-			       range->m_start_idx, range->m_end_idx,
-			       false);
-	    pp_set_prefix (pp, saved_prefix);
-
-	    write_indent (pp, cur_indent + midpoint);
-	    pp_string (pp, start_line_color);
-	    pp_string (pp, "|");
-	    pp_string (pp, end_line_color);
-	    pp_newline (pp);
+	}
+      else
+	{
+	  write_indent (pp, cur_indent + midpoint);
+	  pp_string (pp, start_line_color);
+	  pp_string (pp, "|");
+	  pp_string (pp, end_line_color);
+	  /* No newline here, as diagnostic_show_locus adds a leading
+	     newline.  */
+
+	  char *saved_prefix = pp_take_prefix (pp);
+	  char *prefix;
+	  {
+	    pretty_printer tmp_pp;
+	    write_indent (&tmp_pp, cur_indent + midpoint);
+	    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));
 	  }
-	  break;
+	  pp_set_prefix (pp, prefix);
+	  pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+	  print_event_range (pp, path,
+			     range->m_start_idx, range->m_end_idx,
+			     false);
+	  pp_set_prefix (pp, saved_prefix);
+
+	  write_indent (pp, cur_indent + midpoint);
+	  pp_string (pp, start_line_color);
+	  pp_string (pp, "|");
+	  pp_string (pp, end_line_color);
+	  pp_newline (pp);
 	}
 
       if (i < summary.m_ranges.length () - 1)
 	{
-	  const interprocedural_path_summary::event_range *next_range
+	  const path_summary::event_range *next_range
 	    = &summary.m_ranges[i + 1];
 
-	  if (summary_format == DPSF_SIMPLE)
-	    {
-	      write_indent (pp, cur_indent + midpoint);
-	      pp_string (pp, start_line_color);
-	      pp_printf (pp, "|");
-	      pp_string (pp, end_line_color);
-	      pp_newline (pp);
-	    }
-
 	  if (range->m_stack_depth > next_range->m_stack_depth)
 	    {
 	      /* Show returning from stack frame(s), by printing
@@ -676,8 +694,6 @@ print_path_summary (pretty_printer *pp,
 
 	}
     }
-  // TODO: maybe show state changes?
-  // TODO: maybe show all events
   /* TODO: example of recursion in DejaGnu tests.  */
 }
 
@@ -738,7 +754,7 @@ print_event_range (pretty_printer *pp,
 
       if (use_diagnostic)
 	{
-	  label_text event_text (event.get_desc ());
+	  label_text event_text (event.get_desc (true));
 	  inform (&richloc, "(%i) %s", start_idx + 1, event_text.m_buffer);
 	  event_text.maybe_free ();
 	}
@@ -777,42 +793,38 @@ tree_print_diagnostic_path (diagnostic_context *context,
 {
   const unsigned num_events = path->num_events ();
 
-  /* Attempt to show intraprocedural summary.  */
-  if (path->interprocedural_p ()
-      && context->path_summary_format != DPSF_NONE)
+  switch (context->path_format)
     {
-      inform (UNKNOWN_LOCATION, "summary of interprocedural path");
-
-      interprocedural_path_summary summary (*path);
+    case DPF_NONE:
+      /* Do nothing.  */
+      return;
 
-      char *saved_prefix = pp_take_prefix (context->printer);
-      pp_set_prefix (context->printer, NULL);
-      print_path_summary (context->printer,
-			  summary, path, context->show_path_depths,
-			  context->path_summary_format);
-      pp_flush (context->printer);
-      pp_set_prefix (context->printer, saved_prefix);
-    }
+    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 (true));
+	    gcc_assert (event_text.m_buffer);
+	    inform (event.get_location (),
+		    "(%i) %s", i + 1, event_text.m_buffer);
+	    event_text.maybe_free ();
+	  }
+      }
+      break;
 
-  /* TODO: options for different printing approaches.  */
-  if (context->show_caret && context->show_line_numbers_p)
-    {
-      if (num_events > 0)
-	print_event_range (context->printer, path, 0, num_events - 1,
-			   true);
-    }
-  else
-    {
-      /* Simpler implementation: 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 ());
-	  gcc_assert (event_text.m_buffer);
-	  inform (event.get_location (),
-		  "(%i) %s", i + 1, event_text.m_buffer);
-	  event_text.maybe_free ();
-	}
+    case DPF_INLINE_EVENTS:
+      {
+	/* Consolidate related events.  */
+	path_summary summary (*path);
+	char *saved_prefix = pp_take_prefix (context->printer);
+	pp_set_prefix (context->printer, NULL);
+	print_path_summary (context->printer,
+			    summary, path, context->show_path_depths, false);
+	pp_flush (context->printer);
+	pp_set_prefix (context->printer, saved_prefix);
+      }
     }
 }
 
@@ -832,7 +844,7 @@ tree_make_json_for_path (diagnostic_context *, const diagnostic_path *path)
       if (event.get_location ())
 	event_obj->set ("location",
 			json_from_expanded_location (event.get_location ()));
-      label_text event_text (event.get_desc ());
+      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 ())
@@ -900,12 +912,11 @@ test_empty_path (pretty_printer *event_pp)
   test_diagnostic_path path (event_pp);
   ASSERT_FALSE (path.interprocedural_p ());
 
-  interprocedural_path_summary summary (path);
+  path_summary summary (path);
   ASSERT_EQ (summary.m_ranges.length (), 0);
 
   pretty_printer pp;
-  print_path_summary (&pp, summary, &path, true,
-		      DPSF_INLINE_EVENTS);
+  print_path_summary (&pp, summary, &path, true, true);
   ASSERT_STREQ ("",
 		pp_formatted_text (&pp));
 }
@@ -925,37 +936,25 @@ test_intraprocedural_path (pretty_printer *event_pp)
 
   ASSERT_FALSE (path.interprocedural_p ());
 
-  interprocedural_path_summary summary (path);
+  path_summary summary (path);
   ASSERT_EQ (summary.m_ranges.length (), 1);
 
   {
     pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_SIMPLE);
-    ASSERT_STREQ ("  `foo': events 1-2 (depth 0)\n",
-		  pp_formatted_text (&pp));
-  }
-
-  {
-    pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_EVENT_SUMMARIES);
+    print_path_summary (&pp, summary, &path, true, false);
     ASSERT_STREQ ("  `foo': events 1-2 (depth 0)\n"
-		  "    | (1): first `free'\n"
-		  "    | (2): double `free'\n",
+		  "    |\n"
+		  "    |\n",
 		  pp_formatted_text (&pp));
   }
 
   {
     pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_INLINE_EVENTS);
-#if 0
+    print_path_summary (&pp, summary, &path, true, true);
     ASSERT_STREQ ("  `foo': events 1-2 (depth 0)\n"
 		  "    | (1): first `free'\n"
 		  "    | (2): double `free'\n",
 		  pp_formatted_text (&pp));
-#endif
   }
 }
 
@@ -995,85 +994,50 @@ test_interprocedural_path_1 (pretty_printer *event_pp)
 
   ASSERT_TRUE (path.interprocedural_p ());
 
-  interprocedural_path_summary summary (path);
+  path_summary summary (path);
   ASSERT_EQ (summary.m_ranges.length (), 9);
 
   {
     pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_SIMPLE);
+    print_path_summary (&pp, summary, &path, true, false);
     ASSERT_STREQ
       ("  `test': events 1-2 (depth 0)\n"
        "     |\n"
+       "     |\n"
        "     +--> `make_boxed_int': events 3-4 (depth 1)\n"
        "                  |\n"
+       "                  |\n"
        "                  +--> `wrapped_malloc': events 5-6 (depth 2)\n"
        "                               |\n"
+       "                               |\n"
        "     <-------------------------+\n"
        "     |\n"
        "  `test': events 7-8 (depth 0)\n"
        "     |\n"
+       "     |\n"
        "     +--> `free_boxed_int': events 9-10 (depth 1)\n"
        "                  |\n"
+       "                  |\n"
        "                  +--> `wrapped_free': events 11-12 (depth 2)\n"
        "                              |\n"
+       "                              |\n"
        "     <------------------------+\n"
        "     |\n"
        "  `test': events 13-14 (depth 0)\n"
        "     |\n"
-       "     +--> `free_boxed_int': events 15-16 (depth 1)\n"
-       "                  |\n"
-       "                  +--> `wrapped_free': events 17-18 (depth 2)\n",
-       pp_formatted_text (&pp));
-  }
-
-  /* FIXME: this is a little too verbose.  Would be nice to show
-     just the most pertinent events (here 6, 12, and 18), given that
-     the interprocedural stuff is much clearer, given the picture.  */
-  {
-    pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_EVENT_SUMMARIES);
-    ASSERT_STREQ
-      ("  `test': events 1-2 (depth 0)\n"
-       "     | (1): entering `test'\n"
-       "     | (2): calling `make_boxed_int'\n"
-       "     +--> `make_boxed_int': events 3-4 (depth 1)\n"
-       "                  | (3): entering `make_boxed_int'\n"
-       "                  | (4): calling `wrapped_malloc'\n"
-       "                  +--> `wrapped_malloc': events 5-6 (depth 2)\n"
-       "                               | (5): entering `wrapped_malloc'\n"
-       "                               | (6): calling malloc\n"
-       "     <-------------------------+\n"
        "     |\n"
-       "  `test': events 7-8 (depth 0)\n"
-       "     | (7): returning to `test'\n"
-       "     | (8): calling `free_boxed_int'\n"
-       "     +--> `free_boxed_int': events 9-10 (depth 1)\n"
-       "                  | (9): entering `free_boxed_int'\n"
-       "                  | (10): calling `wrapped_free'\n"
-       "                  +--> `wrapped_free': events 11-12 (depth 2)\n"
-       "                              | (11): entering `wrapped_free'\n"
-       "                              | (12): calling free\n"
-       "     <------------------------+\n"
-       "     |\n"
-       "  `test': events 13-14 (depth 0)\n"
-       "     | (13): returning to `test'\n"
-       "     | (14): calling `free_boxed_int'\n"
        "     +--> `free_boxed_int': events 15-16 (depth 1)\n"
-       "                  | (15): entering `free_boxed_int'\n"
-       "                  | (16): calling `wrapped_free'\n"
+       "                  |\n"
+       "                  |\n"
        "                  +--> `wrapped_free': events 17-18 (depth 2)\n"
-       "                              | (17): entering `wrapped_free'\n"
-       "                              | (18): calling free\n",
+       "                              |\n"
+       "                              |\n",
        pp_formatted_text (&pp));
   }
 
   {
     pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_INLINE_EVENTS);
-#if 0
+    print_path_summary (&pp, summary, &path, true, true);
     ASSERT_STREQ
       ("  `test': events 1-2 (depth 0)\n"
        "     | (1): entering `test'\n"
@@ -1107,7 +1071,6 @@ test_interprocedural_path_1 (pretty_printer *event_pp)
        "                              | (17): entering `wrapped_free'\n"
        "                              | (18): calling free\n",
        pp_formatted_text (&pp));
-#endif
   }
 }
 
@@ -1135,32 +1098,12 @@ test_interprocedural_path_2 (pretty_printer *event_pp)
 
   ASSERT_TRUE (path.interprocedural_p ());
 
-  interprocedural_path_summary summary (path);
+  path_summary summary (path);
   ASSERT_EQ (summary.m_ranges.length (), 5);
 
   {
     pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_SIMPLE);
-    ASSERT_STREQ
-      ("  `foo': events 1-2 (depth 0)\n"
-       "    |\n"
-       "    +--> `bar': events 3-4 (depth 1)\n"
-       "           |\n"
-       "           +--> `baz': event 5 (depth 2)\n"
-       "                  |\n"
-       "           <------+\n"
-       "           |\n"
-       "         `bar': events 6-7 (depth 1)\n"
-       "           |\n"
-       "           +--> `baz': event 8 (depth 2)\n",
-       pp_formatted_text (&pp));
-  }
-
-  {
-    pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_EVENT_SUMMARIES);
+    print_path_summary (&pp, summary, &path, true, true);
     ASSERT_STREQ
       ("  `foo': events 1-2 (depth 0)\n"
        "    | (1): entering `foo'\n"
@@ -1197,43 +1140,24 @@ test_recursion (pretty_printer *event_pp)
 
   ASSERT_TRUE (path.interprocedural_p ());
 
-  interprocedural_path_summary summary (path);
+  path_summary summary (path);
   ASSERT_EQ (summary.m_ranges.length (), 4);
 
-  {
-    pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_SIMPLE);
-    ASSERT_STREQ
-      ("  `factorial': events 1-2 (depth 0)\n"
-       "       |\n"
-       "       +--> `factorial': events 3-4 (depth 1)\n"
-       "                 |\n"
-       "                 +--> `factorial': events 5-6 (depth 2)\n"
-       "                           |\n"
-       "                           +--> `factorial': event 7 (depth 3)\n",
-       pp_formatted_text (&pp));
-  }
-
-  {
-    pretty_printer pp;
-    print_path_summary (&pp, summary, &path, true,
-			DPSF_EVENT_SUMMARIES);
-    ASSERT_STREQ
-      ("  `factorial': events 1-2 (depth 0)\n"
-       "       | (1): entering `factorial'\n"
-       "       | (2): calling `factorial'\n"
-       "       +--> `factorial': events 3-4 (depth 1)\n"
-       "                 | (3): entering `factorial'\n"
-       "                 | (4): calling `factorial'\n"
-       "                 +--> `factorial': events 5-6 (depth 2)\n"
-       "                           | (5): entering `factorial'\n"
-       "                           | (6): calling `factorial'\n"
-       "                           +--> `factorial': event 7 (depth 3)\n"
-       "                                     | (7): entering `factorial'\n",
-       pp_formatted_text (&pp));
-  }
-
+  pretty_printer pp;
+  print_path_summary (&pp, summary, &path, true, true);
+  ASSERT_STREQ
+    ("  `factorial': events 1-2 (depth 0)\n"
+     "       | (1): entering `factorial'\n"
+     "       | (2): calling `factorial'\n"
+     "       +--> `factorial': events 3-4 (depth 1)\n"
+     "                 | (3): entering `factorial'\n"
+     "                 | (4): calling `factorial'\n"
+     "                 +--> `factorial': events 5-6 (depth 2)\n"
+     "                           | (5): entering `factorial'\n"
+     "                           | (6): calling `factorial'\n"
+     "                           +--> `factorial': event 7 (depth 3)\n"
+     "                                     | (7): entering `factorial'\n",
+     pp_formatted_text (&pp));
 }
 
 /* Run all of the selftests within this file.  */
-- 
1.8.5.3

