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.c174
1 files changed, 172 insertions, 2 deletions
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 7c4e389..54da4bc 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -25,6 +25,7 @@ along with this program; see the file COPYING3. If not see
#include "line-map.h"
#include "cpplib.h"
#include "internal.h"
+#include "hashtab.h"
static void trace_include (const struct line_maps *, const struct line_map *);
static const struct line_map * linemap_ordinary_map_lookup (struct line_maps *,
@@ -50,6 +51,120 @@ static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
extern unsigned num_expanded_macros_counter;
extern unsigned num_macro_tokens_counter;
+/* Hash function for location_adhoc_data hashtable. */
+
+static hashval_t
+location_adhoc_data_hash (const void *l)
+{
+ const struct location_adhoc_data *lb =
+ (const struct location_adhoc_data *) l;
+ return (hashval_t) lb->locus + (size_t) &lb->data;
+}
+
+/* Compare function for location_adhoc_data hashtable. */
+
+static int
+location_adhoc_data_eq (const void *l1, const void *l2)
+{
+ const struct location_adhoc_data *lb1 =
+ (const struct location_adhoc_data *) l1;
+ const struct location_adhoc_data *lb2 =
+ (const struct location_adhoc_data *) l2;
+ return lb1->locus == lb2->locus && lb1->data == lb2->data;
+}
+
+/* Update the hashtable when location_adhoc_data is reallocated. */
+
+static int
+location_adhoc_data_update (void **slot, void *data)
+{
+ *((char **) slot) += *((long long *) data);
+ return 1;
+}
+
+/* Combine LOCUS and DATA to a combined adhoc loc. */
+
+source_location
+get_combined_adhoc_loc (struct line_maps *set,
+ source_location locus, void *data)
+{
+ struct location_adhoc_data lb;
+ struct location_adhoc_data **slot;
+
+ linemap_assert (data);
+
+ if (IS_ADHOC_LOC (locus))
+ locus =
+ set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
+ if (locus == 0 && data == NULL)
+ return 0;
+ lb.locus = locus;
+ lb.data = data;
+ slot = (struct location_adhoc_data **)
+ htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
+ if (*slot == NULL)
+ {
+ if (set->location_adhoc_data_map.curr_loc >=
+ set->location_adhoc_data_map.allocated)
+ {
+ char *orig_data = (char *) set->location_adhoc_data_map.data;
+ long long offset;
+ set->location_adhoc_data_map.allocated *= 2;
+ set->location_adhoc_data_map.data =
+ XRESIZEVEC (struct location_adhoc_data,
+ set->location_adhoc_data_map.data,
+ set->location_adhoc_data_map.allocated);
+ offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
+ htab_traverse (set->location_adhoc_data_map.htab,
+ location_adhoc_data_update, &offset);
+ }
+ *slot = set->location_adhoc_data_map.data
+ + set->location_adhoc_data_map.curr_loc;
+ set->location_adhoc_data_map.data[
+ set->location_adhoc_data_map.curr_loc++] = lb;
+ }
+ return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
+}
+
+/* Return the data for the adhoc loc. */
+
+void *
+get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
+}
+
+/* Return the location for the adhoc loc. */
+
+source_location
+get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+}
+
+/* Initialize the location_adhoc_data structure. */
+
+static void
+location_adhoc_data_init (struct line_maps *set)
+{
+ set->location_adhoc_data_map.htab =
+ htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
+ set->location_adhoc_data_map.curr_loc = 0;
+ set->location_adhoc_data_map.allocated = 100;
+ set->location_adhoc_data_map.data = XNEWVEC (struct location_adhoc_data, 100);
+}
+
+/* Finalize the location_adhoc_data structure. */
+void
+location_adhoc_data_fini (struct line_maps *set)
+{
+ set->location_adhoc_data_map.allocated = 0;
+ XDELETEVEC (set->location_adhoc_data_map.data);
+ htab_delete (set->location_adhoc_data_map.htab);
+}
+
/* Initialize a line map set. */
void
@@ -58,6 +173,7 @@ linemap_init (struct line_maps *set)
memset (set, 0, sizeof (struct line_maps));
set->highest_location = RESERVED_LOCATION_COUNT - 1;
set->highest_line = RESERVED_LOCATION_COUNT - 1;
+ location_adhoc_data_init (set);
}
/* Check for and warn about line_maps entered but not exited. */
@@ -408,12 +524,12 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
if (add_map)
{
int column_bits;
- if (max_column_hint > 100000 || highest > 0xC0000000)
+ if (max_column_hint > 100000 || highest > 0x60000000)
{
/* If the column number is ridiculous or we've allocated a huge
number of source_locations, give up on column numbers. */
max_column_hint = 0;
- if (highest >0xF0000000)
+ if (highest >0x70000000)
return 0;
column_bits = 0;
}
@@ -509,6 +625,8 @@ linemap_position_for_line_and_column (struct line_map *map,
const struct line_map*
linemap_lookup (struct line_maps *set, source_location line)
{
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
if (linemap_location_from_macro_expansion_p (set, line))
return linemap_macro_map_lookup (set, line);
return linemap_ordinary_map_lookup (set, line);
@@ -525,6 +643,9 @@ linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
unsigned int md, mn, mx;
const struct line_map *cached, *result;
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
+
if (set == NULL || line < RESERVED_LOCATION_COUNT)
return NULL;
@@ -570,6 +691,9 @@ linemap_macro_map_lookup (struct line_maps *set, source_location line)
unsigned int md, mn, mx;
const struct line_map *cached, *result;
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
if (set == NULL)
@@ -696,6 +820,10 @@ linemap_get_expansion_line (struct line_maps *set,
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return 0;
@@ -720,6 +848,10 @@ linemap_get_expansion_filename (struct line_maps *set,
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return NULL;
@@ -754,6 +886,10 @@ linemap_location_in_system_header_p (struct line_maps *set,
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return false;
@@ -793,6 +929,10 @@ bool
linemap_location_from_macro_expansion_p (struct line_maps *set,
source_location location)
{
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (location <= MAX_SOURCE_LOCATION
&& (set->highest_location
< LINEMAPS_MACRO_LOWEST_LOCATION (set)));
@@ -933,6 +1073,10 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
@@ -967,6 +1111,10 @@ linemap_macro_loc_to_def_point (struct line_maps *set,
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
@@ -1005,6 +1153,10 @@ linemap_macro_loc_to_exp_point (struct line_maps *set,
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
@@ -1074,6 +1226,9 @@ linemap_resolve_location (struct line_maps *set,
enum location_resolution_kind lrk,
const struct line_map **map)
{
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
if (loc < RESERVED_LOCATION_COUNT)
{
/* A reserved location wasn't encoded in a map. Let's return a
@@ -1121,6 +1276,9 @@ linemap_unwind_toward_expansion (struct line_maps *set,
source_location resolved_location;
const struct line_map *resolved_map;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
resolved_location =
linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
resolved_map = linemap_lookup (set, resolved_location);
@@ -1157,6 +1315,9 @@ linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
source_location resolved_loc;
const struct line_map *map0 = NULL, *map1 = NULL;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
map0 = linemap_lookup (set, loc);
if (!linemap_macro_expansion_map_p (map0))
return loc;
@@ -1198,6 +1359,12 @@ linemap_expand_location (struct line_maps *set,
expanded_location xloc;
memset (&xloc, 0, sizeof (xloc));
+ if (IS_ADHOC_LOC (loc))
+ {
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+ xloc.data = set->location_adhoc_data_map.data[
+ loc & MAX_SOURCE_LOCATION].data;
+ }
if (loc < RESERVED_LOCATION_COUNT)
/* The location for this token wasn't generated from a line map.
@@ -1290,6 +1457,9 @@ linemap_dump_location (struct line_maps *set,
const char *path = "", *from = "";
int l = -1, c = -1, s = -1, e = -1;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
if (loc == 0)
return;