Support for 64-bit location_t: libcpp preliminaries

Prepare libcpp to support 64-bit location_t, without yet making
any functional changes, by adding new typedefs that enable code to be
written such that it works with any size location_t. Update the usage of
line maps within libcpp accordingly.

Subsequent patches will prepare the rest of the codebase similarly, and then
afterwards, location_t will be changed to uint64_t.

libcpp/ChangeLog:

	* include/line-map.h (line_map_uint_t): New typedef, the same type
	as location_t.
	(location_diff_t): New typedef.
	(line_map_suggested_range_bits): New constant.
	(struct maps_info_ordinary): Change member types from "unsigned int"
	to "line_map_uint_t".
	(struct maps_info_macro): Likewise.
	(struct location_adhoc_data_map): Likewise.
	(LINEMAPS_ALLOCATED): Change return type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_ALLOCATED): Likewise.
	(LINEMAPS_MACRO_ALLOCATED): Likewise.
	(LINEMAPS_USED): Likewise.
	(LINEMAPS_ORDINARY_USED): Likewise.
	(LINEMAPS_MACRO_USED): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(LINEMAPS_MAP_AT): Change argument type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_MAP_AT): Likewise.
	(LINEMAPS_MACRO_MAP_AT): Likewise.
	(line_map_new_raw): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_dump): Likewise.
	(line_table_dump): Likewise.
	(LINEMAPS_LAST_MAP): Add a linemap_assert() for safety.
	(SOURCE_COLUMN): Use a cast to ensure correctness if location_t
	becomes a 64-bit type.
	* line-map.cc (location_adhoc_data_hash): Don't truncate to 32-bit
	prematurely when hashing.
	(line_maps::get_or_create_combined_loc): Adapt types to support
	potentially 64-bit location_t. Use MAX_LOCATION_T rather than a
	hard-coded constant.
	(line_maps::get_range_from_loc): Adapt types and constants to
	support potentially 64-bit location_t.
	(line_maps::pure_location_p): Likewise.
	(line_maps::get_pure_location): Likewise.
	(line_map_new_raw): Likewise.
	(LAST_SOURCE_LINE_LOCATION): Likewise.
	(linemap_add): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_line_start): Likewise.
	(linemap_position_for_column): Likewise.
	(linemap_position_for_line_and_column): Likewise.
	(linemap_position_for_loc_and_offset): Likewise.
	(linemap_ordinary_map_lookup): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(linemap_dump): Likewise.
	(linemap_dump_location): Likewise.
	(linemap_get_file_highest_location): Likewise.
	(line_table_dump): Likewise.
	(linemap_compare_locations): Avoid signed int overflow in the result.
	* macro.cc (num_expanded_macros_counter): Change type of global
	variable from "unsigned int" to "line_map_uint_t".
	(num_macro_tokens_counter): Likewise.
This commit is contained in:
Lewis Hyatt
2024-10-28 13:19:40 -04:00
committed by Lewis Hyatt
parent fd118f4c54
commit 927625d007
3 changed files with 129 additions and 98 deletions

View File

