A previous patch introduced the ability to print one or more ranges for a diagnostic via a rich_location class.
Another patch generalized source_location (aka location_t) to be both a caret and a range, and generated range information for all tokens coming out of libcpp's lexer. The attached patch combines these efforts by updating the rich_location constructor for a single source_location so that it makes use of the range within the source_location. Doing so requires passing the line_table to the ctor, so that it can extract the range from there. The effect of this is that all of the various "warning", "warning_at" "error", "error_at" diagnostics now emit underlines showing the range of the token associated with the location_t (or input_location), for those frontends using libcpp. Similar things should happen for expressions in the C FE for diagnostics using EXPR_LOCATION. A test case is added showing various token-based warnings that now have underlines (without having to go through and add range information to them). For example: diagnostic-token-ranges.c: In function ‘wide_string_literal_in_asm’: diagnostic-token-ranges.c:68:8: error: wide string literal in ‘asm’ asm (L"nop"); ^~~~~~ gcc/c-family/ChangeLog: * c-opts.c (c_common_init_options): Set global_dc->colorize_source_p. gcc/c/ChangeLog: * c-decl.c (warn_defaults_to): Pass line_table to rich_location ctor. * c-errors.c (pedwarn_c99): Likewise. (pedwarn_c90): Likewise. gcc/cp/ChangeLog: * error.c (pedwarn_cxx98): Pass line_table to rich_location ctor. gcc/ChangeLog: * diagnostic.c (diagnostic_append_note): Pass line_table to rich_location ctor. (emit_diagnostic): Likewise. (inform): Likewise. (inform_n): Likewise. (warning): Likewise. (warning_at): Likewise. (warning_n): Likewise. (pedwarn): Likewise. (permerror): Likewise. (error): Likewise. (error_n): Likewise. (error_at): Likewise. (sorry): Likewise. (fatal_error): Likewise. (internal_error): Likewise. (internal_error_no_backtrace): Likewise. (real_abort): Likewise. * gcc-rich-location.h (gcc_rich_location::gcc_rich_location): Likewise. * genmatch.c (fatal_at): Likewise. (warning_at): Likewise. * rtl-error.c (diagnostic_for_asm): Likewise. gcc/fortran/ChangeLog: * error.c (gfc_warning): Pass line_table to rich_location ctor. (gfc_warning_now_at): Likewise. (gfc_warning_now): Likewise. (gfc_error_now): Likewise. (gfc_fatal_error): Likewise. (gfc_error): Likewise. (gfc_internal_error): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/diagnostic-token-ranges.c: New file. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (test_show_locus): Pass line_table to rich_location ctors. (plugin_init): Remove setting of global_dc->colorize_source_p. * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c: Remove include of gcc-rich-location.h. (get_range_for_expr): Delete. (gcc_rich_location::add_expr): Delete. (emit_warning): Change param from rich_location * to location_t. Require an ad-hoc location, and extract range from it. Use warning_at directly, without using a rich_location. (cb_walk_tree_fn): Pass EXPR_LOCATION (arg) directly to emit_warning, without creating a rich_location. libcpp/ChangeLog: * errors.c (cpp_diagnostic): Pass pfile->line_table to rich_location ctor. (cpp_diagnostic_with_line): Likewise. * include/line-map.h (rich_location::rich_location): Add line_maps * param. * line-map.c (rich_location::rich_location): Likewise; use it to extract the range from the source_location. --- gcc/c-family/c-opts.c | 2 + gcc/c/c-decl.c | 2 +- gcc/c/c-errors.c | 4 +- gcc/cp/error.c | 2 +- gcc/diagnostic.c | 34 +++--- gcc/fortran/error.c | 14 +-- gcc/gcc-rich-location.h | 2 +- gcc/genmatch.c | 8 +- gcc/rtl-error.c | 2 +- gcc/testsuite/gcc.dg/diagnostic-token-ranges.c | 120 +++++++++++++++++++++ .../plugin/diagnostic_plugin_test_show_locus.c | 21 ++-- .../diagnostic_plugin_test_tree_expression_range.c | 70 ++---------- libcpp/errors.c | 4 +- libcpp/include/line-map.h | 2 +- libcpp/line-map.c | 7 +- 15 files changed, 182 insertions(+), 112 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/diagnostic-token-ranges.c diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index bf2e6b0..681a542 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -247,6 +247,8 @@ c_common_init_options (unsigned int decoded_options_count, break; } } + + global_dc->colorize_source_p = true; } /* Handle switch SCODE with argument ARG. VALUE is true, unless no- diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 732080a..39c961e 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5297,7 +5297,7 @@ warn_defaults_to (location_t location, int opt, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c index 0f8b933..647423d 100644 --- a/gcc/c/c-errors.c +++ b/gcc/c/c-errors.c @@ -42,7 +42,7 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool warned = false; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); /* If desired, issue the C99/C11 compat warning, which is more specific @@ -81,7 +81,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); /* Warnings such as -Wvla are the most specific ones. */ diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 2e2ff10..82d18e3 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -3676,7 +3676,7 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 5fe6627..f1c5a96 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -868,7 +868,7 @@ diagnostic_append_note (diagnostic_context *context, diagnostic_info diagnostic; va_list ap; const char *saved_prefix; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); @@ -926,7 +926,7 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt, diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); if (kind == DK_PERMERROR) @@ -953,7 +953,7 @@ inform (location_t location, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); @@ -982,7 +982,7 @@ inform_n (location_t location, int n, const char *singular_gmsgid, { diagnostic_info diagnostic; va_list ap; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, plural_gmsgid); diagnostic_set_info_translated (&diagnostic, @@ -1001,7 +1001,7 @@ warning (int opt, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (input_location); + rich_location richloc (line_table, input_location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING); @@ -1022,7 +1022,7 @@ warning_at (location_t location, int opt, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING); @@ -1060,7 +1060,7 @@ warning_n (location_t location, int opt, int n, const char *singular_gmsgid, diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, plural_gmsgid); diagnostic_set_info_translated (&diagnostic, @@ -1092,7 +1092,7 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); @@ -1115,7 +1115,7 @@ permerror (location_t location, const char *gmsgid, ...) diagnostic_info diagnostic; va_list ap; bool ret; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, @@ -1151,7 +1151,7 @@ error (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (input_location); + rich_location richloc (line_table, input_location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR); @@ -1167,7 +1167,7 @@ error_n (location_t location, int n, const char *singular_gmsgid, { diagnostic_info diagnostic; va_list ap; - rich_location richloc (location); + rich_location richloc (line_table, location); va_start (ap, plural_gmsgid); diagnostic_set_info_translated (&diagnostic, @@ -1183,7 +1183,7 @@ error_at (location_t loc, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (loc); + rich_location richloc (line_table, loc); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR); @@ -1214,7 +1214,7 @@ sorry (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (input_location); + rich_location richloc (line_table, input_location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_SORRY); @@ -1238,7 +1238,7 @@ fatal_error (location_t loc, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (loc); + rich_location richloc (line_table, loc); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_FATAL); @@ -1257,7 +1257,7 @@ internal_error (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (input_location); + rich_location richloc (line_table, input_location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE); @@ -1275,7 +1275,7 @@ internal_error_no_backtrace (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - rich_location richloc (input_location); + rich_location richloc (line_table, input_location); va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE_NOBT); @@ -1346,7 +1346,7 @@ real_abort (void) void source_range::debug (const char *msg) const { - rich_location richloc (m_start); + rich_location richloc (line_table, m_start); richloc.add_range (m_start, m_finish); inform_at_rich_loc (&richloc, "%s", msg); } diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index 4b3d31c..b4f7020 100644 --- a/gcc/fortran/error.c +++ b/gcc/fortran/error.c @@ -773,7 +773,7 @@ gfc_warning (int opt, const char *gmsgid, va_list ap) va_copy (argp, ap); diagnostic_info diagnostic; - rich_location rich_loc (UNKNOWN_LOCATION); + rich_location rich_loc (line_table, UNKNOWN_LOCATION); bool fatal_errors = global_dc->fatal_errors; pretty_printer *pp = global_dc->printer; output_buffer *tmp_buffer = pp->buffer; @@ -1120,7 +1120,7 @@ gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...) { va_list argp; diagnostic_info diagnostic; - rich_location rich_loc (loc); + rich_location rich_loc (line_table, loc); bool ret; va_start (argp, gmsgid); @@ -1138,7 +1138,7 @@ gfc_warning_now (int opt, const char *gmsgid, ...) { va_list argp; diagnostic_info diagnostic; - rich_location rich_loc (UNKNOWN_LOCATION); + rich_location rich_loc (line_table, UNKNOWN_LOCATION); bool ret; va_start (argp, gmsgid); @@ -1158,7 +1158,7 @@ gfc_error_now (const char *gmsgid, ...) { va_list argp; diagnostic_info diagnostic; - rich_location rich_loc (UNKNOWN_LOCATION); + rich_location rich_loc (line_table, UNKNOWN_LOCATION); error_buffer.flag = true; @@ -1176,7 +1176,7 @@ gfc_fatal_error (const char *gmsgid, ...) { va_list argp; diagnostic_info diagnostic; - rich_location rich_loc (UNKNOWN_LOCATION); + rich_location rich_loc (line_table, UNKNOWN_LOCATION); va_start (argp, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL); @@ -1242,7 +1242,7 @@ gfc_error (const char *gmsgid, va_list ap) } diagnostic_info diagnostic; - rich_location richloc (UNKNOWN_LOCATION); + rich_location richloc (line_table, UNKNOWN_LOCATION); bool fatal_errors = global_dc->fatal_errors; pretty_printer *pp = global_dc->printer; output_buffer *tmp_buffer = pp->buffer; @@ -1288,7 +1288,7 @@ gfc_internal_error (const char *gmsgid, ...) { va_list argp; diagnostic_info diagnostic; - rich_location rich_loc (UNKNOWN_LOCATION); + rich_location rich_loc (line_table, UNKNOWN_LOCATION); va_start (argp, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE); diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h index c82cbf1..2f9291d 100644 --- a/gcc/gcc-rich-location.h +++ b/gcc/gcc-rich-location.h @@ -29,7 +29,7 @@ class gcc_rich_location : public rich_location /* Constructing from a location. */ gcc_rich_location (source_location loc) : - rich_location (loc) {} + rich_location (line_table, loc) {} /* Constructing from a source_range. */ gcc_rich_location (source_range src_range) : diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 6bfde06..24edc99 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -111,7 +111,7 @@ __attribute__((format (printf, 2, 3))) #endif fatal_at (const cpp_token *tk, const char *msg, ...) { - rich_location richloc (tk->src_loc); + rich_location richloc (line_table, tk->src_loc); va_list ap; va_start (ap, msg); error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap); @@ -124,7 +124,7 @@ __attribute__((format (printf, 2, 3))) #endif fatal_at (source_location loc, const char *msg, ...) { - rich_location richloc (loc); + rich_location richloc (line_table, loc); va_list ap; va_start (ap, msg); error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap); @@ -137,7 +137,7 @@ __attribute__((format (printf, 2, 3))) #endif warning_at (const cpp_token *tk, const char *msg, ...) { - rich_location richloc (tk->src_loc); + rich_location richloc (line_table, tk->src_loc); va_list ap; va_start (ap, msg); error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap); @@ -150,7 +150,7 @@ __attribute__((format (printf, 2, 3))) #endif warning_at (source_location loc, const char *msg, ...) { - rich_location richloc (loc); + rich_location richloc (line_table, loc); va_list ap; va_start (ap, msg); error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap); diff --git a/gcc/rtl-error.c b/gcc/rtl-error.c index d28be1d..17c5a58 100644 --- a/gcc/rtl-error.c +++ b/gcc/rtl-error.c @@ -69,7 +69,7 @@ diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr, diagnostic_t kind) { diagnostic_info diagnostic; - rich_location richloc (location_for_asm (insn)); + rich_location richloc (line_table, location_for_asm (insn)); diagnostic_set_info (&diagnostic, msg, args_ptr, &richloc, kind); diff --git a/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c b/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c new file mode 100644 index 0000000..ac969e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-token-ranges.c @@ -0,0 +1,120 @@ +/* { dg-options "-fdiagnostics-show-caret -Wc++-compat" } */ + +/* Verify that various diagnostics show source code ranges. */ + +/* These ones merely use token ranges; they don't use tree ranges. */ + +void undeclared_identifier (void) +{ + name; /* { dg-error "'name' undeclared" } */ +/* +{ dg-begin-multiline-output "" } + name; + ^~~~ +{ dg-end-multiline-output "" } +*/ +} + +void unknown_type_name (void) +{ + foo bar; /* { dg-error "unknown type name 'foo'" } */ +/* +{ dg-begin-multiline-output "" } + foo bar; + ^~~ +{ dg-end-multiline-output "" } +*/ + + qux *baz; /* { dg-error "unknown type name 'qux'" } */ +/* +{ dg-begin-multiline-output "" } + qux *baz; + ^~~ +{ dg-end-multiline-output "" } +*/ +} + +void test_identifier_conflicts_with_cplusplus (void) +{ + int new; /* { dg-warning "identifier 'new' conflicts with" } */ +/* +{ dg-begin-multiline-output "" } + int new; + ^~~ +{ dg-end-multiline-output "" } +*/ +} + +extern void +bogus_varargs (...); /* { dg-error "ISO C requires a named argument before '...'" } */ +/* +{ dg-begin-multiline-output "" } + bogus_varargs (...); + ^~~ +{ dg-end-multiline-output "" } +*/ + +extern void +foo (unknown_type param); /* { dg-error "unknown type name 'unknown_type'" } */ +/* +{ dg-begin-multiline-output "" } + foo (unknown_type param); + ^~~~~~~~~~~~ +{ dg-end-multiline-output "" } +*/ + +void wide_string_literal_in_asm (void) +{ + asm (L"nop"); /* { dg-error "wide string literal in 'asm'" } */ +/* +{ dg-begin-multiline-output "" } + asm (L"nop"); + ^~~~~~ +{ dg-end-multiline-output "" } +*/ +} + +void break_and_continue_in_wrong_places (void) +{ + if (0) + break; /* { dg-error "break statement not within loop or switch" } */ +/* { dg-begin-multiline-output "" } + break; + ^~~~~ + { dg-end-multiline-output "" } */ + + if (1) + ; + else + continue; /* { dg-error "continue statement not within a loop" } */ +/* { dg-begin-multiline-output "" } + continue; + ^~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Various examples of bad type decls. */ + +int float bogus; /* { dg-error "two or more data types in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + int float bogus; + ^~~~~ + { dg-end-multiline-output "" } */ + +long long long bogus2; /* { dg-error "'long long long' is too long for GCC" } */ +/* { dg-begin-multiline-output "" } + long long long bogus2; + ^~~~ + { dg-end-multiline-output "" } */ + +long short bogus3; /* { dg-error "both 'long' and 'short' in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + long short bogus3; + ^~~~~ + { dg-end-multiline-output "" } */ + +signed unsigned bogus4; /* { dg-error "both 'signed' and 'unsigned' in declaration specifiers" } */ +/* { dg-begin-multiline-output "" } + signed unsigned bogus4; + ^~~~~~~~ + { 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 3471a4e..4c6120d 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 @@ -163,7 +163,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_simple")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line, 15)); + rich_location richloc (line_table, get_loc (line, 15)); richloc.add_range (get_loc (line, 10), get_loc (line, 14)); richloc.add_range (get_loc (line, 16), get_loc (line, 16)); warning_at_rich_loc (&richloc, 0, "test"); @@ -172,7 +172,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_simple_2")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line, 24)); + rich_location richloc (line_table, get_loc (line, 24)); richloc.add_range (get_loc (line, 6), get_loc (line, 22)); richloc.add_range (get_loc (line, 26), @@ -183,7 +183,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_multiline")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line + 1, 7)); + rich_location richloc (line_table, get_loc (line + 1, 7)); richloc.add_range (get_loc (line, 7), get_loc (line, 23)); richloc.add_range (get_loc (line + 1, 9), @@ -194,7 +194,7 @@ test_show_locus (function *fun) if (0 == strcmp (fnname, "test_many_lines")) { const int line = fnstart_line + 2; - rich_location richloc (get_loc (line + 5, 7)); + rich_location richloc (line_table, get_loc (line + 5, 7)); richloc.add_range (get_loc (line, 7), get_loc (line + 4, 65)); richloc.add_range (get_loc (line + 5, 9), @@ -223,7 +223,7 @@ test_show_locus (function *fun) source_range src_range; src_range.m_start = get_loc (line, 12); src_range.m_finish = get_loc (line, 20); - rich_location richloc (caret); + rich_location richloc (line_table, caret); richloc.set_range (0, src_range, true, false); warning_at_rich_loc (&richloc, 0, "test"); } @@ -237,7 +237,7 @@ test_show_locus (function *fun) source_range src_range; src_range.m_start = get_loc (line, 90); src_range.m_finish = get_loc (line, 98); - rich_location richloc (caret); + rich_location richloc (line_table, caret); richloc.set_range (0, src_range, true, false); warning_at_rich_loc (&richloc, 0, "test"); } @@ -248,7 +248,7 @@ test_show_locus (function *fun) const int line = fnstart_line + 2; location_t caret_a = get_loc (line, 7); location_t caret_b = get_loc (line, 11); - rich_location richloc (caret_a); + rich_location richloc (line_table, caret_a); richloc.add_range (caret_b, caret_b, true); global_dc->caret_chars[0] = 'A'; global_dc->caret_chars[1] = 'B'; @@ -269,7 +269,7 @@ test_show_locus (function *fun) const int line = fnstart_line + 3; location_t caret_a = get_loc (line, 5); location_t caret_b = get_loc (line - 1, 19); - rich_location richloc (caret_a); + rich_location richloc (line_table, caret_a); richloc.add_range (caret_b, caret_b, true); global_dc->caret_chars[0] = '1'; global_dc->caret_chars[1] = '2'; @@ -304,11 +304,6 @@ plugin_init (struct plugin_name_args *plugin_info, if (!plugin_default_version_check (version, &gcc_version)) return 1; - /* For now, tell the dc to expect ranges and thus to colorize the source - lines, not just the carets/underlines. This will be redundant - once the C frontend generates ranges. */ - global_dc->colorize_source_p = true; - for (int i = 0; i < argc; i++) { if (0 == strcmp (argv[i].key, "color")) diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c index 46e97b7..ca54278 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c @@ -29,72 +29,26 @@ #include "plugin-version.h" #include "diagnostic.h" #include "context.h" -#include "gcc-rich-location.h" #include "print-tree.h" -/* - Hack: fails with linker error: -./diagnostic_plugin_test_tree_expression_range.so: undefined symbol: _ZN17gcc_rich_location8add_exprEP9tree_node - since nothing in the tree is using gcc_rich_location::add_expr yet. - - I've tried various workarounds (adding DEBUG_FUNCTION to the - method, taking its address), but can't seem to fix it that way. - So as a nasty workaround, the following material is copied&pasted - from gcc-rich-location.c: */ - -static bool -get_range_for_expr (tree expr, location_range *r) -{ - if (EXPR_HAS_RANGE (expr)) - { - source_range sr = EXPR_LOCATION_RANGE (expr); - - /* Do we have meaningful data? */ - if (sr.m_start && sr.m_finish) - { - r->m_start = expand_location (sr.m_start); - r->m_finish = expand_location (sr.m_finish); - return true; - } - } - - return false; -} - -/* Add a range to the rich_location, covering expression EXPR. */ - -void -gcc_rich_location::add_expr (tree expr) -{ - gcc_assert (expr); - - location_range r; - r.m_show_caret_p = false; - if (get_range_for_expr (expr, &r)) - add_range (&r); -} - -/* FIXME: end of material taken from gcc-rich-location.c */ - - int plugin_is_GPL_compatible; static void -emit_warning (rich_location *richloc) +emit_warning (location_t loc) { - if (richloc->get_num_locations () < 2) + if (!IS_ADHOC_LOC (loc)) { - error_at_rich_loc (richloc, "range not found"); + error_at (loc, "ad-hoc location not found"); return; } - location_range *range = richloc->get_range (1); - warning_at_rich_loc (richloc, 0, - "tree range %i:%i-%i:%i", - range->m_start.line, - range->m_start.column, - range->m_finish.line, - range->m_finish.column); + source_range src_range = get_range_from_adhoc_loc (line_table, loc); + warning_at (loc, 0, + "tree range %i:%i-%i:%i", + LOCATION_LINE (src_range.m_start), + LOCATION_COLUMN (src_range.m_start), + LOCATION_LINE (src_range.m_finish), + LOCATION_COLUMN (src_range.m_finish)); } tree @@ -117,9 +71,7 @@ cb_walk_tree_fn (tree * tp, int * walk_subtrees, /* Get arg 1; print it! */ tree arg = CALL_EXPR_ARG (call_expr, 1); - gcc_rich_location richloc (EXPR_LOCATION (arg)); - richloc.add_expr (arg); - emit_warning (&richloc); + emit_warning (EXPR_LOCATION (arg)); return NULL_TREE; } diff --git a/libcpp/errors.c b/libcpp/errors.c index c351c11..8790e10 100644 --- a/libcpp/errors.c +++ b/libcpp/errors.c @@ -57,7 +57,7 @@ cpp_diagnostic (cpp_reader * pfile, int level, int reason, if (!pfile->cb.error) abort (); - rich_location richloc (src_loc); + rich_location richloc (pfile->line_table, src_loc); ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap); return ret; @@ -140,7 +140,7 @@ cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason, if (!pfile->cb.error) abort (); - rich_location richloc (src_loc); + rich_location richloc (pfile->line_table, src_loc); richloc.override_column (column); ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap); diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index de1c55c..0ef29d9 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -1192,7 +1192,7 @@ class rich_location /* Constructors. */ /* Constructing from a location. */ - rich_location (source_location loc); + rich_location (line_maps *set, source_location loc); /* Constructing from a source_range. */ rich_location (source_range src_range); diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 3810c88..2cbd56a 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -1774,13 +1774,14 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary, /* Construct a rich_location with location LOC as its initial range. */ -rich_location::rich_location (source_location loc) : +rich_location::rich_location (line_maps *set, source_location loc) : m_loc (loc), m_num_ranges (0), m_have_expanded_location (false) { - /* Set up the 0th range: */ - add_range (loc, loc, true); + /* Set up the 0th range, extracting any range from LOC. */ + source_range src_range = get_range_from_loc (set, loc); + add_range (src_range, true); m_ranges[0].m_caret = lazily_expand_location (); } -- 1.8.5.3