aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorKen Matsui <kmatsui@gcc.gnu.org>2023-12-06 21:32:58 -0800
committerJason Merrill <jason@redhat.com>2023-12-10 13:11:22 -0500
commitdf3559d951ba6572e254a1bd1ef9a34b6e543325 (patch)
treeefe4339cbc3111b99897841555ad756724f2cc6c /gcc/cp
parent400cd0c26cf86fe75b0e4d42f9976b3125bcfd43 (diff)
downloadgcc-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>
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/parser.cc53
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);