summaryrefslogtreecommitdiff
path: root/gcc/diagnostic.c
diff options
context:
space:
mode:
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-16 12:31:00 +0000
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-16 12:31:00 +0000
commit389a90090343044071c1f6d1e00be17b76504040 (patch)
treee38c12f0ed89361988c13ec74581d698238467a0 /gcc/diagnostic.c
parent091723223d8d2b0dd7da37c1e94a67cfcaf5b69b (diff)
downloadgcc-389a90090343044071c1f6d1e00be17b76504040.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223237 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/diagnostic.c')
-rw-r--r--gcc/diagnostic.c121
1 files changed, 85 insertions, 36 deletions
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 2196406f881..54e3fcfa818 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 = &ap;
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);