This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 1/2] Support location tracking for built-in macro tokens
- From: Dodji Seketeli <dodji at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Nicholas Ormrod <nicholas dot ormrod at hotmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 15 Jul 2014 15:27:48 +0200
- Subject: [PATCH 1/2] Support location tracking for built-in macro tokens
- Authentication-results: sourceware.org; auth=none
- References: <87d2du4xsu dot fsf at redhat dot com> <53ADD6C2 dot 9030200 at redhat dot com> <877g3uo6cq dot fsf at redhat dot com> <COL129-W8177087E5B88848923A685F5010 at phx dot gbl> <871tu1fhjh dot fsf at redhat dot com> <53B9991D dot 7090401 at redhat dot com> <871ttt8l8l dot fsf at redhat dot com> <53BEE945 dot 6080905 at redhat dot com> <86iomyvkai dot fsf at redhat dot com>
Hello,
When a built-in macro is expanded, the location of the token in the
epansion list is the location of the expansion point of the built-in
macro.
This patch creates a virtual location for that token instead,
effectively tracking locations of tokens resulting from built-in macro
tokens.
libcpp/
* include/line-map.h (line_maps::builtin_location): New data
member.
(line_map_init): Add a new parameter to initialize the new
line_maps::builtin_location data member.
* line-map.c (linemap_init): Initialize the
line_maps::builtin_location data member.
* macro.c (builtin_macro): Create a macro map and track the token
resulting from the expansion of a built-in macro.
gcc/
* input.h (is_location_from_builtin_token): New function
declaration.
* input.c (is_location_from_builtin_token): New function
definition.
* toplev.c (general_init): Tell libcpp what the pre-defined
spelling location for built-in tokens is.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
gcc/input.c | 16 ++++++++++++++++
gcc/input.h | 1 +
gcc/toplev.c | 2 +-
libcpp/include/line-map.h | 12 ++++++++++--
libcpp/line-map.c | 4 +++-
libcpp/macro.c | 23 ++++++++++++++++++++++-
6 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/gcc/input.c b/gcc/input.c
index 63cd062..f3fd0e9 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -713,6 +713,22 @@ location_get_source_line (expanded_location xloc,
return read ? buffer : NULL;
}
+/* Test if the location originates from the spelling location of a
+ builtin-tokens. That is, return TRUE if LOC is a (possibly
+ virtual) location of a built-in token that appears in the expansion
+ list of a macro. Please note that this function also works on
+ tokens that result from built-in tokens. For instance, the
+ function would return true if passed a token "4" that is the result
+ of the expansion of the built-in __LINE__ macro. */
+bool
+is_location_from_builtin_token (source_location loc)
+{
+ const line_map *map = NULL;
+ loc = linemap_resolve_location (line_table, loc,
+ LRK_SPELLING_LOCATION, &map);
+ return loc == BUILTINS_LOCATION;
+}
+
/* Expand the source location LOC into a human readable location. If
LOC is virtual, it resolves to the expansion point of the involved
macro. If LOC resolves to a builtin location, the file name of the
diff --git a/gcc/input.h b/gcc/input.h
index d910bb8..1def793 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -36,6 +36,7 @@ extern GTY(()) struct line_maps *line_table;
extern char builtins_location_check[(BUILTINS_LOCATION
< RESERVED_LOCATION_COUNT) ? 1 : -1];
+extern bool is_location_from_builtin_token (source_location);
extern expanded_location expand_location (source_location);
extern const char *location_get_source_line (expanded_location xloc,
int *line_size);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e35b826..9e747e5 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1157,7 +1157,7 @@ general_init (const char *argv0)
init_ggc ();
init_stringpool ();
line_table = ggc_alloc<line_maps> ();
- linemap_init (line_table);
+ linemap_init (line_table, BUILTINS_LOCATION);
line_table->reallocator = realloc_for_line_map;
line_table->round_alloc_size = ggc_round_alloc_size;
init_ttree ();
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 9886314..0c8f588 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -315,6 +315,10 @@ struct GTY(()) line_maps {
line_map_round_alloc_size_func round_alloc_size;
struct location_adhoc_data_map location_adhoc_data_map;
+
+ /* The special location value that is used as spelling location for
+ built-in tokens. */
+ source_location builtin_location;
};
/* Returns the pointer to the memory region where information about
@@ -447,8 +451,12 @@ extern source_location get_location_from_adhoc_loc (struct line_maps *,
extern void rebuild_location_adhoc_htab (struct line_maps *);
-/* Initialize a line map set. */
-extern void linemap_init (struct line_maps *);
+/* Initialize a line map set. SET is the line map set to initialize
+ and BUILTIN_LOCATION is the special location value to be used as
+ spelling location for built-in tokens. This BUILTIN_LOCATION has
+ to be strictly less than RESERVED_LOCATION_COUNT. */
+extern void linemap_init (struct line_maps *set,
+ source_location builtin_location);
/* Check for and warn about line_maps entered but not exited. */
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index f9a7658..a4055c2 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -175,13 +175,15 @@ location_adhoc_data_fini (struct line_maps *set)
/* Initialize a line map set. */
void
-linemap_init (struct line_maps *set)
+linemap_init (struct line_maps *set,
+ source_location builtin_location)
{
memset (set, 0, sizeof (struct line_maps));
set->highest_location = RESERVED_LOCATION_COUNT - 1;
set->highest_line = RESERVED_LOCATION_COUNT - 1;
set->location_adhoc_data_map.htab =
htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
+ set->builtin_location = builtin_location;
}
/* Check for and warn about line_maps entered but not exited. */
diff --git a/libcpp/macro.c b/libcpp/macro.c
index ab4817e..3b8fa40 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -428,7 +428,28 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
/* Set pfile->cur_token as required by _cpp_lex_direct. */
pfile->cur_token = _cpp_temp_token (pfile);
- _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
+ cpp_token *token = _cpp_lex_direct (pfile);
+ if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED)
+ {
+ /* We are tracking tokens resulting from macro expansion.
+ Create a macro line map and generate a virtual location for
+ the token resulting from the expansion of the built-in
+ macro. */
+ source_location *virt_locs = NULL;
+ _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs);
+ const line_map * map =
+ linemap_enter_macro (pfile->line_table, node,
+ token->src_loc, 1);
+ tokens_buff_add_token (token_buf, virt_locs, token,
+ pfile->line_table->builtin_location,
+ pfile->line_table->builtin_location,
+ map, /*macro_token_index=*/0);
+ push_extended_tokens_context (pfile, node, token_buf, virt_locs,
+ (const cpp_token **)token_buf->base,
+ 1);
+ }
+ else
+ _cpp_push_token_context (pfile, NULL, token, 1);
if (pfile->buffer->cur != pfile->buffer->rlimit)
cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
NODE_NAME (node));
--
Dodji