aboutsummaryrefslogtreecommitdiff
path: root/libcpp/line-map.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcpp/line-map.c')
-rw-r--r--libcpp/line-map.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 3d82e9bfca9..3c19f93b7a5 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -1712,6 +1712,9 @@ linemap_get_statistics (struct line_maps *set,
s->macro_maps_used_size = macro_maps_used_size;
s->duplicated_macro_maps_locations_size =
duplicated_macro_maps_locations_size;
+ s->adhoc_table_size = (set->location_adhoc_data_map.allocated
+ * sizeof (struct location_adhoc_data));
+ s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
}
@@ -1752,3 +1755,133 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
fprintf (stream, "\n");
}
}
+
+/* class rich_location. */
+
+/* Construct a rich_location with location LOC as its initial range. */
+
+rich_location::rich_location (source_location loc) :
+ m_loc (loc),
+ m_num_ranges (0),
+ m_have_expanded_location (false)
+{
+ /* Set up the 0th range: */
+ add_range (loc, loc, true);
+ m_ranges[0].m_caret = lazily_expand_location ();
+}
+
+/* Construct a rich_location with source_range SRC_RANGE as its
+ initial range. */
+
+rich_location::rich_location (source_range src_range)
+: m_loc (src_range.m_start),
+ m_num_ranges (0),
+ m_have_expanded_location (false)
+{
+ /* Set up the 0th range: */
+ add_range (src_range, true);
+}
+
+/* Get an expanded_location for this rich_location's primary
+ location. */
+
+expanded_location
+rich_location::lazily_expand_location ()
+{
+ if (!m_have_expanded_location)
+ {
+ m_expanded_location
+ = linemap_client_expand_location_to_spelling_point (m_loc);
+ m_have_expanded_location = true;
+ }
+
+ return m_expanded_location;
+}
+
+/* Set the column of the primary location. */
+
+void
+rich_location::override_column (int column)
+{
+ lazily_expand_location ();
+ m_expanded_location.column = column;
+}
+
+/* Add the given range. */
+
+void
+rich_location::add_range (source_location start, source_location finish,
+ bool show_caret_p)
+{
+ linemap_assert (m_num_ranges < MAX_RANGES);
+
+ location_range *range = &m_ranges[m_num_ranges++];
+ range->m_start = linemap_client_expand_location_to_spelling_point (start);
+ range->m_finish = linemap_client_expand_location_to_spelling_point (finish);
+ range->m_caret = range->m_start;
+ range->m_show_caret_p = show_caret_p;
+}
+
+/* Add the given range. */
+
+void
+rich_location::add_range (source_range src_range, bool show_caret_p)
+{
+ linemap_assert (m_num_ranges < MAX_RANGES);
+
+ add_range (src_range.m_start, src_range.m_finish, show_caret_p);
+}
+
+void
+rich_location::add_range (location_range *src_range)
+{
+ linemap_assert (m_num_ranges < MAX_RANGES);
+
+ m_ranges[m_num_ranges++] = *src_range;
+}
+
+/* Add or overwrite the range given by IDX. It must either
+ overwrite an existing range, or add one *exactly* on the end of
+ the array.
+
+ This is primarily for use by gcc when implementing diagnostic
+ format decoders e.g. the "+" in the C/C++ frontends, for handling
+ format codes like "%q+D" (which writes the source location of a
+ tree back into range 0 of the rich_location).
+
+ If SHOW_CARET_P is true, then the range should be rendered with
+ a caret at its starting location. This
+ is for use by the Fortran frontend, for implementing the
+ "%C" and "%L" format codes. */
+
+void
+rich_location::set_range (unsigned int idx, source_range src_range,
+ bool show_caret_p, bool overwrite_loc_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);
+
+ location_range *locrange = &m_ranges[idx];
+ locrange->m_start
+ = linemap_client_expand_location_to_spelling_point (src_range.m_start);
+ locrange->m_finish
+ = linemap_client_expand_location_to_spelling_point (src_range.m_finish);
+
+ locrange->m_show_caret_p = show_caret_p;
+ if (overwrite_loc_p)
+ locrange->m_caret = locrange->m_start;
+
+ /* Are we adding a range onto the end? */
+ if (idx == m_num_ranges)
+ m_num_ranges = idx + 1;
+
+ if (idx == 0 && overwrite_loc_p)
+ {
+ m_loc = src_range.m_start;
+ /* Mark any cached value here as dirty. */
+ m_have_expanded_location = false;
+ }
+}