aboutsummaryrefslogtreecommitdiff
path: root/libcpp/include/line-map.h
diff options
context:
space:
mode:
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;
};