parser.c (cp_parser_decltype_expr): Split out...
* parser.c (cp_parser_decltype_expr): Split out... (cp_parser_decltype): ...from here. From-SVN: r197247
This commit is contained in:
parent
4185fb7350
commit
15914ac8b1
2 changed files with 76 additions and 61 deletions
|
@ -1,5 +1,8 @@
|
|||
2013-03-29 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
|
134
gcc/cp/parser.c
134
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);
|
||||
tree expr;
|
||||
|
||||
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 %<decltype%> 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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Parse a `decltype' type. Returns the type.
|
||||
|
||||
simple-type-specifier:
|
||||
decltype ( expression ) */
|
||||
|
||||
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 %<decltype%> 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue