From 9d52d32b169d0e2b614eb32519d16735c32dec62 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 1 Sep 2015 13:11:31 -0400
Subject: [PATCH 25/49] Add overloads of inform, warning_at, etc that take a
 source_range

Various followup patches convert variables from "location_t" to
"source_range".  For the places where we issue diagnostics using
these variables, it's useful to have overloaded variants of
"warning_at" etc that take a source_range, allowing these
diagnostics to display underlines without needing to be rewritten.

gcc/ChangeLog:
	* diagnostic-core.h (warning_at): Add a overloaded declaration
	taking a source_range.
	(error_at): Likewise.
	(pedwarn): Likewise.
	(permerror): Likewise.
	(inform): Likewise.
	* diagnostic.c (inform): Implement new overloaded variant taking
	a source_range.
	(warning_at): Likewise.
	(pedwarn): Likewise.
	(permerror): Likewise.
	(error_at): Likewise.

gcc/c/ChangeLog:
	* c-errors.c (pedwarn_c99): Move bulk of implementation to...
	(pedwarn_c99_va): New function.
	(pedwarn_c99): New overload, taking a source_range.
	(pedwarn_c90): Move bulk of implementation to...
	(pedwarn_c90_va): New function.
	(pedwarn_c90): New overload, taking a source_range.
	* c-tree.h (pedwarn_c90): New declaration of overloaded function
	taking a source_range.
	(pedwarn_c99): Likewise.
---
 gcc/c/c-errors.c      | 97 +++++++++++++++++++++++++++++++++++++++++----------
 gcc/c/c-tree.h        |  4 +++
 gcc/diagnostic-core.h |  7 ++++
 gcc/diagnostic.c      | 84 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 173 insertions(+), 19 deletions(-)

diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c
index 647423d..a07752e 100644
--- a/gcc/c/c-errors.c
+++ b/gcc/c/c-errors.c
@@ -30,26 +30,34 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h"
 #include "opts.h"
 
+static bool
+pedwarn_c99_va (rich_location *richloc, int opt,
+		const char *gmsgid, va_list *args)
+     ATTRIBUTE_GCC_DIAG(3,0);
+
+static void
+pedwarn_c90_va (rich_location *richloc, int opt,
+		const char *gmsgid, va_list *args)
+     ATTRIBUTE_GCC_DIAG(3,0);
+
 /* Issue an ISO C99 pedantic warning MSGID if -pedantic outside C11 mode,
    otherwise issue warning MSGID if -Wc99-c11-compat is specified.
    This function is supposed to be used for matters that are allowed in
    ISO C11 but not supported in ISO C99, thus we explicitly don't pedwarn
    when C11 is specified.  */
 
-bool
-pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
+static bool
+pedwarn_c99_va (rich_location *richloc, int opt,
+		const char *gmsgid, va_list *args)
 {
   diagnostic_info diagnostic;
-  va_list ap;
   bool warned = false;
-  rich_location richloc (line_table, location);
 
-  va_start (ap, gmsgid);
   /* If desired, issue the C99/C11 compat warning, which is more specific
      than -pedantic.  */
   if (warn_c99_c11_compat > 0)
     {
-      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+      diagnostic_set_info (&diagnostic, gmsgid, args, richloc,
 			   (pedantic && !flag_isoc11)
 			   ? DK_PEDWARN : DK_WARNING);
       diagnostic.option_index = OPT_Wc99_c11_compat;
@@ -61,14 +69,43 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
   /* For -pedantic outside C11, issue a pedwarn.  */
   else if (pedantic && !flag_isoc11)
     {
-      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
+      diagnostic_set_info (&diagnostic, gmsgid, args, richloc, DK_PEDWARN);
       diagnostic.option_index = opt;
       warned = report_diagnostic (&diagnostic);
     }
-  va_end (ap);
   return warned;
 }
 
+/* As pedwarn_c99_va above, but at LOCATION.  */
+
+bool
+pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  bool ret;
+  rich_location richloc (line_table, location);
+
+  va_start (ap, gmsgid);
+  ret = pedwarn_c99_va (&richloc, opt, gmsgid, &ap);
+  va_end (ap);
+  return ret;
+}
+
+/* As pedwarn_c99_va above, but at SRC_RANGE.  */
+
+bool
+pedwarn_c99 (source_range src_range, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  bool ret;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  ret = pedwarn_c99_va (&richloc, opt, gmsgid, &ap);
+  va_end (ap);
+  return ret;
+}
+
 /* Issue an ISO C90 pedantic warning MSGID if -pedantic outside C99 mode,
    otherwise issue warning MSGID if -Wc90-c99-compat is specified, or if
    a specific option such as -Wlong-long is specified.
@@ -76,35 +113,33 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
    ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn
    when C99 is specified.  (There is no flag_c90.)  */
 
