From 8eb59e38d2fee782b0c4b4768554acce2074df1a Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 1 Sep 2015 09:51:08 -0400
Subject: [PATCH 09/67] FIXME: Add -fdump-location-details, though I don't know
 if I ever used it (compiles, no ChangeLog or test coverage)

---
 gcc/common.opt               |  4 +++
 gcc/diagnostic.c             | 68 +++++++++++++++++++++++++++++++++++++++++++-
 gcc/diagnostic.h             |  2 ++
 gcc/opts.c                   |  4 +++
 gcc/testsuite/lib/gcc-dg.exp | 11 ++++++-
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index fb9e9da..5de1318 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1171,6 +1171,10 @@ fdump-go-spec=
 Common RejectNegative Joined Var(flag_dump_go_spec)
 -fdump-go-spec=filename	Write all declarations to file as Go code
 
+fdump-location-details
+Common Report Var(flag_dump_location_details)
+Emit details of location data in a machine-parseable form
+
 fdump-noaddr
 Common Report Var(flag_dump_noaddr)
 Suppress output of addresses in debugging dumps
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 393c1bd..0660537 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -186,6 +186,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
   context->x_data = NULL;
   context->lock = 0;
   context->inhibit_notes_p = false;
+  context->dump_location_details = false;
 }
 
 /* Maybe initialize the color support. We require clients to do this
@@ -321,7 +322,72 @@ diagnostic_build_prefix (diagnostic_context *context,
   locus_cs = colorize_start (pp_show_color (pp), "locus");
   locus_ce = colorize_stop (pp_show_color (pp));
 
-  expanded_location s = diagnostic_expand_location (diagnostic);
+  expanded_location s = diagnostic->richloc->lazily_expand_location ();
+
+  /* If -fdump-location-details, then emit range information.
+     This feature is intended for writing DejaGnu tests, and so
+     the format is primarily intended to be easy to write
+     regexps for (without requiring lots of escaping), and for
+     humans to read, rather than for parsing by IDEs.
+
+     This range information is parsed by process-message
+     within gcc-dg.exp, which expects a column number, a colon,
+     then an arbitrary amount of text describing ranges, terminated
+     by a colon-followed-by-a-space.  */
+  if (context->dump_location_details)
+    {
+      char *ranges_str = NULL;
+      char *result;
+      for (rich_location::range_iter iter = diagnostic->richloc->iter_ranges ();
+	   !iter.at_end ();
+	   iter.next())
+	{
+	  location_range *range = *iter;
+	  char *range_str;
+	  char *caption_str;
+	  /* If there's a caption, include it, followed by an '@'
+	     symbol.  */
+	  if (range->m_caption)
+	    caption_str = build_message_string ("%s@", range->m_caption);
+	  else
+	    caption_str = NULL;
+	  /* Omit the line numbers if both are the same as that of the
+	     caret, to make DejaGnu regexps more resilient against
+	     changes of line-number.  */
+	  if (s.line == range->m_start.line
+	      && s.line== range->m_finish.line)
+	    range_str = build_message_string (":%sc%d-c%d",
+					      caption_str ? caption_str : "",
+					      range->m_start.column,
+					      range->m_finish.column);
+	  else
+	    range_str = build_message_string (":%sr%dc%d-r%dc%d",
+					      caption_str ? caption_str : "",
+					      range->m_start.line,
+					      range->m_start.column,
+					      range->m_finish.line,
+					      range->m_finish.column);
+	  free (caption_str);
+
+	  if (ranges_str)
+	    {
+	      char *old_ranges_str = ranges_str;
+	      ranges_str = concat (ranges_str, range_str, NULL);
+	      free (range_str);
+	      free (old_ranges_str);
+	    }
+	  else
+	    ranges_str = range_str;
+	}
+      result = build_message_string ("%s%s:%d:%d%s:%s %s%s%s",
+				     locus_cs,
+				     s.file, s.line, s.column,
+				     ranges_str ? ranges_str : "",
+				     locus_ce,
+				     text_cs, text, text_ce);
+      free (ranges_str);
+      return result;
+    }
   return
     (s.file == NULL
      ? build_message_string ("%s%s:%s %s%s%s", locus_cs, progname, locus_ce,
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 5763a18..4807319 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -188,6 +188,8 @@ struct diagnostic_context
   int lock;
 
   bool inhibit_notes_p;
+
+  bool dump_location_details;
 };
 
 static inline void
diff --git a/gcc/opts.c b/gcc/opts.c
index 468a802..74e1af9 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1797,6 +1797,10 @@ common_handle_option (struct gcc_options *opts,
       /* Deferred.  */
       break;
 
+    case OPT_fdump_location_details:
+      dc->dump_location_details = value;
+      break;
+
     case OPT_ffast_math:
       set_fast_math_flags (opts, value);
       break;
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 322583b..303b096 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -937,7 +937,16 @@ proc process-message { msgproc msgprefix dgargs } {
 
     # Handle column numbers from the specified expression (if there is
     # one) and set up the search expression that will be used by DejaGnu.
-    if [regexp "^(\[0-9\]+):" $expmsg "" column] {
+    if [regexp "^(\[0-9\]+:.+): " $expmsg "" location_dump] {
+	# The expression includes a dump of range information from
+	# -fdump-location-details (a column number, a colon, then an
+	# arbitrary amount of text describing ranges, then a colon
+	# followed by a space).
+	# Remove the dump from the original expression and move it
+	# to the proper place in the search expression.
+	regsub "^(\[0-9\]+:.+): " $expmsg "" expmsg
+	set expmsg "$location_dump: $msgprefix\[^\n\]*$expmsg"
+    } elseif [regexp "^(\[0-9\]+):" $expmsg "" column] {
 	# The expression in the directive included a column number.
 	# Remove "COLUMN:" from the original expression and move it
 	# to the proper place in the search expression.
-- 
1.8.5.3

