re PR c++/24985 (caret diagnostics)

2012-04-11  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR 24985
gcc/
        * diagnostic.h (show_caret): Declare.
	(caret_max_width): Declare.
	(diagnostic_show_locus): Declare.
        * diagnostic.c (diagnostic_initialize): Initialize to false.
        (diagnostic_show_locus): New.
        (diagnostic_report_diagnostic): Call it.
	(getenv_columns): New.
	(adjust_line): New.
	(diagnostic_set_caret_max_width): New.
        * input.c (read_line): New.
	(location_get_source_line): New.
        * input.h (location_get_source_line): Declare.
        * toplev.c (general_init): Initialize show_caret from options.
        * dwarf2out.c (gen_producer_string): Handle fdiagnostics-show-caret.
        * opts.c (common_handle_option): Likewise.
	* pretty-print.h (pp_get_prefix): New.
	(pp_base_get_prefix): New.
        * common.opt (fdiagnostics-show-caret): New option.
	* doc/invoke.texi (fdiagnostics-show-caret): Document it.
testsuite/
        * lib/prune.exp: Add -fno-diagnostics-show-caret.
libstdc++-v3/
	* testsuite/lib/prune.exp: Handle caret.
libmudflap/
	* testsuite/lib/libmudflap.exp: Handle caret.

From-SVN: r186305
This commit is contained in:
Manuel López-Ibáñez 2012-04-11 09:26:48 +00:00
parent 13a7578b18
commit 9fec00429d
17 changed files with 241 additions and 1 deletions

View File

@ -1,3 +1,26 @@
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 24985
* diagnostic.h (show_caret): Declare.
(caret_max_width): Declare.
(diagnostic_show_locus): Declare.
* diagnostic.c (diagnostic_initialize): Initialize to false.
(diagnostic_show_locus): New.
(diagnostic_report_diagnostic): Call it.
(getenv_columns): New.
(adjust_line): New.
(diagnostic_set_caret_max_width): New.
* input.c (read_line): New.
(location_get_source_line): New.
* input.h (location_get_source_line): Declare.
* toplev.c (general_init): Initialize show_caret from options.
* dwarf2out.c (gen_producer_string): Handle fdiagnostics-show-caret.
* opts.c (common_handle_option): Likewise.
* pretty-print.h (pp_get_prefix): New.
(pp_base_get_prefix): New.
* common.opt (fdiagnostics-show-caret): New option.
* doc/invoke.texi (fdiagnostics-show-caret): Document it.
2012-04-11 Richard Guenther <rguenther@suse.de>
PR rtl-optimization/52881

View File

@ -999,6 +999,10 @@ Enum(diagnostic_prefixing_rule) String(once) Value(DIAGNOSTICS_SHOW_PREFIX_ONCE)
EnumValue
Enum(diagnostic_prefixing_rule) String(every-line) Value(DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE)
fdiagnostics-show-caret
Common Var(flag_diagnostics_show_caret) Init(1)
Show the source line with a caret indicating the column
fdiagnostics-show-option
Common Var(flag_diagnostics_show_option) Init(1)
Amend appropriate diagnostic messages with the command line option that controls them

View File

