On Sun, 15 Oct 2023, Ken Matsui wrote:

> This patch accepts the use of built-in trait identifiers when they are
> actually not used as traits.  Specifically, we check if the subsequent token
> is '(' for ordinary built-in traits or is '<' only for the special
> __type_pack_element built-in trait.  If those identifiers are used
> differently, the parser treats them as normal identifiers.  This allows
> us to accept code like: struct __is_pointer {};.

LGTM, thanks

> 
> gcc/cp/ChangeLog:
> 
>       * parser.cc (cp_lexer_lookup_trait): Rename to ...
>       (cp_lexer_peek_trait): ... this.  Handle a subsequent token for
>       the corresponding built-in trait.
>       (cp_lexer_lookup_trait_expr): Rename to ...
>       (cp_lexer_peek_trait_expr): ... this.
>       (cp_lexer_lookup_trait_type): Rename to ...
>       (cp_lexer_peek_trait_type): ... this.
>       (cp_lexer_next_token_is_decl_specifier_keyword): Call
>       cp_lexer_peek_trait_type.
>       (cp_parser_simple_type_specifier): Likewise.
>       (cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.
> 
> Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org>
> ---
>  gcc/cp/parser.cc | 48 ++++++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 18 deletions(-)
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index eba5272be03..0f2a1baee6a 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -246,12 +246,12 @@ static void cp_lexer_start_debugging
>    (cp_lexer *) ATTRIBUTE_UNUSED;
>  static void cp_lexer_stop_debugging
>    (cp_lexer *) ATTRIBUTE_UNUSED;
> -static const cp_trait *cp_lexer_lookup_trait
> -  (const cp_token *);
> -static const cp_trait *cp_lexer_lookup_trait_expr
> -  (const cp_token *);
> -static const cp_trait *cp_lexer_lookup_trait_type
> -  (const cp_token *);
> +static const cp_trait *cp_lexer_peek_trait
> +  (cp_lexer *lexer, const cp_token *);
> +static const cp_trait *cp_lexer_peek_trait_expr
> +  (cp_lexer *lexer, const cp_token *);
> +static const cp_trait *cp_lexer_peek_trait_type
> +  (cp_lexer *lexer, const cp_token *);
>  
>  static cp_token_cache *cp_token_cache_new
>    (cp_token *, cp_token *);
> @@ -1195,19 +1195,31 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
>      }
>  }
>  
> -/* Look ups the corresponding built-in trait if a given token is
> +/* Peeks the corresponding built-in trait if a given token is
>     a built-in trait.  Otherwise, returns nullptr.  */
>  
>  static const cp_trait *
> -cp_lexer_lookup_trait (const cp_token *token)
> +cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
>  {
> -  tree id = token->u.value;
> +  tree id = token1->u.value;
>  
> -  if (token->type == CPP_NAME
> +  if (token1->type == CPP_NAME
>        && TREE_CODE (id) == IDENTIFIER_NODE
>        && IDENTIFIER_TRAIT_P (id))
> -    return &cp_traits[IDENTIFIER_CP_INDEX (id)];
> +    {
> +      const cp_trait &trait = cp_traits[IDENTIFIER_CP_INDEX (id)];
> +      const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
>  
> +      /* Check if the subsequent token is a `<' token to
> +         __type_pack_element or is a `(' token to everything else.  */
> +      const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
> +      if (is_pack_element && token2->type != CPP_LESS)
> +     return nullptr;
> +      if (!is_pack_element && token2->type != CPP_OPEN_PAREN)
> +     return nullptr;
> +
> +      return &trait;
> +    }
>    return nullptr;
>  }
>  
> @@ -1215,9 +1227,9 @@ cp_lexer_lookup_trait (const cp_token *token)
>     built-in trait.  */
>  
>  static const cp_trait *
> -cp_lexer_lookup_trait_expr (const cp_token *token)
> +cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
>  {
> -  const cp_trait *trait = cp_lexer_lookup_trait (token);
> +  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
>    if (trait && !trait->type)
>      return trait;
>  
> @@ -1228,9 +1240,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
>     built-in trait.  */
>  
>  static const cp_trait *
> -cp_lexer_lookup_trait_type (const cp_token *token)
> +cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
>  {
> -  const cp_trait *trait = cp_lexer_lookup_trait (token);
> +  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
>    if (trait && trait->type)
>      return trait;
>  
> @@ -1245,7 +1257,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
> *lexer)
>    cp_token *token;
>  
>    token = cp_lexer_peek_token (lexer);
> -  if (cp_lexer_lookup_trait_type (token))
> +  if (cp_lexer_peek_trait_type (lexer, token))
>      return true;
>    return cp_keyword_starts_decl_specifier_p (token->keyword);
>  }
> @@ -6117,7 +6129,7 @@ cp_parser_primary_expression (cp_parser *parser,
>        keyword.  */
>      case CPP_NAME:
>        {
> -     const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
> +     const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
>       if (trait)
>         return cp_parser_trait (parser, trait);
>        }
> @@ -20126,7 +20138,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
>      }
>  
>    /* If token is a type-yielding built-in traits, parse it.  */
> -  const cp_trait* trait = cp_lexer_lookup_trait_type (token);
> +  const cp_trait* trait = cp_lexer_peek_trait_type (parser->lexer, token);
>    if (trait)
>      {
>        type = cp_parser_trait (parser, trait);
> -- 
> 2.42.0
> 
> 

Reply via email to