Less verbose fix-it hints for missing header files (PR 87091)

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
This commit is contained in:
David Malcolm 2018-08-27 14:02:05 +00:00 committed by David Malcolm
parent df308f8160
commit 85204e23e2
36 changed files with 316 additions and 108 deletions

View 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> 2018-08-27 David Malcolm <dmalcolm@redhat.com>
PR 87091 PR 87091

View 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> 2018-08-27 Martin Liska <mliska@suse.cz>
* c-common.c (check_function_restrict): Use new function * c-common.c (check_function_restrict): Use new function

View File

@ -6131,7 +6131,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
gcc_unreachable (); gcc_unreachable ();
} }
if (done_lexing) 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, diagnostic_set_info_translated (&diagnostic, msg, ap,
richloc, dlevel); richloc, dlevel);
diagnostic_override_option_index (&diagnostic, 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 hint_loc = hint->get_start_loc ();
location_t old_loc = richloc->get_loc (); location_t old_loc = richloc->get_loc ();
richloc->set_range (0, hint_loc, true); richloc->set_range (0, hint_loc, SHOW_RANGE_WITH_CARET);
richloc->add_range (old_loc, false); richloc->add_range (old_loc);
} }
} }
@ -8475,10 +8475,16 @@ static added_includes_t *added_includes;
location. location.
This function is idempotent: a header will be added at most once to 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 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 (); location_t loc = richloc->get_loc ();
const char *file = LOCATION_FILE (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); char *text = xasprintf ("#include %s\n", header);
richloc->add_fixit_insert_before (include_insert_loc, text); richloc->add_fixit_insert_before (include_insert_loc, text);
free (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 /* Attempt to convert a braced array initializer list CTOR for array

View 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 int c_flt_eval_method (bool ts18661_p);
extern void add_no_sanitize_value (tree node, unsigned int flags); 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, extern void maybe_suggest_missing_token_insertion (rich_location *richloc,
enum cpp_ttype token_type, enum cpp_ttype token_type,
location_t prev_token_loc); location_t prev_token_loc);

View File

@ -4352,7 +4352,7 @@ test_type_mismatch_range_labels ()
range_label_for_type_mismatch param_label (integer_type_node, range_label_for_type_mismatch param_label (integer_type_node,
char_type_node); char_type_node);
gcc_rich_location richloc (fmt, &fmt_label); 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; test_diagnostic_context dc;
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);

View File

@ -2429,7 +2429,7 @@ warn_for_restrict (unsigned param_pos, tree *argarray, unsigned nargs)
{ {
arg = argarray[pos - 1]; arg = argarray[pos - 1];
if (EXPR_HAS_LOCATION (arg)) 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 (), return warning_n (&richloc, OPT_Wrestrict, arg_positions.length (),

View File

@ -192,7 +192,7 @@ suggest_missing_header::~suggest_missing_header ()
return; return;
gcc_rich_location richloc (get_location ()); 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, inform (&richloc,
"%qs is defined in header %qs;" "%qs is defined in header %qs;"
" did you forget to %<#include %s%>?", " did you forget to %<#include %s%>?",

View 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> 2018-08-27 Martin Liska <mliska@suse.cz>
* c-decl.c (locate_old_decl): Use new function * c-decl.c (locate_old_decl): Use new function

View File

@ -3446,7 +3446,7 @@ implicitly_declare (location_t loc, tree functionid)
if (header != NULL && warned) if (header != NULL && warned)
{ {
rich_location richloc (line_table, loc); rich_location richloc (line_table, loc);
maybe_add_include_fixit (&richloc, header); maybe_add_include_fixit (&richloc, header, true);
inform (&richloc, inform (&richloc,
"include %qs or provide a declaration of %qD", "include %qs or provide a declaration of %qD",
header, decl); header, decl);

View File

@ -161,7 +161,8 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
{ {
t = va_arg (*text->args_ptr, tree); t = va_arg (*text->args_ptr, tree);
if (set_locus) 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) switch (*spec)

View 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> 2018-08-27 Martin Liska <mliska@suse.cz>
* call.c (build_call_a): Use new function * call.c (build_call_a): Use new function

View File

@ -10737,14 +10737,14 @@ grokdeclarator (const cp_declarator *declarator,
if (signed_p && unsigned_p) if (signed_p && unsigned_p)
{ {
gcc_rich_location richloc (declspecs->locations[ds_signed]); 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, error_at (&richloc,
"%<signed%> and %<unsigned%> specified together"); "%<signed%> and %<unsigned%> specified together");
} }
else if (long_p && short_p) else if (long_p && short_p)
{ {
gcc_rich_location richloc (declspecs->locations[ds_long]); 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"); error_at (&richloc, "%<long%> and %<short%> specified together");
} }
else if (TREE_CODE (type) != INTEGER_TYPE else if (TREE_CODE (type) != INTEGER_TYPE
@ -10888,7 +10888,7 @@ grokdeclarator (const cp_declarator *declarator,
if (staticp == 2) if (staticp == 2)
{ {
gcc_rich_location richloc (declspecs->locations[ds_virtual]); 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%> " error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
"and %<static%>", dname); "and %<static%>", dname);
storage_class = sc_none; storage_class = sc_none;
@ -10897,7 +10897,7 @@ grokdeclarator (const cp_declarator *declarator,
if (constexpr_p) if (constexpr_p)
{ {
gcc_rich_location richloc (declspecs->locations[ds_virtual]); 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%> " error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
"and %<constexpr%>", dname); "and %<constexpr%>", dname);
} }
@ -11448,7 +11448,7 @@ grokdeclarator (const cp_declarator *declarator,
{ {
/* Cannot be both friend and virtual. */ /* Cannot be both friend and virtual. */
gcc_rich_location richloc (declspecs->locations[ds_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"); error_at (&richloc, "virtual functions cannot be friends");
friendp = 0; friendp = 0;
} }

View File

@ -4119,7 +4119,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
pp_string (pp, result); pp_string (pp, result);
if (set_locus && t != NULL) 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; return true;
#undef next_tree #undef next_tree
#undef next_tcode #undef next_tcode

View File

@ -5630,7 +5630,7 @@ maybe_suggest_missing_std_header (location_t location, tree name)
if (cxx_dialect >= header_hint->min_dialect) if (cxx_dialect >= header_hint->min_dialect)
{ {
const char *header = header_hint->header; const char *header = header_hint->header;
maybe_add_include_fixit (&richloc, header); maybe_add_include_fixit (&richloc, header, true);
inform (&richloc, inform (&richloc,
"%<std::%s%> is defined in header %qs;" "%<std::%s%> is defined in header %qs;"
" did you forget to %<#include %s%>?", " did you forget to %<#include %s%>?",

View File

@ -4133,7 +4133,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
else if (curr_type != CPP_STRING) else if (curr_type != CPP_STRING)
{ {
rich_location rich_loc (line_table, tok->location); 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, error_at (&rich_loc,
"unsupported non-standard concatenation " "unsupported non-standard concatenation "
"of string literals"); "of string literals");
@ -17755,7 +17755,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|| cp_parser_is_keyword (token, RID_STRUCT)) || cp_parser_is_keyword (token, RID_STRUCT))
{ {
gcc_rich_location richloc (token->location); gcc_rich_location richloc (token->location);
richloc.add_range (input_location, false); richloc.add_range (input_location);
richloc.add_fixit_remove (); richloc.add_fixit_remove ();
pedwarn (&richloc, 0, "elaborated-type-specifier for " pedwarn (&richloc, 0, "elaborated-type-specifier for "
"a scoped enum must not use the %qD keyword", "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); gcc_rich_location richloc (location);
if (gnu != decl_specs->gnu_thread_keyword_p) 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, error_at (&richloc,
"both %<__thread%> and %<thread_local%> specified"); "both %<__thread%> and %<thread_local%> specified");
} }

View File

@ -26077,7 +26077,7 @@ listify (tree arg)
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list)) if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
{ {
gcc_rich_location richloc (input_location); gcc_rich_location richloc (input_location);
maybe_add_include_fixit (&richloc, "<initializer_list>"); maybe_add_include_fixit (&richloc, "<initializer_list>", false);
error_at (&richloc, error_at (&richloc,
"deducing from brace-enclosed initializer list" "deducing from brace-enclosed initializer list"
" requires %<#include <initializer_list>%>"); " requires %<#include <initializer_list>%>");

View File

@ -317,7 +317,7 @@ typeid_ok_p (void)
if (!COMPLETE_TYPE_P (const_type_info_type_node)) if (!COMPLETE_TYPE_P (const_type_info_type_node))
{ {
gcc_rich_location richloc (input_location); gcc_rich_location richloc (input_location);
maybe_add_include_fixit (&richloc, "<typeinfo>"); maybe_add_include_fixit (&richloc, "<typeinfo>", false);
error_at (&richloc, error_at (&richloc,
"must %<#include <typeinfo>%> before using" "must %<#include <typeinfo>%> before using"
" %<typeid%>"); " %<typeid%>");

View File

@ -126,7 +126,7 @@ class layout_range
public: public:
layout_range (const expanded_location *start_exploc, layout_range (const expanded_location *start_exploc,
const expanded_location *finish_exploc, const expanded_location *finish_exploc,
bool show_caret_p, enum range_display_kind range_display_kind,
const expanded_location *caret_exploc, const expanded_location *caret_exploc,
const range_label *label); const range_label *label);
@ -135,7 +135,7 @@ class layout_range
layout_point m_start; layout_point m_start;
layout_point m_finish; layout_point m_finish;
bool m_show_caret_p; enum range_display_kind m_range_display_kind;
layout_point m_caret; layout_point m_caret;
const range_label *m_label; 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, layout_range::layout_range (const expanded_location *start_exploc,
const expanded_location *finish_exploc, const expanded_location *finish_exploc,
bool show_caret_p, enum range_display_kind range_display_kind,
const expanded_location *caret_exploc, const expanded_location *caret_exploc,
const range_label *label) const range_label *label)
: m_start (*start_exploc), : m_start (*start_exploc),
m_finish (*finish_exploc), m_finish (*finish_exploc),
m_show_caret_p (show_caret_p), m_range_display_kind (range_display_kind),
m_caret (*caret_exploc), m_caret (*caret_exploc),
m_label (label) 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}; = {"test.c", start_line, start_col, NULL, false};
const expanded_location finish_exploc const expanded_location finish_exploc
= {"test.c", end_line, end_col, NULL, false}; = {"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); &start_exploc, NULL);
} }
@ -986,13 +986,13 @@ layout::maybe_add_location_range (const location_range *loc_range,
return false; return false;
if (finish.file != m_exploc.file) if (finish.file != m_exploc.file)
return false; 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) if (caret.file != m_exploc.file)
return false; return false;
/* Sanitize the caret location for non-primary ranges. */ /* Sanitize the caret location for non-primary ranges. */
if (m_layout_ranges.length () > 0) 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)) if (!compatible_locations_p (loc_range->m_loc, m_primary_loc))
/* Discard any non-primary ranges that can't be printed /* Discard any non-primary ranges that can't be printed
sanely relative to the primary location. */ 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, /* Everything is now known to be in the correct source file,
but it may require further sanitization. */ 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); loc_range->m_label);
/* If we have a range that finishes before it starts (perhaps /* 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; return false;
if (!will_show_line_p (finish.line)) if (!will_show_line_p (finish.line))
return false; 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)) if (!will_show_line_p (caret.line))
return false; return false;
} }
@ -1362,8 +1362,12 @@ layout::should_print_annotation_line_p (linenum_type row) const
layout_range *range; layout_range *range;
int i; int i;
FOR_EACH_VEC_ELT (m_layout_ranges, i, range) 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; return false;
} }
@ -2102,13 +2106,18 @@ layout::get_state_at_point (/* Inputs. */
int i; int i;
FOR_EACH_VEC_ELT (m_layout_ranges, i, range) 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)) if (range->contains_point (row, column))
{ {
out_state->range_idx = i; out_state->range_idx = i;
/* Are we at the range's caret? is it visible? */ /* Are we at the range's caret? is it visible? */
out_state->draw_caret_p = false; 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 && row == range->m_caret.m_line
&& column == range->m_caret.m_column) && column == range->m_caret.m_column)
out_state->draw_caret_p = true; 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); layout layout (global_dc, this, DK_ERROR);
location_range loc_range; location_range loc_range;
loc_range.m_loc = loc; 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)) if (!layout.maybe_add_location_range (&loc_range, true))
return false; return false;
add_range (loc, false); add_range (loc);
return true; return true;
} }
@ -2421,8 +2430,8 @@ test_one_liner_multiple_carets_and_ranges ()
dc.caret_chars[2] = 'C'; dc.caret_chars[2] = 'C';
rich_location richloc (line_table, foo); rich_location richloc (line_table, foo);
richloc.add_range (bar, true); richloc.add_range (bar, SHOW_RANGE_WITH_CARET);
richloc.add_range (field, true); richloc.add_range (field, SHOW_RANGE_WITH_CARET);
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);
ASSERT_STREQ ("\n" ASSERT_STREQ ("\n"
" foo = bar.field;\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); location_t finish = linemap_position_for_column (line_table, 15);
rich_location richloc (line_table, equals); rich_location richloc (line_table, equals);
location_t field = make_location (start, start, finish); location_t field = make_location (start, start, finish);
richloc.add_range (field, false); richloc.add_range (field);
richloc.add_fixit_replace (field, "m_field"); richloc.add_fixit_replace (field, "m_field");
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);
/* The replacement range is indicated in the annotation line, /* 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 label1 ("1");
text_range_label label2 ("2"); text_range_label label2 ("2");
gcc_rich_location richloc (foo, &label0); gcc_rich_location richloc (foo, &label0);
richloc.add_range (bar, false, &label1); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
richloc.add_range (field, false, &label2); richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
{ {
test_diagnostic_context dc; test_diagnostic_context dc;
@ -2722,8 +2731,8 @@ test_one_liner_labels ()
text_range_label label1 ("label 1"); text_range_label label1 ("label 1");
text_range_label label2 ("label 2"); text_range_label label2 ("label 2");
gcc_rich_location richloc (foo, &label0); gcc_rich_location richloc (foo, &label0);
richloc.add_range (bar, false, &label1); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
richloc.add_range (field, false, &label2); richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
test_diagnostic_context dc; test_diagnostic_context dc;
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@ -2744,8 +2753,8 @@ test_one_liner_labels ()
text_range_label label1 ("bbbb"); text_range_label label1 ("bbbb");
text_range_label label2 ("c"); text_range_label label2 ("c");
gcc_rich_location richloc (foo, &label0); gcc_rich_location richloc (foo, &label0);
richloc.add_range (bar, false, &label1); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
richloc.add_range (field, false, &label2); richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
test_diagnostic_context dc; test_diagnostic_context dc;
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@ -2764,8 +2773,8 @@ test_one_liner_labels ()
text_range_label label1 ("1"); text_range_label label1 ("1");
text_range_label label2 ("2"); text_range_label label2 ("2");
gcc_rich_location richloc (field, &label0); gcc_rich_location richloc (field, &label0);
richloc.add_range (bar, false, &label1); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
richloc.add_range (foo, false, &label2); richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label2);
test_diagnostic_context dc; test_diagnostic_context dc;
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);
@ -2784,8 +2793,8 @@ test_one_liner_labels ()
text_range_label label1 ("label 1"); text_range_label label1 ("label 1");
text_range_label label2 ("label 2"); text_range_label label2 ("label 2");
gcc_rich_location richloc (bar, &label0); gcc_rich_location richloc (bar, &label0);
richloc.add_range (bar, false, &label1); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
richloc.add_range (bar, false, &label2); richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label2);
test_diagnostic_context dc; test_diagnostic_context dc;
diagnostic_show_locus (&dc, &richloc, DK_ERROR); diagnostic_show_locus (&dc, &richloc, DK_ERROR);

View 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> 2018-08-25 Janus Weil <janus@gcc.gnu.org>
PR fortran/86545 PR fortran/86545

View 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, = linemap_position_for_loc_and_offset (line_table,
loc->lb->location, loc->lb->location,
offset); 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]); pp_string (pp, result[loc_num]);
return true; return true;
} }

View File

@ -47,7 +47,7 @@ gcc_rich_location::add_expr (tree expr, range_label *label)
gcc_assert (expr); gcc_assert (expr);
if (CAN_HAVE_RANGE_P (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, /* If T is an expression, add a range for it to the rich_location,

View 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. */ For use e.g. when implementing "+" in client format decoders. */
void 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); 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 location_t

