diff options
author | Ken Matsui <kmatsui@gcc.gnu.org> | 2023-12-06 21:32:58 -0800 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-12-10 13:11:22 -0500 |
commit | df3559d951ba6572e254a1bd1ef9a34b6e543325 (patch) | |
tree | efe4339cbc3111b99897841555ad756724f2cc6c | |
parent | 400cd0c26cf86fe75b0e4d42f9976b3125bcfd43 (diff) | |
download | gcc-df3559d951ba6572e254a1bd1ef9a34b6e543325.zip gcc-df3559d951ba6572e254a1bd1ef9a34b6e543325.tar.gz gcc-df3559d951ba6572e254a1bd1ef9a34b6e543325.tar.bz2 |
c++: Accept the use of built-in trait identifiers
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 {};.
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 <kmatsui@gcc.gnu.org>
-rw-r--r-- | gcc/cp/parser.cc | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index f23ef6b..9e76426 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 *); +static const cp_trait *cp_lexer_peek_trait_expr + (cp_lexer *); +static const cp_trait *cp_lexer_peek_trait_type + (cp_lexer *); static cp_token_cache *cp_token_cache_new (cp_token *, cp_token *); @@ -1188,15 +1188,29 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) } } -/* Look ups the corresponding built-in trait if a given token is - a built-in trait. Otherwise, returns nullptr. */ +/* Peeks the corresponding built-in trait if the first token is + a built-in trait and the second token is either `(' or `<' depending + on the trait. Otherwise, returns nullptr. */ static const cp_trait * -cp_lexer_lookup_trait (const cp_token *token) +cp_lexer_peek_trait (cp_lexer *lexer) { - if (token->type == CPP_NAME && IDENTIFIER_TRAIT_P (token->u.value)) - return &cp_traits[IDENTIFIER_CP_INDEX (token->u.value)]; + const cp_token *token1 = cp_lexer_peek_token (lexer); + if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value)) + { + const cp_trait &trait = cp_traits[IDENTIFIER_CP_INDEX (token1->u.value)]; + 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; } @@ -1204,9 +1218,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_trait *trait = cp_lexer_lookup_trait (token); + const cp_trait *trait = cp_lexer_peek_trait (lexer); if (trait && !trait->type) return trait; @@ -1217,9 +1231,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_trait *trait = cp_lexer_lookup_trait (token); + const cp_trait *trait = cp_lexer_peek_trait (lexer); if (trait && trait->type) return trait; @@ -1233,9 +1247,10 @@ 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)) return true; + + token = cp_lexer_peek_token (lexer); return cp_keyword_starts_decl_specifier_p (token->keyword); } @@ -6133,7 +6148,7 @@ cp_parser_primary_expression (cp_parser *parser, `::' as the beginning of a qualified-id, or the "operator" keyword. */ case CPP_NAME: - if (const cp_trait* trait = cp_lexer_lookup_trait_expr (token)) + if (const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer)) return cp_parser_trait (parser, trait); /* FALLTHRU */ case CPP_SCOPE: @@ -20153,7 +20168,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); if (trait) { type = cp_parser_trait (parser, trait); |