Allow calling diagnostic_show_locus without a diagnostic_info
Much of diagnostic-show-locus.c currently expects a diagnostic_info *, but it only uses the rich_location and the diagnostic_t. Change the signature of diagnostic_show_locus from: void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *); to: void diagnostic_show_locus (diagnostic_context *, rich_location *richloc, diagnostic_t diagnostic_kind); so that it can be used for things other than diagnostics. Use this flexibility to add selftests for diagnostic_show_locus. gcc/c-family/ChangeLog: * c-opts.c (c_diagnostic_finalizer): Update for change to diagnostic_show_locus. gcc/ChangeLog: * diagnostic-show-locus.c (colorizer::colorizer): Replace diagnostic param with diagnostic_kind. (class colorizer): Similarly replace field m_diagnostic with m_diagnostic_kind. (colorizer::colorizer): Replace diagnostic param with diagnostic_kind. (colorizer::begin_state): Update for above field change. (layout::layout): Replace diagnostic param with rich_location * and diagnostic_kind. (diagnostic_show_locus): Replace diagnostic param with richloc and diagnostic_kind. (class selftest::test_diagnostic_context): New class. (selftest::test_diagnostic_show_locus_unknown_location): New function. (selftest::test_one_liner_simple_caret): New function. (selftest::test_one_liner_caret_and_range): New function. (selftest::test_one_liner_multiple_carets_and_ranges): New function. (selftest::test_one_liner_fixit_remove): New function. (selftest::test_one_liner_fixit_replace): New function. (selftest::test_diagnostic_show_locus_one_liner): New function. (selftest::diagnostic_show_locus_c_tests): Call the new test functions. * diagnostic.c (diagnostic_initialize): Initialize colorize_source_p, show_ruler_p and parseable_fixits_p. (default_diagnostic_finalizer): Update for change to diagnostic_show_locus. (diagnostic_append_note): Likewise. * diagnostic.h (diagnostic_show_locus): Replace const diagnostic_info * param with location * and diagnostic_t. gcc/fortran/ChangeLog: * error.c (gfc_diagnostic_starter): Update for change to diagnostic_show_locus. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (custom_diagnostic_finalizer): Update for change to diagnostic_show_locus. From-SVN: r239586
This commit is contained in:
parent
cb18fd07f2
commit
cc015f3abe
|
@ -1,3 +1,36 @@
|
|||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* diagnostic-show-locus.c (colorizer::colorizer): Replace diagnostic
|
||||
param with diagnostic_kind.
|
||||
(class colorizer): Similarly replace field m_diagnostic with
|
||||
m_diagnostic_kind.
|
||||
(colorizer::colorizer): Replace diagnostic
|
||||
param with diagnostic_kind.
|
||||
(colorizer::begin_state): Update for above field change.
|
||||
(layout::layout): Replace diagnostic param with rich_location *
|
||||
and diagnostic_kind.
|
||||
(diagnostic_show_locus): Replace diagnostic param with richloc
|
||||
and diagnostic_kind.
|
||||
(class selftest::test_diagnostic_context): New class.
|
||||
(selftest::test_diagnostic_show_locus_unknown_location): New
|
||||
function.
|
||||
(selftest::test_one_liner_simple_caret): New function.
|
||||
(selftest::test_one_liner_caret_and_range): New function.
|
||||
(selftest::test_one_liner_multiple_carets_and_ranges): New
|
||||
function.
|
||||
(selftest::test_one_liner_fixit_remove): New function.
|
||||
(selftest::test_one_liner_fixit_replace): New function.
|
||||
(selftest::test_diagnostic_show_locus_one_liner): New function.
|
||||
(selftest::diagnostic_show_locus_c_tests): Call the new test
|
||||
functions.
|
||||
* diagnostic.c (diagnostic_initialize): Initialize
|
||||
colorize_source_p, show_ruler_p and parseable_fixits_p.
|
||||
(default_diagnostic_finalizer): Update for change to
|
||||
diagnostic_show_locus.
|
||||
(diagnostic_append_note): Likewise.
|
||||
* diagnostic.h (diagnostic_show_locus): Replace
|
||||
const diagnostic_info * param with location * and diagnostic_t.
|
||||
|
||||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* input.c (saved_line_table): New global.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* c-opts.c (c_diagnostic_finalizer): Update for change to
|
||||
diagnostic_show_locus.
|
||||
|
||||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* c-common.c: Include "spellcheck.h".
|
||||
|
|
|
@ -164,7 +164,7 @@ static void
|
|||
c_diagnostic_finalizer (diagnostic_context *context,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
diagnostic_show_locus (context, diagnostic);
|
||||
diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
|
||||
/* By default print macro expansion contexts in the diagnostic
|
||||
finalizer -- for tokens resulting from macro expansion. */
|
||||
virt_loc_aware_diagnostic_finalizer (context, diagnostic);
|
||||
|
|
|
@ -74,7 +74,7 @@ class colorizer
|
|||
{
|
||||
public:
|
||||
colorizer (diagnostic_context *context,
|
||||
const diagnostic_info *diagnostic);
|
||||
diagnostic_t diagnostic_kind);
|
||||
~colorizer ();
|
||||
|
||||
void set_range (int range_idx) { set_state (range_idx); }
|
||||
|
@ -90,7 +90,7 @@ class colorizer
|
|||
static const int STATE_NORMAL_TEXT = -1;
|
||||
|
||||
diagnostic_context *m_context;
|
||||
const diagnostic_info *m_diagnostic;
|
||||
diagnostic_t m_diagnostic_kind;
|
||||
int m_current_state;
|
||||
const char *m_caret_cs;
|
||||
const char *m_caret_ce;
|
||||
|
@ -187,7 +187,8 @@ class layout
|
|||
{
|
||||
public:
|
||||
layout (diagnostic_context *context,
|
||||
const diagnostic_info *diagnostic);
|
||||
rich_location *richloc,
|
||||
diagnostic_t diagnostic_kind);
|
||||
|
||||
int get_num_line_spans () const { return m_line_spans.length (); }
|
||||
const line_span *get_line_span (int idx) const { return &m_line_spans[idx]; }
|
||||
|
@ -239,9 +240,9 @@ class layout
|
|||
different kinds of things we might need to print. */
|
||||
|
||||
colorizer::colorizer (diagnostic_context *context,
|
||||
const diagnostic_info *diagnostic) :
|
||||
diagnostic_t diagnostic_kind) :
|
||||
m_context (context),
|
||||
m_diagnostic (diagnostic),
|
||||
m_diagnostic_kind (diagnostic_kind),
|
||||
m_current_state (STATE_NORMAL_TEXT)
|
||||
{
|
||||
m_caret_ce = colorize_stop (pp_show_color (context->printer));
|
||||
|
@ -288,7 +289,7 @@ colorizer::begin_state (int state)
|
|||
pp_string
|
||||
(m_context->printer,
|
||||
colorize_start (pp_show_color (m_context->printer),
|
||||
diagnostic_get_color_for_kind (m_diagnostic->kind)));
|
||||
diagnostic_get_color_for_kind (m_diagnostic_kind)));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -699,18 +700,18 @@ compatible_locations_p (location_t loc_a, location_t loc_b)
|
|||
will fit within the max_width provided by the diagnostic_context. */
|
||||
|
||||
layout::layout (diagnostic_context * context,
|
||||
const diagnostic_info *diagnostic)
|
||||
rich_location *richloc,
|
||||
diagnostic_t diagnostic_kind)
|
||||
: m_context (context),
|
||||
m_pp (context->printer),
|
||||
m_diagnostic_kind (diagnostic->kind),
|
||||
m_exploc (diagnostic->richloc->get_expanded_location (0)),
|
||||
m_colorizer (context, diagnostic),
|
||||
m_diagnostic_kind (diagnostic_kind),
|
||||
m_exploc (richloc->get_expanded_location (0)),
|
||||
m_colorizer (context, diagnostic_kind),
|
||||
m_colorize_source_p (context->colorize_source_p),
|
||||
m_layout_ranges (rich_location::MAX_RANGES),
|
||||
m_line_spans (1 + rich_location::MAX_RANGES),
|
||||
m_x_offset (0)
|
||||
{
|
||||
rich_location *richloc = diagnostic->richloc;
|
||||
source_location primary_loc = richloc->get_range (0)->m_loc;
|
||||
|
||||
for (unsigned int idx = 0; idx < richloc->get_num_locations (); idx++)
|
||||
|
@ -1276,30 +1277,32 @@ layout::show_ruler (int max_column) const
|
|||
|
||||
void
|
||||
diagnostic_show_locus (diagnostic_context * context,
|
||||
const diagnostic_info *diagnostic)
|
||||
rich_location *richloc,
|
||||
diagnostic_t diagnostic_kind)
|
||||
{
|
||||
pp_newline (context->printer);
|
||||
|
||||
location_t loc = richloc->get_loc ();
|
||||
/* Do nothing if source-printing has been disabled. */
|
||||
if (!context->show_caret)
|
||||
return;
|
||||
|
||||
/* Don't attempt to print source for UNKNOWN_LOCATION and for builtins. */
|
||||
if (diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION)
|
||||
if (loc <= BUILTINS_LOCATION)
|
||||
return;
|
||||
|
||||
/* Don't print the same source location twice in a row, unless we have
|
||||
fix-it hints. */
|
||||
if (diagnostic_location (diagnostic, 0) == context->last_location
|
||||
&& diagnostic->richloc->get_num_fixit_hints () == 0)
|
||||
if (loc == context->last_location
|
||||
&& richloc->get_num_fixit_hints () == 0)
|
||||
return;
|
||||
|
||||
context->last_location = diagnostic_location (diagnostic, 0);
|
||||
context->last_location = loc;
|
||||
|
||||
const char *saved_prefix = pp_get_prefix (context->printer);
|
||||
pp_set_prefix (context->printer, NULL);
|
||||
|
||||
layout layout (context, diagnostic);
|
||||
layout layout (context, richloc, diagnostic_kind);
|
||||
for (int line_span_idx = 0; line_span_idx < layout.get_num_line_spans ();
|
||||
line_span_idx++)
|
||||
{
|
||||
|
@ -1319,7 +1322,7 @@ diagnostic_show_locus (diagnostic_context * context,
|
|||
if (layout.print_source_line (row, &lbounds))
|
||||
{
|
||||
layout.print_annotation_line (row, lbounds);
|
||||
layout.print_any_fixits (row, diagnostic->richloc);
|
||||
layout.print_any_fixits (row, richloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1331,6 +1334,206 @@ diagnostic_show_locus (diagnostic_context * context,
|
|||
|
||||
namespace selftest {
|
||||
|
||||
/* Selftests for diagnostic_show_locus. */
|
||||
|
||||
/* Convenience subclass of diagnostic_context for testing
|
||||
diagnostic_show_locus. */
|
||||
|
||||
class test_diagnostic_context : public diagnostic_context
|
||||
{
|
||||
public:
|
||||
test_diagnostic_context ()
|
||||
{
|
||||
diagnostic_initialize (this, 0);
|
||||
show_caret = true;
|
||||
}
|
||||
~test_diagnostic_context ()
|
||||
{
|
||||
diagnostic_finish (this);
|
||||
}
|
||||
};
|
||||
|
||||
/* Verify that diagnostic_show_locus works sanely on UNKNOWN_LOCATION. */
|
||||
|
||||
static void
|
||||
test_diagnostic_show_locus_unknown_location ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n", pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Verify that diagnostic_show_locus works sanely for various
|
||||
single-line cases.
|
||||
|
||||
All of these work on the following 1-line source file:
|
||||
.0000000001111111
|
||||
.1234567890123456
|
||||
"foo = bar.field;\n"
|
||||
which is set up by test_diagnostic_show_locus_one_liner and calls
|
||||
them. */
|
||||
|
||||
/* Just a caret. */
|
||||
|
||||
static void
|
||||
test_one_liner_simple_caret ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t caret = linemap_position_for_column (line_table, 10);
|
||||
rich_location richloc (line_table, caret);
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ^\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Caret and range. */
|
||||
|
||||
static void
|
||||
test_one_liner_caret_and_range ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t caret = linemap_position_for_column (line_table, 10);
|
||||
location_t start = linemap_position_for_column (line_table, 7);
|
||||
location_t finish = linemap_position_for_column (line_table, 15);
|
||||
location_t loc = make_location (caret, start, finish);
|
||||
rich_location richloc (line_table, loc);
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ~~~^~~~~~\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Multiple ranges and carets. */
|
||||
|
||||
static void
|
||||
test_one_liner_multiple_carets_and_ranges ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t foo
|
||||
= make_location (linemap_position_for_column (line_table, 2),
|
||||
linemap_position_for_column (line_table, 1),
|
||||
linemap_position_for_column (line_table, 3));
|
||||
dc.caret_chars[0] = 'A';
|
||||
|
||||
location_t bar
|
||||
= make_location (linemap_position_for_column (line_table, 8),
|
||||
linemap_position_for_column (line_table, 7),
|
||||
linemap_position_for_column (line_table, 9));
|
||||
dc.caret_chars[1] = 'B';
|
||||
|
||||
location_t field
|
||||
= make_location (linemap_position_for_column (line_table, 13),
|
||||
linemap_position_for_column (line_table, 11),
|
||||
linemap_position_for_column (line_table, 15));
|
||||
dc.caret_chars[2] = 'C';
|
||||
|
||||
rich_location richloc (line_table, foo);
|
||||
richloc.add_range (bar, true);
|
||||
richloc.add_range (field, true);
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ~A~ ~B~ ~~C~~\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Insertion fix-it hint: adding an "&" to the front of "bar.field". */
|
||||
|
||||
static void
|
||||
test_one_liner_fixit_insert ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t caret = linemap_position_for_column (line_table, 7);
|
||||
rich_location richloc (line_table, caret);
|
||||
richloc.add_fixit_insert (caret, "&");
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ^\n"
|
||||
" &\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Removal fix-it hint: removal of the ".field". */
|
||||
|
||||
static void
|
||||
test_one_liner_fixit_remove ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t start = linemap_position_for_column (line_table, 10);
|
||||
location_t finish = linemap_position_for_column (line_table, 15);
|
||||
location_t dot = make_location (start, start, finish);
|
||||
rich_location richloc (line_table, dot);
|
||||
source_range range;
|
||||
range.m_start = start;
|
||||
range.m_finish = finish;
|
||||
richloc.add_fixit_remove (range);
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ^~~~~~\n"
|
||||
" ------\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Replace fix-it hint: replacing "field" with "m_field". */
|
||||
|
||||
static void
|
||||
test_one_liner_fixit_replace ()
|
||||
{
|
||||
test_diagnostic_context dc;
|
||||
location_t start = linemap_position_for_column (line_table, 11);
|
||||
location_t finish = linemap_position_for_column (line_table, 15);
|
||||
location_t field = make_location (start, start, finish);
|
||||
rich_location richloc (line_table, field);
|
||||
source_range range;
|
||||
range.m_start = start;
|
||||
range.m_finish = finish;
|
||||
richloc.add_fixit_replace (range, "m_field");
|
||||
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
|
||||
ASSERT_STREQ ("\n"
|
||||
" foo = bar.field;\n"
|
||||
" ^~~~~\n"
|
||||
" m_field\n",
|
||||
pp_formatted_text (dc.printer));
|
||||
}
|
||||
|
||||
/* Run the various one-liner tests. */
|
||||
|
||||
static void
|
||||
test_diagnostic_show_locus_one_liner (const line_table_case &case_)
|
||||
{
|
||||
/* Create a tempfile and write some text to it.
|
||||
....................0000000001111111.
|
||||
....................1234567890123456. */
|
||||
const char *content = "foo = bar.field;\n";
|
||||
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
|
||||
line_table_test ltt (case_);
|
||||
|
||||
linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
|
||||
|
||||
location_t line_end = linemap_position_for_column (line_table, 16);
|
||||
|
||||
/* Don't attempt to run the tests if column data might be unavailable. */
|
||||
if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
return;
|
||||
|
||||
ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end));
|
||||
ASSERT_EQ (1, LOCATION_LINE (line_end));
|
||||
ASSERT_EQ (16, LOCATION_COLUMN (line_end));
|
||||
|
||||
test_one_liner_simple_caret ();
|
||||
test_one_liner_caret_and_range ();
|
||||
test_one_liner_multiple_carets_and_ranges ();
|
||||
test_one_liner_fixit_insert ();
|
||||
test_one_liner_fixit_remove ();
|
||||
test_one_liner_fixit_replace ();
|
||||
}
|
||||
|
||||
/* Run all of the selftests within this file. */
|
||||
|
||||
void
|
||||
|
@ -1341,6 +1544,10 @@ diagnostic_show_locus_c_tests ()
|
|||
test_range_contains_point_for_multiple_lines ();
|
||||
|
||||
test_get_line_width_without_trailing_whitespace ();
|
||||
|
||||
test_diagnostic_show_locus_unknown_location ();
|
||||
|
||||
for_each_line_table_case (test_diagnostic_show_locus_one_liner);
|
||||
}
|
||||
|
||||
} // namespace selftest
|
||||
|
|
|
@ -171,6 +171,9 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
|
|||
context->x_data = NULL;
|
||||
context->lock = 0;
|
||||
context->inhibit_notes_p = false;
|
||||
context->colorize_source_p = false;
|
||||
context->show_ruler_p = false;
|
||||
context->parseable_fixits_p = false;
|
||||
}
|
||||
|
||||
/* Maybe initialize the color support. We require clients to do this
|
||||
|
@ -575,7 +578,7 @@ void
|
|||
default_diagnostic_finalizer (diagnostic_context *context,
|
||||
diagnostic_info *diagnostic)
|
||||
{
|
||||
diagnostic_show_locus (context, diagnostic);
|
||||
diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
|
||||
pp_destroy_prefix (context->printer);
|
||||
pp_flush (context->printer);
|
||||
}
|
||||
|
@ -1025,7 +1028,7 @@ diagnostic_append_note (diagnostic_context *context,
|
|||
pp_output_formatted_text (context->printer);
|
||||
pp_destroy_prefix (context->printer);
|
||||
pp_set_prefix (context->printer, saved_prefix);
|
||||
diagnostic_show_locus (context, &diagnostic);
|
||||
diagnostic_show_locus (context, &richloc, DK_NOTE);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
|
|
@ -284,7 +284,9 @@ extern void diagnostic_initialize (diagnostic_context *, int);
|
|||
extern void diagnostic_color_init (diagnostic_context *, int value = -1);
|
||||
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 *);
|
||||
extern void diagnostic_show_locus (diagnostic_context *,
|
||||
rich_location *richloc,
|
||||
diagnostic_t diagnostic_kind);
|
||||
|
||||
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
|
||||
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* error.c (gfc_diagnostic_starter): Update for change to
|
||||
diagnostic_show_locus.
|
||||
|
||||
2016-08-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR fortran/67496
|
||||
|
|
|
@ -1093,7 +1093,7 @@ gfc_diagnostic_starter (diagnostic_context *context,
|
|||
free (locus_prefix);
|
||||
/* Fortran uses an empty line between locus and caret line. */
|
||||
pp_newline (context->printer);
|
||||
diagnostic_show_locus (context, diagnostic);
|
||||
diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
|
||||
/* If the caret line was shown, the prefix does not contain the
|
||||
locus. */
|
||||
pp_set_prefix (context->printer, kind_prefix);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
|
||||
(custom_diagnostic_finalizer): Update for change to
|
||||
diagnostic_show_locus.
|
||||
|
||||
2016-08-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* gcc.dg/cpp/misspelled-directive-1.c: New testcase.
|
||||
|
|
|
@ -133,7 +133,7 @@ custom_diagnostic_finalizer (diagnostic_context *context,
|
|||
bool old_show_color = pp_show_color (context->printer);
|
||||
if (force_show_locus_color)
|
||||
pp_show_color (context->printer) = true;
|
||||
diagnostic_show_locus (context, diagnostic);
|
||||
diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
|
||||
pp_show_color (context->printer) = old_show_color;
|
||||
|
||||
pp_destroy_prefix (context->printer);
|
||||
|
|
Loading…
Reference in New Issue