View File

@ -36,7 +36,8 @@ struct text_info
void **x_data; void **x_data;
rich_location *m_richloc; 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; location_t get_location (unsigned int index_of_location) const;
}; };

View File

@ -171,7 +171,7 @@ format_warning_n_va (const substring_loc &fmt_loc,
gcc_rich_location richloc (primary_loc, primary_label); gcc_rich_location richloc (primary_loc, primary_label);
if (param_loc != UNKNOWN_LOCATION) 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) if (!err && corrected_substring && substring_within_range)
richloc.add_fixit_replace (fmt_substring_range, corrected_substring); richloc.add_fixit_replace (fmt_substring_range, corrected_substring);

View 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> 2018-08-27 David Malcolm <dmalcolm@redhat.com>
PR 87091 PR 87091

View File

View File

@ -13,13 +13,10 @@
int foo (void) { return strlen(""); } int foo (void) { return strlen(""); }
/* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */ /* { 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 #if 0
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
+#include <string.h> +#include <string.h>
/* This is padding (to avoid the output containing DejaGnu directives). */ /* This is padding (to avoid the output containing DejaGnu directives). */
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
#endif #endif
/* We need this, to consume a stray line marker for the bogus line. */
/* { dg-regexp ".*fixits-pr84852-1.c:-812156810:25:" } */

