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 /libcpp/include/line-map.h | |
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 'libcpp/include/line-map.h')
-rw-r--r-- | libcpp/include/line-map.h | 145 |
1 files changed, 132 insertions, 13 deletions
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 122e474..0c95b29 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -1288,6 +1288,128 @@ struct location_range bool m_show_caret_p; }; +/* A partially-embedded vec for use within rich_location for storing + ranges and fix-it hints. + + Elements [0..NUM_EMBEDDED) are allocated within m_embed, after + that they are within the dynamically-allocated m_extra. + + This allows for static allocation in the common case, whilst + supporting the rarer case of an arbitrary number of elements. + + Dynamic allocation is not performed unless it's needed. */ + +template <typename T, int NUM_EMBEDDED> +class semi_embedded_vec +{ + public: + semi_embedded_vec (); + ~semi_embedded_vec (); + + unsigned int count () const { return m_num; } + T& operator[] (int idx); + const T& operator[] (int idx) const; + + void push (const T&); + void truncate (int len); + + private: + int m_num; + T m_embedded[NUM_EMBEDDED]; + int m_alloc; + T *m_extra; +}; + +/* Constructor for semi_embedded_vec. In particular, no dynamic allocation + is done. */ + +template <typename T, int NUM_EMBEDDED> +semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec () +: m_num (0), m_alloc (0), m_extra (NULL) +{ +} + +/* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */ + +template <typename T, int NUM_EMBEDDED> +semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec () +{ + XDELETEVEC (m_extra); +} + +/* Look up element IDX, mutably. */ + +template <typename T, int NUM_EMBEDDED> +T& +semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) +{ + linemap_assert (idx < m_num); + if (idx < NUM_EMBEDDED) + return m_embedded[idx]; + else + { + linemap_assert (m_extra != NULL); + return m_extra[idx - NUM_EMBEDDED]; + } +} + +/* Look up element IDX (const). */ + +template <typename T, int NUM_EMBEDDED> +const T& +semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) const +{ + linemap_assert (idx < m_num); + if (idx < NUM_EMBEDDED) + return m_embedded[idx]; + else + { + linemap_assert (m_extra != NULL); + return m_extra[idx - NUM_EMBEDDED]; + } +} + +/* Append VALUE to the end of the semi_embedded_vec. */ + +template <typename T, int NUM_EMBEDDED> +void +semi_embedded_vec<T, NUM_EMBEDDED>::push (const T& value) +{ + int idx = m_num++; + if (idx < NUM_EMBEDDED) + m_embedded[idx] = value; + else + { + /* Offset "idx" to be an index within m_extra. */ + idx -= NUM_EMBEDDED; + if (NULL == m_extra) + { + linemap_assert (m_alloc == 0); + m_alloc = 16; + m_extra = XNEWVEC (T, m_alloc); + } + else if (idx >= m_alloc) + { + linemap_assert (m_alloc > 0); + m_alloc *= 2; + m_extra = XRESIZEVEC (T, m_extra, m_alloc); + } + linemap_assert (m_extra); + linemap_assert (idx < m_alloc); + m_extra[idx] = value; + } +} + +/* Truncate to length LEN. No deallocation is performed. */ + +template <typename T, int NUM_EMBEDDED> +void +semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len) +{ + linemap_assert (len <= m_num); + m_num = len; +} + class fixit_hint; class fixit_insert; class fixit_remove; @@ -1387,13 +1509,10 @@ class rich_location set_range (line_maps *set, unsigned int idx, source_location loc, bool show_caret_p); - unsigned int get_num_locations () const { return m_num_ranges; } + unsigned int get_num_locations () const { return m_ranges.count (); } - location_range *get_range (unsigned int idx) - { - linemap_assert (idx < m_num_ranges); - return &m_ranges[idx]; - } + const location_range *get_range (unsigned int idx) const; + location_range *get_range (unsigned int idx); expanded_location get_expanded_location (unsigned int idx); @@ -1446,29 +1565,29 @@ class rich_location add_fixit_replace (source_range src_range, const char *new_content); - unsigned int get_num_fixit_hints () const { return m_num_fixit_hints; } + unsigned int get_num_fixit_hints () const { return m_fixit_hints.count (); } fixit_hint *get_fixit_hint (int idx) const { return m_fixit_hints[idx]; } fixit_hint *get_last_fixit_hint () const; private: bool reject_impossible_fixit (source_location where); + void add_fixit (fixit_hint *hint); public: - static const int MAX_RANGES = 3; - static const int MAX_FIXIT_HINTS = 2; + static const int STATICALLY_ALLOCATED_RANGES = 3; protected: line_maps *m_line_table; - unsigned int m_num_ranges; - location_range m_ranges[MAX_RANGES]; + semi_embedded_vec <location_range, STATICALLY_ALLOCATED_RANGES> m_ranges; int m_column_override; bool m_have_expanded_location; expanded_location m_expanded_location; - unsigned int m_num_fixit_hints; - fixit_hint *m_fixit_hints[MAX_FIXIT_HINTS]; + static const int MAX_STATIC_FIXIT_HINTS = 2; + semi_embedded_vec <fixit_hint *, MAX_STATIC_FIXIT_HINTS> m_fixit_hints; + bool m_seen_impossible_fixit; }; |