Implement -fdiagnostics-parseable-fixits
gcc/ChangeLog: * common.opt (fdiagnostics-parseable-fixits): New option. * diagnostic.c: Include "selftest.h". (print_escaped_string): New function. (print_parseable_fixits): New function. (diagnostic_report_diagnostic): Call print_parseable_fixits. (selftest::assert_print_escaped_string): New function. (ASSERT_PRINT_ESCAPED_STRING_STREQ): New macro. (selftest::test_print_escaped_string): New function. (selftest::test_print_parseable_fixits_none): New function. (selftest::test_print_parseable_fixits_insert): New function. (selftest::test_print_parseable_fixits_remove): New function. (selftest::test_print_parseable_fixits_replace): New function. (selftest::diagnostic_c_tests): New function. * diagnostic.h (struct diagnostic_context): Add field "parseable_fixits_p". * doc/invoke.texi (Diagnostic Message Formatting Options): Add -fdiagnostics-parseable-fixits. (-fdiagnostics-parseable-fixits): New option. * opts.c (common_handle_option): Handle -fdiagnostics-parseable-fixits. * selftest-run-tests.c (selftest::run_tests): Call selftest::diagnostic_c_tests. * selftest.h (selftest::diagnostic_c_tests): New prototype. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c: New file. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic-test-show-locus-parseable-fixits.c to sources for diagnostic_plugin_test_show_locus.c. * lib/gcc-defs.exp (freeform_regexps): New global. (dg-regexp): New function. (handle-dg-regexps): New function. * lib/gcc-dg.exp (cleanup-after-saved-dg-test): Reset freeform_regexps to the empty list. * lib/prune.exp (prune_gcc_output): Call handle-dg-regexps. libcpp/ChangeLog: * include/line-map.h (fixit_hint::get_start_loc): New pure virtual function. (fixit_hint::maybe_get_end_loc): Likewise. (fixit_insert::get_start_loc): New function, implementing fixit_hint::get_start_loc. (fixit_insert::maybe_get_end_loc): New function, implementing fixit_hint::maybe_get_end_loc. (fixit_remove::get_start_loc): New function, implementing fixit_hint::get_start_loc. (fixit_remove::maybe_get_end_loc): New function, implementing fixit_hint::maybe_get_end_loc. (fixit_replace::get_start_loc): New function, implementing fixit_hint::get_start_loc. (fixit_replace::maybe_get_end_loc): New function, implementing fixit_hint::maybe_get_end_loc. From-SVN: r237712
This commit is contained in:
parent
d53c039815
commit
a93eac6a84
@ -1,3 +1,29 @@
|
||||
2016-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* common.opt (fdiagnostics-parseable-fixits): New option.
|
||||
* diagnostic.c: Include "selftest.h".
|
||||
(print_escaped_string): New function.
|
||||
(print_parseable_fixits): New function.
|
||||
(diagnostic_report_diagnostic): Call print_parseable_fixits.
|
||||
(selftest::assert_print_escaped_string): New function.
|
||||
(ASSERT_PRINT_ESCAPED_STRING_STREQ): New macro.
|
||||
(selftest::test_print_escaped_string): New function.
|
||||
(selftest::test_print_parseable_fixits_none): New function.
|
||||
(selftest::test_print_parseable_fixits_insert): New function.
|
||||
(selftest::test_print_parseable_fixits_remove): New function.
|
||||
(selftest::test_print_parseable_fixits_replace): New function.
|
||||
(selftest::diagnostic_c_tests): New function.
|
||||
* diagnostic.h (struct diagnostic_context): Add field
|
||||
"parseable_fixits_p".
|
||||
* doc/invoke.texi (Diagnostic Message Formatting Options): Add
|
||||
-fdiagnostics-parseable-fixits.
|
||||
(-fdiagnostics-parseable-fixits): New option.
|
||||
* opts.c (common_handle_option): Handle
|
||||
-fdiagnostics-parseable-fixits.
|
||||
* selftest-run-tests.c (selftest::run_tests): Call
|
||||
selftest::diagnostic_c_tests.
|
||||
* selftest.h (selftest::diagnostic_c_tests): New prototype.
|
||||
|
||||
2016-06-22 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
PR middle-end/71488
|
||||
|
@ -1185,6 +1185,10 @@ Enum(diagnostic_color_rule) String(always) Value(DIAGNOSTICS_COLOR_YES)
|
||||
EnumValue
|
||||
Enum(diagnostic_color_rule) String(auto) Value(DIAGNOSTICS_COLOR_AUTO)
|
||||
|
||||
fdiagnostics-parseable-fixits
|
||||
Common Var(flag_diagnostics_parseable_fixits)
|
||||
Print fixit hints in machine-readable form.
|
||||
|
||||
fdiagnostics-show-option
|
||||
Common Var(flag_diagnostics_show_option) Init(1)
|
||||
Amend appropriate diagnostic messages with the command line option that controls them.
|
||||
|
258
gcc/diagnostic.c
258
gcc/diagnostic.c
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "backtrace.h"
|
||||
#include "diagnostic.h"
|
||||
#include "diagnostic-color.h"
|
||||
#include "selftest.h"
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
@ -667,6 +668,112 @@ diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
|
||||
context->n_classification_history ++;
|
||||
}
|
||||
|
||||
/* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
|
||||
escaping rules for -fdiagnostics-parseable-fixits. */
|
||||
|
||||
static void
|
||||
print_escaped_string (pretty_printer *pp, const char *text)
|
||||
{
|
||||
gcc_assert (pp);
|
||||
gcc_assert (text);
|
||||
|
||||
pp_character (pp, '"');
|
||||
for (const char *ch = text; *ch; ch++)
|
||||
{
|
||||
switch (*ch)
|
||||
{
|
||||
case '\\':
|
||||
/* Escape backslash as two backslashes. */
|
||||
pp_string (pp, "\\\\");
|
||||
break;
|
||||
case '\t':
|
||||
/* Escape tab as "\t". */
|
||||
pp_string (pp, "\\t");
|
||||
break;
|
||||
case '\n':
|
||||
/* Escape newline as "\n". */
|
||||
pp_string (pp, "\\n");
|
||||
break;
|
||||
case '"':
|
||||
/* Escape doublequotes as \". */
|
||||
pp_string (pp, "\\\"");
|
||||
break;
|
||||
default:
|
||||
if (ISPRINT (*ch))
|
||||
pp_character (pp, *ch);
|
||||
else
|
||||
/* Use octal for non-printable chars. */
|
||||
{
|
||||
unsigned char c = (*ch & 0xff);
|
||||
pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pp_character (pp, '"');
|
||||
}
|
||||
|
||||
/* Implementation of -fdiagnostics-parseable-fixits. Print a
|
||||
machine-parseable version of all fixits in RICHLOC to PP. */
|
||||
|
||||
static void
|
||||
print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
|
||||
{
|
||||
gcc_assert (pp);
|
||||
gcc_assert (richloc);
|
||||
|
||||
for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
|
||||
{
|
||||
const fixit_hint *hint = richloc->get_fixit_hint (i);
|
||||
source_location start_loc = hint->get_start_loc ();
|
||||
expanded_location start_exploc = expand_location (start_loc);
|
||||
pp_string (pp, "fix-it:");
|
||||
print_escaped_string (pp, start_exploc.file);
|
||||
source_location end_loc;
|
||||
|
||||
/* For compatibility with clang, print as a half-open range. */
|
||||
if (hint->maybe_get_end_loc (&end_loc))
|
||||
{
|
||||
expanded_location end_exploc = expand_location (end_loc);
|
||||
pp_printf (pp, ":{%i:%i-%i:%i}:",
|
||||
start_exploc.line, start_exploc.column,
|
||||
end_exploc.line, end_exploc.column + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pp_printf (pp, ":{%i:%i-%i:%i}:",
|
||||
start_exploc.line, start_exploc.column,
|
||||
start_exploc.line, start_exploc.column);
|
||||
}
|
||||
switch (hint->get_kind ())
|
||||
{
|
||||
case fixit_hint::INSERT:
|
||||
{
|
||||
const fixit_insert *insert
|
||||
= static_cast <const fixit_insert *> (hint);
|
||||
print_escaped_string (pp, insert->get_string ());
|
||||
}
|
||||
break;
|
||||
|
||||
case fixit_hint::REMOVE:
|
||||
print_escaped_string (pp, "");
|
||||
break;
|
||||
|
||||
case fixit_hint::REPLACE:
|
||||
{
|
||||
const fixit_replace *replace
|
||||
= static_cast <const fixit_replace *> (hint);
|
||||
print_escaped_string (pp, replace->get_string ());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
pp_newline (pp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Report a diagnostic message (an error or a warning) as specified by
|
||||
DC. This function is *the* subroutine in terms of which front-ends
|
||||
should implement their specific diagnostic handling modules. The
|
||||
@ -828,6 +935,11 @@ diagnostic_report_diagnostic (diagnostic_context *context,
|
||||
(*diagnostic_starter (context)) (context, diagnostic);
|
||||
pp_output_formatted_text (context->printer);
|
||||
(*diagnostic_finalizer (context)) (context, diagnostic);
|
||||
if (context->parseable_fixits_p)
|
||||
{
|
||||
print_parseable_fixits (context->printer, diagnostic->richloc);
|
||||
pp_flush (context->printer);
|
||||
}
|
||||
diagnostic_action_after_output (context, diagnostic->kind);
|
||||
diagnostic->message.format_spec = saved_format_spec;
|
||||
diagnostic->x_data = NULL;
|
||||
@ -1290,3 +1402,149 @@ real_abort (void)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
#if CHECKING_P
|
||||
|
||||
namespace selftest {
|
||||
|
||||
/* Helper function for test_print_escaped_string. */
|
||||
|
||||
static void
|
||||
assert_print_escaped_string (const location &loc, const char *expected_output,
|
||||
const char *input)
|
||||
{
|
||||
pretty_printer pp;
|
||||
print_escaped_string (&pp, input);
|
||||
ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
|
||||
}
|
||||
|
||||
#define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
|
||||
assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
|
||||
|
||||
/* Tests of print_escaped_string. */
|
||||
|
||||
static void
|
||||
test_print_escaped_string ()
|
||||
{
|
||||
/* Empty string. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
|
||||
|
||||
/* Non-empty string. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
|
||||
|
||||
/* Various things that need to be escaped: */
|
||||
/* Backslash. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
|
||||
"before\\after");
|
||||
/* Tab. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
|
||||
"before\tafter");
|
||||
/* Newline. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
|
||||
"before\nafter");
|
||||
/* Double quote. */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
|
||||
"before\"after");
|
||||
|
||||
/* Non-printable characters: BEL: '\a': 0x07 */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
|
||||
"before\aafter");
|
||||
/* Non-printable characters: vertical tab: '\v': 0x0b */
|
||||
ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
|
||||
"before\vafter");
|
||||
}
|
||||
|
||||
/* Tests of print_parseable_fixits. */
|
||||
|
||||
/* Verify that print_parseable_fixits emits the empty string if there
|
||||
are no fixits. */
|
||||
|
||||
static void
|
||||
test_print_parseable_fixits_none ()
|
||||
{
|
||||
pretty_printer pp;
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
print_parseable_fixits (&pp, &richloc);
|
||||
ASSERT_STREQ ("", pp_formatted_text (&pp));
|
||||
}
|
||||
|
||||
/* Verify that print_parseable_fixits does the right thing if there
|
||||
is an insertion fixit hint. */
|
||||
|
||||
static void
|
||||
test_print_parseable_fixits_insert ()
|
||||
{
|
||||
pretty_printer pp;
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
|
||||
linemap_line_start (line_table, 5, 100);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
location_t where = linemap_position_for_column (line_table, 10);
|
||||
richloc.add_fixit_insert (where, "added content");
|
||||
|
||||
print_parseable_fixits (&pp, &richloc);
|
||||
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
|
||||
pp_formatted_text (&pp));
|
||||
}
|
||||
|
||||
/* Verify that print_parseable_fixits does the right thing if there
|
||||
is an removal fixit hint. */
|
||||
|
||||
static void
|
||||
test_print_parseable_fixits_remove ()
|
||||
{
|
||||
pretty_printer pp;
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
|
||||
linemap_line_start (line_table, 5, 100);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
source_range where;
|
||||
where.m_start = linemap_position_for_column (line_table, 10);
|
||||
where.m_finish = linemap_position_for_column (line_table, 20);
|
||||
richloc.add_fixit_remove (where);
|
||||
|
||||
print_parseable_fixits (&pp, &richloc);
|
||||
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
|
||||
pp_formatted_text (&pp));
|
||||
}
|
||||
|
||||
/* Verify that print_parseable_fixits does the right thing if there
|
||||
is an replacement fixit hint. */
|
||||
|
||||
static void
|
||||
test_print_parseable_fixits_replace ()
|
||||
{
|
||||
pretty_printer pp;
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
|
||||
linemap_line_start (line_table, 5, 100);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
source_range where;
|
||||
where.m_start = linemap_position_for_column (line_table, 10);
|
||||
where.m_finish = linemap_position_for_column (line_table, 20);
|
||||
richloc.add_fixit_replace (where, "replacement");
|
||||
|
||||
print_parseable_fixits (&pp, &richloc);
|
||||
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
|
||||
pp_formatted_text (&pp));
|
||||
}
|
||||
|
||||
/* Run all of the selftests within this file. */
|
||||
|
||||
void
|
||||
diagnostic_c_tests ()
|
||||
{
|
||||
test_print_escaped_string ();
|
||||
test_print_parseable_fixits_none ();
|
||||
test_print_parseable_fixits_insert ();
|
||||
test_print_parseable_fixits_remove ();
|
||||
test_print_parseable_fixits_replace ();
|
||||
}
|
||||
|
||||
} // namespace selftest
|
||||
|
||||
#endif /* #if CHECKING_P */
|
||||
|
@ -205,6 +205,10 @@ struct diagnostic_context
|
||||
/* Usable by plugins; if true, print a debugging ruler above the
|
||||
source output. */
|
||||
bool show_ruler_p;
|
||||
|
||||
/* If true, print fixits in machine-parseable form after the
|
||||
rest of the diagnostic. */
|
||||
bool parseable_fixits_p;
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
@ -246,7 +246,8 @@ Objective-C and Objective-C++ Dialects}.
|
||||
@gccoptlist{-fmessage-length=@var{n} @gol
|
||||
-fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol
|
||||
-fdiagnostics-color=@r{[}auto@r{|}never@r{|}always@r{]} @gol
|
||||
-fno-diagnostics-show-option -fno-diagnostics-show-caret}
|
||||
-fno-diagnostics-show-option -fno-diagnostics-show-caret @gol
|
||||
-fdiagnostics-parseable-fixits}
|
||||
|
||||
@item Warning Options
|
||||
@xref{Warning Options,,Options to Request or Suppress Warnings}.
|
||||
@ -3389,6 +3390,37 @@ the @option{-fmessage-length=n} option is given. When the output is done
|
||||
to the terminal, the width is limited to the width given by the
|
||||
@env{COLUMNS} environment variable or, if not set, to the terminal width.
|
||||
|
||||
@item -fdiagnostics-parseable-fixits
|
||||
@opindex fdiagnostics-parseable-fixits
|
||||
Emit fix-it hints in a machine-parseable format, suitable for consumption
|
||||
by IDEs. For each fix-it, a line will be printed after the relevant
|
||||
diagnostic, starting with the string ``fix-it:''. For example:
|
||||
|
||||
@smallexample
|
||||
fix-it:"test.c":@{45:3-45:21@}:"gtk_widget_show_all"
|
||||
@end smallexample
|
||||
|
||||
The location is expressed as a half-open range, expressed as a count of
|
||||
bytes, starting at byte 1 for the initial column. In the above example,
|
||||
bytes 3 through 20 of line 45 of ``test.c'' are to be replaced with the
|
||||
given string:
|
||||
|
||||
@smallexample
|
||||
00000000011111111112222222222
|
||||
12345678901234567890123456789
|
||||
gtk_widget_showall (dlg);
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
gtk_widget_show_all
|
||||
@end smallexample
|
||||
|
||||
The filename and replacement string escape backslash as ``\\", tab as ``\t'',
|
||||
newline as ``\n'', double quotes as ``\"'', non-printable characters as octal
|
||||
(e.g. vertical tab as ``\013'').
|
||||
|
||||
An empty replacement string indicates that the given range is to be removed.
|
||||
An empty range (e.g. ``45:3-45:3'') indicates that the string is to
|
||||
be inserted at the given position.
|
||||
|
||||
@end table
|
||||
|
||||
@node Warning Options
|
||||
|
@ -1871,6 +1871,10 @@ common_handle_option (struct gcc_options *opts,
|
||||
diagnostic_color_init (dc, value);
|
||||
break;
|
||||
|
||||
case OPT_fdiagnostics_parseable_fixits:
|
||||
dc->parseable_fixits_p = value;
|
||||
break;
|
||||
|
||||
case OPT_fdiagnostics_show_option:
|
||||
dc->show_option_requested = value;
|
||||
break;
|
||||
|
@ -59,6 +59,7 @@ selftest::run_tests ()
|
||||
/* Higher-level tests, or for components that other selftests don't
|
||||
rely on. */
|
||||
diagnostic_show_locus_c_tests ();
|
||||
diagnostic_c_tests ();
|
||||
fold_const_c_tests ();
|
||||
spellcheck_c_tests ();
|
||||
spellcheck_tree_c_tests ();
|
||||
|
@ -72,6 +72,7 @@ extern void assert_streq (const location &loc,
|
||||
/* Declarations for specific families of tests (by source file), in
|
||||
alphabetical order. */
|
||||
extern void bitmap_c_tests ();
|
||||
extern void diagnostic_c_tests ();
|
||||
extern void diagnostic_show_locus_c_tests ();
|
||||
extern void et_forest_c_tests ();
|
||||
extern void fold_const_c_tests ();
|
||||
|
@ -1,3 +1,17 @@
|
||||
2016-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c: New
|
||||
file.
|
||||
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add
|
||||
diagnostic-test-show-locus-parseable-fixits.c to sources for
|
||||
diagnostic_plugin_test_show_locus.c.
|
||||
* lib/gcc-defs.exp (freeform_regexps): New global.
|
||||
(dg-regexp): New function.
|
||||
(handle-dg-regexps): New function.
|
||||
* lib/gcc-dg.exp (cleanup-after-saved-dg-test): Reset
|
||||
freeform_regexps to the empty list.
|
||||
* lib/prune.exp (prune_gcc_output): Call handle-dg-regexps.
|
||||
|
||||
2016-06-22 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
PR middle-end/71488
|
||||
|
@ -0,0 +1,41 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdiagnostics-parseable-fixits" } */
|
||||
|
||||
/* This is a collection of unittests for diagnostic_show_locus;
|
||||
see the overview in diagnostic_plugin_test_show_locus.c.
|
||||
|
||||
In particular, note the discussion of why we need a very long line here:
|
||||
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
and that we can't use macros in this file. */
|
||||
|
||||
/* Unit test for rendering of insertion fixit hints
|
||||
(example taken from PR 62316). */
|
||||
|
||||
void test_fixit_insert (void)
|
||||
{
|
||||
#if 0
|
||||
int a[2][2] = { 0, 1 , 2, 3 }; /* { dg-warning "insertion hints" } */
|
||||
/* { dg-regexp "fix-it:.*\\{17:20-17:20\\}:.*" } */
|
||||
/* { dg-regexp "fix-it:.*\\{17:24-17:24\\}:.*" } */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unit test for rendering of "remove" fixit hints. */
|
||||
|
||||
void test_fixit_remove (void)
|
||||
{
|
||||
#if 0
|
||||
int a;; /* { dg-warning "example of a removal hint" } */
|
||||
/* { dg-regexp "fix-it:.*\\{28:9-28:10\\}:.*" } */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unit test for rendering of "replace" fixit hints. */
|
||||
|
||||
void test_fixit_replace (void)
|
||||
{
|
||||
#if 0
|
||||
gtk_widget_showall (dlg); /* { dg-warning "example of a replacement hint" } */
|
||||
/* { dg-regexp "fix-it:.*\\{38:3-38:21\\}:.*" } */
|
||||
#endif
|
||||
}
|
@ -65,7 +65,8 @@ set plugin_test_list [list \
|
||||
{ wide-int_plugin.c wide-int-test-1.c } \
|
||||
{ diagnostic_plugin_test_show_locus.c \
|
||||
diagnostic-test-show-locus-bw.c \
|
||||
diagnostic-test-show-locus-color.c } \
|
||||
diagnostic-test-show-locus-color.c \
|
||||
diagnostic-test-show-locus-parseable-fixits.c } \
|
||||
{ diagnostic_plugin_test_tree_expression_range.c \
|
||||
diagnostic-test-expressions-1.c } \
|
||||
{ diagnostic_plugin_show_trees.c \
|
||||
|
@ -352,3 +352,54 @@ proc gcc-set-multilib-library-path { compiler } {
|
||||
|
||||
return $libpath
|
||||
}
|
||||
|
||||
# A list of all uses of dg-regexp, each entry of the form:
|
||||
# line-number regexp
|
||||
# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test.
|
||||
set freeform_regexps []
|
||||
|
||||
# Directive for looking for a regexp, without any line numbers or other
|
||||
# prefixes.
|
||||
|
||||
proc dg-regexp { args } {
|
||||
verbose "dg-regexp: args: $args" 2
|
||||
|
||||
global freeform_regexps
|
||||
lappend freeform_regexps $args
|
||||
}
|
||||
|
||||
# Hook to be called by prune.exp's prune_gcc_output to
|
||||
# look for the expected dg-regexp expressions, pruning them,
|
||||
# reporting PASS for those that are found, and FAIL for
|
||||
# those that weren't found.
|
||||
#
|
||||
# It returns a pruned version of its output.
|
||||
|
||||
proc handle-dg-regexps { text } {
|
||||
global freeform_regexps
|
||||
global testname_with_flags
|
||||
|
||||
foreach entry $freeform_regexps {
|
||||
verbose " entry: $entry" 3
|
||||
|
||||
set linenum [lindex $entry 0]
|
||||
set rexp [lindex $entry 1]
|
||||
|
||||
# Escape newlines in $rexp so that we can print them in
|
||||
# pass/fail results.
|
||||
set escaped_regex [string map {"\n" "\\n"} $rexp]
|
||||
verbose "escaped_regex: ${escaped_regex}" 4
|
||||
|
||||
set title "$testname_with_flags dg-regexp $linenum"
|
||||
|
||||
# Use "regsub" to attempt to prune the pattern from $text
|
||||
if {[regsub -line $rexp $text "" text]} {
|
||||
# Success; the multiline pattern was pruned.
|
||||
pass "$title was found: \"$escaped_regex\""
|
||||
} else {
|
||||
fail "$title not found: \"$escaped_regex\""
|
||||
}
|
||||
}
|
||||
|
||||
return $text
|
||||
}
|
||||
|
@ -899,6 +899,7 @@ if { [info procs saved-dg-test] == [list] } {
|
||||
global saved_compiler_env_var
|
||||
global keep_saved_temps_suffixes
|
||||
global multiline_expected_outputs
|
||||
global freeform_regexps
|
||||
|
||||
set additional_files ""
|
||||
set additional_sources ""
|
||||
@ -924,6 +925,7 @@ if { [info procs saved-dg-test] == [list] } {
|
||||
unset testname_with_flags
|
||||
}
|
||||
set multiline_expected_outputs []
|
||||
set freeform_regexps []
|
||||
}
|
||||
|
||||
proc dg-test { args } {
|
||||
|
@ -73,6 +73,9 @@ proc prune_gcc_output { text } {
|
||||
# Call into multiline.exp to handle any multiline output directives.
|
||||
set text [handle-multiline-outputs $text]
|
||||
|
||||
# Handle any freeform regexps.
|
||||
set text [handle-dg-regexps $text]
|
||||
|
||||
#send_user "After:$text\n"
|
||||
|
||||
return $text
|
||||
|
@ -1,3 +1,21 @@
|
||||
2016-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* include/line-map.h (fixit_hint::get_start_loc): New pure virtual
|
||||
function.
|
||||
(fixit_hint::maybe_get_end_loc): Likewise.
|
||||
(fixit_insert::get_start_loc): New function, implementing
|
||||
fixit_hint::get_start_loc.
|
||||
(fixit_insert::maybe_get_end_loc): New function, implementing
|
||||
fixit_hint::maybe_get_end_loc.
|
||||
(fixit_remove::get_start_loc): New function, implementing
|
||||
fixit_hint::get_start_loc.
|
||||
(fixit_remove::maybe_get_end_loc): New function, implementing
|
||||
fixit_hint::maybe_get_end_loc.
|
||||
(fixit_replace::get_start_loc): New function, implementing
|
||||
fixit_hint::get_start_loc.
|
||||
(fixit_replace::maybe_get_end_loc): New function, implementing
|
||||
fixit_hint::maybe_get_end_loc.
|
||||
|
||||
2016-06-21 John David Anglin <danglin@gcc.gnu.org>
|
||||
|
||||
* line-map.c (location_adhoc_data_update): Use int64_t instead of
|
||||
|
@ -1418,6 +1418,8 @@ public:
|
||||
|
||||
virtual enum kind get_kind () const = 0;
|
||||
virtual bool affects_line_p (const char *file, int line) = 0;
|
||||
virtual source_location get_start_loc () const = 0;
|
||||
virtual bool maybe_get_end_loc (source_location *out) const = 0;
|
||||
};
|
||||
|
||||
class fixit_insert : public fixit_hint
|
||||
@ -1428,6 +1430,8 @@ class fixit_insert : public fixit_hint
|
||||
~fixit_insert ();
|
||||
enum kind get_kind () const { return INSERT; }
|
||||
bool affects_line_p (const char *file, int line);
|
||||
source_location get_start_loc () const { return m_where; }
|
||||
bool maybe_get_end_loc (source_location *) const { return false; }
|
||||
|
||||
source_location get_location () const { return m_where; }
|
||||
const char *get_string () const { return m_bytes; }
|
||||
@ -1447,6 +1451,12 @@ class fixit_remove : public fixit_hint
|
||||
|
||||
enum kind get_kind () const { return REMOVE; }
|
||||
bool affects_line_p (const char *file, int line);
|
||||
source_location get_start_loc () const { return m_src_range.m_start; }
|
||||
bool maybe_get_end_loc (source_location *out) const
|
||||
{
|
||||
*out = m_src_range.m_finish;
|
||||
return true;
|
||||
}
|
||||
|
||||
source_range get_range () const { return m_src_range; }
|
||||
|
||||
@ -1463,6 +1473,12 @@ class fixit_replace : public fixit_hint
|
||||
|
||||
enum kind get_kind () const { return REPLACE; }
|
||||
bool affects_line_p (const char *file, int line);
|
||||
source_location get_start_loc () const { return m_src_range.m_start; }
|
||||
bool maybe_get_end_loc (source_location *out) const
|
||||
{
|
||||
*out = m_src_range.m_finish;
|
||||
return true;
|
||||
}
|
||||
|
||||
source_range get_range () const { return m_src_range; }
|
||||
const char *get_string () const { return m_bytes; }
|
||||
|
Loading…
Reference in New Issue
Block a user