@ -78,6 +78,35 @@ file_name_as_prefix (const char *f)
/* Return the value of the getenv("COLUMNS") as an integer. If the
value is not set to a positive integer, then return INT_MAX. */
static int
getenv_columns (void)
{
const char * s = getenv ("COLUMNS");
if (s != NULL) {
int n = atoi (s);
if (n > 0)
return n;
}
return INT_MAX;
}
/* Set caret_max_width to value. */
void
diagnostic_set_caret_max_width (diagnostic_context *context, int value)
{
/* One minus to account for the leading empty space. */
value = value ? value - 1
: (isatty (fileno (context->printer->buffer->stream))
? getenv_columns () - 1: INT_MAX);
if (value <= 0)
value = INT_MAX;
context->caret_max_width = value;
}
/* Initialize the diagnostic message outputting machinery. */
void
diagnostic_initialize (diagnostic_context *context, int n_opts)
@ -100,6 +129,8 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
for (i = 0; i < n_opts; i++)
context->classify_diagnostic[i] = DK_UNSPECIFIED;
context->show_caret = false;
diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
context->show_option_requested = false;
context->abort_on_error = false;
context->show_column = false;
@ -196,6 +227,72 @@ diagnostic_build_prefix (diagnostic_context *context,
: build_message_string ("%s:%d: %s", s.file, s.line, text));
}
/* 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. */
static const char *
adjust_line (const char *line, int max_width, int *column_p)
{
int right_margin = 10;
int line_width = strlen (line);
int column = *column_p;
right_margin = MIN(line_width - column, right_margin);
right_margin = max_width - right_margin;
if (line_width >= max_width && column > right_margin)
{
line += column - right_margin;
*column_p = right_margin;
}
return line;
}
/* Print the physical source line corresponding to the location of
this diagnostics, and a caret indicating the precise column. */
void
diagnostic_show_locus (diagnostic_context * context,
const diagnostic_info *diagnostic)
{
const char *line;
char *buffer;
expanded_location s;
int max_width;
const char *saved_prefix;
if (!context->show_caret
|| diagnostic->location <= BUILTINS_LOCATION)
return;
s = expand_location(diagnostic->location);
line = location_get_source_line (s);
if (line == NULL)
return;
max_width = context->caret_max_width;
line = adjust_line (line, max_width, &(s.column));
pp_newline (context->printer);
saved_prefix = pp_get_prefix (context->printer);
pp_set_prefix (context->printer, NULL);
pp_character (context->printer, ' ');
while (max_width > 0 && *line != '\0')
{
char c = *line == '\t' ? ' ' : *line;
pp_character (context->printer, c);
max_width--;
line++;
}
pp_newline (context->printer);
/* pp_printf does not implement %*c. */
buffer = XALLOCAVEC (char, s.column + 3);
snprintf (buffer, s.column + 3, " %*c", s.column, '^');
pp_string (context->printer, buffer);
pp_set_prefix (context->printer, saved_prefix);
}
/* Take any action which is expected to happen after the diagnostic
is written out. This function does not always return. */
static void
@ -547,6 +644,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
pp_format (context->printer, &diagnostic->message);
(*diagnostic_starter (context)) (context, diagnostic);
pp_output_formatted_text (context->printer);
diagnostic_show_locus (context, diagnostic);
(*diagnostic_finalizer (context)) (context, diagnostic);
pp_flush (context->printer);
diagnostic_action_after_output (context, diagnostic);

View File

@ -99,6 +99,13 @@ struct diagnostic_context
int *push_list;
int n_push;
/* True if we should print the source line with a caret indicating
the location. */
bool show_caret;
/* Maximum width of the source line printed. */
int caret_max_width;
/* True if we should print the command line option which controls
each diagnostic, if known. */
bool show_option_requested;
@ -254,6 +261,7 @@ extern diagnostic_context *global_dc;
extern void diagnostic_initialize (diagnostic_context *, int);
extern void diagnostic_finish (diagnostic_context *);
extern void diagnostic_report_current_module (diagnostic_context *, location_t);
extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *);
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
@ -275,6 +283,8 @@ extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
extern char *diagnostic_build_prefix (diagnostic_context *, diagnostic_info *);
void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
/* Pure text formatting support functions. */
extern char *file_name_as_prefix (const char *);

View File

@ -230,7 +230,7 @@ Objective-C and Objective-C++ Dialects}.
@xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
@gccoptlist{-fmessage-length=@var{n} @gol
-fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol
-fno-diagnostics-show-option}
-fno-diagnostics-show-option -fno-diagnostics-show-caret}
@item Warning Options
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@ -2894,6 +2894,13 @@ command-line option that directly controls the diagnostic (if such an
option is known to the diagnostic machinery). Specifying the
@option{-fno-diagnostics-show-option} flag suppresses that behavior.
@item -fno-diagnostics-show-caret
@opindex fno-diagnostics-show-caret
@opindex fdiagnostics-show-caret
By default, each diagnostic emitted includes the original source line
and a caret '^' indicating the column. This option suppresses this
information.
@end table
@node Warning Options

View File

@ -18369,6 +18369,7 @@ gen_producer_string (void)
case OPT__output_pch_:
case OPT_fdiagnostics_show_location_:
case OPT_fdiagnostics_show_option:
case OPT_fdiagnostics_show_caret:
case OPT_fverbose_asm:
case OPT____:
case OPT__sysroot_:

View File

@ -50,6 +50,65 @@ expand_location (source_location loc)
return xloc;
}
/* Reads one line from file into a static buffer. */
static const char *
read_line (FILE *file)
{
static char *string;
static size_t string_len;
size_t pos = 0;
char *ptr;
if (!string_len)
{
string_len = 200;
string = XNEWVEC (char, string_len);
}
while ((ptr = fgets (string + pos, string_len - pos, file)))
{
size_t len = strlen (string + pos);
if (string[pos + len - 1] == '\n')
{
string[pos + len - 1] = 0;
return string;
}
pos += len;
ptr = XNEWVEC (char, string_len * 2);
if (ptr)
{
memcpy (ptr, string, pos);
string = ptr;
string_len += 2;
}
else
pos = 0;
}
return pos ? string : NULL;
}
/* Return the physical source line that corresponds to xloc in a
buffer that is statically allocated. The newline is replaced by
the null character. */
const char *
location_get_source_line(expanded_location xloc)
{
const char *buffer;
int lines = 1;
FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
if (!stream)
return NULL;
while ((buffer = read_line (stream)) && lines < xloc.line)
lines++;
fclose (stream);
return buffer;
}
#define ONE_K 1024
#define ONE_M (ONE_K * ONE_K)

