diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-20 20:08:47 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-20 20:08:47 +0000 |
commit | 734caf844448fdbacd488ee19b96e20c751fe063 (patch) | |
tree | f65f921f35a1b100513886cbde83b0f1b31e72d9 /libcpp/line-map.c | |
parent | 219e09fcec6667d6af390f8a361927bdc069d720 (diff) | |
download | gcc-734caf844448fdbacd488ee19b96e20c751fe063.tar.gz |
PR 62314: add ability to add fixit-hints to a diagnostic
This is the combination of two patches:
[PATCH 01/02] PR/62314: add ability to add fixit-hints
[PATCH 02/02] C FE: add fix-it hint for . vs ->
gcc/ChangeLog:
PR 62314
* diagnostic-show-locus.c (colorizer::set_fixit_hint): New.
(class layout): Update comment
(layout::print_any_fixits): New method.
(layout::move_to_column): New method.
(diagnostic_show_locus): Add call to layout.print_any_fixits.
gcc/c/ChangeLog:
PR 62314
* c-typeck.c (should_suggest_deref_p): New function.
(build_component_ref): Special-case POINTER_TYPE when
generating a "not a structure of union" error message, and
suggest a "->" rather than a ".", providing a fix-it hint.
gcc/testsuite/ChangeLog:
PR 62314
* gcc.dg/fixits.c: New file.
* gcc.dg/plugin/diagnostic-test-show-locus-ascii-bw.c
(test_fixit_insert): New.
(test_fixit_remove): New.
(test_fixit_replace): New.
* gcc.dg/plugin/diagnostic-test-show-locus-ascii-color.c
(test_fixit_insert): New.
(test_fixit_remove): New.
(test_fixit_replace): New.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Add tests of rendering fixit hints.
libcpp/ChangeLog:
PR 62314
* include/line-map.h (source_range::intersects_line_p): New
method.
(rich_location::~rich_location): New.
(rich_location::add_fixit_insert): New method.
(rich_location::add_fixit_remove): New method.
(rich_location::add_fixit_replace): New method.
(rich_location::get_num_fixit_hints): New accessor.
(rich_location::get_fixit_hint): New accessor.
(rich_location::MAX_FIXIT_HINTS): New constant.
(rich_location::m_num_fixit_hints): New field.
(rich_location::m_fixit_hints): New field.
(class fixit_hint): New class.
(class fixit_insert): New class.
(class fixit_remove): New class.
(class fixit_replace): New class.
* line-map.c (source_range::intersects_line_p): New method.
(rich_location::rich_location): Add initialization of
m_num_fixit_hints to both ctors.
(rich_location::~rich_location): New.
(rich_location::add_fixit_insert): New method.
(rich_location::add_fixit_remove): New method.
(rich_location::add_fixit_replace): New method.
(fixit_insert::fixit_insert): New.
(fixit_insert::~fixit_insert): New.
(fixit_insert::affects_line_p): New.
(fixit_remove::fixit_remove): New.
(fixit_remove::affects_line_p): New.
(fixit_replace::fixit_replace): New.
(fixit_replace::~fixit_replace): New.
(fixit_replace::affects_line_p): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230674 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp/line-map.c')
-rw-r--r-- | libcpp/line-map.c | 136 |
1 files changed, 134 insertions, 2 deletions
diff --git a/libcpp/line-map.c b/libcpp/line-map.c index c5aa4223b1b..42843038e3b 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -1947,6 +1947,28 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary, } } +/* struct source_range. */ + +/* Is there any part of this range on the given line? */ + +bool +source_range::intersects_line_p (const char *file, int line) const +{ + expanded_location exploc_start + = linemap_client_expand_location_to_spelling_point (m_start); + if (file != exploc_start.file) + return false; + if (line < exploc_start.line) + return false; + expanded_location exploc_finish + = linemap_client_expand_location_to_spelling_point (m_finish); + if (file != exploc_finish.file) + return false; + if (line > exploc_finish.line) + return false; + return true; +} + /* class rich_location. */ /* Construct a rich_location with location LOC as its initial range. */ @@ -1954,7 +1976,8 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary, rich_location::rich_location (line_maps *set, source_location loc) : m_loc (loc), m_num_ranges (0), - m_have_expanded_location (false) + m_have_expanded_location (false), + m_num_fixit_hints (0) { /* Set up the 0th range, extracting any range from LOC. */ source_range src_range = get_range_from_loc (set, loc); @@ -1968,12 +1991,21 @@ rich_location::rich_location (line_maps *set, source_location loc) : rich_location::rich_location (source_range src_range) : m_loc (src_range.m_start), m_num_ranges (0), - m_have_expanded_location (false) + m_have_expanded_location (false), + m_num_fixit_hints (0) { /* Set up the 0th range: */ add_range (src_range, true); } +/* The destructor for class rich_location. */ + +rich_location::~rich_location () +{ + for (unsigned int i = 0; i < m_num_fixit_hints; i++) + delete m_fixit_hints[i]; +} + /* Get an expanded_location for this rich_location's primary location. */ @@ -2077,3 +2109,103 @@ rich_location::set_range (unsigned int idx, source_range src_range, m_have_expanded_location = false; } } + +/* Add a fixit-hint, suggesting insertion of NEW_CONTENT + at WHERE. */ + +void +rich_location::add_fixit_insert (source_location where, + const char *new_content) +{ + linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS); + m_fixit_hints[m_num_fixit_hints++] + = new fixit_insert (where, new_content); +} + +/* Add a fixit-hint, suggesting removal of the content at + SRC_RANGE. */ + +void +rich_location::add_fixit_remove (source_range src_range) +{ + linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS); + m_fixit_hints[m_num_fixit_hints++] = new fixit_remove (src_range); +} + +/* Add a fixit-hint, suggesting replacement of the content at + SRC_RANGE with NEW_CONTENT. */ + +void +rich_location::add_fixit_replace (source_range src_range, + const char *new_content) +{ + linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS); + m_fixit_hints[m_num_fixit_hints++] + = new fixit_replace (src_range, new_content); +} + +/* class fixit_insert. */ + +fixit_insert::fixit_insert (source_location where, + const char *new_content) +: m_where (where), + m_bytes (xstrdup (new_content)), + m_len (strlen (new_content)) +{ +} + +fixit_insert::~fixit_insert () +{ + free (m_bytes); +} + +/* Implementation of fixit_hint::affects_line_p for fixit_insert. */ + +bool +fixit_insert::affects_line_p (const char *file, int line) +{ + expanded_location exploc + = linemap_client_expand_location_to_spelling_point (m_where); + if (file == exploc.file) + if (line == exploc.line) + return true; + return false; +} + +/* class fixit_remove. */ + +fixit_remove::fixit_remove (source_range src_range) +: m_src_range (src_range) +{ +} + +/* Implementation of fixit_hint::affects_line_p for fixit_remove. */ + +bool +fixit_remove::affects_line_p (const char *file, int line) +{ + return m_src_range.intersects_line_p (file, line); +} + +/* class fixit_replace. */ + +fixit_replace::fixit_replace (source_range src_range, + const char *new_content) +: m_src_range (src_range), + m_bytes (xstrdup (new_content)), + m_len (strlen (new_content)) +{ +} + +fixit_replace::~fixit_replace () +{ + free (m_bytes); +} + +/* Implementation of fixit_hint::affects_line_p for fixit_replace. */ + +bool +fixit_replace::affects_line_p (const char *file, int line) +{ + return m_src_range.intersects_line_p (file, line); +} |