[PATCH 05/10] Add ranges to libcpp tokens (via ad-hoc data, unoptimized)
David Malcolm
dmalcolm@redhat.com
Fri Oct 23 20:26:00 GMT 2015
This patch:
- generalizes the meaning of the source_location (aka location_t) type
from being a caret within the source code to being a caret plus
a source_range. The latter data is stored purely in the ad-hoc data
lookaside for now.
- captures ranges for libcpp tokens by generating source_location
values with caret == start and finish == the last character of the
token
This is elegant, since we can store caret+range data in location_t as
before, without having to track ranges everywhere: all location_t
values (such as input_location) become the ranges of tokens; a followup
patch fixes the diagnostic machinery to automatically extract the
ranges when building rich_location instances, which means that all
calls to warning, warning_at, error, error_at etc get underlines
showing the range of the pertinent token "for free".
However, it's inefficient, since it means generating an ad-hoc location
for every token in libcpp. A followup patch optimizes this by packing
short ranges into location_t, without needing to use ad-hoc locations,
which covers most tokens efficiently.
gcc/ChangeLog:
* gimple.h (gimple_set_block): Use set_block function.
* tree-cfg.c (move_block_to_fn): Likewise.
(move_block_to_fn): Likewise.
* tree-inline.c (copy_phis_for_bb): Likewise.
* tree.c (tree_set_block): Likewise.
(set_block): New function.
* tree.h (set_block): New declaration.
libcpp/ChangeLog:
* include/cpplib.h (struct cpp_token): Update comment for src_loc
to indicate that the range of the token is "baked into" the
source_location.
* include/line-map.h (location_adhoc_data): Add source_range
field.
(get_combined_adhoc_loc): Add source_range param.
(get_range_from_adhoc_loc): New declaration.
(get_range_from_loc): New inline function.
(COMBINE_LOCATION_DATA): Add source_range param.
* lex.c (_cpp_lex_direct): Capture the range of the token, baking
it into token->src_loc via a call to COMBINE_LOCATION_DATA.
* line-map.c (location_adhoc_data_hash): Add the src_range into
the hash value.
(location_adhoc_data_eq): Require equality of the src_range
values.
(get_combined_adhoc_loc): Add src_range param, and store it
within the lookaside table. Remove the requirement that data
is non-NULL.
(get_range_from_adhoc_loc): New function.
(linemap_expand_location): Extract the data pointer before
extracting the location.
---
gcc/gimple.h | 6 +-----
gcc/tree-cfg.c | 9 ++-------
gcc/tree-inline.c | 5 +----
gcc/tree.c | 11 +++++++----
gcc/tree.h | 3 +++
libcpp/include/cpplib.h | 3 ++-
libcpp/include/line-map.h | 23 ++++++++++++++++++++---
libcpp/lex.c | 10 ++++++++++
libcpp/line-map.c | 26 ++++++++++++++++++++------
9 files changed, 66 insertions(+), 30 deletions(-)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index a456f54..ba66931 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1709,11 +1709,7 @@ gimple_block (const gimple *g)
static inline void
gimple_set_block (gimple *g, tree block)
{
- if (block)
- g->location =
- COMBINE_LOCATION_DATA (line_table, g->location, block);
- else
- g->location = LOCATION_LOCUS (g->location);
+ g->location = set_block (g->location, block);
}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 735ac46..8ef2443 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6739,10 +6739,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
continue;
if (d->orig_block == NULL_TREE || block == d->orig_block)
{
- if (d->new_block == NULL_TREE)
- locus = LOCATION_LOCUS (locus);
- else
- locus = COMBINE_LOCATION_DATA (line_table, locus, d->new_block);
+ locus = set_block (locus, d->new_block);
gimple_phi_arg_set_location (phi, i, locus);
}
}
@@ -6802,9 +6799,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
tree block = LOCATION_BLOCK (e->goto_locus);
if (d->orig_block == NULL_TREE
|| block == d->orig_block)
- e->goto_locus = d->new_block ?
- COMBINE_LOCATION_DATA (line_table, e->goto_locus, d->new_block) :
- LOCATION_LOCUS (e->goto_locus);
+ e->goto_locus = set_block (e->goto_locus, d->new_block);
}
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 9b525f3..58eca90 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2352,10 +2352,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
tree *n;
n = id->decl_map->get (LOCATION_BLOCK (locus));
gcc_assert (n);
- if (*n)
- locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
- else
- locus = LOCATION_LOCUS (locus);
+ locus = set_block (locus, *n);
}
else
locus = LOCATION_LOCUS (locus);
diff --git a/gcc/tree.c b/gcc/tree.c
index f78a2c2..426803c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11669,10 +11669,7 @@ tree_set_block (tree t, tree b)
if (IS_EXPR_CODE_CLASS (c))
{
- if (b)
- t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b);
- else
- t->exp.locus = LOCATION_LOCUS (t->exp.locus);
+ t->exp.locus = set_block (t->exp.locus, b);
}
else
gcc_unreachable ();
@@ -13656,5 +13653,11 @@ nonnull_arg_p (const_tree arg)
return false;
}
+location_t
+set_block (location_t loc, tree block)
+{
+ source_range src_range = get_range_from_loc (line_table, loc);
+ return COMBINE_LOCATION_DATA (line_table, loc, src_range, block);
+}
#include "gt-tree.h"
diff --git a/gcc/tree.h b/gcc/tree.h
index 4c803f4..92cc929 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5139,6 +5139,9 @@ type_with_alias_set_p (const_tree t)
return false;
}
+extern location_t
+set_block (location_t loc, tree block);
+
extern void gt_ggc_mx (tree &);
extern void gt_pch_nx (tree &);
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index a2bdfa0..f5c2a21 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -237,7 +237,8 @@ struct GTY(()) cpp_identifier {
/* A preprocessing token. This has been carefully packed and should
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
struct GTY(()) cpp_token {
- source_location src_loc; /* Location of first char of token. */
+ source_location src_loc; /* Location of first char of token,
+ together with range of full token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned short flags; /* flags - see above */
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 84a5ab7..de1c55c 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -512,9 +512,11 @@ struct GTY(()) maps_info_macro {
unsigned int cache;
};
-/* Data structure to associate an arbitrary data to a source location. */
+/* Data structure to associate a source_range together with an arbitrary
+ data pointer with a source location. */
struct GTY(()) location_adhoc_data {
source_location locus;
+ source_range src_range;
void * GTY((skip)) data;
};
@@ -813,10 +815,14 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
extern void location_adhoc_data_fini (struct line_maps *);
extern source_location get_combined_adhoc_loc (struct line_maps *,
- source_location, void *);
+ source_location,
+ source_range,
+ void *);
extern void *get_data_from_adhoc_loc (struct line_maps *, source_location);
extern source_location get_location_from_adhoc_loc (struct line_maps *,
source_location);
+extern source_range get_range_from_adhoc_loc (struct line_maps *,
+ source_location);
/* Get whether location LOC is an ad-hoc location. */
@@ -826,14 +832,25 @@ IS_ADHOC_LOC (source_location loc)
return (loc & MAX_SOURCE_LOCATION) != loc;
}
+inline source_range
+get_range_from_loc (struct line_maps *set,
+ source_location loc)
+{
+ if (IS_ADHOC_LOC (loc))
+ return get_range_from_adhoc_loc (set, loc);
+ else
+ return source_range::from_location (loc);
+}
+
/* Combine LOC and BLOCK, giving a combined adhoc location. */
inline source_location
COMBINE_LOCATION_DATA (struct line_maps *set,
source_location loc,
+ source_range src_range,
void *block)
{
- return get_combined_adhoc_loc (set, loc, block);
+ return get_combined_adhoc_loc (set, loc, src_range, block);
}
extern void rebuild_location_adhoc_htab (struct line_maps *);
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 0aa1090..f4c964f 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -2723,6 +2723,16 @@ _cpp_lex_direct (cpp_reader *pfile)
break;
}
+ source_range tok_range;
+ tok_range.m_start = result->src_loc;
+ tok_range.m_finish =
+ linemap_position_for_column (pfile->line_table,
+ CPP_BUF_COLUMN (buffer, buffer->cur));
+
+ result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table,
+ result->src_loc,
+ tok_range, NULL);
+
return result;
}
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 3c19f93..3810c88 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -69,7 +69,10 @@ 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;
+ return ((hashval_t) lb->locus
+ + (hashval_t) lb->src_range.m_start
+ + (hashval_t) lb->src_range.m_finish
+ + (size_t) lb->data);
}
/* Compare function for location_adhoc_data hashtable. */
@@ -81,7 +84,10 @@ location_adhoc_data_eq (const void *l1, const void *l2)
(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;
+ return (lb1->locus == lb2->locus
+ && lb1->src_range.m_start == lb2->src_range.m_start
+ && lb1->src_range.m_finish == lb2->src_range.m_finish
+ && lb1->data == lb2->data);
}
/* Update the hashtable when location_adhoc_data is reallocated. */
@@ -110,19 +116,20 @@ rebuild_location_adhoc_htab (struct line_maps *set)
source_location
get_combined_adhoc_loc (struct line_maps *set,
- source_location locus, void *data)
+ source_location locus,
+ source_range src_range,
+ 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.src_range = src_range;
lb.data = data;
slot = (struct location_adhoc_data **)
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
@@ -177,6 +184,13 @@ get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
}
+source_range
+get_range_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].src_range;
+}
+
/* Finalize the location_adhoc_data structure. */
void
location_adhoc_data_fini (struct line_maps *set)
@@ -1478,9 +1492,9 @@ linemap_expand_location (struct line_maps *set,
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;
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
}
if (loc < RESERVED_LOCATION_COUNT)
--
1.8.5.3
More information about the Gcc-patches
mailing list