View File

@ -38,6 +38,7 @@ extern char builtins_location_check[(BUILTINS_LOCATION
< RESERVED_LOCATION_COUNT) ? 1 : -1];
extern expanded_location expand_location (source_location);
extern const char * location_get_source_line(expanded_location xloc);
/* Historically GCC used location_t, while cpp used source_location.
This could be removed but it hardly seems worth the effort. */

View File

@ -1499,6 +1499,10 @@ common_handle_option (struct gcc_options *opts,
case OPT_fdiagnostics_show_location_:
diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
break;
case OPT_fdiagnostics_show_caret:
dc->show_caret = value;
break;
case OPT_fdiagnostics_show_option:
dc->show_option_requested = value;
@ -1539,6 +1543,7 @@ common_handle_option (struct gcc_options *opts,
case OPT_fmessage_length_:
pp_set_line_maximum_length (dc->printer, value);
diagnostic_set_caret_max_width (dc, value);
break;
case OPT_fpack_struct_:

View File

@ -201,6 +201,9 @@ struct pretty_print_info
#define pp_set_line_maximum_length(PP, L) \
pp_base_set_line_maximum_length (pp_base (PP), L)
#define pp_set_prefix(PP, P) pp_base_set_prefix (pp_base (PP), P)
#define pp_get_prefix(PP) pp_base_get_prefix (pp_base (PP))
static inline const char *
pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
#define pp_destroy_prefix(PP) pp_base_destroy_prefix (pp_base (PP))
#define pp_remaining_character_count_for_line(PP) \
pp_base_remaining_character_count_for_line (pp_base (PP))

View File

@ -1,3 +1,8 @@
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 24985
* lib/prune.exp: Add -fno-diagnostics-show-caret.
2012-04-11 Richard Guenther <rguenther@suse.de>
PR rtl-optimization/52881

View File

@ -17,6 +17,8 @@
# Prune messages from gcc that aren't useful.
set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret $TEST_ALWAYS_FLAGS"
proc prune_gcc_output { text } {
#send_user "Before:$text\n"

View File

@ -1169,6 +1169,8 @@ general_init (const char *argv0)
/* Set a default printer. Language specific initializations will
override it later. */
pp_format_decoder (global_dc->printer) = &default_tree_printer;
global_dc->show_caret
= global_options_init.x_flag_diagnostics_show_caret;
global_dc->show_option_requested
= global_options_init.x_flag_diagnostics_show_option;
global_dc->show_column

View File

@ -1,3 +1,8 @@
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 24985
* testsuite/lib/libmudflap.exp: Handle caret.
2012-01-19 Jakub Jelinek <jakub@redhat.com>
PR libmudflap/40778

View File

@ -298,6 +298,9 @@ proc libmudflap-dg-prune { system text } {
proc prune_gcc_output { text } {
# Ignore caret diagnostics. Unfortunately dejaGNU trims leading
# spaces, so one cannot rely on them being present.
regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
regsub -all {(^|\n)[^\n]*ld: warning: libgcc_s[^\n]*not found[^\n]*try using[^\n]*} $text "" text
regsub -all {(^|\n)[^\n]*In function.*pthread_create[^\n]*} $text "" text
regsub -all {(^|\n)[^\n]*the use of .pthread.*is deprecated[^\n]*} $text "" text

View File

@ -1,3 +1,8 @@
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 24985
* testsuite/lib/prune.exp: Handle caret.
2012-04-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Partially revert:

View File

@ -32,6 +32,12 @@ proc dg-prune-output { args } {
proc libstdc++-dg-prune { system text } {
global additional_prunes
# send_user "Before:$text\n"
# Ignore caret diagnostics. Unfortunately dejaGNU trims leading
# spaces, so one cannot rely on them being present.
regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
# Cygwin warns about -ffunction-sections
regsub -all "(^|\n)\[^\n\]*: -ffunction-sections may affect debugging on some targets\[^\n\]*" $text "" text
@ -68,5 +74,6 @@ proc libstdc++-dg-prune { system text } {
}
}
# send_user "After:$text\n"
return $text
}