-void
-pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
+static void
+pedwarn_c90_va (rich_location *richloc, int opt,
+		const char *gmsgid, va_list *args)
 {
   diagnostic_info diagnostic;
-  va_list ap;
-  rich_location richloc (line_table, location);
 
-  va_start (ap, gmsgid);
   /* Warnings such as -Wvla are the most specific ones.  */
   if (opt != OPT_Wpedantic)
     {
       int opt_var = *(int *) option_flag_var (opt, &global_options);
       if (opt_var == 0)
-        goto out;
+	return;
       else if (opt_var > 0)
 	{
-	  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+	  diagnostic_set_info (&diagnostic, gmsgid, args, richloc,
 			       (pedantic && !flag_isoc99)
 			       ? DK_PEDWARN : DK_WARNING);
 	  diagnostic.option_index = opt;
 	  report_diagnostic (&diagnostic);
-	  goto out;
+	  return;
 	}
     }
   /* Maybe we want to issue the C90/C99 compat warning, which is more
      specific than -pedantic.  */
   if (warn_c90_c99_compat > 0)
     {
-      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+      diagnostic_set_info (&diagnostic, gmsgid, args, richloc,
 			   (pedantic && !flag_isoc99)
 			   ? DK_PEDWARN : DK_WARNING);
       diagnostic.option_index = OPT_Wc90_c99_compat;
@@ -116,10 +151,34 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
   /* For -pedantic outside C99, issue a pedwarn.  */
   else if (pedantic && !flag_isoc99)
     {
-      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
+      diagnostic_set_info (&diagnostic, gmsgid, args, richloc, DK_PEDWARN);
       diagnostic.option_index = opt;
       report_diagnostic (&diagnostic);
     }
-out:
+}
+
+/* As pedwarn_c90_va above, but at LOCATION.  */
+
+void
+pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  rich_location richloc (line_table, location);
+
+  va_start (ap, gmsgid);
+  pedwarn_c90_va (&richloc, opt, gmsgid, &ap);
+  va_end (ap);
+}
+
+/* As pedwarn_c90_va above, but at SRC_RANGE.  */
+
+void
+pedwarn_c90 (source_range src_range, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  pedwarn_c90_va (&richloc, opt, gmsgid, &ap);
   va_end (ap);
 }
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index ffa0598..bb791ec 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -717,8 +717,12 @@ extern bool tag_exists_p (enum tree_code, tree);
 /* In c-errors.c */
 extern void pedwarn_c90 (location_t, int opt, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
+extern void pedwarn_c90 (source_range, int opt, const char *, ...)
+    ATTRIBUTE_GCC_DIAG(3,4);
 extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
+extern bool pedwarn_c99 (source_range, int opt, const char *, ...)
+    ATTRIBUTE_GCC_DIAG(3,4);
 
 extern void
 set_c_expr_source_range (c_expr *expr,
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index a8a7c37..419fdd9 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -63,12 +63,15 @@ extern bool warning_n (location_t, int, int, const char *, const char *, ...)
     ATTRIBUTE_GCC_DIAG(4,6) ATTRIBUTE_GCC_DIAG(5,6);
 extern bool warning_at (location_t, int, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
+extern bool warning_at (source_range, int, const char *, ...)
+    ATTRIBUTE_GCC_DIAG(3,4);
 extern bool warning_at_rich_loc (rich_location *, int, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void error_n (location_t, int, const char *, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
 extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern void error_at (source_range, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void error_at_rich_loc (rich_location *, const char *, ...)
   ATTRIBUTE_GCC_DIAG(2,3);
 extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3)
@@ -76,11 +79,15 @@ extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3)
 /* Pass one of the OPT_W* from options.h as the second parameter.  */
 extern bool pedwarn (location_t, int, const char *, ...)
      ATTRIBUTE_GCC_DIAG(3,4);
+extern bool pedwarn (source_range, int, const char *, ...)
+     ATTRIBUTE_GCC_DIAG(3,4);
 extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern bool permerror (source_range, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool permerror_at_rich_loc (rich_location *, const char *,
 				   ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern void inform (source_range, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void inform_at_rich_loc (rich_location *, const char *,
 				...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void inform_n (location_t, int, const char *, const char *, ...)
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index d961d0c..f67cbb8 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -961,6 +961,21 @@ inform (location_t location, const char *gmsgid, ...)
   va_end (ap);
 }
 
+/* Same as "inform", but at SRC_RANGE.  */
+
+void
+inform (source_range src_range, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 /* Same as "inform", but at RICHLOC.  */
 void
 inform_at_rich_loc (rich_location *richloc, const char *gmsgid, ...)
@@ -1032,6 +1047,24 @@ warning_at (location_t location, int opt, const char *gmsgid, ...)
   return ret;
 }
 
+/* Same as warning at, but using SRC_RANGE.  */
+
+bool
+warning_at (source_range src_range, int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  bool ret;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING);
+  diagnostic.option_index = opt;
+  ret = report_diagnostic (&diagnostic);
+  va_end (ap);
+  return ret;
+}
+
 /* Same as warning at, but using RICHLOC.  */
 
 bool
@@ -1102,6 +1135,24 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...)
   return ret;
 }
 
+/* Same as pedwarn, but using SRC_RANGE.  */
+
+bool
+pedwarn (source_range src_range, int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  bool ret;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,  DK_PEDWARN);
+  diagnostic.option_index = opt;
+  ret = report_diagnostic (&diagnostic);
+  va_end (ap);
+  return ret;
+}
+
 /* A "permissive" error at LOCATION: issues an error unless
    -fpermissive was given on the command line, in which case it issues
    a warning.  Use this for things that really should be errors but we
@@ -1126,6 +1177,25 @@ permerror (location_t location, const char *gmsgid, ...)
   return ret;
 }
 
+/* Same as "permerror", but at SRC_RANGE.  */
+
+bool
+permerror (source_range src_range, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  bool ret;
+  rich_location richloc (src_range);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+                       permissive_error_kind (global_dc));
+  diagnostic.option_index = permissive_error_option (global_dc);
+  ret = report_diagnostic (&diagnostic);
+  va_end (ap);
+  return ret;
+}
+
 /* Same as "permerror", but at RICHLOC.  */
 
 bool
@@ -1191,6 +1261,20 @@ error_at (location_t loc, const char *gmsgid, ...)
   va_end (ap);
 }
 
+/* Same as ebove, but use range LOC instead of input_location.  */
+void
+error_at (source_range loc, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  rich_location richloc (loc);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 /* Same as above, but use RICH_LOC.  */
 
 void
-- 
1.8.5.3