View File

@ -13,13 +13,10 @@
int foo (void) { return strlen(""); } int foo (void) { return strlen(""); }
/* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */ /* { 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 #if 0
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
+#include <string.h> +#include <string.h>
/* This is padding (to avoid the output containing DejaGnu directives). */ /* This is padding (to avoid the output containing DejaGnu directives). */
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
#endif #endif
/* We need this, to consume a stray line marker for the bogus line. */
/* { dg-regexp ".*fixits-pr84852-2.c:-812156810:25:" } */

View File

@ -7,18 +7,15 @@
void test (int i, int j) void test (int i, int j)
{ {
printf ("%i of %i\n", i, j); /* { dg-warning "implicit declaration" } */ 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 #if 0
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
9 | printf ("%i of %i\n", i, j); 9 | printf ("%i of %i\n", i, j);
| ^~~~~~ | ^~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
+++ |+#include <stdio.h> + |+#include <stdio.h>
1 | /* Example of a fix-it hint that adds a #include directive, 1 | /* Example of a fix-it hint that adds a #include directive,
....
9 | printf ("%i of %i\n", i, j);
| ^~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
#endif #endif
} }

View File

@ -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 "" } */
}

View File

@ -145,9 +145,11 @@ custom_diagnostic_finalizer (diagnostic_context *context,
static void static void
add_range (rich_location *richloc, location_t start, location_t finish, 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); label);
} }
@ -176,8 +178,8 @@ test_show_locus (function *fun)
{ {
const int line = fnstart_line + 2; const int line = fnstart_line + 2;
rich_location richloc (line_table, get_loc (line, 15)); 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, 10), get_loc (line, 14));
add_range (&richloc, get_loc (line, 16), get_loc (line, 16), false); add_range (&richloc, get_loc (line, 16), get_loc (line, 16));
warning_at (&richloc, 0, "test"); warning_at (&richloc, 0, "test");
} }
@ -185,8 +187,8 @@ test_show_locus (function *fun)
{ {
const int line = fnstart_line + 2; const int line = fnstart_line + 2;
rich_location richloc (line_table, get_loc (line, 24)); 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, 6), get_loc (line, 22));
add_range (&richloc, get_loc (line, 26), get_loc (line, 43), false); add_range (&richloc, get_loc (line, 26), get_loc (line, 43));
warning_at (&richloc, 0, "test"); warning_at (&richloc, 0, "test");
} }
@ -195,9 +197,8 @@ test_show_locus (function *fun)
const int line = fnstart_line + 2; const int line = fnstart_line + 2;
text_range_label label ("label"); text_range_label label ("label");
rich_location richloc (line_table, get_loc (line + 1, 7), &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, 7), get_loc (line, 23));
add_range (&richloc, get_loc (line + 1, 9), get_loc (line + 1, 26), add_range (&richloc, get_loc (line + 1, 9), get_loc (line + 1, 26));
false);
warning_at (&richloc, 0, "test"); warning_at (&richloc, 0, "test");
} }
@ -208,10 +209,10 @@ test_show_locus (function *fun)
text_range_label label1 ("label 1"); text_range_label label1 ("label 1");
text_range_label label2 ("label 2"); text_range_label label2 ("label 2");
rich_location richloc (line_table, get_loc (line + 5, 7), &label0); rich_location richloc (line_table, get_loc (line + 5, 7), &label0);
add_range (&richloc, get_loc (line, 7), get_loc (line + 4, 65), false, add_range (&richloc, get_loc (line, 7), get_loc (line + 4, 65),
&label1); SHOW_RANGE_WITHOUT_CARET, &label1);
add_range (&richloc, get_loc (line + 5, 9), get_loc (line + 10, 61), 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"); warning_at (&richloc, 0, "test");
} }
@ -250,7 +251,8 @@ test_show_locus (function *fun)
get_loc (line, 90), get_loc (line, 90),
get_loc (line, 98)), get_loc (line, 98)),
&label0); &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"); richloc.add_fixit_replace ("bar * foo");
warning_at (&richloc, 0, "test"); warning_at (&richloc, 0, "test");
global_dc->show_ruler_p = false; global_dc->show_ruler_p = false;
@ -270,7 +272,8 @@ test_show_locus (function *fun)
get_loc (line, 98)), get_loc (line, 98)),
&label0); &label0);
richloc.add_fixit_replace ("bar * foo"); 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"); warning_at (&richloc, 0, "test");
global_dc->show_ruler_p = false; 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_a = get_loc (line, 7);
location_t caret_b = get_loc (line, 11); location_t caret_b = get_loc (line, 11);
rich_location richloc (line_table, caret_a); 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[0] = 'A';
global_dc->caret_chars[1] = 'B'; global_dc->caret_chars[1] = 'B';
warning_at (&richloc, 0, "test"); 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_a = get_loc (line, 5);
location_t caret_b = get_loc (line - 1, 19); location_t caret_b = get_loc (line - 1, 19);
rich_location richloc (line_table, caret_a); 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[0] = '1';
global_dc->caret_chars[1] = '2'; global_dc->caret_chars[1] = '2';
warning_at (&richloc, 0, "test"); warning_at (&richloc, 0, "test");
@ -449,7 +452,7 @@ test_show_locus (function *fun)
location_t word location_t word
= make_location (start_of_word, start_of_word, = make_location (start_of_word, start_of_word,
end_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. */ /* Add a fixit, converting to upper case. */
char_span word_span = content.subspan (start_idx, idx - start_idx); char_span word_span = content.subspan (start_idx, idx - start_idx);

View File

@ -290,7 +290,7 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
} }
if (set_locus) 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)) if (DECL_P (t))
{ {

View File

@ -3962,7 +3962,7 @@ newline_and_indent (pretty_printer *pp, int spc)
void void
percent_K_format (text_info *text, location_t loc, tree block) 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); gcc_assert (pp_ti_abstract_origin (text) != NULL);
*pp_ti_abstract_origin (text) = NULL; *pp_ti_abstract_origin (text) = NULL;

View 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> 2018-08-24 H.J. Lu <hongjiu.lu@intel.com>
PR bootstrap/86872 PR bootstrap/86872

View File

@ -1283,6 +1283,36 @@ typedef struct
class range_label; 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 /* A location within a rich_location: a caret&range, with
the caret potentially flagged for display, and an optional the caret potentially flagged for display, and an optional
label. */ label. */
@ -1291,16 +1321,7 @@ struct location_range
{ {
source_location m_loc; source_location m_loc;
/* Should a caret be drawn for this range? Typically this is enum range_display_kind m_range_display_kind;
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;
/* If non-NULL, the label for this range. */ /* If non-NULL, the label for this range. */
const range_label *m_label; const range_label *m_label;
@ -1567,6 +1588,18 @@ class fixit_hint;
added via added via
richloc.add_fixit_replace ("color"); 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 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 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. 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; source_location get_loc (unsigned int idx) const;
void 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); const range_label *label = NULL);
void 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 (); } unsigned int get_num_locations () const { return m_ranges.count (); }

