Less verbose fix-it hints for missing header files (PR 87091)
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 27 Aug 2018 14:02:05 +0000 (14:02 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 27 Aug 2018 14:02:05 +0000 (14:02 +0000)
This patch tweaks maybe_add_include_fixit so that if we're emitting a note
about adding the header file, the note's primary location will be replaced
by that of the fix-it hint, to avoid repeating a location we've already
emitted (or one close to it).

For example, this simplifies:

  ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:27: error: msg 1
  87 |       using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
     |                           ^~~~~~
  ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:22: note: msg 2
   73 | # include <debug/vector>
  +++ |+#include <vector>
   74 | #endif
  ....
   87 |       using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
      |                      ^~~

to:

  ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:27: error: msg 1
  87 |       using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
     |                           ^~~~~~
  ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
   73 | # include <debug/vector>
  +++ |+#include <vector>
   74 | #endif

eliminating the repetition of line 87 in the note.

Doing so requires converting show_caret_p to a tri-state, to avoid
meaninglessly printing a caret for the first column in the next line
(and colorizing it):

  ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
   73 | # include <debug/vector>
  +++ |+#include <vector>
   74 | #endif
      | ^

gcc/c-family/ChangeLog:
PR 87091
* c-common.c (c_cpp_error): Update for conversion of show_caret_p
to a tri-state.
(maybe_suggest_missing_token_insertion): Likewise.
(maybe_add_include_fixit): Add param "override_location".  If set,
and source-printing is enabled, then override the rich_location's
primary location with that of the insertion point for the fix-it
hint, marking it with SHOW_LINES_WITHOUT_RANGE.
* c-common.h (extern void maybe_add_include_fixit): Add bool
param.
* c-format.c (selftest::test_type_mismatch_range_labels): Update
for conversion of show_caret_p to a tri-state.
* c-warn.c (warn_for_restrict): Likewise.
* known-headers.cc
(suggest_missing_header::~suggest_missing_header): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.

gcc/c/ChangeLog:
PR 87091
* c-decl.c (implicitly_declare): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.
* c-objc-common.c (c_tree_printer): Update for conversion of
show_caret_p to a tri-state.

gcc/cp/ChangeLog:
PR 87091
* decl.c (grokdeclarator): Update for conversion of show_caret_p
to a tri-state.
* error.c (cp_printer): Likewise.
* name-lookup.c (maybe_suggest_missing_std_header): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.
* parser.c (cp_parser_string_literal): Update for conversion of
show_caret_p to a tri-state.
(cp_parser_elaborated_type_specifier): Likewise.
(set_and_check_decl_spec_loc): Likewise.
* pt.c (listify): Update call to maybe_add_include_fixit to not
override the location, as it is for an error.
* rtti.c (typeid_ok_p): Likewise.

gcc/ChangeLog:
PR 87091
* diagnostic-show-locus.c (class layout_range): Update for
conversion of show_caret_p to a tri-state.
(layout_range::layout_range): Likewise.
(make_range): Likewise.
(layout::maybe_add_location_range): Likewise.
(layout::should_print_annotation_line_p): Don't show annotation
lines for ranges that are SHOW_LINES_WITHOUT_RANGE.
(layout::get_state_at_point): Update for conversion of
show_caret_p to a tri-state.  Bail out early for
SHOW_LINES_WITHOUT_RANGE, so that such ranges don't affect
underlining or source colorization.
(gcc_rich_location::add_location_if_nearby): Update for conversion
of show_caret_p to a tri-state.
(selftest::test_one_liner_multiple_carets_and_ranges): Likewise.
(selftest::test_one_liner_fixit_replace_equal_secondary_range):
Likewise.
(selftest::test_one_liner_labels): Likewise.
* gcc-rich-location.c (gcc_rich_location::add_expr): Update for
conversion of show_caret_p to a tri-state.
* pretty-print.c (text_info::set_location): Likewise.
* pretty-print.h (text_info::set_location): Likewise.
* substring-locations.c (format_warning_n_va): Likewise.
* tree-diagnostic.c (default_tree_printer): Likewise.
* tree-pretty-print.c (newline_and_indent): Likewise.

gcc/fortran/ChangeLog:
PR 87091
* error.c (gfc_format_decoder): Update for conversion of
show_caret_p to a tri-state.

gcc/testsuite/ChangeLog:
PR 87091
* gcc.dg/empty.h: New file.
* gcc.dg/fixits-pr84852-1.c: Update for move of fix-it hint to
top of file and removal of redundant second printing of warning
location.
* gcc.dg/fixits-pr84852-2.c: Likewise.
* gcc.dg/missing-header-fixit-3.c: Likewise.
* gcc.dg/missing-header-fixit-4.c: New test.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Update for
conversion of show_caret_p to a tri-state.

libcpp/ChangeLog:
PR 87091
* include/line-map.h (enum range_display_kind): New enum.
(struct location_range): Replace field "m_show_caret_p" with
"m_range_display_kind", converting from bool to the new enum.
(class rich_location): Add example of line insertion fix-it hint.
(rich_location::add_range): Convert param "show_caret_p" from bool
to enum range_display_kind and rename to "range_display_kind",
giving it a default of SHOW_RANGE_WITHOUT_CARET.
(rich_location::set_range): Likewise, albeit without a default.
* line-map.c (rich_location::rich_location): Update for conversion
of show_caret_p to tri-state enum.
(rich_location::add_range): Likewise.
(rich_location::set_range): Likewise.

From-SVN: r263885

36 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c-format.c
gcc/c-family/c-warn.c
gcc/c-family/known-headers.cc
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/c/c-objc-common.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/diagnostic-show-locus.c
gcc/fortran/ChangeLog
gcc/fortran/error.c
gcc/gcc-rich-location.c
gcc/pretty-print.c
gcc/pretty-print.h
gcc/substring-locations.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/empty.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/fixits-pr84852-1.c
gcc/testsuite/gcc.dg/fixits-pr84852-2.c
gcc/testsuite/gcc.dg/missing-header-fixit-3.c
gcc/testsuite/gcc.dg/missing-header-fixit-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
gcc/tree-diagnostic.c
gcc/tree-pretty-print.c
libcpp/ChangeLog
libcpp/include/line-map.h
libcpp/line-map.c

index f3ee5cf877304b8707c6122629cd286cb2298b2e..4c4969deda351f9c780423e2dc979b4a28864eb0 100644 (file)
@@ -1,3 +1,31 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * diagnostic-show-locus.c (class layout_range): Update for
+       conversion of show_caret_p to a tri-state.
+       (layout_range::layout_range): Likewise.
+       (make_range): Likewise.
+       (layout::maybe_add_location_range): Likewise.
+       (layout::should_print_annotation_line_p): Don't show annotation
+       lines for ranges that are SHOW_LINES_WITHOUT_RANGE.
+       (layout::get_state_at_point): Update for conversion of
+       show_caret_p to a tri-state.  Bail out early for
+       SHOW_LINES_WITHOUT_RANGE, so that such ranges don't affect
+       underlining or source colorization.
+       (gcc_rich_location::add_location_if_nearby): Update for conversion
+       of show_caret_p to a tri-state.
+       (selftest::test_one_liner_multiple_carets_and_ranges): Likewise.
+       (selftest::test_one_liner_fixit_replace_equal_secondary_range):
+       Likewise.
+       (selftest::test_one_liner_labels): Likewise.
+       * gcc-rich-location.c (gcc_rich_location::add_expr): Update for
+       conversion of show_caret_p to a tri-state.
+       * pretty-print.c (text_info::set_location): Likewise.
+       * pretty-print.h (text_info::set_location): Likewise.
+       * substring-locations.c (format_warning_n_va): Likewise.
+       * tree-diagnostic.c (default_tree_printer): Likewise.
+       * tree-pretty-print.c (newline_and_indent): Likewise.
+
 2018-08-27  David Malcolm  <dmalcolm@redhat.com>
 
        PR 87091
index 2ca6662c3c5fcf92dfb94dd46a7cdcef0cc83b0d..2e844d47d48e3ccc837cf0026665de2625b8a574 100644 (file)
@@ -1,3 +1,23 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * c-common.c (c_cpp_error): Update for conversion of show_caret_p
+       to a tri-state.
+       (maybe_suggest_missing_token_insertion): Likewise.
+       (maybe_add_include_fixit): Add param "override_location".  If set,
+       and source-printing is enabled, then override the rich_location's
+       primary location with that of the insertion point for the fix-it
+       hint, marking it with SHOW_LINES_WITHOUT_RANGE.
+       * c-common.h (extern void maybe_add_include_fixit): Add bool
+       param.
+       * c-format.c (selftest::test_type_mismatch_range_labels): Update
+       for conversion of show_caret_p to a tri-state.
+       * c-warn.c (warn_for_restrict): Likewise.
+       * known-headers.cc
+       (suggest_missing_header::~suggest_missing_header): Update call to
+       maybe_add_include_fixit to suggest overriding the location, as it
+       is for a note.
+
 2018-08-27  Martin Liska  <mliska@suse.cz>
 
        * c-common.c (check_function_restrict): Use new function
index 0b0969b5216ed4c2132b5be02024249c16a65b0f..6a5d99171a035e1fff76a17694fcc4e8e8c0674c 100644 (file)
@@ -6131,7 +6131,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
       gcc_unreachable ();
     }
   if (done_lexing)
