aboutsummaryrefslogtreecommitdiff
path: root/libcpp/include/line-map.h
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2016-08-31 00:35:01 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2016-08-31 00:35:01 +0000
commitb816477a5ad7277b3a588e9a58cbcd764152b8d2 (patch)
tree4e3390b81b9f7a7b900db1de9278ee74805abf77 /libcpp/include/line-map.h
parentfb8e9c5e8ee12831db4a020f7ccb63ac7bbf9dee (diff)
downloadgcc-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.h145
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;
};