On Tue, Jul 15, 2014 at 3:27 PM, Dodji Seketeli <do...@redhat.com> wrote:
> 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.

No testcase?

Richard.

> 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 <do...@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

Reply via email to