diff options
author | David Malcolm <dmalcolm@redhat.com> | 2016-08-31 00:35:01 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2016-08-31 00:35:01 +0000 |
commit | b816477a5ad7277b3a588e9a58cbcd764152b8d2 (patch) | |
tree | 4e3390b81b9f7a7b900db1de9278ee74805abf77 /gcc | |
parent | fb8e9c5e8ee12831db4a020f7ccb63ac7bbf9dee (diff) | |
download | gcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.zip gcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.tar.gz gcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.tar.bz2 |
Remove arbitrary limits from rich_location
This patch eliminates the hard-coded limits within rich_location
(up to 3 ranges, up to 2 fixits). The common case is still
handled by embedding the values inside rich_location - it only
uses dynamic allocation if these limits are exceeded, so
creation of rich_location instances on the stack should still
be fast. This is implemented via a new container class,
semi_embedded_vec <T, N>.
gcc/ChangeLog:
* diagnostic-show-locus.c (colorizer::begin_state): Support more
than 3 ranges per diagnostic by alternating between color 1 and
color 2.
(layout::layout): Replace use of rich_location::MAX_RANGES
with richloc->get_num_locations ().
(layout::calculate_line_spans): Replace use of
rich_location::MAX_RANGES with m_layout_ranges.length ().
(layout::print_annotation_line): Handle arbitrary numbers of
ranges in caret-printing by defaulting to '^'.
(selftest::test_one_liner_many_fixits): New function.
(test_diagnostic_show_locus_one_liner): Call it.
* diagnostic.c (diagnostic_initialize): Update for renaming
of rich_location::MAX_RANGES to
rich_location::STATICALLY_ALLOCATED_RANGES.
* diagnostic.h (struct diagnostic_context): Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-test-show-locus-bw.c
(test_many_nested_locations): New function.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Handle "test_many_nested_locations".
libcpp/ChangeLog:
* include/line-map.h (class semi_embedded_vec): New class.
(semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec): New ctor.
(semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec): New
dtor.
(semi_embedded_vec<T, NUM_EMBEDDED>::operator[]): New methods.
(semi_embedded_vec<T, NUM_EMBEDDED>::push): New method.
(semi_embedded_vec<T, NUM_EMBEDDED>::truncate): New method.
(rich_location::get_num_locations): Reimplement in terms of
m_ranges.
(rich_location::get_range): Make non-inline.
(rich_location::get_num_fixit_hints): Reimplement in terms of
m_fixit_hints.
(rich_location::add_fixit): New function.
(rich_location::MAX_RANGES): Rename to...
(rich_location::STATICALLY_ALLOCATED_RANGES): ...this.
(rich_location::MAX_FIXIT_HINTS): Rename to...
(rich_location::STATICALLY_ALLOCATED_RANGES): ...this, and make
private.
(rich_location::m_num_ranges): Eliminate in favor of...
(rich_location::m_ranges): ...this, converting from a fixed-size
array to a semi_embedded_vec.
(rich_location::m_num_fixit_hints): Eliminate in favor of...
(rich_location::m_fixit_hints): ...this, converting from a
fixed-size array to a semi_embedded_vec.
* line-map.c (rich_location::rich_location): Update for above
changes.
(rich_location::~rich_location): Likewise.
(rich_location::get_loc): Likewise.
(rich_location::get_range): New methods.
(rich_location::add_range): Update for above changes.
(rich_location::set_range): Likewise.
(rich_location::add_fixit_insert): Likewise.
(rich_location::add_fixit_replace): Likewise.
(rich_location::get_last_fixit_hint): Likewise.
(rich_location::reject_impossible_fixit): Likewise.
(rich_location::add_fixit): New method.
From-SVN: r239879
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/diagnostic-show-locus.c | 64 | ||||
-rw-r--r-- | gcc/diagnostic.c | 2 | ||||
-rw-r--r-- | gcc/diagnostic.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c | 53 |
7 files changed, 181 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa764e8..54f2f7a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,23 @@ 2016-08-30 David Malcolm <dmalcolm@redhat.com> + * diagnostic-show-locus.c (colorizer::begin_state): Support more + than 3 ranges per diagnostic by alternating between color 1 and + color 2. + (layout::layout): Replace use of rich_location::MAX_RANGES + with richloc->get_num_locations (). + (layout::calculate_line_spans): Replace use of + rich_location::MAX_RANGES with m_layout_ranges.length (). + (layout::print_annotation_line): Handle arbitrary numbers of + ranges in caret-printing by defaulting to '^'. + (selftest::test_one_liner_many_fixits): New function. + (test_diagnostic_show_locus_one_liner): Call it. + * diagnostic.c (diagnostic_initialize): Update for renaming + of rich_location::MAX_RANGES to + rich_location::STATICALLY_ALLOCATED_RANGES. + * diagnostic.h (struct diagnostic_context): Likewise. + +2016-08-30 David Malcolm <dmalcolm@redhat.com> + * selftest.c (selftest::named_temp_file::named_temp_file): New ctor. (selftest::temp_source_file::~temp_source_file): Move to... diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c index 60f6820..a22a660 100644 --- a/gcc/diagnostic-show-locus.c +++ b/gcc/diagnostic-show-locus.c @@ -317,8 +317,12 @@ colorizer::begin_state (int state) break; default: - /* We don't expect more than 3 ranges per diagnostic. */ - gcc_unreachable (); + /* For ranges beyond 2, alternate between color 1 and color 2. */ + { + gcc_assert (state > 2); + pp_string (m_context->printer, + state % 2 ? m_range1 : m_range2); + } break; } } @@ -720,8 +724,8 @@ layout::layout (diagnostic_context * context, 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_layout_ranges (richloc->get_num_locations ()), + m_line_spans (1 + richloc->get_num_locations ()), m_x_offset (0) { source_location primary_loc = richloc->get_range (0)->m_loc; @@ -904,7 +908,7 @@ layout::calculate_line_spans () /* Populate tmp_spans with individual spans, for each of m_exploc, and for m_layout_ranges. */ - auto_vec<line_span> tmp_spans (1 + rich_location::MAX_RANGES); + auto_vec<line_span> tmp_spans (1 + m_layout_ranges.length ()); tmp_spans.safe_push (line_span (m_exploc.line, m_exploc.line)); for (unsigned int i = 0; i < m_layout_ranges.length (); i++) { @@ -1050,8 +1054,15 @@ layout::print_annotation_line (int row, const line_bounds lbounds) /* Within a range. Draw either the caret or an underline. */ m_colorizer.set_range (state.range_idx); if (state.draw_caret_p) - /* Draw the caret. */ - pp_character (m_pp, m_context->caret_chars[state.range_idx]); + { + /* Draw the caret. */ + char caret_char; + if (state.range_idx < rich_location::STATICALLY_ALLOCATED_RANGES) + caret_char = m_context->caret_chars[state.range_idx]; + else + caret_char = '^'; + pp_character (m_pp, caret_char); + } else pp_character (m_pp, '~'); } @@ -1654,6 +1665,44 @@ test_one_liner_fixit_validation_adhoc_locations () } } +/* Ensure that we can add an arbitrary number of fix-it hints to a + rich_location. */ + +static void +test_one_liner_many_fixits () +{ + test_diagnostic_context dc; + location_t equals = linemap_position_for_column (line_table, 5); + rich_location richloc (line_table, equals); + for (int i = 0; i < 19; i++) + richloc.add_fixit_insert ("a"); + ASSERT_EQ (19, richloc.get_num_fixit_hints ()); + diagnostic_show_locus (&dc, &richloc, DK_ERROR); + ASSERT_STREQ ("\n" + " foo = bar.field;\n" + " ^\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n" + " a\n", + pp_formatted_text (dc.printer)); +} + /* Run the various one-liner tests. */ static void @@ -1687,6 +1736,7 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_) test_one_liner_fixit_replace_non_equal_range (); test_one_liner_fixit_replace_equal_secondary_range (); test_one_liner_fixit_validation_adhoc_locations (); + test_one_liner_many_fixits (); } /* Verify that fix-it hints are appropriately consolidated. diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index b47da38..47b4c79 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -147,7 +147,7 @@ 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)); - for (i = 0; i < rich_location::MAX_RANGES; i++) + for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) context->caret_chars[i] = '^'; context->show_option_requested = false; context->abort_on_error = false; diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 104e39c..0727644 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -109,7 +109,7 @@ struct diagnostic_context int caret_max_width; /* Character used for caret diagnostics. */ - char caret_chars[rich_location::MAX_RANGES]; + char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES]; /* True if we should print the command line option which controls each diagnostic, if known. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6e3b706..cf97b39 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2016-08-30 David Malcolm <dmalcolm@redhat.com> + * gcc.dg/plugin/diagnostic-test-show-locus-bw.c + (test_many_nested_locations): New function. + * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c + (test_show_locus): Handle "test_many_nested_locations". + +2016-08-30 David Malcolm <dmalcolm@redhat.com> + * g++.dg/template/double-greater-than-fixit.C: New test case. 2016-08-30 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c index 2748fa1..e8112bf 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c @@ -205,3 +205,47 @@ int test_percent_q_plus_d (void) { dg-end-multiline-output "" } */ return local; } + +/* Test of many nested locations and fixits. */ + +void test_many_nested_locations (void) +{ + /* { dg-warning "test of 70 locations" } + Lorem ipsum dolor sit amet, consectetur adipiscing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis + aute irure dolor in reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt + mollit anim id est laborum. + */ +/* { dg-begin-multiline-output "" } + /* + ^ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, + ^~~~~ ^~~~~ ^~~~~ ^~~ ^~~~ ^~~~~~~~~~~ ^~~~~~~~~~ ^~~~ + LOREM IPSUM DOLOR SIT AMET CONSECTETUR ADIPISCING ELIT + sed do eiusmod tempor incididunt ut labore et dolore magna + ^~~ ^~ ^~~~~~~ ^~~~~~ ^~~~~~~~~~ ^~ ^~~~~~ ^~ ^~~~~~ ^~~~~ + SED DO EIUSMOD TEMPOR INCIDIDUNT UT LABORE ET DOLORE MAGNA + aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ^~~~~~ ^~ ^~~~ ^~ ^~~~~ ^~~~~~ ^~~~ ^~~~~~~ ^~~~~~~~~~~~ + ALIQUA UT ENIM AD MINIM VENIAM QUIS NOSTRUD EXERCITATION + ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis + ^~~~~~~ ^~~~~~~ ^~~~ ^~ ^~~~~~~ ^~ ^~ ^~~~~~~ ^~~~~~~~~ ^~~~ + ULLAMCO LABORIS NISI UT ALIQUIP EX EA COMMODO CONSEQUAT DUIS + aute irure dolor in reprehenderit in voluptate velit esse cillum + ^~~~ ^~~~~ ^~~~~ ^~ ^~~~~~~~~~~~~ ^~ ^~~~~~~~~ ^~~~~ ^~~~ ^~~~~~ + AUTE IRURE DOLOR IN REPREHENDERIT IN VOLUPTATE VELIT ESSE CILLUM + dolore eu fugiat nulla pariatur. Excepteur sint occaecat + ^~~~~~ ^~ ^~~~~~ ^~~~~ ^~~~~~~~ ^~~~~~~~~ ^~~~ ^~~~~~~~ + DOLORE EU FUGIAT NULLA PARIATUR EXCEPTEUR SINT OCCAECAT + cupidatat non proident, sunt in culpa qui officia deserunt + ^~~~~~~~~ ^~~ ^~~~~~~~ ^~~~ ^~ ^~~~~ ^~~ ^~~~~~~ ^~~~~~~~ + CUPIDATAT NON PROIDENT SUNT IN CULPA QUI OFFICIA DESERUNT + mollit anim id est laborum. + ^~~~~~ ^~~~ ^~ ^~~ ^~~~~~~ + MOLLIT ANIM ID EST LABORUM + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index d57400d..ea28f04 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -325,6 +325,59 @@ test_show_locus (function *fun) warning_at (input_location, 0, "example of plus in format code for %q+D", local); } + + /* Example of many locations and many fixits. + Underline (separately) every word in a comment, and convert them + to upper case. */ + if (0 == strcmp (fnname, "test_many_nested_locations")) + { + const char *file = LOCATION_FILE (fnstart); + const int start_line = fnstart_line + 2; + const int finish_line = start_line + 7; + location_t loc = get_loc (start_line - 1, 2); + rich_location richloc (line_table, loc); + for (int line = start_line; line <= finish_line; line++) + { + int line_size; + const char *content = location_get_source_line (file, line, + &line_size); + gcc_assert (content); + /* Split line up into words. */ + for (int idx = 0; idx < line_size; idx++) + { + if (ISALPHA (content[idx])) + { + int start_idx = idx; + while (idx < line_size && ISALPHA (content[idx])) + idx++; + if (idx == line_size || !ISALPHA (content[idx])) + { + location_t start_of_word = get_loc (line, start_idx); + location_t end_of_word = get_loc (line, idx - 1); + location_t word + = make_location (start_of_word, start_of_word, + end_of_word); + richloc.add_range (word, true); + + /* Add a fixit, converting to upper case. */ + char *copy = xstrndup (content + start_idx, + idx - start_idx); + for (char *ch = copy; *ch; ch++) + *ch = TOUPPER (*ch); + richloc.add_fixit_replace (word, copy); + free (copy); + } + } + } + } + /* Verify that we added enough locations to fully exercise + rich_location. We want to exceed both the + statically-allocated buffer in class rich_location, + and then trigger a reallocation of the dynamic buffer. */ + gcc_assert (richloc.get_num_locations () > 3 + (2 * 16)); + warning_at_rich_loc (&richloc, 0, "test of %i locations", + richloc.get_num_locations ()); + } } unsigned int |