diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2015-05-16 12:31:00 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2015-05-16 12:31:00 +0000 |
commit | 2a2703a2bd0046ed60a2054df1f4f3ba5c793062 (patch) | |
tree | e38c12f0ed89361988c13ec74581d698238467a0 /gcc/diagnostic.c | |
parent | 40de31cfe4e8959e5f92c82aa34550693897d29c (diff) | |
download | gcc-2a2703a2bd0046ed60a2054df1f4f3ba5c793062.zip gcc-2a2703a2bd0046ed60a2054df1f4f3ba5c793062.tar.gz gcc-2a2703a2bd0046ed60a2054df1f4f3ba5c793062.tar.bz2 |
re PR fortran/44054 (Handle -Werror, -Werror=, -fdiagnostics-show-option, !GCC$ diagnostic (pragmas) and color)
gcc/fortran/ChangeLog:
2015-05-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054
Replace all calls to gfc_notify_std_1 with gfc_notify_std and
gfc_warning_1 with gfc_warning.
* decl.c (gfc_verify_c_interop_param): Here.
* resolve.c (resolve_branch): Here.
(resolve_fl_derived): Here.
* dependency.c (gfc_check_argument_var_dependency):
* scanner.c (preprocessor_line): Use gfc_warning_now_at. Fix line
counter and locations before and after warning.
* gfortran.h (gfc_warning_1, gfc_warning_now_1, gfc_notify_std_1):
Delete.
(gfc_warning_now_at): Declare.
* error.c (gfc_warning_1): Delete.
(gfc_notify_std_1): Delete.
(gfc_warning_now_1): Delete.
(gfc_format_decoder): Handle two locations.
(gfc_diagnostic_build_prefix): Rename as
gfc_diagnostic_build_kind_prefix.
(gfc_diagnostic_build_locus_prefix): Take an expanded_location
instead of diagnostic_info.
(gfc_diagnostic_build_locus_prefix): Add overload that takes two
expanded_location.
(gfc_diagnostic_starter): Handle two locations.
(gfc_warning_now_at): New.
(gfc_diagnostics_init): Initialize caret_chars array.
(gfc_diagnostics_finish): Reset caret_chars array to default.
gcc/cp/ChangeLog:
2015-05-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054
* error.c (cp_diagnostic_starter): Use diagnostic_location
function.
(cp_print_error_function): Likewise.
(cp_printer): Replace locus pointer with accessor function.
gcc/c/ChangeLog:
2015-05-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054
* c-objc-common.c (c_tree_printer): Replace locus pointer with
accessor function.
gcc/ChangeLog:
2015-05-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054
* tree-pretty-print.c (percent_K_format): Replace locus pointer
with accessor function.
* tree-diagnostic.c (diagnostic_report_current_function): Use
diagnostic_location function.
(maybe_unwind_expanded_macro_loc): Likewise.
(virt_loc_aware_diagnostic_finalizer): Likewise.
(default_tree_printer): Replace locus pointer with accessor function.
* diagnostic.c (diagnostic_initialize): Initialize caret_chars array.
(diagnostic_set_info_translated): Initialize second location.
(diagnostic_build_prefix): Use CARET_LINE_MARGIN.
(diagnostic_show_locus): Handle two locations. Call
diagnostic_print_caret_line.
(diagnostic_print_caret_line): New.
(default_diagnostic_starter): Use diagnostic_location function.
(diagnostic_report_diagnostic): Use diagnostic_location function.
(verbatim): Do not set text.locus.
* diagnostic.h (struct diagnostic_info): Remove location field.
(struct diagnostic_context): Make caret_chars an array of two.
(diagnostic_location): New inline.
(diagnostic_expand_location): Handle two locations.
(diagnostic_same_line): New inline.
(diagnostic_print_caret_line): Declare.
(CARET_LINE_MARGIN): New constant.
* pretty-print.c (pp_printf): Do not set text.locus.
(pp_verbatim): Do not set text.locus.
* pretty-print.h (MAX_LOCATIONS_PER_MESSAGE): New constant.
(struct text_info): Replace locus pointer with locations
array. Add accessor functions.
gcc/testsuite/ChangeLog:
2015-05-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054
* lib/gfortran-dg.exp: Update regex to handle two locations for
the same diagnostic without caret.
* gfortran.dg/badline.f: Test also that line numbers are correct
before and after "left but not entered" warning.
From-SVN: r223237
Diffstat (limited to 'gcc/diagnostic.c')
-rw-r--r-- | gcc/diagnostic.c | 121 |
1 files changed, 85 insertions, 36 deletions
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 2196406..54e3fcf 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -146,7 +146,8 @@ diagnostic_initialize (diagnostic_context *context, int n_opts) context->classify_diagnostic[i] = DK_UNSPECIFIED; context->show_caret = false; diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer)); - context->caret_char = '^'; + for (i = 0; i < MAX_LOCATIONS_PER_MESSAGE; i++) + context->caret_chars[i] = '^'; context->show_option_requested = false; context->abort_on_error = false; context->show_column = false; @@ -241,7 +242,9 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, diagnostic->message.err_no = errno; diagnostic->message.args_ptr = args; diagnostic->message.format_spec = msg; - diagnostic->location = location; + diagnostic->message.set_location (0, location); + for (int i = 1; i < MAX_LOCATIONS_PER_MESSAGE; i++) + diagnostic->message.set_location (i, UNKNOWN_LOCATION); diagnostic->override_column = 0; diagnostic->kind = kind; diagnostic->option_index = 0; @@ -309,14 +312,14 @@ diagnostic_build_prefix (diagnostic_context *context, /* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than MAX_WIDTH by some margin, then adjust the start of the line such that the COLUMN is smaller than MAX_WIDTH minus the margin. The - margin is either 10 characters or the difference between the column - and the length of the line, whatever is smaller. The length of - LINE is given by LINE_WIDTH. */ + margin is either CARET_LINE_MARGIN characters or the difference + between the column and the length of the line, whatever is smaller. + The length of LINE is given by LINE_WIDTH. */ static const char * adjust_line (const char *line, int line_width, int max_width, int *column_p) { - int right_margin = 10; + int right_margin = CARET_LINE_MARGIN; int column = *column_p; gcc_checking_assert (line_width >= column); @@ -331,35 +334,69 @@ adjust_line (const char *line, int line_width, } /* Print the physical source line corresponding to the location of - this diagnostic, and a caret indicating the precise column. */ + this diagnostic, and a caret indicating the precise column. This + function only prints two caret characters if the two locations + given by DIAGNOSTIC are on the same line according to + diagnostic_same_line(). */ void diagnostic_show_locus (diagnostic_context * context, const diagnostic_info *diagnostic) { - const char *line; - int line_width; - char *buffer; - expanded_location s; - int max_width; - const char *saved_prefix; - const char *caret_cs, *caret_ce; - if (!context->show_caret - || diagnostic->location <= BUILTINS_LOCATION - || diagnostic->location == context->last_location) + || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION + || diagnostic_location (diagnostic, 0) == context->last_location) return; - context->last_location = diagnostic->location; - s = diagnostic_expand_location (diagnostic); - line = location_get_source_line (s, &line_width); - if (line == NULL || s.column > line_width) - return; + context->last_location = diagnostic_location (diagnostic, 0); + expanded_location s0 = diagnostic_expand_location (diagnostic, 0); + expanded_location s1 = { }; + /* Zero-initialized. This is checked later by diagnostic_print_caret_line. */ - max_width = context->caret_max_width; - line = adjust_line (line, line_width, max_width, &(s.column)); + if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION) + s1 = diagnostic_expand_location (diagnostic, 1); + diagnostic_print_caret_line (context, s0, s1, + context->caret_chars[0], + context->caret_chars[1]); +} + +/* Print (part) of the source line given by xloc1 with caret1 pointing + at the column. If xloc2.column != 0 and it fits within the same + line as xloc1 according to diagnostic_same_line (), then caret2 is + printed at xloc2.colum. Otherwise, the caller has to set up things + to print a second caret line for xloc2. */ +void +diagnostic_print_caret_line (diagnostic_context * context, + expanded_location xloc1, + expanded_location xloc2, + char caret1, char caret2) +{ + if (!diagnostic_same_line (context, xloc1, xloc2)) + /* This will mean ignore xloc2. */ + xloc2.column = 0; + else if (xloc1.column == xloc2.column) + xloc2.column++; + + int cmax = MAX (xloc1.column, xloc2.column); + int line_width; + const char *line = location_get_source_line (xloc1, &line_width); + if (line == NULL || cmax > line_width) + return; + + /* Center the interesting part of the source line to fit in + max_width, and adjust all columns accordingly. */ + int max_width = context->caret_max_width; + int offset = (int) cmax; + line = adjust_line (line, line_width, max_width, &offset); + offset -= cmax; + cmax += offset; + xloc1.column += offset; + if (xloc2.column) + xloc2.column += offset; + + /* Print the source line. */ pp_newline (context->printer); - saved_prefix = pp_get_prefix (context->printer); + const char *saved_prefix = pp_get_prefix (context->printer); pp_set_prefix (context->printer, NULL); pp_space (context->printer); while (max_width > 0 && line_width > 0) @@ -373,15 +410,28 @@ diagnostic_show_locus (diagnostic_context * context, line++; } pp_newline (context->printer); + + /* Print the caret under the line. */ + const char *caret_cs, *caret_ce; caret_cs = colorize_start (pp_show_color (context->printer), "caret"); caret_ce = colorize_stop (pp_show_color (context->printer)); + int cmin = xloc2.column + ? MIN (xloc1.column, xloc2.column) : xloc1.column; + int caret_min = cmin == xloc1.column ? caret1 : caret2; + int caret_max = cmin == xloc1.column ? caret2 : caret1; - /* pp_printf does not implement %*c. */ - size_t len = s.column + 3 + strlen (caret_cs) + strlen (caret_ce); - buffer = XALLOCAVEC (char, len); - snprintf (buffer, len, "%s %*c%s", caret_cs, s.column, context->caret_char, - caret_ce); - pp_string (context->printer, buffer); + pp_space (context->printer); + int i; + for (i = 0; i < cmin; i++) + pp_space (context->printer); + pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce); + + if (xloc2.column) + { + for (i++; i < cmax; i++) + pp_space (context->printer); + pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce); + } pp_set_prefix (context->printer, saved_prefix); pp_needs_newline (context->printer) = true; } @@ -604,7 +654,7 @@ void default_diagnostic_starter (diagnostic_context *context, diagnostic_info *diagnostic) { - diagnostic_report_current_module (context, diagnostic->location); + diagnostic_report_current_module (context, diagnostic_location (diagnostic)); pp_set_prefix (context->printer, diagnostic_build_prefix (context, diagnostic)); } @@ -716,7 +766,7 @@ bool diagnostic_report_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic) { - location_t location = diagnostic->location; + location_t location = diagnostic_location (diagnostic); diagnostic_t orig_diag_kind = diagnostic->kind; const char *saved_format_spec; @@ -825,7 +875,8 @@ diagnostic_report_diagnostic (diagnostic_context *context, || diagnostic_kind_count (context, DK_SORRY) > 0) && !context->abort_on_error) { - expanded_location s = expand_location (diagnostic->location); + expanded_location s + = expand_location (diagnostic_location (diagnostic)); fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", s.file, s.line); exit (ICE_EXIT_CODE); @@ -859,7 +910,6 @@ diagnostic_report_diagnostic (diagnostic_context *context, free (option_text); } } - diagnostic->message.locus = &diagnostic->location; diagnostic->message.x_data = &diagnostic->x_data; diagnostic->x_data = NULL; pp_format (context->printer, &diagnostic->message); @@ -920,7 +970,6 @@ verbatim (const char *gmsgid, ...) text.err_no = errno; text.args_ptr = ≈ text.format_spec = _(gmsgid); - text.locus = NULL; text.x_data = NULL; pp_format_verbatim (global_dc->printer, &text); pp_newline_and_flush (global_dc->printer); |