mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-10-04 16:08:34 +00:00
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
This commit is contained in:
committed by
David Malcolm
parent
fb8e9c5e8e
commit
b816477a5a
@@ -1,3 +1,42 @@
|
||||
2016-08-30 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2016-08-30 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* include/line-map.h (rich_location::add_fixit_insert): Add
|
||||
|
||||
+132
-13
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
+53
-39
@@ -1983,10 +1983,10 @@ source_range::intersects_line_p (const char *file, int line) const
|
||||
|
||||
rich_location::rich_location (line_maps *set, source_location loc) :
|
||||
m_line_table (set),
|
||||
m_num_ranges (0),
|
||||
m_ranges (),
|
||||
m_column_override (0),
|
||||
m_have_expanded_location (false),
|
||||
m_num_fixit_hints (0),
|
||||
m_fixit_hints (),
|
||||
m_seen_impossible_fixit (false)
|
||||
{
|
||||
add_range (loc, true);
|
||||
@@ -1996,8 +1996,8 @@ rich_location::rich_location (line_maps *set, source_location loc) :
|
||||
|
||||
rich_location::~rich_location ()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_num_fixit_hints; i++)
|
||||
delete m_fixit_hints[i];
|
||||
for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
|
||||
delete get_fixit_hint (i);
|
||||
}
|
||||
|
||||
/* Get location IDX within this rich_location. */
|
||||
@@ -2005,8 +2005,24 @@ rich_location::~rich_location ()
|
||||
source_location
|
||||
rich_location::get_loc (unsigned int idx) const
|
||||
{
|
||||
linemap_assert (idx < m_num_ranges);
|
||||
return m_ranges[idx].m_loc;
|
||||
const location_range *locrange = get_range (idx);
|
||||
return locrange->m_loc;
|
||||
}
|
||||
|
||||
/* Get range IDX within this rich_location. */
|
||||
|
||||
const location_range *
|
||||
rich_location::get_range (unsigned int idx) const
|
||||
{
|
||||
return &m_ranges[idx];
|
||||
}
|
||||
|
||||
/* Mutable access to range IDX within this rich_location. */
|
||||
|
||||
location_range *
|
||||
rich_location::get_range (unsigned int idx)
|
||||
{
|
||||
return &m_ranges[idx];
|
||||
}
|
||||
|
||||
/* Expand location IDX within this rich_location. */
|
||||
@@ -2049,11 +2065,10 @@ rich_location::override_column (int column)
|
||||
void
|
||||
rich_location::add_range (source_location loc, bool show_caret_p)
|
||||
{
|
||||
linemap_assert (m_num_ranges < MAX_RANGES);
|
||||
|
||||
location_range *range = &m_ranges[m_num_ranges++];
|
||||
range->m_loc = loc;
|
||||
range->m_show_caret_p = show_caret_p;
|
||||
location_range range;
|
||||
range.m_loc = loc;
|
||||
range.m_show_caret_p = show_caret_p;
|
||||
m_ranges.push (range);
|
||||
}
|
||||
|
||||
/* Add or overwrite the location given by IDX, setting its location to LOC,
|
||||
@@ -2073,19 +2088,18 @@ void
|
||||
rich_location::set_range (line_maps * /*set*/, unsigned int idx,
|
||||
source_location loc, bool show_caret_p)
|
||||
{
|
||||
linemap_assert (idx < MAX_RANGES);
|
||||
|
||||
/* We can either overwrite an existing range, or add one exactly
|
||||
on the end of the array. */
|
||||
linemap_assert (idx <= m_num_ranges);
|
||||
linemap_assert (idx <= m_ranges.count ());
|
||||
|
||||
location_range *locrange = &m_ranges[idx];
|
||||
locrange->m_loc = loc;
|
||||
locrange->m_show_caret_p = show_caret_p;
|
||||
|
||||
/* Are we adding a range onto the end? */
|
||||
if (idx == m_num_ranges)
|
||||
m_num_ranges = idx + 1;
|
||||
if (idx == m_ranges.count ())
|
||||
add_range (loc, show_caret_p);
|
||||
else
|
||||
{
|
||||
location_range *locrange = get_range (idx);
|
||||
locrange->m_loc = loc;
|
||||
locrange->m_show_caret_p = show_caret_p;
|
||||
}
|
||||
|
||||
if (idx == 0)
|
||||
/* Mark any cached value here as dirty. */
|
||||
@@ -2114,10 +2128,7 @@ rich_location::add_fixit_insert (source_location where,
|
||||
|
||||
if (reject_impossible_fixit (where))
|
||||
return;
|
||||
|
||||
linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
|
||||
m_fixit_hints[m_num_fixit_hints++]
|
||||
= new fixit_insert (where, new_content);
|
||||
add_fixit (new fixit_insert (where, new_content));
|
||||
}
|
||||
|
||||
/* Methods for adding removal fix-it hints. */
|
||||
@@ -2217,8 +2228,6 @@ void
|
||||
rich_location::add_fixit_replace (source_range src_range,
|
||||
const char *new_content)
|
||||
{
|
||||
linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
|
||||
|
||||
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);
|
||||
|
||||
@@ -2229,14 +2238,11 @@ rich_location::add_fixit_replace (source_range src_range,
|
||||
|
||||
/* Consolidate neighboring fixits. */
|
||||
fixit_hint *prev = get_last_fixit_hint ();
|
||||
if (m_num_fixit_hints > 0)
|
||||
{
|
||||
if (prev->maybe_append_replace (m_line_table, src_range, new_content))
|
||||
return;
|
||||
}
|
||||
if (prev)
|
||||
if (prev->maybe_append_replace (m_line_table, src_range, new_content))
|
||||
return;
|
||||
|
||||
m_fixit_hints[m_num_fixit_hints++]
|
||||
= new fixit_replace (src_range, new_content);
|
||||
add_fixit (new fixit_replace (src_range, new_content));
|
||||
}
|
||||
|
||||
/* Get the last fix-it hint within this rich_location, or NULL if none. */
|
||||
@@ -2244,8 +2250,8 @@ rich_location::add_fixit_replace (source_range src_range,
|
||||
fixit_hint *
|
||||
rich_location::get_last_fixit_hint () const
|
||||
{
|
||||
if (m_num_fixit_hints > 0)
|
||||
return m_fixit_hints[m_num_fixit_hints - 1];
|
||||
if (m_fixit_hints.count () > 0)
|
||||
return get_fixit_hint (m_fixit_hints.count () - 1);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -2275,13 +2281,21 @@ rich_location::reject_impossible_fixit (source_location where)
|
||||
m_seen_impossible_fixit = true;
|
||||
|
||||
/* Purge the rich_location of any fix-its that were already added. */
|
||||
for (unsigned int i = 0; i < m_num_fixit_hints; i++)
|
||||
delete m_fixit_hints[i];
|
||||
m_num_fixit_hints = 0;
|
||||
for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
|
||||
delete get_fixit_hint (i);
|
||||
m_fixit_hints.truncate (0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Add HINT to the fix-it hints in this rich_location. */
|
||||
|
||||
void
|
||||
rich_location::add_fixit (fixit_hint *hint)
|
||||
{
|
||||
m_fixit_hints.push (hint);
|
||||
}
|
||||
|
||||
/* class fixit_insert. */
|
||||
|
||||
fixit_insert::fixit_insert (source_location where,
|
||||
|
||||
Reference in New Issue
Block a user