From: Jason Merrill Date: Fri, 29 Mar 2013 19:51:29 +0000 (-0400) Subject: parser.c (cp_parser_decltype_expr): Split out... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=15914ac8b16b3e88dc13b08f143f90ac5baad126;p=gcc.git parser.c (cp_parser_decltype_expr): Split out... * parser.c (cp_parser_decltype_expr): Split out... (cp_parser_decltype): ...from here. From-SVN: r197247 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6686bdcbecb..577740963c9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2013-03-29 Jason Merrill + * parser.c (cp_parser_decltype_expr): Split out... + (cp_parser_decltype): ...from here. + PR c++/56774 PR c++/35722 * pt.c (unify_pack_expansion): Fix indexing. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 09c5dff7cea..d36c984d9d5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11286,59 +11286,15 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) finish_static_assert (condition, message, saved_loc, member_p); } -/* Parse a `decltype' type. Returns the type. - - simple-type-specifier: - decltype ( expression ) */ +/* Parse the expression in decltype ( expression ). */ static tree -cp_parser_decltype (cp_parser *parser) +cp_parser_decltype_expr (cp_parser *parser, + bool &id_expression_or_member_access_p) { - tree expr; - bool id_expression_or_member_access_p = false; - const char *saved_message; - bool saved_integral_constant_expression_p; - bool saved_non_integral_constant_expression_p; cp_token *id_expr_start_token; - cp_token *start_token = cp_lexer_peek_token (parser->lexer); - - if (start_token->type == CPP_DECLTYPE) - { - /* Already parsed. */ - cp_lexer_consume_token (parser->lexer); - return start_token->u.value; - } - - /* Look for the `decltype' token. */ - if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE)) - return error_mark_node; - - /* Types cannot be defined in a `decltype' expression. Save away the - old message. */ - saved_message = parser->type_definition_forbidden_message; - - /* And create the new one. */ - parser->type_definition_forbidden_message - = G_("types may not be defined in % expressions"); - - /* The restrictions on constant-expressions do not apply inside - decltype expressions. */ - saved_integral_constant_expression_p - = parser->integral_constant_expression_p; - saved_non_integral_constant_expression_p - = parser->non_integral_constant_expression_p; - parser->integral_constant_expression_p = false; - - /* Do not actually evaluate the expression. */ - ++cp_unevaluated_operand; - - /* Do not warn about problems with the expression. */ - ++c_inhibit_evaluation_warnings; + tree expr; - /* Parse the opening `('. */ - if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - return error_mark_node; - /* First, try parsing an id-expression. */ id_expr_start_token = cp_lexer_peek_token (parser->lexer); cp_parser_parse_tentatively (parser); @@ -11428,32 +11384,88 @@ cp_parser_decltype (cp_parser *parser) cp_parser_parse_definitely (parser); else { - bool saved_greater_than_is_operator_p; - /* Abort our attempt to parse an id-expression or member access expression. */ cp_parser_abort_tentative_parse (parser); - /* Within a parenthesized expression, a `>' token is always - the greater-than operator. */ - saved_greater_than_is_operator_p - = parser->greater_than_is_operator_p; - parser->greater_than_is_operator_p = true; - /* Parse a full expression. */ expr = cp_parser_expression (parser, /*cast_p=*/false, /*decltype*/true, NULL); + } + + return expr; +} + +/* Parse a `decltype' type. Returns the type. + + simple-type-specifier: + decltype ( expression ) */ - /* The `>' token might be the end of a template-id or - template-parameter-list now. */ - parser->greater_than_is_operator_p - = saved_greater_than_is_operator_p; +static tree +cp_parser_decltype (cp_parser *parser) +{ + tree expr; + bool id_expression_or_member_access_p = false; + const char *saved_message; + bool saved_integral_constant_expression_p; + bool saved_non_integral_constant_expression_p; + bool saved_greater_than_is_operator_p; + cp_token *start_token = cp_lexer_peek_token (parser->lexer); + + if (start_token->type == CPP_DECLTYPE) + { + /* Already parsed. */ + cp_lexer_consume_token (parser->lexer); + return start_token->u.value; } + /* Look for the `decltype' token. */ + if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE)) + return error_mark_node; + + /* Parse the opening `('. */ + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return error_mark_node; + + /* Types cannot be defined in a `decltype' expression. Save away the + old message. */ + saved_message = parser->type_definition_forbidden_message; + + /* And create the new one. */ + parser->type_definition_forbidden_message + = G_("types may not be defined in % expressions"); + + /* The restrictions on constant-expressions do not apply inside + decltype expressions. */ + saved_integral_constant_expression_p + = parser->integral_constant_expression_p; + saved_non_integral_constant_expression_p + = parser->non_integral_constant_expression_p; + parser->integral_constant_expression_p = false; + + /* Within a parenthesized expression, a `>' token is always + the greater-than operator. */ + saved_greater_than_is_operator_p + = parser->greater_than_is_operator_p; + parser->greater_than_is_operator_p = true; + + /* Do not actually evaluate the expression. */ + ++cp_unevaluated_operand; + + /* Do not warn about problems with the expression. */ + ++c_inhibit_evaluation_warnings; + + expr = cp_parser_decltype_expr (parser, id_expression_or_member_access_p); + /* Go back to evaluating expressions. */ --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; + /* The `>' token might be the end of a template-id or + template-parameter-list now. */ + parser->greater_than_is_operator_p + = saved_greater_than_is_operator_p; + /* Restore the old message and the integral constant expression flags. */ parser->type_definition_forbidden_message = saved_message;