-    richloc->set_range (0, input_location, true);
+    richloc->set_range (0, input_location, SHOW_RANGE_WITH_CARET);
   diagnostic_set_info_translated (&diagnostic, msg, ap,
                                  richloc, dlevel);
   diagnostic_override_option_index (&diagnostic,
@@ -8336,8 +8336,8 @@ maybe_suggest_missing_token_insertion (rich_location *richloc,
       location_t hint_loc = hint->get_start_loc ();
       location_t old_loc = richloc->get_loc ();
 
-      richloc->set_range (0, hint_loc, true);
-      richloc->add_range (old_loc, false);
+      richloc->set_range (0, hint_loc, SHOW_RANGE_WITH_CARET);
+      richloc->add_range (old_loc);
     }
 }
 
@@ -8475,10 +8475,16 @@ static added_includes_t *added_includes;
    location.
 
    This function is idempotent: a header will be added at most once to
-   any given file.  */
+   any given file.
+
+   If OVERRIDE_LOCATION is true, then if a fix-it is added and will be
+   printed, then RICHLOC's primary location will be replaced by that of
+   the fix-it hint (for use by "inform" notes where the location of the
+   issue has already been reported).  */
 
 void
-maybe_add_include_fixit (rich_location *richloc, const char *header)
+maybe_add_include_fixit (rich_location *richloc, const char *header,
+                        bool override_location)
 {
   location_t loc = richloc->get_loc ();
   const char *file = LOCATION_FILE (loc);
@@ -8506,6 +8512,33 @@ maybe_add_include_fixit (rich_location *richloc, const char *header)
   char *text = xasprintf ("#include %s\n", header);
   richloc->add_fixit_insert_before (include_insert_loc, text);
   free (text);
+
+  if (override_location && global_dc->show_caret)
+    {
+      /* Replace the primary location with that of the insertion point for the
+        fix-it hint.
+
+        We use SHOW_LINES_WITHOUT_RANGE so that we don't meaningless print a
+        caret for the insertion point (or colorize it).
+
+        Hence we print e.g.:
+
+        ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
+         73 | # include <debug/vector>
+        +++ |+#include <vector>
+         74 | #endif
+
+        rather than:
+
+        ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
+         73 | # include <debug/vector>
+        +++ |+#include <vector>
+         74 | #endif
+            | ^
+
+        avoiding the caret on the first column of line 74.  */
+      richloc->set_range (0, include_insert_loc, SHOW_LINES_WITHOUT_RANGE);
+    }
 }
 
 /* Attempt to convert a braced array initializer list CTOR for array
index 9b05e60525074b88ecf24f003534ecd937dbba4f..c5e2028cbaa48aa3e1238c95fc413b37245bcc8c 100644 (file)
@@ -1327,7 +1327,7 @@ excess_precision_mode_join (enum flt_eval_method, enum flt_eval_method);
 extern int c_flt_eval_method (bool ts18661_p);
 extern void add_no_sanitize_value (tree node, unsigned int flags);
 
-extern void maybe_add_include_fixit (rich_location *, const char *);
+extern void maybe_add_include_fixit (rich_location *, const char *, bool);
 extern void maybe_suggest_missing_token_insertion (rich_location *richloc,
                                                   enum cpp_ttype token_type,
                                                   location_t prev_token_loc);
index 035878fd954f49b2a240cea75292ccba83c77424..98c49cf5d186b8a65b8e6c7f5042ee99ebbc3117 100644 (file)
@@ -4352,7 +4352,7 @@ test_type_mismatch_range_labels ()
   range_label_for_type_mismatch param_label (integer_type_node,
                                             char_type_node);
   gcc_rich_location richloc (fmt, &fmt_label);
-  richloc.add_range (param, false, &param_label);
+  richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, &param_label);
 
   test_diagnostic_context dc;
   diagnostic_show_locus (&dc, &richloc, DK_ERROR);
index 95b66c1eabb41130884e2f6ab884347f58deb706..a1a7f9359644c6d635854e2bc2e03d92e122762d 100644 (file)
@@ -2429,7 +2429,7 @@ warn_for_restrict (unsigned param_pos, tree *argarray, unsigned nargs)
     {
       arg = argarray[pos - 1];
       if (EXPR_HAS_LOCATION (arg))
-       richloc.add_range (EXPR_LOCATION (arg), false);
+       richloc.add_range (EXPR_LOCATION (arg));
     }
 
   return warning_n (&richloc, OPT_Wrestrict, arg_positions.length (),
index 5524d21631824beac9bccdee412e9d51c958ccb7..b0763cfe984871257b5f7a2252db152c2abe23c6 100644 (file)
@@ -192,7 +192,7 @@ suggest_missing_header::~suggest_missing_header ()
     return;
 
   gcc_rich_location richloc (get_location ());
-  maybe_add_include_fixit (&richloc, m_header_hint);
+  maybe_add_include_fixit (&richloc, m_header_hint, true);
   inform (&richloc,
          "%qs is defined in header %qs;"
          " did you forget to %<#include %s%>?",
index b3e499e58997d308d5e76d0addb80087df3e926a..d459dc465a18748213ce7a99e01d5615b8a20559 100644 (file)
@@ -1,3 +1,12 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * c-decl.c (implicitly_declare): Update call to
+       maybe_add_include_fixit to suggest overriding the location, as it
+       is for a note.
+       * c-objc-common.c (c_tree_printer): Update for conversion of
+       show_caret_p to a tri-state.
+
 2018-08-27  Martin Liska  <mliska@suse.cz>
 
        * c-decl.c (locate_old_decl): Use new function
index 80647ee0207ba2e4c43a2fb490a8782ce7f6d38a..feafc022768aee33239bc10b0bf67e22c9c45006 100644 (file)
@@ -3446,7 +3446,7 @@ implicitly_declare (location_t loc, tree functionid)
                  if (header != NULL && warned)
                    {
                      rich_location richloc (line_table, loc);
-                     maybe_add_include_fixit (&richloc, header);
+                     maybe_add_include_fixit (&richloc, header, true);
                      inform (&richloc,
                              "include %qs or provide a declaration of %qD",
                              header, decl);
index 238af199ab5222fb3946866fe4945b892b5fdcf8..12e777a48455948a461acf8bb190fb13f6feff77 100644 (file)
@@ -161,7 +161,8 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
     {
       t = va_arg (*text->args_ptr, tree);
       if (set_locus)
-       text->set_location (0, DECL_SOURCE_LOCATION (t), true);
+       text->set_location (0, DECL_SOURCE_LOCATION (t),
+                           SHOW_RANGE_WITH_CARET);
     }
 
   switch (*spec)
index e6d62082bf9068c2707f3a0c1485603c7b72ee02..a05049c747ac873b02e8831257e2c957781c0922 100644 (file)
@@ -1,3 +1,20 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * decl.c (grokdeclarator): Update for conversion of show_caret_p
+       to a tri-state.
+       * error.c (cp_printer): Likewise.
+       * name-lookup.c (maybe_suggest_missing_std_header): Update call to
+       maybe_add_include_fixit to suggest overriding the location, as it
+       is for a note.
+       * parser.c (cp_parser_string_literal): Update for conversion of
+       show_caret_p to a tri-state.
+       (cp_parser_elaborated_type_specifier): Likewise.
+       (set_and_check_decl_spec_loc): Likewise.
+       * pt.c (listify): Update call to maybe_add_include_fixit to not
+       override the location, as it is for an error.
+       * rtti.c (typeid_ok_p): Likewise.
+
 2018-08-27  Martin Liska  <mliska@suse.cz>
 
        * call.c (build_call_a): Use new function
index c9c5fa6b4d5ad88d607f63ef59815dc678557274..d9f4d3489292c0f14cb9ef4effc8a9345cfa2f23 100644 (file)
@@ -10737,14 +10737,14 @@ grokdeclarator (const cp_declarator *declarator,
       if (signed_p && unsigned_p)
        {
          gcc_rich_location richloc (declspecs->locations[ds_signed]);
-         richloc.add_range (declspecs->locations[ds_unsigned], false);
+         richloc.add_range (declspecs->locations[ds_unsigned]);
          error_at (&richloc,
                    "%<signed%> and %<unsigned%> specified together");
        }
       else if (long_p && short_p)
        {
          gcc_rich_location richloc (declspecs->locations[ds_long]);
-         richloc.add_range (declspecs->locations[ds_short], false);
+         richloc.add_range (declspecs->locations[ds_short]);
          error_at (&richloc, "%<long%> and %<short%> specified together");
        }
       else if (TREE_CODE (type) != INTEGER_TYPE
@@ -10888,7 +10888,7 @@ grokdeclarator (const cp_declarator *declarator,
       if (staticp == 2)
        {
          gcc_rich_location richloc (declspecs->locations[ds_virtual]);
-         richloc.add_range (declspecs->locations[ds_storage_class], false);
+         richloc.add_range (declspecs->locations[ds_storage_class]);
          error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
                    "and %<static%>", dname);
          storage_class = sc_none;
@@ -10897,7 +10897,7 @@ grokdeclarator (const cp_declarator *declarator,
       if (constexpr_p)
        {
          gcc_rich_location richloc (declspecs->locations[ds_virtual]);
-         richloc.add_range (declspecs->locations[ds_constexpr], false);
+         richloc.add_range (declspecs->locations[ds_constexpr]);
          error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
                    "and %<constexpr%>", dname);
        }
@@ -11448,7 +11448,7 @@ grokdeclarator (const cp_declarator *declarator,
                  {
                    /* Cannot be both friend and virtual.  */
                    gcc_rich_location richloc (declspecs->locations[ds_virtual]);
