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.c83
1 files changed, 49 insertions, 34 deletions
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index bbb6963..1a6902a 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -1,5 +1,5 @@
/* Map (unsigned int) keys to (source file, line, column) triples.
- Copyright (C) 2001-2020 Free Software Foundation, Inc.
+ Copyright (C) 2001-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -621,27 +621,32 @@ linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
}
/* A linemap at LWM-1 was interrupted to insert module locations & imports.
- Append a new map, continuing the interrupted one. */
+ Append a new map, continuing the interrupted one. Return the start location
+ of the new map, or 0 if failed (because we ran out of locations. */
-void
+unsigned
linemap_module_restore (line_maps *set, unsigned lwm)
{
- if (lwm && lwm != LINEMAPS_USED (set, false))
+ linemap_assert (lwm);
+
+ const line_map_ordinary *pre_map
+ = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
+ unsigned src_line = SOURCE_LINE (pre_map, LAST_SOURCE_LINE_LOCATION (pre_map));
+ location_t inc_at = pre_map->included_from;
+ if (const line_map_ordinary *post_map
+ = (linemap_check_ordinary
+ (linemap_add (set, LC_RENAME_VERBATIM,
+ ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
+ ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
{
- const line_map_ordinary *pre_map
- = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
- unsigned src_line = SOURCE_LINE (pre_map,
- LAST_SOURCE_LINE_LOCATION (pre_map));
- location_t inc_at = pre_map->included_from;
- if (const line_map_ordinary *post_map
- = (linemap_check_ordinary
- (linemap_add (set, LC_RENAME_VERBATIM,
- ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
- ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
- /* linemap_add will think we were included from the same as
- the preceeding map. */
- const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
+ /* linemap_add will think we were included from the same as the preceeding
+ map. */
+ const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
+
+ return post_map->start_location;
}
+
+ return 0;
}
/* Returns TRUE if the line table set tracks token locations across
@@ -976,16 +981,15 @@ linemap_position_for_loc_and_offset (line_maps *set,
(loc + offset) should be less than the first location encoded by
the next line map of the set. Otherwise, we try to encode the
location in the next map. */
- while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
+ for (; map != LINEMAPS_LAST_ORDINARY_MAP (set)
&& (loc + (column_offset << map->m_range_bits)
- >= MAP_START_LOCATION (&map[1])))
- {
- map = &map[1];
- /* If the next map starts in a higher line, we cannot encode the
- location there. */
- if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
- return loc;
- }
+ >= MAP_START_LOCATION (map + 1)); map++)
+ /* If the next map is a different file, or starts in a higher line, we
+ cannot encode the location there. */
+ if ((map + 1)->reason != LC_RENAME
+ || line < ORDINARY_MAP_STARTING_LINE_NUMBER (map + 1)
+ || 0 != strcmp (LINEMAP_FILE (map + 1), LINEMAP_FILE (map)))
+ return loc;
column += column_offset;
@@ -1316,7 +1320,7 @@ linemap_location_from_macro_expansion_p (const class line_maps *set,
if (IS_ADHOC_LOC (location))
location = get_location_from_adhoc_loc (set, location);
- return IS_MACRO_LOC (location);
+ return location >= LINEMAPS_MACRO_LOWEST_LOCATION (set);
}
/* Given two virtual locations *LOC0 and *LOC1, return the first
@@ -1422,17 +1426,20 @@ linemap_compare_locations (line_maps *set,
/* So pre and post represent two tokens that are present in a
same macro expansion. Let's see if the token for pre was
before the token for post in that expansion. */
- unsigned i0, i1;
const struct line_map *map =
first_map_in_common (set, pre, post, &l0, &l1);
if (map == NULL)
- /* This should not be possible. */
- abort ();
-
- i0 = l0 - MAP_START_LOCATION (map);
- i1 = l1 - MAP_START_LOCATION (map);
- return i1 - i0;
+ /* This should not be possible while we have column information, but if
+ we don't, the tokens could be from separate macro expansions on the
+ same line. */
+ gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS);
+ else
+ {
+ unsigned i0 = l0 - MAP_START_LOCATION (map);
+ unsigned i1 = l1 - MAP_START_LOCATION (map);
+ return i1 - i0;
+ }
}
if (IS_ADHOC_LOC (l0))
@@ -2425,6 +2432,14 @@ rich_location::maybe_add_fixit (location_t start,
stop_supporting_fixits ();
return;
}
+ /* If we have very long lines, tokens will eventually fall back to
+ having column == 0.
+ We can't handle fix-it hints that use such locations. */
+ if (exploc_start.column == 0 || exploc_next_loc.column == 0)
+ {
+ stop_supporting_fixits ();
+ return;
+ }
const char *newline = strchr (new_content, '\n');
if (newline)