From 3b6d8b254bb7c6cd6c15baea392d57b6caaf21f0 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 20 Oct 2015 17:42:55 -0400
Subject: [PATCH] Add colorize_source_p to diagnostic_context

gcc/ChangeLog:
	* diagnostic-show-locus.c (class layout): Add field
	"m_colorize_source_p".
	(layout::layout): Initialize m_colorize_source_p field from the
	diagnostic context.
	(layout::print_line): Only colorize the source line if
	m_colorize_source_p.
	* diagnostic.h (struct diagnostic_context): Add field
	"colorize_source_p".

gcc/testsuite/ChangeLog:
	* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (plugin_init):
	Set global_dc->colorize_source_p.
---
 gcc/diagnostic-show-locus.c                        | 37 ++++++++++++++++------
 gcc/diagnostic.h                                   |  9 ++++++
 .../plugin/diagnostic_plugin_test_show_locus.c     |  5 +++
 3 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index b6c9040..6865209 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -166,6 +166,7 @@ class layout
   diagnostic_t m_diagnostic_kind;
   expanded_location m_exploc;
   colorizer m_colorizer;
+  bool m_colorize_source_p;
   auto_vec <layout_range> m_layout_ranges;
   int m_first_line;
   int m_last_line;
@@ -419,6 +420,7 @@ layout::layout (diagnostic_context * context,
   m_diagnostic_kind (diagnostic->kind),
   m_exploc (diagnostic->richloc->lazily_expand_location ()),
   m_colorizer (context, diagnostic),
+  m_colorize_source_p (context->colorize_source_p),
   m_layout_ranges (rich_location::MAX_RANGES),
   m_first_line (m_exploc.line),
   m_last_line  (m_exploc.line),
@@ -478,7 +480,7 @@ layout::layout (diagnostic_context * context,
 /* Print text describing a line of source code.
    This typically prints two lines:
 
-   (1) the source code itself, colorized at any ranges, and
+   (1) the source code itself, potentially colorized at any ranges, and
    (2) an annotation line containing any carets/underlines
    describing the ranges.  */
 
@@ -507,15 +509,30 @@ layout::print_line (int row)
   int column;
   for (column = 1 + m_x_offset; column <= line_width; column++)
     {
-      bool in_range_p;
-      point_state state;
-      in_range_p = get_state_at_point (row, column,
-				       0, INT_MAX,
-				       &state);
-      if (in_range_p)
-	m_colorizer.set_range (state.range_idx);
-      else
-	m_colorizer.set_normal_text ();
+      /* Assuming colorization is enabled for the caret and underline
+	 characters, we may also colorize the associated characters
+	 within the source line.
+
+	 For frontends that generate range information, we color the
+	 associated characters in the source line the same as the
+	 carets and underlines in the annotation line, to make it easier
+	 for the reader to see the pertinent code.
+
+	 For frontends that only generate carets, we don't colorize the
+	 characters above them, since this would look strange (e.g.
+	 colorizing just the first character in a token).  */
+      if (m_colorize_source_p)
+	{
+	  bool in_range_p;
+	  point_state state;
+	  in_range_p = get_state_at_point (row, column,
+					   0, INT_MAX,
+					   &state);
+	  if (in_range_p)
+	    m_colorizer.set_range (state.range_idx);
+	  else
+	    m_colorizer.set_normal_text ();
+	}
       char c = *line == '\t' ? ' ' : *line;
       if (c == '\0')
 	c = ' ';
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index d4ebf86..153e84c 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -183,6 +183,15 @@ struct diagnostic_context
   int lock;
 
   bool inhibit_notes_p;
+
+  /* When printing source code, should the characters at carets and ranges
+     be colorized? (assuming colorization is on at all).
+     This should be true for frontends that generate range information
+     (so that the ranges of code are colorized),
+     and false for frontends that merely specify points within the
+     source code (to avoid e.g. colorizing just the first character in
+     a token, which would look strange).  */
+  bool colorize_source_p;
 };
 
 static inline void
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
index e49cf46..3471a4e 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
@@ -304,6 +304,11 @@ plugin_init (struct plugin_name_args *plugin_info,
   if (!plugin_default_version_check (version, &gcc_version))
     return 1;
 
+  /* For now, tell the dc to expect ranges and thus to colorize the source
+     lines, not just the carets/underlines.  This will be redundant
+     once the C frontend generates ranges.  */
+  global_dc->colorize_source_p = true;
+
   for (int i = 0; i < argc; i++)
     {
       if (0 == strcmp (argv[i].key, "color"))
-- 
1.8.5.3