-                   richloc.add_range (declspecs->locations[ds_friend], false);
+                   richloc.add_range (declspecs->locations[ds_friend]);
                    error_at (&richloc, "virtual functions cannot be friends");
                    friendp = 0;
                  }
index 452ecb954677769ff9c16b13e408cf64fbc43ee6..5bab3f345ed8d8ebf0a191f27a491cc9e5c6cf8a 100644 (file)
@@ -4119,7 +4119,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
 
   pp_string (pp, result);
   if (set_locus && t != NULL)
-    text->set_location (0, location_of (t), true);
+    text->set_location (0, location_of (t), SHOW_RANGE_WITH_CARET);
   return true;
 #undef next_tree
 #undef next_tcode
index 8e009b29d61137e8c0bf75b82cf8ff55c7efd335..c0a12d746343a5c92f73d82ac66e1ec6526863dd 100644 (file)
@@ -5630,7 +5630,7 @@ maybe_suggest_missing_std_header (location_t location, tree name)
   if (cxx_dialect >= header_hint->min_dialect)
     {
       const char *header = header_hint->header;
-      maybe_add_include_fixit (&richloc, header);
+      maybe_add_include_fixit (&richloc, header, true);
       inform (&richloc,
              "%<std::%s%> is defined in header %qs;"
              " did you forget to %<#include %s%>?",
index 49d476b383fb37f38d9191ac9d50373b37331a7f..d8d4301272eb3b4a9f6310bcf4858cdd1de4a009 100644 (file)
@@ -4133,7 +4133,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
              else if (curr_type != CPP_STRING)
                {
                  rich_location rich_loc (line_table, tok->location);
-                 rich_loc.add_range (last_tok_loc, false);
+                 rich_loc.add_range (last_tok_loc);
                  error_at (&rich_loc,
                            "unsupported non-standard concatenation "
                            "of string literals");
@@ -17755,7 +17755,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
          || cp_parser_is_keyword (token, RID_STRUCT))
        {
          gcc_rich_location richloc (token->location);
-         richloc.add_range (input_location, false);
+         richloc.add_range (input_location);
          richloc.add_fixit_remove ();
          pedwarn (&richloc, 0, "elaborated-type-specifier for "
                   "a scoped enum must not use the %qD keyword",
@@ -28390,7 +28390,7 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
          gcc_rich_location richloc (location);
          if (gnu != decl_specs->gnu_thread_keyword_p)
            {
-             richloc.add_range (decl_specs->locations[ds_thread], false);
+             richloc.add_range (decl_specs->locations[ds_thread]);
              error_at (&richloc,
                        "both %<__thread%> and %<thread_local%> specified");
            }
index efed9a1bf60e92a911b2f9a3495eb0a6eb68bc71..a7266e368fc47838fbeba5791420c8eb4d244046 100644 (file)
@@ -26077,7 +26077,7 @@ listify (tree arg)
   if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
     {    
       gcc_rich_location richloc (input_location);
-      maybe_add_include_fixit (&richloc, "<initializer_list>");
+      maybe_add_include_fixit (&richloc, "<initializer_list>", false);
       error_at (&richloc,
                "deducing from brace-enclosed initializer list"
                " requires %<#include <initializer_list>%>");
index 6692fb7ff861722c636a3b5b1d0506a074070ad2..94a921987815b30bb6e6c8e6108c5e93f2907582 100644 (file)
@@ -317,7 +317,7 @@ typeid_ok_p (void)
   if (!COMPLETE_TYPE_P (const_type_info_type_node))
     {
       gcc_rich_location richloc (input_location);
-      maybe_add_include_fixit (&richloc, "<typeinfo>");
+      maybe_add_include_fixit (&richloc, "<typeinfo>", false);
       error_at (&richloc,
                "must %<#include <typeinfo>%> before using"
                " %<typeid%>");
index d305ada14566fe3ebd894b0c0555007fb9214162..6ce8a0f4a9b7e1bc949c95797dc10e3be19a69e9 100644 (file)
@@ -126,7 +126,7 @@ class layout_range
  public:
   layout_range (const expanded_location *start_exploc,
                const expanded_location *finish_exploc,
-               bool show_caret_p,
+               enum range_display_kind range_display_kind,
                const expanded_location *caret_exploc,
                const range_label *label);
 
@@ -135,7 +135,7 @@ class layout_range
 
   layout_point m_start;
   layout_point m_finish;
-  bool m_show_caret_p;
+  enum range_display_kind m_range_display_kind;
   layout_point m_caret;
   const range_label *m_label;
 };
@@ -412,12 +412,12 @@ colorizer::get_color_by_name (const char *name)
 
 layout_range::layout_range (const expanded_location *start_exploc,
                            const expanded_location *finish_exploc,
-                           bool show_caret_p,
+                           enum range_display_kind range_display_kind,
                            const expanded_location *caret_exploc,
                            const range_label *label)
 : m_start (*start_exploc),
   m_finish (*finish_exploc),
-  m_show_caret_p (show_caret_p),
+  m_range_display_kind (range_display_kind),
   m_caret (*caret_exploc),
   m_label (label)
 {
@@ -545,7 +545,7 @@ make_range (int start_line, int start_col, int end_line, int end_col)
     = {"test.c", start_line, start_col, NULL, false};
   const expanded_location finish_exploc
     = {"test.c", end_line, end_col, NULL, false};
-  return layout_range (&start_exploc, &finish_exploc, false,
+  return layout_range (&start_exploc, &finish_exploc, SHOW_RANGE_WITHOUT_CARET,
                       &start_exploc, NULL);
 }
 
@@ -986,13 +986,13 @@ layout::maybe_add_location_range (const location_range *loc_range,
     return false;
   if (finish.file != m_exploc.file)
     return false;
-  if (loc_range->m_show_caret_p)
+  if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
     if (caret.file != m_exploc.file)
       return false;
 
   /* Sanitize the caret location for non-primary ranges.  */
   if (m_layout_ranges.length () > 0)
-    if (loc_range->m_show_caret_p)
+    if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
       if (!compatible_locations_p (loc_range->m_loc, m_primary_loc))
        /* Discard any non-primary ranges that can't be printed
           sanely relative to the primary location.  */
@@ -1000,7 +1000,7 @@ layout::maybe_add_location_range (const location_range *loc_range,
 
   /* Everything is now known to be in the correct source file,
      but it may require further sanitization.  */
-  layout_range ri (&start, &finish, loc_range->m_show_caret_p, &caret,
+  layout_range ri (&start, &finish, loc_range->m_range_display_kind, &caret,
                   loc_range->m_label);
 
   /* If we have a range that finishes before it starts (perhaps
@@ -1037,7 +1037,7 @@ layout::maybe_add_location_range (const location_range *loc_range,
        return false;
       if (!will_show_line_p (finish.line))
        return false;
-      if (loc_range->m_show_caret_p)
+      if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
        if (!will_show_line_p (caret.line))
          return false;
     }
@@ -1362,8 +1362,12 @@ layout::should_print_annotation_line_p (linenum_type row) const
   layout_range *range;
   int i;
   FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
-    if (range->intersects_line_p (row))
-      return true;
+    {
+      if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE)
+       return false;
+      if (range->intersects_line_p (row))
+       return true;
+    }
   return false;
 }
 
@@ -2102,13 +2106,18 @@ layout::get_state_at_point (/* Inputs.  */
   int i;
   FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
     {
+      if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE)
+       /* Bail out early, so that such ranges don't affect underlining or
+          source colorization.  */
+       continue;
+
       if (range->contains_point (row, column))
        {
          out_state->range_idx = i;
 
          /* Are we at the range's caret?  is it visible? */
          out_state->draw_caret_p = false;
-         if (range->m_show_caret_p
+         if (range->m_range_display_kind == SHOW_RANGE_WITH_CARET
              && row == range->m_caret.m_line
              && column == range->m_caret.m_column)
            out_state->draw_caret_p = true;
@@ -2267,11 +2276,11 @@ gcc_rich_location::add_location_if_nearby (location_t loc)
   layout layout (global_dc, this, DK_ERROR);
   location_range loc_range;
   loc_range.m_loc = loc;
-  loc_range.m_show_caret_p = false;
+  loc_range.m_range_display_kind = SHOW_RANGE_WITHOUT_CARET;
   if (!layout.maybe_add_location_range (&loc_range, true))
     return false;
 
-  add_range (loc, false);
+  add_range (loc);
   return true;
 }
 
@@ -2421,8 +2430,8 @@ test_one_liner_multiple_carets_and_ranges ()
   dc.caret_chars[2] = 'C';
 
   rich_location richloc (line_table, foo);
-  richloc.add_range (bar, true);
-  richloc.add_range (field, true);
+  richloc.add_range (bar, SHOW_RANGE_WITH_CARET);
+  richloc.add_range (field, SHOW_RANGE_WITH_CARET);
   diagnostic_show_locus (&dc, &richloc, DK_ERROR);
   ASSERT_STREQ ("\n"
                " foo = bar.field;\n"
@@ -2543,7 +2552,7 @@ test_one_liner_fixit_replace_equal_secondary_range ()
   location_t finish = linemap_position_for_column (line_table, 15);
   rich_location richloc (line_table, equals);
   location_t field = make_location (start, start, finish);
-  richloc.add_range (field, false);
+  richloc.add_range (field);
   richloc.add_fixit_replace (field, "m_field");
   diagnostic_show_locus (&dc, &richloc, DK_ERROR);
   /* The replacement range is indicated in the annotation line,
@@ -2690,8 +2699,8 @@ test_one_liner_labels ()
     text_range_label label1 ("1");
     text_range_label label2 ("2");
     gcc_rich_location richloc (foo, &label0);
-    richloc.add_range (bar, false, &label1);
-    richloc.add_range (field, false, &label2);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
+    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
 
     {
       test_diagnostic_context dc;
@@ -2722,8 +2731,8 @@ test_one_liner_labels ()
     text_range_label label1 ("label 1");
     text_range_label label2 ("label 2");
     gcc_rich_location richloc (foo, &label0);
-    richloc.add_range (bar, false, &label1);
-    richloc.add_range (field, false, &label2);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
+    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
 
     test_diagnostic_context dc;
     diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@@ -2744,8 +2753,8 @@ test_one_liner_labels ()
     text_range_label label1 ("bbbb");
     text_range_label label2 ("c");
     gcc_rich_location richloc (foo, &label0);
-    richloc.add_range (bar, false, &label1);
-    richloc.add_range (field, false, &label2);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
+    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
 
     test_diagnostic_context dc;
     diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@@ -2764,8 +2773,8 @@ test_one_liner_labels ()
     text_range_label label1 ("1");
     text_range_label label2 ("2");
     gcc_rich_location richloc (field, &label0);
-    richloc.add_range (bar, false, &label1);
-    richloc.add_range (foo, false, &label2);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
+    richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label2);
 
     test_diagnostic_context dc;
     diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@@ -2784,8 +2793,8 @@ test_one_liner_labels ()
     text_range_label label1 ("label 1");
     text_range_label label2 ("label 2");
     gcc_rich_location richloc (bar, &label0);
-    richloc.add_range (bar, false, &label1);
-    richloc.add_range (bar, false, &label2);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
+    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label2);
 
     test_diagnostic_context dc;
     diagnostic_show_locus (&dc, &richloc, DK_ERROR);
index 22c40527bc69b4f4fef0bceb414a3a971f8a03ae..c8249f63380eb738b5def9f436e6057c84b17c70 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * error.c (gfc_format_decoder): Update for conversion of
+       show_caret_p to a tri-state.
+
 2018-08-25  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/86545
index 7e882ba76bf91eabfbba5cf5ab5eb3b7d90d739c..b3b0138b0c39f11a45457f4751207edf88b556c4 100644 (file)
@@ -953,7 +953,7 @@ gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec,
          = linemap_position_for_loc_and_offset (line_table,
                                                 loc->lb->location,
                                                 offset);
-       text->set_location (loc_num, src_loc, true);
+       text->set_location (loc_num, src_loc, SHOW_RANGE_WITH_CARET);
        pp_string (pp, result[loc_num]);
        return true;
       }
index 2576c7387ee38d4bc5a33d48350243894dd46f2d..81beb61661c6a81dce0060a578f5f692e4a4114a 100644 (file)
@@ -47,7 +47,7 @@ gcc_rich_location::add_expr (tree expr, range_label *label)
   gcc_assert (expr);
 
   if (CAN_HAVE_RANGE_P (expr))
-    add_range (EXPR_LOCATION (expr), false, label);
+    add_range (EXPR_LOCATION (expr), SHOW_RANGE_WITHOUT_CARET, label);
 }
 
 /* If T is an expression, add a range for it to the rich_location,
index 02967d05f75395c1eedc93fcef52a98c20788e81..7dd900b3bbf6028b6a01a4722e4fd171fd2d11ac 100644 (file)
@@ -705,10 +705,11 @@ static void pp_quoted_string (pretty_printer *, const char *, size_t = -1);
    For use e.g. when implementing "+" in client format decoders.  */
 
 void
-text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p)
+text_info::set_location (unsigned int idx, location_t loc,
+                        enum range_display_kind range_display_kind)
 {
   gcc_checking_assert (m_richloc);
-  m_richloc->set_range (idx, loc, show_caret_p);
+  m_richloc->set_range (idx, loc, range_display_kind);
 }
 
 location_t
index 0d67e3080500ad8db054a65d02e34623f0962e26..2decc516b1f08790598913b92e7eb75cc73dd536 100644 (file)
@@ -36,7 +36,8 @@ struct text_info
   void **x_data;
   rich_location *m_richloc;
 
-  void set_location (unsigned int idx, location_t loc, bool caret_p);
+  void set_location (unsigned int idx, location_t loc,
+                    enum range_display_kind range_display_kind);
   location_t get_location (unsigned int index_of_location) const;
 };
 
index 1981394a3f0b8c3b394a2ff411d92a88bb71662b..faf78845840d01e945b328417493231f3161aeca 100644 (file)
@@ -171,7 +171,7 @@ format_warning_n_va (const substring_loc &fmt_loc,
   gcc_rich_location richloc (primary_loc, primary_label);
 
   if (param_loc != UNKNOWN_LOCATION)
-    richloc.add_range (param_loc, false, param_label);
+    richloc.add_range (param_loc, SHOW_RANGE_WITHOUT_CARET, param_label);
 
   if (!err && corrected_substring && substring_within_range)
     richloc.add_fixit_replace (fmt_substring_range, corrected_substring);
index 24e2047e268b715206bd40379f33c628b7715df6..d99816171e48c73659edec15dfe54a0b486862eb 100644 (file)
@@ -1,3 +1,16 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * gcc.dg/empty.h: New file.
+       * gcc.dg/fixits-pr84852-1.c: Update for move of fix-it hint to
+       top of file and removal of redundant second printing of warning
+       location.
+       * gcc.dg/fixits-pr84852-2.c: Likewise.
+       * gcc.dg/missing-header-fixit-3.c: Likewise.
+       * gcc.dg/missing-header-fixit-4.c: New test.
+       * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Update for
+       conversion of show_caret_p to a tri-state.
+
 2018-08-27  David Malcolm  <dmalcolm@redhat.com>
 
        PR 87091
diff --git a/gcc/testsuite/gcc.dg/empty.h b/gcc/testsuite/gcc.dg/empty.h
new file mode 100644 (file)
index 0000000..e69de29
index 98087abd92980ede5befb6ac6f98f149e93de953..346626b4eb975f6a72bc0d264280f7995c28abd8 100644 (file)
 int foo (void) { return strlen(""); }
 
 /* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */
-/* { dg-message "include '<string.h>' or provide a declaration of 'strlen'" "" { target *-*-* } -812156810 } */
+/* { dg-message "include '<string.h>' or provide a declaration of 'strlen'" "" { target *-*-* } 1 } */
 #if 0
 { dg-begin-multiline-output "" }
 +#include <string.h>
  /* This is padding (to avoid the output containing DejaGnu directives).  */
 { dg-end-multiline-output "" }
 #endif
-
-/* We need this, to consume a stray line marker for the bogus line.  */
-/* { dg-regexp ".*fixits-pr84852-1.c:-812156810:25:" } */
index 0674ef546891f2f02f66c239fedd9abb49c3554e..9bc70f59b59dbe11db2da396c96c4747323e5238 100644 (file)
 int foo (void) { return strlen(""); }
 
 /* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */
-/* { dg-message "include '<string.h>' or provide a declaration of 'strlen'" "" { target *-*-* } -812156810 } */
+/* { dg-message "include '<string.h>' or provide a declaration of 'strlen'" "" { target *-*-* } 1 } */
 #if 0
 { dg-begin-multiline-output "" }
 +#include <string.h>
  /* This is padding (to avoid the output containing DejaGnu directives).  */
 { dg-end-multiline-output "" }
 #endif
-
-/* We need this, to consume a stray line marker for the bogus line.  */
-/* { dg-regexp ".*fixits-pr84852-2.c:-812156810:25:" } */
index 7c72b1decc8eceeca42aceb4ba9f34d2cbd6f702..a692b4d21b392c323dc4c939257d4487434ef821 100644 (file)
@@ -7,18 +7,15 @@
 void test (int i, int j)
 {
   printf ("%i of %i\n", i, j); /* { dg-warning "implicit declaration" } */
-  /* { dg-message "include '<stdio.h>' or provide a declaration of 'printf'" "" { target *-*-* } .-1 } */
+  /* { dg-message "include '<stdio.h>' or provide a declaration of 'printf'" "" { target *-*-* } 1 } */
 #if 0
 /* { dg-begin-multiline-output "" }
 9 |   printf ("%i of %i\n", i, j);
   |   ^~~~~~
    { dg-end-multiline-output "" } */
 /* { dg-begin-multiline-output "" }
-+++ |+#include <stdio.h>
-  1 | /* Example of a fix-it hint that adds a #include directive,
-....
-  9 |   printf ("%i of %i\n", i, j);
-    |   ^~~~~~
++ |+#include <stdio.h>
+1 | /* Example of a fix-it hint that adds a #include directive,
    { dg-end-multiline-output "" } */
 #endif
 }
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-4.c b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
new file mode 100644 (file)
index 0000000..0ed3e2c
--- /dev/null
@@ -0,0 +1,23 @@
+/* Example of a fix-it hint that adds a #include directive,
+   adding them after a pre-existing #include directive.  */
+#include "empty.h"
+int the_next_line;
+
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+
+void test (int i, int j)
+{
+  printf ("%i of %i\n", i, j); /* { dg-line printf } */
+  /* { dg-warning "implicit declaration of function" "" { target *-*-* } printf } */
+  /* { dg-warning "incompatible implicit declaration" "" { target *-*-* } printf } */
+  /* { dg-begin-multiline-output "" }
+10 |   printf ("%i of %i\n", i, j);
+   |   ^~~~~~
+   { dg-end-multiline-output "" } */
+  /* { dg-message "include '<stdio.h>' or provide a declaration of 'printf'" "" { target *-*-* } 4 } */
+  /* { dg-begin-multiline-output "" }
+3 | #include "empty.h"
++ |+#include <stdio.h>
+4 | int the_next_line;
+   { dg-end-multiline-output "" } */
+}
index 3d7853813ae5d0120e961b3037dd59f0d6fb0daf..a55efafddff392bce6d5050ec8d815277423dae2 100644 (file)
@@ -145,9 +145,11 @@ custom_diagnostic_finalizer (diagnostic_context *context,
 
 static void
 add_range (rich_location *richloc, location_t start, location_t finish,
-          bool show_caret_p, const range_label *label = NULL)
+          enum range_display_kind range_display_kind
+            = SHOW_RANGE_WITHOUT_CARET,
+          const range_label *label = NULL)
 {
-  richloc->add_range (make_location (start, start, finish), show_caret_p,
+  richloc->add_range (make_location (start, start, finish), range_display_kind,
                      label);
 }
 
@@ -176,8 +178,8 @@ test_show_locus (function *fun)
     {
       const int line = fnstart_line + 2;
       rich_location richloc (line_table, get_loc (line, 15));
-      add_range (&richloc, get_loc (line, 10), get_loc (line, 14), false);
-      add_range (&richloc, get_loc (line, 16), get_loc (line, 16), false);
+      add_range (&richloc, get_loc (line, 10), get_loc (line, 14));
+      add_range (&richloc, get_loc (line, 16), get_loc (line, 16));
       warning_at (&richloc, 0, "test");
     }
 
@@ -185,8 +187,8 @@ test_show_locus (function *fun)
     {
       const int line = fnstart_line + 2;
       rich_location richloc (line_table, get_loc (line, 24));
-      add_range (&richloc, get_loc (line, 6), get_loc (line, 22), false);
-      add_range (&richloc, get_loc (line, 26), get_loc (line, 43), false);
+      add_range (&richloc, get_loc (line, 6), get_loc (line, 22));
+      add_range (&richloc, get_loc (line, 26), get_loc (line, 43));
       warning_at (&richloc, 0, "test");
     }
 
@@ -195,9 +197,8 @@ test_show_locus (function *fun)
       const int line = fnstart_line + 2;
       text_range_label label ("label");
       rich_location richloc (line_table, get_loc (line + 1, 7), &label);
-      add_range (&richloc, get_loc (line, 7), get_loc (line, 23), false);
-      add_range (&richloc, get_loc (line + 1, 9), get_loc (line + 1, 26),
-                false);
+      add_range (&richloc, get_loc (line, 7), get_loc (line, 23));
+      add_range (&richloc, get_loc (line + 1, 9), get_loc (line + 1, 26));
       warning_at (&richloc, 0, "test");
     }
 
@@ -208,10 +209,10 @@ test_show_locus (function *fun)
       text_range_label label1 ("label 1");
       text_range_label label2 ("label 2");
       rich_location richloc (line_table, get_loc (line + 5, 7), &label0);
-      add_range (&richloc, get_loc (line, 7), get_loc (line + 4, 65), false,
-                &label1);
+      add_range (&richloc, get_loc (line, 7), get_loc (line + 4, 65),
+                SHOW_RANGE_WITHOUT_CARET, &label1);
       add_range (&richloc, get_loc (line + 5, 9), get_loc (line + 10, 61),
-                false, &label2);
+                SHOW_RANGE_WITHOUT_CARET, &label2);
       warning_at (&richloc, 0, "test");
     }
 
@@ -250,7 +251,8 @@ test_show_locus (function *fun)
                                            get_loc (line, 90),
                                            get_loc (line, 98)),
                             &label0);
-      richloc.add_range (get_loc (line, 35), false, &label1);
+      richloc.add_range (get_loc (line, 35), SHOW_RANGE_WITHOUT_CARET,
+                        &label1);
       richloc.add_fixit_replace ("bar * foo");
       warning_at (&richloc, 0, "test");
       global_dc->show_ruler_p = false;
@@ -270,7 +272,8 @@ test_show_locus (function *fun)
                                            get_loc (line, 98)),
                             &label0);
       richloc.add_fixit_replace ("bar * foo");
-      richloc.add_range (get_loc (line, 34), false, &label1);
+      richloc.add_range (get_loc (line, 34), SHOW_RANGE_WITHOUT_CARET,
+                        &label1);
       warning_at (&richloc, 0, "test");
       global_dc->show_ruler_p = false;
     }
@@ -282,7 +285,7 @@ test_show_locus (function *fun)
       location_t caret_a = get_loc (line, 7);
       location_t caret_b = get_loc (line, 11);
       rich_location richloc (line_table, caret_a);
-      add_range (&richloc, caret_b, caret_b, true);
+      add_range (&richloc, caret_b, caret_b, SHOW_RANGE_WITH_CARET);
       global_dc->caret_chars[0] = 'A';
       global_dc->caret_chars[1] = 'B';
       warning_at (&richloc, 0, "test");
@@ -400,7 +403,7 @@ test_show_locus (function *fun)
       location_t caret_a = get_loc (line, 5);
       location_t caret_b = get_loc (line - 1, 19);
       rich_location richloc (line_table, caret_a);
-      richloc.add_range (caret_b, true);
+      richloc.add_range (caret_b, SHOW_RANGE_WITH_CARET);
       global_dc->caret_chars[0] = '1';
       global_dc->caret_chars[1] = '2';
       warning_at (&richloc, 0, "test");
@@ -449,7 +452,7 @@ test_show_locus (function *fun)
                      location_t word
                        = make_location (start_of_word, start_of_word,
                                         end_of_word);
-                     richloc.add_range (word, true, &label);
+                     richloc.add_range (word, SHOW_RANGE_WITH_CARET, &label);
 
                      /* Add a fixit, converting to upper case.  */
                      char_span word_span = content.subspan (start_idx, idx - start_idx);
index 6b03b31c2297fa8c15f2b0d41d40b563e5a6b3f5..c4a200f7fbc633c1220a77506077123387b58fb9 100644 (file)
@@ -290,7 +290,7 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
     }
 
   if (set_locus)
-    text->set_location (0, DECL_SOURCE_LOCATION (t), true);
+    text->set_location (0, DECL_SOURCE_LOCATION (t), SHOW_RANGE_WITH_CARET);
 
   if (DECL_P (t))
     {
index 622142719ee1d7208910ec85612332a73ddbbacf..990cc2167c7590e01e5046cb103e2d3901f56932 100644 (file)
@@ -3962,7 +3962,7 @@ newline_and_indent (pretty_printer *pp, int spc)
 void
 percent_K_format (text_info *text, location_t loc, tree block)
 {
-  text->set_location (0, loc, true);
+  text->set_location (0, loc, SHOW_RANGE_WITH_CARET);
   gcc_assert (pp_ti_abstract_origin (text) != NULL);
   *pp_ti_abstract_origin (text) = NULL;
 
index cbf4cbf704209ad85e22e26e46e4022505397084..7b716cf9a3e973d216ced67c3096f23cab9d0995 100644 (file)
@@ -1,3 +1,19 @@
+2018-08-27  David Malcolm  <dmalcolm@redhat.com>
+
+       PR 87091
+       * include/line-map.h (enum range_display_kind): New enum.
+       (struct location_range): Replace field "m_show_caret_p" with
+       "m_range_display_kind", converting from bool to the new enum.
+       (class rich_location): Add example of line insertion fix-it hint.
+       (rich_location::add_range): Convert param "show_caret_p" from bool
+       to enum range_display_kind and rename to "range_display_kind",
+       giving it a default of SHOW_RANGE_WITHOUT_CARET.
+       (rich_location::set_range): Likewise, albeit without a default.
+       * line-map.c (rich_location::rich_location): Update for conversion
+       of show_caret_p to tri-state enum.
+       (rich_location::add_range): Likewise.
+       (rich_location::set_range): Likewise.
+
 2018-08-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR bootstrap/86872
index 4f0ff8719a79abe5779851205de0549f60b1436e..e74ccbb5703e869806638f29c16c0067c2b68108 100644 (file)
@@ -1283,6 +1283,36 @@ typedef struct
 
 class range_label;
 
+/* A hint to diagnostic_show_locus on how to print a source range within a
+   rich_location.
+
+   Typically this is SHOW_RANGE_WITH_CARET for the 0th range, and
+   SHOW_RANGE_WITHOUT_CARET for subsequent ranges,
+   but the Fortran frontend uses SHOW_RANGE_WITH_CARET repeatedly for
+   printing things like:
+
+       x = x + y
+           1   2
+       Error: Shapes for operands at (1) and (2) are not conformable
+
+   where "1" and "2" are notionally carets.  */
+
+enum range_display_kind
+{
+  /* Show the pertinent source line(s), the caret, and underline(s).  */
+  SHOW_RANGE_WITH_CARET,
+
+  /* Show the pertinent source line(s) and underline(s), but don't
+     show the caret (just an underline).  */
+  SHOW_RANGE_WITHOUT_CARET,
+
+  /* Just show the source lines; don't show the range itself.
+     This is for use when displaying some line-insertion fix-it hints (for
+     showing the user context on the change, for when it doesn't make sense
+     to highlight the first column on the next line).  */
+  SHOW_LINES_WITHOUT_RANGE
+};
+
 /* A location within a rich_location: a caret&range, with
    the caret potentially flagged for display, and an optional
    label.  */
@@ -1291,16 +1321,7 @@ struct location_range
 {
   source_location m_loc;
 
-  /* Should a caret be drawn for this range?  Typically this is
-     true for the 0th range, and false for subsequent ranges,
-     but the Fortran frontend overrides this for rendering things like:
-
-       x = x + y
-           1   2
-       Error: Shapes for operands at (1) and (2) are not conformable
-
-     where "1" and "2" are notionally carets.  */
-  bool m_show_caret_p;
+  enum range_display_kind m_range_display_kind;
 
   /* If non-NULL, the label for this range.  */
   const range_label *m_label;
@@ -1567,6 +1588,18 @@ class fixit_hint;
    added via
      richloc.add_fixit_replace ("color");
 
+   Example J: fix-it hint: line insertion
+   **************************************
+
+     3 | #include <stddef.h>
+     + |+#include <stdio.h>
+     4 | int the_next_line;
+
+   This rich location has a single range at line 4 column 1, marked
+   with SHOW_LINES_WITHOUT_RANGE (to avoid printing a meaningless caret
+   on the "i" of int).  It has a insertion fix-it hint of the string
+   "#include <stdio.h>\n".
+
    Adding a fix-it hint can fail: for example, attempts to insert content
    at the transition between two line maps may fail due to there being no
    source_location (aka location_t) value to express the new location.
@@ -1610,11 +1643,14 @@ class rich_location
   source_location get_loc (unsigned int idx) const;
 
   void
-  add_range (source_location loc,  bool show_caret_p,
+  add_range (source_location loc,
+            enum range_display_kind range_display_kind
+              = SHOW_RANGE_WITHOUT_CARET,
             const range_label *label = NULL);
 
   void
-  set_range (unsigned int idx, source_location loc, bool show_caret_p);
+  set_range (unsigned int idx, source_location loc,
+            enum range_display_kind range_display_kind);
 
   unsigned int get_num_locations () const { return m_ranges.count (); }
 
index b5e1f13da357dc7d3c15e2303e282622a14d6367..73d94443090004ebba1cda5fcab42ef5ca652d3d 100644 (file)
@@ -2005,7 +2005,7 @@ rich_location::rich_location (line_maps *set, source_location loc,
   m_seen_impossible_fixit (false),
   m_fixits_cannot_be_auto_applied (false)
 {
-  add_range (loc, true, label);
+  add_range (loc, SHOW_RANGE_WITH_CARET, label);
 }
 
 /* The destructor for class rich_location.  */
@@ -2081,18 +2081,19 @@ rich_location::override_column (int column)
 /* Add the given range.  */
 
 void
-rich_location::add_range (source_location loc, bool show_caret_p,
+rich_location::add_range (source_location loc,
+                         enum range_display_kind range_display_kind,
                          const range_label *label)
 {
   location_range range;
   range.m_loc = loc;
-  range.m_show_caret_p = show_caret_p;
+  range.m_range_display_kind = range_display_kind;
   range.m_label = label;
   m_ranges.push (range);
 }
 
 /* Add or overwrite the location given by IDX, setting its location to LOC,
-   and setting its "should my caret be printed" flag to SHOW_CARET_P.
+   and setting its m_range_display_kind to RANGE_DISPLAY_KIND.
 
    It must either overwrite an existing location, or add one *exactly* on
    the end of the array.
@@ -2106,19 +2107,19 @@ rich_location::add_range (source_location loc, bool show_caret_p,
 
 void
 rich_location::set_range (unsigned int idx, source_location loc,
-                         bool show_caret_p)
+                         enum range_display_kind range_display_kind)
 {
   /* We can either overwrite an existing range, or add one exactly
      on the end of the array.  */
   linemap_assert (idx <= m_ranges.count ());
 
   if (idx == m_ranges.count ())
-    add_range (loc,  show_caret_p);
+    add_range (loc, range_display_kind);
   else
     {
       location_range *locrange = get_range (idx);
       locrange->m_loc = loc;
-      locrange->m_show_caret_p = show_caret_p;
+      locrange->m_range_display_kind = range_display_kind;
     }
 
   if (idx == 0)