View File

@ -2005,7 +2005,7 @@ rich_location::rich_location (line_maps *set, source_location loc,
m_seen_impossible_fixit (false), m_seen_impossible_fixit (false),
m_fixits_cannot_be_auto_applied (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. */ /* The destructor for class rich_location. */
@ -2081,18 +2081,19 @@ rich_location::override_column (int column)
/* Add the given range. */ /* Add the given range. */
void 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) const range_label *label)
{ {
location_range range; location_range range;
range.m_loc = loc; range.m_loc = loc;
range.m_show_caret_p = show_caret_p; range.m_range_display_kind = range_display_kind;
range.m_label = label; range.m_label = label;
m_ranges.push (range); m_ranges.push (range);
} }
/* Add or overwrite the location given by IDX, setting its location to LOC, /* 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 It must either overwrite an existing location, or add one *exactly* on
the end of the array. the end of the array.
@ -2106,19 +2107,19 @@ rich_location::add_range (source_location loc, bool show_caret_p,
void void
rich_location::set_range (unsigned int idx, source_location loc, 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 /* We can either overwrite an existing range, or add one exactly
on the end of the array. */ on the end of the array. */
linemap_assert (idx <= m_ranges.count ()); linemap_assert (idx <= m_ranges.count ());
if (idx == m_ranges.count ()) if (idx == m_ranges.count ())
add_range (loc, show_caret_p); add_range (loc, range_display_kind);
else else
{ {
location_range *locrange = get_range (idx); location_range *locrange = get_range (idx);
locrange->m_loc = loc; locrange->m_loc = loc;
locrange->m_show_caret_p = show_caret_p; locrange->m_range_display_kind = range_display_kind;
} }
if (idx == 0) if (idx == 0)