@@ -87,9 +87,9 @@ enum lc_reason
gcc there is a single line_maps instance: "line_table", declared in gcc there is a single line_maps instance: "line_table", declared in
gcc/input.h and defined in gcc/input.cc. gcc/input.h and defined in gcc/input.cc.
The values of the keys are intended to be internal to libcpp, The values of the keys are intended to be internal to libcpp, but for
but for ease-of-understanding the implementation, they are currently ease-of-understanding the implementation, they are currently assigned as
assigned as follows: follows in the case of 32-bit location_t:
Actual | Value | Meaning Actual | Value | Meaning
-----------+-------------------------------+------------------------------- -----------+-------------------------------+-------------------------------
@@ -292,6 +292,12 @@ enum lc_reason
To further see how location_t works in practice, see the To further see how location_t works in practice, see the
worked example in libcpp/location-example.txt. */ worked example in libcpp/location-example.txt. */
typedef unsigned int location_t; typedef unsigned int location_t;
typedef int64_t location_diff_t;
/* Sometimes we need a type that has the same size as location_t but that does
not represent a location. This typedef provides more clarity in those
cases. */
typedef location_t line_map_uint_t;
/* Do not track column numbers higher than this one. As a result, the /* Do not track column numbers higher than this one. As a result, the
range of column_bits is [12, 18] (or 0 if column numbers are range of column_bits is [12, 18] (or 0 if column numbers are
@@ -311,6 +317,10 @@ const location_t LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
/* Highest possible source location encoded within an ordinary map. */ /* Highest possible source location encoded within an ordinary map. */
const location_t LINE_MAP_MAX_LOCATION = 0x70000000; const location_t LINE_MAP_MAX_LOCATION = 0x70000000;
/* This is the number of range bits suggested to enable, if range tracking is
desired. */
const int line_map_suggested_range_bits = 5;
/* A range of source locations. /* A range of source locations.
Ranges are closed: Ranges are closed:
@@ -728,15 +738,15 @@ struct GTY(()) maps_info_ordinary {
line_map_ordinary * GTY ((length ("%h.used"))) maps; line_map_ordinary * GTY ((length ("%h.used"))) maps;
/* The total number of allocated maps. */ /* The total number of allocated maps. */
unsigned int allocated; line_map_uint_t allocated;
/* The number of elements used in maps. This number is smaller /* The number of elements used in maps. This number is smaller
or equal to ALLOCATED. */ or equal to ALLOCATED. */
unsigned int used; line_map_uint_t used;
/* The index of the last ordinary map that was looked up with /* The index of the last ordinary map that was looked up with
linemap_lookup. */ linemap_lookup. */
mutable unsigned int m_cache; mutable line_map_uint_t m_cache;
}; };
struct GTY(()) maps_info_macro { struct GTY(()) maps_info_macro {
@@ -745,15 +755,15 @@ struct GTY(()) maps_info_macro {
line_map_macro * GTY ((length ("%h.used"))) maps; line_map_macro * GTY ((length ("%h.used"))) maps;
/* The total number of allocated maps. */ /* The total number of allocated maps. */
unsigned int allocated; line_map_uint_t allocated;
/* The number of elements used in maps. This number is smaller /* The number of elements used in maps. This number is smaller
or equal to ALLOCATED. */ or equal to ALLOCATED. */
unsigned int used; line_map_uint_t used;
/* The index of the last macro map that was looked up with /* The index of the last macro map that was looked up with
linemap_lookup. */ linemap_lookup. */
mutable unsigned int m_cache; mutable line_map_uint_t m_cache;
}; };
/* Data structure to associate a source_range together with an arbitrary /* Data structure to associate a source_range together with an arbitrary
@@ -780,7 +790,7 @@ struct htab;
struct GTY(()) location_adhoc_data_map { struct GTY(()) location_adhoc_data_map {
struct htab * GTY((skip)) htab; struct htab * GTY((skip)) htab;
location_t curr_loc; location_t curr_loc;
unsigned int allocated; line_map_uint_t allocated;
struct location_adhoc_data GTY((length ("%h.allocated"))) *data; struct location_adhoc_data GTY((length ("%h.allocated"))) *data;
}; };
@@ -861,13 +871,13 @@ public:
/* The default value of range_bits in ordinary line maps. */ /* The default value of range_bits in ordinary line maps. */
unsigned int default_range_bits; unsigned int default_range_bits;
unsigned int m_num_optimized_ranges; line_map_uint_t m_num_optimized_ranges;
unsigned int m_num_unoptimized_ranges; line_map_uint_t m_num_unoptimized_ranges;
}; };
/* Returns the number of allocated maps so far. MAP_KIND shall be TRUE /* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
if we are interested in macro maps, FALSE otherwise. */ if we are interested in macro maps, FALSE otherwise. */
inline unsigned int inline line_map_uint_t
LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind) LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
{ {
if (map_kind) if (map_kind)
@@ -878,7 +888,7 @@ LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
/* As above, but by reference (e.g. as an lvalue). */ /* As above, but by reference (e.g. as an lvalue). */
inline unsigned int & inline line_map_uint_t &
LINEMAPS_ALLOCATED (line_maps *set, bool map_kind) LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
{ {
if (map_kind) if (map_kind)
@@ -889,7 +899,7 @@ LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
/* Returns the number of used maps so far. MAP_KIND shall be TRUE if /* Returns the number of used maps so far. MAP_KIND shall be TRUE if
we are interested in macro maps, FALSE otherwise.*/ we are interested in macro maps, FALSE otherwise.*/
inline unsigned int inline line_map_uint_t
LINEMAPS_USED (const line_maps *set, bool map_kind) LINEMAPS_USED (const line_maps *set, bool map_kind)
{ {
if (map_kind) if (map_kind)
@@ -900,7 +910,7 @@ LINEMAPS_USED (const line_maps *set, bool map_kind)
/* As above, but by reference (e.g. as an lvalue). */ /* As above, but by reference (e.g. as an lvalue). */
inline unsigned int & inline line_map_uint_t &
LINEMAPS_USED (line_maps *set, bool map_kind) LINEMAPS_USED (line_maps *set, bool map_kind)
{ {
if (map_kind) if (map_kind)
@@ -911,7 +921,7 @@ LINEMAPS_USED (line_maps *set, bool map_kind)
/* Return the map at a given index. */ /* Return the map at a given index. */
inline line_map * inline line_map *
LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index) LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, line_map_uint_t index)
{ {
if (map_kind) if (map_kind)
return &set->info_macro.maps[index]; return &set->info_macro.maps[index];
@@ -925,29 +935,29 @@ LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index)
inline line_map * inline line_map *
LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind) LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind)
{ {
linemap_assert (LINEMAPS_USED (set, map_kind));
return LINEMAPS_MAP_AT (set, map_kind, return LINEMAPS_MAP_AT (set, map_kind,
LINEMAPS_USED (set, map_kind) - 1); LINEMAPS_USED (set, map_kind) - 1);
} }
/* Returns the INDEXth ordinary map. */ /* Returns the INDEXth ordinary map. */
inline line_map_ordinary * inline line_map_ordinary *
LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index) LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, line_map_uint_t index)
{ {
linemap_assert (index >= 0 linemap_assert (index < LINEMAPS_USED (set, false));
&& (unsigned int)index < LINEMAPS_USED (set, false));
return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index); return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index);
} }
/* Return the number of ordinary maps allocated in the line table /* Return the number of ordinary maps allocated in the line table
SET. */ SET. */
inline unsigned int inline line_map_uint_t
LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set) LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set)
{ {
return LINEMAPS_ALLOCATED (set, false); return LINEMAPS_ALLOCATED (set, false);
} }
/* Return the number of ordinary maps used in the line table SET. */ /* Return the number of ordinary maps used in the line table SET. */
inline unsigned int inline line_map_uint_t
LINEMAPS_ORDINARY_USED (const line_maps *set) LINEMAPS_ORDINARY_USED (const line_maps *set)
{ {
return LINEMAPS_USED (set, false); return LINEMAPS_USED (set, false);
@@ -963,23 +973,22 @@ LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set)
/* Returns the INDEXth macro map. */ /* Returns the INDEXth macro map. */
inline line_map_macro * inline line_map_macro *
LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index) LINEMAPS_MACRO_MAP_AT (const line_maps *set, line_map_uint_t index)
{ {
linemap_assert (index >= 0 linemap_assert (index < LINEMAPS_USED (set, true));
&& (unsigned int)index < LINEMAPS_USED (set, true));
return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index); return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index);
} }
/* Returns the number of macro maps that were allocated in the line /* Returns the number of macro maps that were allocated in the line
table SET. */ table SET. */
inline unsigned int inline line_map_uint_t
LINEMAPS_MACRO_ALLOCATED (const line_maps *set) LINEMAPS_MACRO_ALLOCATED (const line_maps *set)
{ {
return LINEMAPS_ALLOCATED (set, true); return LINEMAPS_ALLOCATED (set, true);
} }
/* Returns the number of macro maps used in the line table SET. */ /* Returns the number of macro maps used in the line table SET. */
inline unsigned int inline line_map_uint_t
LINEMAPS_MACRO_USED (const line_maps *set) LINEMAPS_MACRO_USED (const line_maps *set)
{ {
return LINEMAPS_USED (set, true); return LINEMAPS_USED (set, true);
@@ -1044,7 +1053,7 @@ extern location_t linemap_line_start
(class line_maps *set, linenum_type to_line, unsigned int max_column_hint); (class line_maps *set, linenum_type to_line, unsigned int max_column_hint);
/* Allocate a raw block of line maps, zero initialized. */ /* Allocate a raw block of line maps, zero initialized. */
extern line_map *line_map_new_raw (line_maps *, bool, unsigned); extern line_map *line_map_new_raw (line_maps *, bool, line_map_uint_t);
/* Add a mapping of logical source line to physical source file and /* Add a mapping of logical source line to physical source file and
line number. This function creates an "ordinary map", which is a line number. This function creates an "ordinary map", which is a
@@ -1094,8 +1103,8 @@ extern void linemap_module_reparent
/* Restore the linemap state such that the map at LWM-1 continues. /* Restore the linemap state such that the map at LWM-1 continues.
Return start location of the new map. */ Return start location of the new map. */
extern unsigned linemap_module_restore extern location_t linemap_module_restore
(line_maps *, unsigned lwm); (line_maps *, line_map_uint_t lwm);
/* Given a logical source location, returns the map which the /* Given a logical source location, returns the map which the
corresponding (source file, line, column) triplet can be deduced corresponding (source file, line, column) triplet can be deduced
@@ -1106,7 +1115,7 @@ extern unsigned linemap_module_restore
extern const line_map *linemap_lookup extern const line_map *linemap_lookup
(const line_maps *, location_t); (const line_maps *, location_t);
unsigned linemap_lookup_macro_index (const line_maps *, location_t); line_map_uint_t linemap_lookup_macro_index (const line_maps *, location_t);
/* Returns TRUE if the line table set tracks token locations across /* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */ macro expansion, FALSE otherwise. */
@@ -1165,7 +1174,8 @@ inline linenum_type
SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc) SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc)
{ {
return ((loc - ord_map->start_location) return ((loc - ord_map->start_location)
& ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits; & ((location_t (1) << ord_map->m_column_and_range_bits) - 1))
>> ord_map->m_range_bits;
} }
@@ -1244,7 +1254,8 @@ const struct line_map *first_map_in_common (const line_maps *set,
comes before the token of POST, 0 if PRE denotes the location of comes before the token of POST, 0 if PRE denotes the location of
the same token as the token for POST, and a negative value the same token as the token for POST, and a negative value
otherwise. */ otherwise. */
int linemap_compare_locations (const line_maps *set, int
linemap_compare_locations (const line_maps *set,
location_t pre, location_t pre,
location_t post); location_t post);
@@ -1413,12 +1424,13 @@ void linemap_dump_location (const line_maps *, location_t, FILE *);
/* Dump line map at index IX in line table SET to STREAM. If STREAM /* Dump line map at index IX in line table SET to STREAM. If STREAM
is NULL, use stderr. IS_MACRO is true if the caller wants to is NULL, use stderr. IS_MACRO is true if the caller wants to
dump a macro map, false otherwise. */ dump a macro map, false otherwise. */
void linemap_dump (FILE *, const line_maps *, unsigned, bool); void linemap_dump (FILE *, const line_maps *, line_map_uint_t, bool);
/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used. /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
specifies how many macro maps to dump. */ specifies how many macro maps to dump. */
void line_table_dump (FILE *, const line_maps *, unsigned int, unsigned int); void line_table_dump (FILE *, const line_maps *,
line_map_uint_t, line_map_uint_t);
/* An enum for distinguishing the various parts within a location_t. */ /* An enum for distinguishing the various parts within a location_t. */

View File

@@ -26,6 +26,9 @@ along with this program; see the file COPYING3. If not see
#include "internal.h" #include "internal.h"
#include "hashtab.h" #include "hashtab.h"
/* Useful for the bit manipulations in this file. */
static constexpr location_t loc_one = 1;
static void trace_include (const line_maps *, const line_map_ordinary *); static void trace_include (const line_maps *, const line_map_ordinary *);
static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps *, static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps *,
location_t); location_t);
@@ -45,8 +48,8 @@ static location_t linemap_macro_loc_to_exp_point (const line_maps *,
const line_map_ordinary **); const line_map_ordinary **);
/* Counters defined in macro.cc. */ /* Counters defined in macro.cc. */
extern unsigned num_expanded_macros_counter; extern line_map_uint_t num_expanded_macros_counter;
extern unsigned num_macro_tokens_counter; extern line_map_uint_t num_macro_tokens_counter;
/* Destructor for class line_maps. /* Destructor for class line_maps.
Ensure non-GC-managed memory is released. */ Ensure non-GC-managed memory is released. */
@@ -64,11 +67,11 @@ location_adhoc_data_hash (const void *l)
{ {
const struct location_adhoc_data *lb = const struct location_adhoc_data *lb =
(const struct location_adhoc_data *) l; (const struct location_adhoc_data *) l;
return ((hashval_t) lb->locus return lb->locus
+ (hashval_t) lb->src_range.m_start + lb->src_range.m_start
+ (hashval_t) lb->src_range.m_finish + lb->src_range.m_finish
+ (size_t) lb->data + (size_t) lb->data
+ lb->discriminator); + lb->discriminator;
} }
/* Compare function for location_adhoc_data hashtable. */ /* Compare function for location_adhoc_data hashtable. */
@@ -197,9 +200,9 @@ line_maps::get_or_create_combined_loc (location_t locus,
linemap_assert (pure_location_p (locus)); linemap_assert (pure_location_p (locus));
const line_map *map = linemap_lookup (this, locus); const line_map *map = linemap_lookup (this, locus);
const line_map_ordinary *ordmap = linemap_check_ordinary (map); const line_map_ordinary *ordmap = linemap_check_ordinary (map);
unsigned int int_diff = src_range.m_finish - src_range.m_start; auto int_diff = src_range.m_finish - src_range.m_start;
unsigned int col_diff = (int_diff >> ordmap->m_range_bits); auto col_diff = (int_diff >> ordmap->m_range_bits);
if (col_diff < (1U << ordmap->m_range_bits)) if (col_diff < (loc_one << ordmap->m_range_bits))
{ {
location_t packed = locus | col_diff; location_t packed = locus | col_diff;
m_num_optimized_ranges++; m_num_optimized_ranges++;
@@ -255,7 +258,7 @@ line_maps::get_or_create_combined_loc (location_t locus,
m_location_adhoc_data_map.data[m_location_adhoc_data_map.curr_loc++] m_location_adhoc_data_map.data[m_location_adhoc_data_map.curr_loc++]
= lb; = lb;
} }
return ((*slot) - m_location_adhoc_data_map.data) | 0x80000000; return ((*slot) - m_location_adhoc_data_map.data) | (1 + MAX_LOCATION_T);
} }
/* Construct a location with caret at CARET, ranging from START to /* Construct a location with caret at CARET, ranging from START to
@@ -339,7 +342,7 @@ line_maps::get_range_from_loc (location_t loc) const
const line_map *map = linemap_lookup (this, loc); const line_map *map = linemap_lookup (this, loc);
const line_map_ordinary *ordmap = linemap_check_ordinary (map); const line_map_ordinary *ordmap = linemap_check_ordinary (map);
source_range result; source_range result;
int offset = loc & ((1 << ordmap->m_range_bits) - 1); auto offset = loc & ((loc_one << ordmap->m_range_bits) - 1);
result.m_start = loc - offset; result.m_start = loc - offset;
result.m_finish = result.m_start + (offset << ordmap->m_range_bits); result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
return result; return result;
@@ -378,7 +381,7 @@ line_maps::pure_location_p (location_t loc) const
return true; return true;
const line_map_ordinary *ordmap = linemap_check_ordinary (map); const line_map_ordinary *ordmap = linemap_check_ordinary (map);
if (loc & ((1U << ordmap->m_range_bits) - 1)) if (loc & ((loc_one << ordmap->m_range_bits) - 1))
return false; return false;
return true; return true;
@@ -408,7 +411,7 @@ line_maps::get_pure_location (location_t loc) const
const line_map *map = linemap_lookup (this, loc); const line_map *map = linemap_lookup (this, loc);
const line_map_ordinary *ordmap = linemap_check_ordinary (map); const line_map_ordinary *ordmap = linemap_check_ordinary (map);
return loc & ~((1 << ordmap->m_range_bits) - 1); return loc & ~((loc_one << ordmap->m_range_bits) - 1);
} }
location_t location_t
@@ -464,10 +467,10 @@ linemap_check_files_exited (const line_maps *set)
/* Create NUM zero-initialized maps of type MACRO_P. */ /* Create NUM zero-initialized maps of type MACRO_P. */
line_map * line_map *
line_map_new_raw (line_maps *set, bool macro_p, unsigned num) line_map_new_raw (line_maps *set, bool macro_p, line_map_uint_t num)
{ {
unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p); auto num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
unsigned num_maps_used = LINEMAPS_USED (set, macro_p); auto num_maps_used = LINEMAPS_USED (set, macro_p);
if (num > num_maps_allocated - num_maps_used) if (num > num_maps_allocated - num_maps_used)
{ {
@@ -504,7 +507,7 @@ line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
/* Now alloc_size contains the exact memory size we would get if /* Now alloc_size contains the exact memory size we would get if
we have asked for the initial alloc_size amount of memory. we have asked for the initial alloc_size amount of memory.
Let's get back to the number of map that amounts to. */ Let's get back to the number of map that amounts to. */
unsigned num_maps = alloc_size / size_of_a_map; line_map_uint_t num_maps = alloc_size / size_of_a_map;
buffer = set->m_reallocator (buffer, num_maps * size_of_a_map); buffer = set->m_reallocator (buffer, num_maps * size_of_a_map);
memset ((char *)buffer + num_maps_used * size_of_a_map, 0, memset ((char *)buffer + num_maps_used * size_of_a_map, 0,
(num_maps - num_maps_used) * size_of_a_map); (num_maps - num_maps_used) * size_of_a_map);
@@ -546,7 +549,7 @@ LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
{ {
return (((map[1].start_location - 1 return (((map[1].start_location - 1
- map->start_location) - map->start_location)
& ~((1 << map->m_column_and_range_bits) - 1)) & ~((loc_one << map->m_column_and_range_bits) - 1))
+ map->start_location); + map->start_location);
} }
@@ -573,8 +576,8 @@ linemap_add (line_maps *set, enum lc_reason reason,
unsigned range_bits = 0; unsigned range_bits = 0;
if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS) if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
range_bits = set->default_range_bits; range_bits = set->default_range_bits;
start_location += (1 << range_bits) - 1; start_location += (loc_one << range_bits) - 1;
start_location &= ~((1 << range_bits) - 1); start_location &= ~((loc_one << range_bits) - 1);
linemap_assert (!LINEMAPS_ORDINARY_USED (set) linemap_assert (!LINEMAPS_ORDINARY_USED (set)
|| (start_location || (start_location
@@ -660,7 +663,7 @@ linemap_add (line_maps *set, enum lc_reason reason,
/* The location of the end of the just-closed map. */ /* The location of the end of the just-closed map. */
map->included_from map->included_from
= (((map[0].start_location - 1 - map[-1].start_location) = (((map[0].start_location - 1 - map[-1].start_location)
& ~((1 << map[-1].m_column_and_range_bits) - 1)) & ~((loc_one << map[-1].m_column_and_range_bits) - 1))
+ map[-1].start_location); + map[-1].start_location);
set->depth++; set->depth++;
if (set->trace_includes) if (set->trace_includes)
@@ -707,8 +710,8 @@ linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
Append a new map, continuing the interrupted one. Return the start location 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. */ of the new map, or 0 if failed (because we ran out of locations. */
unsigned location_t
linemap_module_restore (line_maps *set, unsigned lwm) linemap_module_restore (line_maps *set, line_map_uint_t lwm)
{ {
linemap_assert (lwm); linemap_assert (lwm);
@@ -847,7 +850,7 @@ linemap_line_start (line_maps *set, linenum_type to_line,
location_t r; location_t r;
linenum_type last_line = linenum_type last_line =
SOURCE_LINE (map, set->highest_line); SOURCE_LINE (map, set->highest_line);
int line_delta = to_line - last_line; auto line_delta = (linenum_arith_t) to_line - (linenum_arith_t) last_line;
bool add_map = false; bool add_map = false;
linemap_assert (map->m_column_and_range_bits >= map->m_range_bits); linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits; int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
@@ -897,7 +900,8 @@ linemap_line_start (line_maps *set, linenum_type to_line,
single line we can sometimes just increase its column_bits instead. */ single line we can sometimes just increase its column_bits instead. */
if (line_delta < 0 if (line_delta < 0
|| last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
|| SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits)) || SOURCE_COLUMN (map, highest) >= (loc_one
<< (column_bits - range_bits))
|| ( /* We can't reuse the map if the line offset is sufficiently || ( /* We can't reuse the map if the line offset is sufficiently
large to cause overflow when computing location_t values. */ large to cause overflow when computing location_t values. */
(to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
@@ -913,11 +917,12 @@ linemap_line_start (line_maps *set, linenum_type to_line,
map->m_column_and_range_bits = column_bits; map->m_column_and_range_bits = column_bits;
map->m_range_bits = range_bits; map->m_range_bits = range_bits;
r = (MAP_START_LOCATION (map) r = (MAP_START_LOCATION (map)
+ ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) + (location_t (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
<< column_bits)); << column_bits));
} }
else else
r = set->highest_line + (line_delta << map->m_column_and_range_bits); r = set->highest_line + (location_t (line_delta)
<< map->m_column_and_range_bits);
/* Locations of ordinary tokens are always lower than locations of /* Locations of ordinary tokens are always lower than locations of
macro tokens. */ macro tokens. */
@@ -992,7 +997,7 @@ linemap_position_for_column (line_maps *set, unsigned int to_column)
} }
} }
line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set); line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
r = r + (to_column << map->m_range_bits); r = r + (location_t (to_column) << map->m_range_bits);
if (r >= set->highest_location) if (r >= set->highest_location)
set->highest_location = r; set->highest_location = r;
return r; return r;
@@ -1010,10 +1015,10 @@ linemap_position_for_line_and_column (line_maps *set,
linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line); linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
location_t r = MAP_START_LOCATION (ord_map); location_t r = MAP_START_LOCATION (ord_map);
r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map)) r += (location_t (line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
<< ord_map->m_column_and_range_bits); << ord_map->m_column_and_range_bits);
if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS) if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1)) r += ((column & ((loc_one << ord_map->m_column_and_range_bits) - 1))
<< ord_map->m_range_bits); << ord_map->m_range_bits);
location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set); location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
if (r >= upper_limit) if (r >= upper_limit)
@@ -1050,10 +1055,12 @@ linemap_position_for_loc_and_offset (line_maps *set,
/* We find the real location and shift it. */ /* We find the real location and shift it. */
loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map); loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
auto shifted_offset = location_t (column_offset) << map->m_range_bits;
/* The new location (loc + offset) should be higher than the first /* The new location (loc + offset) should be higher than the first
location encoded by MAP. This can fail if the line information location encoded by MAP. This can fail if the line information
is messed up because of line directives (see PR66415). */ is messed up because of line directives (see PR66415). */
if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits)) if (MAP_START_LOCATION (map) >= loc + shifted_offset)
return loc; return loc;
linenum_type line = SOURCE_LINE (map, loc); linenum_type line = SOURCE_LINE (map, loc);
@@ -1064,8 +1071,7 @@ linemap_position_for_loc_and_offset (line_maps *set,
the next line map of the set. Otherwise, we try to encode the the next line map of the set. Otherwise, we try to encode the
location in the next map. */ location in the next map. */
for (; map != LINEMAPS_LAST_ORDINARY_MAP (set) for (; map != LINEMAPS_LAST_ORDINARY_MAP (set)
&& (loc + (column_offset << map->m_range_bits) && loc + shifted_offset >= MAP_START_LOCATION (map + 1); map++)
>= MAP_START_LOCATION (map + 1)); map++)
/* If the next map is a different file, or starts in a higher line, we /* If the next map is a different file, or starts in a higher line, we
cannot encode the location there. */ cannot encode the location there. */
if ((map + 1)->reason != LC_RENAME if ((map + 1)->reason != LC_RENAME
@@ -1116,8 +1122,8 @@ linemap_ordinary_map_lookup (const line_maps *set, location_t line)
if (set == NULL || line < RESERVED_LOCATION_COUNT) if (set == NULL || line < RESERVED_LOCATION_COUNT)
return NULL; return NULL;
unsigned mn = set->info_ordinary.m_cache; auto mn = set->info_ordinary.m_cache;
unsigned mx = LINEMAPS_ORDINARY_USED (set); auto mx = LINEMAPS_ORDINARY_USED (set);
const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn); const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
/* We should get a segfault if no line_maps have been added yet. */ /* We should get a segfault if no line_maps have been added yet. */
@@ -1134,7 +1140,7 @@ linemap_ordinary_map_lookup (const line_maps *set, location_t line)
while (mx - mn > 1) while (mx - mn > 1)
{ {
unsigned md = (mn + mx) / 2; auto md = (mn + mx) / 2;
if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line) if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
mx = md; mx = md;
else else
@@ -1163,18 +1169,18 @@ linemap_macro_map_lookup (const line_maps *set, location_t line)
if (set == NULL) if (set == NULL)
return NULL; return NULL;
unsigned ix = linemap_lookup_macro_index (set, line); auto ix = linemap_lookup_macro_index (set, line);
const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix); const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
linemap_assert (MAP_START_LOCATION (result) <= line); linemap_assert (MAP_START_LOCATION (result) <= line);
return result; return result;
} }
unsigned line_map_uint_t
linemap_lookup_macro_index (const line_maps *set, location_t line) linemap_lookup_macro_index (const line_maps *set, location_t line)
{ {
unsigned mn = set->info_macro.m_cache; auto mn = set->info_macro.m_cache;
unsigned mx = LINEMAPS_MACRO_USED (set); auto mx = LINEMAPS_MACRO_USED (set);
const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn); const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
if (line >= MAP_START_LOCATION (cached)) if (line >= MAP_START_LOCATION (cached))
@@ -1188,7 +1194,7 @@ linemap_lookup_macro_index (const line_maps *set, location_t line)
while (mn < mx) while (mn < mx)
{ {
unsigned md = (mx + mn) / 2; auto md = (mx + mn) / 2;
if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line) if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
mn = md + 1; mn = md + 1;
else else
@@ -1529,7 +1535,10 @@ linemap_compare_locations (const line_maps *set,
if (IS_ADHOC_LOC (l1)) if (IS_ADHOC_LOC (l1))
l1 = get_location_from_adhoc_loc (set, l1); l1 = get_location_from_adhoc_loc (set, l1);
return l1 - l0; /* This function is intended e.g. for implementing a qsort() comparator, so it
needs to return really an "int" and not something larger. */
const auto res = (location_diff_t)l1 - (location_diff_t)l0;
return res < INT_MIN ? INT_MIN : res > INT_MAX ? INT_MAX : res;
} }
/* Print an include trace, for e.g. the -H option of the preprocessor. */ /* Print an include trace, for e.g. the -H option of the preprocessor. */
@@ -1914,7 +1923,8 @@ linemap_expand_location (const line_maps *set,
dump a macro map, false otherwise. */ dump a macro map, false otherwise. */
void void
linemap_dump (FILE *stream, const line_maps *set, unsigned ix, bool is_macro) linemap_dump (FILE *stream, const line_maps *set, line_map_uint_t ix,
bool is_macro)
{ {
const char *const lc_reasons_v[LC_HWM] const char *const lc_reasons_v[LC_HWM]
= { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM", = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
@@ -1936,8 +1946,10 @@ linemap_dump (FILE *stream, const line_maps *set, unsigned ix, bool is_macro)
reason = LC_ENTER_MACRO; reason = LC_ENTER_MACRO;
} }
fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n", fprintf (stream, "Map #%llu [%p] - LOC: %llu - REASON: %s - SYSP: %s\n",
ix, (void *) map, map->start_location, (unsigned long long) ix,
(void *) map,
(unsigned long long) map->start_location,
reason < LC_HWM ? lc_reasons_v[reason] : "???", reason < LC_HWM ? lc_reasons_v[reason] : "???",
((!is_macro ((!is_macro
&& ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map))) && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
@@ -1948,10 +1960,12 @@ linemap_dump (FILE *stream, const line_maps *set, unsigned ix, bool is_macro)
const line_map_ordinary *includer_map const line_map_ordinary *includer_map
= linemap_included_from_linemap (set, ord_map); = linemap_included_from_linemap (set, ord_map);
fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map), fprintf (stream, "File: %s:%u\n", ORDINARY_MAP_FILE_NAME (ord_map),
ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map)); ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
fprintf (stream, "Included from: [%d] %s\n", const long long from_ind
includer_map ? int (includer_map - set->info_ordinary.maps) : -1, = includer_map ? includer_map - set->info_ordinary.maps : -1;
fprintf (stream, "Included from: [%lld] %s\n",
from_ind,
includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None"); includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
} }
else else
@@ -2010,8 +2024,10 @@ linemap_dump_location (const line_maps *set,
/* P: path, L: line, C: column, S: in-system-header, M: map address, /* P: path, L: line, C: column, S: in-system-header, M: map address,
E: macro expansion?, LOC: original location, R: resolved location */ E: macro expansion?, LOC: original location, R: resolved location */
fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}", fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%llu,R:%llu}",
path, from, l, c, s, (void*)map, e, loc, location); path, from, l, c, s, (void*)map, e,
(unsigned long long) loc,
(unsigned long long) location);
} }
/* Return the highest location emitted for a given file for which /* Return the highest location emitted for a given file for which
@@ -2030,7 +2046,7 @@ linemap_get_file_highest_location (const line_maps *set,
return false; return false;
/* Now look for the last ordinary map created for FILE_NAME. */ /* Now look for the last ordinary map created for FILE_NAME. */
int i; location_diff_t i;
for (i = set->info_ordinary.used - 1; i >= 0; --i) for (i = set->info_ordinary.used - 1; i >= 0; --i)
{ {
const char *fname = set->info_ordinary.maps[i].to_file; const char *fname = set->info_ordinary.maps[i].to_file;
@@ -2045,7 +2061,7 @@ linemap_get_file_highest_location (const line_maps *set,
location of the next map minus one, or -- if the map is the location of the next map minus one, or -- if the map is the
latest one -- the highest location of the set. */ latest one -- the highest location of the set. */
location_t result; location_t result;
if (i == (int) set->info_ordinary.used - 1) if ((location_t) i == set->info_ordinary.used - 1)
result = set->highest_location; result = set->highest_location;
else else
result = set->info_ordinary.maps[i + 1].start_location - 1; result = set->info_ordinary.maps[i + 1].start_location - 1;
@@ -2122,10 +2138,10 @@ linemap_get_statistics (const line_maps *set,
specifies how many macro maps to dump. */ specifies how many macro maps to dump. */
void void
line_table_dump (FILE *stream, const line_maps *set, unsigned int num_ordinary, line_table_dump (FILE *stream, const line_maps *set,
unsigned int num_macro) line_map_uint_t num_ordinary, line_map_uint_t num_macro)
{ {
unsigned int i; line_map_uint_t i;
if (set == NULL) if (set == NULL)
return; return;
@@ -2133,10 +2149,13 @@ line_table_dump (FILE *stream, const line_maps *set, unsigned int num_ordinary,
if (stream == NULL) if (stream == NULL)
stream = stderr; stream = stderr;
fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set)); fprintf (stream, "# of ordinary maps: %llu\n",
fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set)); (unsigned long long) LINEMAPS_ORDINARY_USED (set));
fprintf (stream, "# of macro maps: %llu\n",
(unsigned long long) LINEMAPS_MACRO_USED (set));
fprintf (stream, "Include stack depth: %d\n", set->depth); fprintf (stream, "Include stack depth: %d\n", set->depth);
fprintf (stream, "Highest location: %u\n", set->highest_location); fprintf (stream, "Highest location: %llu\n",
(unsigned long long) set->highest_location);
if (num_ordinary) if (num_ordinary)
{ {

View File

@@ -364,10 +364,10 @@ static cpp_hashnode* macro_of_context (cpp_context *context);
/* Statistical counter tracking the number of macros that got /* Statistical counter tracking the number of macros that got
expanded. */ expanded. */
unsigned num_expanded_macros_counter = 0; line_map_uint_t num_expanded_macros_counter = 0;
/* Statistical counter tracking the total number tokens resulting /* Statistical counter tracking the total number tokens resulting
from macro expansion. */ from macro expansion. */
unsigned num_macro_tokens_counter = 0; line_map_uint_t num_macro_tokens_counter = 0;
/* Wrapper around cpp_get_token to skip CPP_PADDING tokens /* Wrapper around cpp_get_token to skip CPP_PADDING tokens
and not consume CPP_EOF. */ and not consume CPP_EOF. */