diff options
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 32 | ||||
-rw-r--r-- | libcpp/include/line-map.h | 90 | ||||
-rw-r--r-- | libcpp/line-map.c | 218 |
3 files changed, 127 insertions, 213 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 63cd5a5..ab225d5 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,35 @@ +2017-05-01 David Malcolm <dmalcolm@redhat.com> + + * include/line-map.h (source_range::intersects_line_p): Delete. + (rich_location::add_fixit): Delete. + (rich_location::maybe_add_fixit): New method. + (class fixit_hint): Reimplement in terms of... + (class fixit_replace): ...this. + (class fixit_insert): Delete. + * line-map.c (linemap_position_for_loc_and_offset): Drop overzealous + linemap_assert_fails. + (source_range::intersects_line_p): Rename to... + (fixit_hint::affects_line_p): New function. + (rich_location::add_fixit_insert_before): Reimplement in terms of + maybe_add_fixit, moving validation there. + (rich_location::add_fixit_insert_after): Likewise. + (column_before_p): Delete. + (rich_location::add_fixit_replace): Reimplement in terms of + maybe_add_fixit, moving validation there. Convert closed input range + to half-open range. + (rich_location::add_fixit): Delete. + (rich_location::maybe_add_fixit): New function. + (fixit_insert::fixit_insert): Delete. + (fixit_insert::~fixit_insert): Delete. + (fixit_insert::affects_line_p): Delete. + (fixit_insert::maybe_append_replace): Delete. + (fixit_replace::fixit_replace): Rename to... + (fixit_hint::fixit_hint): ...this, rewriting as necessary. + (fixit_replace::~fixit_replace): Delete. + (fixit_replace::affects_line_p): Delete. + (fixit_replace::maybe_append_replace): Rename to... + (fixit_hint::maybe_append): ...this, rewriting as necessary. + 2017-04-03 Jonathan Wakely <jwakely@redhat.com> * include/line-map.h (LINEMAPS_MACRO_MAPS): Fix typo in comment. diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 522e8bb..0c44f01 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -305,9 +305,6 @@ struct GTY(()) source_range result.m_finish = finish; return result; } - - /* Is there any part of this range on the given line? */ - bool intersects_line_p (const char *file, int line) const; }; /* Memory allocation function typedef. Works like xrealloc. */ @@ -1416,8 +1413,6 @@ semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len) } class fixit_hint; - class fixit_insert; - class fixit_replace; /* A "rich" source code location, for use when printing diagnostics. A rich_location has one or more carets&ranges, where the carets @@ -1667,7 +1662,9 @@ class rich_location private: bool reject_impossible_fixit (source_location where); void stop_supporting_fixits (); - void add_fixit (fixit_hint *hint); + void maybe_add_fixit (source_location start, + source_location next_loc, + const char *new_content); public: static const int STATICALLY_ALLOCATED_RANGES = 3; @@ -1687,72 +1684,41 @@ protected: bool m_seen_impossible_fixit; }; -class fixit_hint -{ -public: - enum kind {INSERT, REPLACE}; - - virtual ~fixit_hint () {} - - virtual enum kind get_kind () const = 0; - virtual bool affects_line_p (const char *file, int line) const = 0; - virtual source_location get_start_loc () const = 0; - virtual bool maybe_get_end_loc (source_location *out) const = 0; - /* Vfunc for consolidating successor fixits. */ - virtual bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content) = 0; -}; - -class fixit_insert : public fixit_hint -{ - public: - fixit_insert (source_location where, - const char *new_content); - ~fixit_insert (); - enum kind get_kind () const { return INSERT; } - bool affects_line_p (const char *file, int line) const; - source_location get_start_loc () const { return m_where; } - bool maybe_get_end_loc (source_location *) const { return false; } - bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content); - - source_location get_location () const { return m_where; } - const char *get_string () const { return m_bytes; } - size_t get_length () const { return m_len; } +/* A fix-it hint: a suggested insertion, replacement, or deletion of text. + We handle these three types of edit with one class, by representing + them as replacement of a half-open range: + [start, next_loc) + Insertions have start == next_loc: "replace" the empty string at the + start location with the new string. + Deletions are replacement with the empty string. */ - private: - source_location m_where; - char *m_bytes; - size_t m_len; -}; - -class fixit_replace : public fixit_hint +class fixit_hint { public: - fixit_replace (source_range src_range, - const char *new_content); - ~fixit_replace (); + fixit_hint (source_location start, + source_location next_loc, + const char *new_content); + ~fixit_hint () { free (m_bytes); } - enum kind get_kind () const { return REPLACE; } bool affects_line_p (const char *file, int line) const; - 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; - } - bool maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content); + source_location get_start_loc () const { return m_start; } + source_location get_next_loc () const { return m_next_loc; } + bool maybe_append (source_location start, + source_location next_loc, + const char *new_content); - source_range get_range () const { return m_src_range; } const char *get_string () const { return m_bytes; } size_t get_length () const { return m_len; } + bool insertion_p () const { return m_start == m_next_loc; } + private: - source_range m_src_range; + /* We don't use source_range here since, unlike most places, + this is a half-open/half-closed range: + [start, next_loc) + so that we can support insertion via start == next_loc. */ + source_location m_start; + source_location m_next_loc; char *m_bytes; size_t m_len; }; diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 949489e..176e58d 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -881,8 +881,7 @@ linemap_position_for_loc_and_offset (struct line_maps *set, loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; /* This function does not support virtual locations yet. */ - if (linemap_assert_fails - (!linemap_location_from_macro_expansion_p (set, loc))) + if (linemap_location_from_macro_expansion_p (set, loc)) return loc; if (column_offset == 0 @@ -2003,28 +2002,6 @@ 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. */ @@ -2173,16 +2150,7 @@ rich_location::add_fixit_insert_before (source_location where, const char *new_content) { source_location start = get_range_from_loc (m_line_table, where).m_start; - - if (reject_impossible_fixit (start)) - return; - /* We do not yet support newlines within fix-it hints. */ - if (strchr (new_content, '\n')) - { - stop_supporting_fixits (); - return; - } - add_fixit (new fixit_insert (start, new_content)); + maybe_add_fixit (start, start, new_content); } /* Add a fixit-hint, suggesting insertion of NEW_CONTENT @@ -2202,10 +2170,6 @@ rich_location::add_fixit_insert_after (source_location where, const char *new_content) { source_location finish = get_range_from_loc (m_line_table, where).m_finish; - - if (reject_impossible_fixit (finish)) - return; - source_location next_loc = linemap_position_for_loc_and_offset (m_line_table, finish, 1); @@ -2217,7 +2181,7 @@ rich_location::add_fixit_insert_after (source_location where, return; } - add_fixit (new fixit_insert (next_loc, new_content)); + maybe_add_fixit (next_loc, next_loc, new_content); } /* Methods for adding removal fix-it hints. */ @@ -2250,44 +2214,6 @@ rich_location::add_fixit_remove (source_range src_range) add_fixit_replace (src_range, ""); } -/* Return true iff A is in the column directly before B, on the - same line of the same source file. */ - -static bool -column_before_p (line_maps *set, source_location a, source_location b) -{ - if (IS_ADHOC_LOC (a)) - a = get_location_from_adhoc_loc (set, a); - if (IS_ADHOC_LOC (b)) - b = get_location_from_adhoc_loc (set, b); - - /* They must both be in ordinary maps. */ - const struct line_map *linemap_a = linemap_lookup (set, a); - if (linemap_macro_expansion_map_p (linemap_a)) - return false; - const struct line_map *linemap_b = linemap_lookup (set, b); - if (linemap_macro_expansion_map_p (linemap_b)) - return false; - - /* To be on the same line, they must be in the same ordinary map. */ - if (linemap_a != linemap_b) - return false; - - linenum_type line_a - = SOURCE_LINE (linemap_check_ordinary (linemap_a), a); - linenum_type line_b - = SOURCE_LINE (linemap_check_ordinary (linemap_b), b); - if (line_a != line_b) - return false; - - linenum_type column_a - = SOURCE_COLUMN (linemap_check_ordinary (linemap_a), a); - linenum_type column_b - = SOURCE_COLUMN (linemap_check_ordinary (linemap_b), b); - - return column_b == column_a + 1; -} - /* Add a fixit-hint, suggesting replacement of the content covered by range 0 with NEW_CONTENT. */ @@ -2317,28 +2243,22 @@ void rich_location::add_fixit_replace (source_range src_range, const char *new_content) { - src_range.m_start = get_pure_location (m_line_table, src_range.m_start); - src_range.m_finish = get_pure_location (m_line_table, src_range.m_finish); - - if (reject_impossible_fixit (src_range.m_start)) - return; - if (reject_impossible_fixit (src_range.m_finish)) - return; + source_location start = get_pure_location (m_line_table, src_range.m_start); + source_location finish = get_pure_location (m_line_table, src_range.m_finish); - /* We do not yet support newlines within fix-it hints. */ - if (strchr (new_content, '\n')) + /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */ + source_location next_loc + = linemap_position_for_loc_and_offset (m_line_table, finish, 1); + /* linemap_position_for_loc_and_offset can fail, if so, it returns + its input value. */ + if (next_loc == finish) { stop_supporting_fixits (); return; } + finish = next_loc; - /* Consolidate neighboring fixits. */ - fixit_hint *prev = get_last_fixit_hint (); - if (prev) - if (prev->maybe_append_replace (m_line_table, src_range, new_content)) - return; - - add_fixit (new fixit_replace (src_range, new_content)); + maybe_add_fixit (start, finish, new_content); } /* Get the last fix-it hint within this rich_location, or NULL if none. */ @@ -2392,89 +2312,85 @@ rich_location::stop_supporting_fixits () m_fixit_hints.truncate (0); } -/* Add HINT to the fix-it hints in this rich_location. */ +/* Add HINT to the fix-it hints in this rich_location, + consolidating into the prior fixit if possible. */ void -rich_location::add_fixit (fixit_hint *hint) +rich_location::maybe_add_fixit (source_location start, + source_location next_loc, + const char *new_content) { - m_fixit_hints.push (hint); -} - -/* 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. */ + if (reject_impossible_fixit (start)) + return; + if (reject_impossible_fixit (next_loc)) + return; -bool -fixit_insert::affects_line_p (const char *file, int line) const -{ - expanded_location exploc - = linemap_client_expand_location_to_spelling_point (m_where); - if (file == exploc.file) - if (line == exploc.line) - return true; - return false; -} + /* We do not yet support newlines within fix-it hints. */ + if (strchr (new_content, '\n')) + { + stop_supporting_fixits (); + return; + } -/* Implementation of maybe_append_replace for fixit_insert. Reject - the attempt to consolidate fix-its. */ + /* Consolidate neighboring fixits. */ + fixit_hint *prev = get_last_fixit_hint (); + if (prev) + if (prev->maybe_append (start, next_loc, new_content)) + return; -bool -fixit_insert::maybe_append_replace (line_maps *, source_range, const char *) -{ - return false; + m_fixit_hints.push (new fixit_hint (start, next_loc, new_content)); } -/* class fixit_replace. */ +/* class fixit_hint. */ -fixit_replace::fixit_replace (source_range src_range, - const char *new_content) -: m_src_range (src_range), +fixit_hint::fixit_hint (source_location start, + source_location next_loc, + const char *new_content) +: m_start (start), + m_next_loc (next_loc), 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. */ +/* Does this fix-it hint affect the given line? */ bool -fixit_replace::affects_line_p (const char *file, int line) const +fixit_hint::affects_line_p (const char *file, int line) const { - return m_src_range.intersects_line_p (file, line); + 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_next_loc + = linemap_client_expand_location_to_spelling_point (m_next_loc); + if (file != exploc_next_loc.file) + return false; + if (line > exploc_next_loc.line) + return false; + return true; } -/* Implementation of maybe_append_replace for fixit_replace. If - possible, merge the new replacement into this one and return true. +/* Method for consolidating fix-it hints, for use by + rich_location::maybe_add_fixit. + If possible, merge a pending fix-it hint with the given params + into this one and return true. Otherwise return false. */ bool -fixit_replace::maybe_append_replace (line_maps *set, - source_range src_range, - const char *new_content) +fixit_hint::maybe_append (source_location start, + source_location next_loc, + const char *new_content) { - /* Does SRC_RANGE start immediately after this one finishes? */ - if (!column_before_p (set, m_src_range.m_finish, src_range.m_start)) + /* For consolidation to be possible, START must be at this hint's + m_next_loc. */ + if (start != m_next_loc) return false; - /* We have neighboring replacements; merge them. */ - m_src_range.m_finish = src_range.m_finish; + /* If so, we have neighboring replacements; merge them. */ + m_next_loc = next_loc; size_t extra_len = strlen (new_content); m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1); memcpy (m_bytes + m_len, new_content, extra_len); |