From 85204e23e2fed09fc07159ab5607e0b760269561 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 27 Aug 2018 14:02:05 +0000 Subject: [PATCH] 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 +++ |+#include 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 +++ |+#include 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 +++ |+#include 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 --- gcc/ChangeLog | 28 +++++++++ gcc/c-family/ChangeLog | 20 ++++++ gcc/c-family/c-common.c | 43 +++++++++++-- gcc/c-family/c-common.h | 2 +- gcc/c-family/c-format.c | 2 +- gcc/c-family/c-warn.c | 2 +- gcc/c-family/known-headers.cc | 2 +- gcc/c/ChangeLog | 9 +++ gcc/c/c-decl.c | 2 +- gcc/c/c-objc-common.c | 3 +- gcc/cp/ChangeLog | 17 +++++ gcc/cp/decl.c | 10 +-- gcc/cp/error.c | 2 +- gcc/cp/name-lookup.c | 2 +- gcc/cp/parser.c | 6 +- gcc/cp/pt.c | 2 +- gcc/cp/rtti.c | 2 +- gcc/diagnostic-show-locus.c | 63 +++++++++++-------- gcc/fortran/ChangeLog | 6 ++ gcc/fortran/error.c | 2 +- gcc/gcc-rich-location.c | 2 +- gcc/pretty-print.c | 5 +- gcc/pretty-print.h | 3 +- gcc/substring-locations.c | 2 +- gcc/testsuite/ChangeLog | 13 ++++ gcc/testsuite/gcc.dg/empty.h | 0 gcc/testsuite/gcc.dg/fixits-pr84852-1.c | 5 +- gcc/testsuite/gcc.dg/fixits-pr84852-2.c | 5 +- gcc/testsuite/gcc.dg/missing-header-fixit-3.c | 9 +-- gcc/testsuite/gcc.dg/missing-header-fixit-4.c | 23 +++++++ .../diagnostic_plugin_test_show_locus.c | 37 ++++++----- gcc/tree-diagnostic.c | 2 +- gcc/tree-pretty-print.c | 2 +- libcpp/ChangeLog | 16 +++++ libcpp/include/line-map.h | 60 ++++++++++++++---- libcpp/line-map.c | 15 ++--- 36 files changed, 316 insertions(+), 108 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/empty.h create mode 100644 gcc/testsuite/gcc.dg/missing-header-fixit-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3ee5cf8773..4c4969deda3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2018-08-27 David Malcolm + + 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 PR 87091 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2ca6662c3c5..2e844d47d48 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,23 @@ +2018-08-27 David Malcolm + + 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 * c-common.c (check_function_restrict): Use new function diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 0b0969b5216..6a5d99171a0 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 + +++ |+#include + 74 | #endif + + rather than: + + ../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2 + 73 | # include + +++ |+#include + 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 diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 9b05e605250..c5e2028cbaa 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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); diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 035878fd954..98c49cf5d18 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -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, ¶m_label); + richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, ¶m_label); test_diagnostic_context dc; diagnostic_show_locus (&dc, &richloc, DK_ERROR); diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 95b66c1eabb..a1a7f935964 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -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 (), diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc index 5524d216318..b0763cfe984 100644 --- a/gcc/c-family/known-headers.cc +++ b/gcc/c-family/known-headers.cc @@ -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%>?", diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b3e499e5899..d459dc465a1 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2018-08-27 David Malcolm + + 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 * c-decl.c (locate_old_decl): Use new function diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 80647ee0207..feafc022768 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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); diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c index 238af199ab5..12e777a4845 100644 --- a/gcc/c/c-objc-common.c +++ b/gcc/c/c-objc-common.c @@ -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) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e6d62082bf9..a05049c747a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2018-08-27 David Malcolm + + 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 * call.c (build_call_a): Use new function diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c9c5fa6b4d5..d9f4d348929 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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, "% and % 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, "% and % 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 % " "and %", 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 % " "and %", 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; } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 452ecb95467..5bab3f345ed 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 8e009b29d61..c0a12d74634 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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, "% is defined in header %qs;" " did you forget to %<#include %s%>?", diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 49d476b383f..d8d4301272e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 % specified"); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index efed9a1bf60..a7266e368fc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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, ""); + maybe_add_include_fixit (&richloc, "", false); error_at (&richloc, "deducing from brace-enclosed initializer list" " requires %<#include %>"); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 6692fb7ff86..94a92198781 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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, ""); + maybe_add_include_fixit (&richloc, "", false); error_at (&richloc, "must %<#include %> before using" " %"); diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c index d305ada1456..6ce8a0f4a9b 100644 --- a/gcc/diagnostic-show-locus.c +++ b/gcc/diagnostic-show-locus.c @@ -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); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 22c40527bc6..c8249f63380 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2018-08-27 David Malcolm + + PR 87091 + * error.c (gfc_format_decoder): Update for conversion of + show_caret_p to a tri-state. + 2018-08-25 Janus Weil PR fortran/86545 diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index 7e882ba76bf..b3b0138b0c3 100644 --- a/gcc/fortran/error.c +++ b/gcc/fortran/error.c @@ -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; } diff --git a/gcc/gcc-rich-location.c b/gcc/gcc-rich-location.c index 2576c7387ee..81beb61661c 100644 --- a/gcc/gcc-rich-location.c +++ b/gcc/gcc-rich-location.c @@ -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, diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c index 02967d05f75..7dd900b3bbf 100644 --- a/gcc/pretty-print.c +++ b/gcc/pretty-print.c @@ -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 diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h index 0d67e308050..2decc516b1f 100644 --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -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; }; diff --git a/gcc/substring-locations.c b/gcc/substring-locations.c index 1981394a3f0..faf78845840 100644 --- a/gcc/substring-locations.c +++ b/gcc/substring-locations.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24e2047e268..d99816171e4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2018-08-27 David Malcolm + + 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 PR 87091 diff --git a/gcc/testsuite/gcc.dg/empty.h b/gcc/testsuite/gcc.dg/empty.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gcc/testsuite/gcc.dg/fixits-pr84852-1.c b/gcc/testsuite/gcc.dg/fixits-pr84852-1.c index 98087abd929..346626b4eb9 100644 --- a/gcc/testsuite/gcc.dg/fixits-pr84852-1.c +++ b/gcc/testsuite/gcc.dg/fixits-pr84852-1.c @@ -13,13 +13,10 @@ int foo (void) { return strlen(""); } /* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */ -/* { dg-message "include '' or provide a declaration of 'strlen'" "" { target *-*-* } -812156810 } */ +/* { dg-message "include '' or provide a declaration of 'strlen'" "" { target *-*-* } 1 } */ #if 0 { dg-begin-multiline-output "" } +#include /* 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:" } */ diff --git a/gcc/testsuite/gcc.dg/fixits-pr84852-2.c b/gcc/testsuite/gcc.dg/fixits-pr84852-2.c index 0674ef54689..9bc70f59b59 100644 --- a/gcc/testsuite/gcc.dg/fixits-pr84852-2.c +++ b/gcc/testsuite/gcc.dg/fixits-pr84852-2.c @@ -13,13 +13,10 @@ int foo (void) { return strlen(""); } /* { dg-warning "incompatible implicit declaration of built-in function 'strlen'" "" { target *-*-* } -812156810 } */ -/* { dg-message "include '' or provide a declaration of 'strlen'" "" { target *-*-* } -812156810 } */ +/* { dg-message "include '' or provide a declaration of 'strlen'" "" { target *-*-* } 1 } */ #if 0 { dg-begin-multiline-output "" } +#include /* 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:" } */ diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-3.c b/gcc/testsuite/gcc.dg/missing-header-fixit-3.c index 7c72b1decc8..a692b4d21b3 100644 --- a/gcc/testsuite/gcc.dg/missing-header-fixit-3.c +++ b/gcc/testsuite/gcc.dg/missing-header-fixit-3.c @@ -7,18 +7,15 @@ void test (int i, int j) { printf ("%i of %i\n", i, j); /* { dg-warning "implicit declaration" } */ - /* { dg-message "include '' or provide a declaration of 'printf'" "" { target *-*-* } .-1 } */ + /* { dg-message "include '' 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 - 1 | /* Example of a fix-it hint that adds a #include directive, -.... - 9 | printf ("%i of %i\n", i, j); - | ^~~~~~ ++ |+#include +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 index 00000000000..0ed3e2c2922 --- /dev/null +++ b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c @@ -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 '' or provide a declaration of 'printf'" "" { target *-*-* } 4 } */ + /* { dg-begin-multiline-output "" } +3 | #include "empty.h" ++ |+#include +4 | int the_next_line; + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index 3d7853813ae..a55efafddff 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -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); diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c index 6b03b31c229..c4a200f7fbc 100644 --- a/gcc/tree-diagnostic.c +++ b/gcc/tree-diagnostic.c @@ -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)) { diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 622142719ee..990cc2167c7 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -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; diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index cbf4cbf7042..7b716cf9a3e 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,19 @@ +2018-08-27 David Malcolm + + 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 PR bootstrap/86872 diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 4f0ff8719a7..e74ccbb5703 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -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 + + |+#include + 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 \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 (); } diff --git a/libcpp/line-map.c b/libcpp/line-map.c index b5e1f13da35..73d94443090 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -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)