/* postfix-expression ( expression-list [opt] ) */
{
bool koenig_p;
- tree args = (cp_parser_parenthesized_expression_list
- (parser, false,
- /*cast_p=*/false,
- /*non_constant_p=*/NULL));
+ bool is_builtin_constant_p;
+ bool saved_integral_constant_expression_p = false;
+ bool saved_non_integral_constant_expression_p = false;
+ tree args;
+
+ is_builtin_constant_p
+ = DECL_IS_BUILTIN_CONSTANT_P (postfix_expression);
+ if (is_builtin_constant_p)
+ {
+ /* The whole point of __builtin_constant_p is to allow
+ non-constant expressions to appear as arguments. */
+ 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;
+ }
+ args = (cp_parser_parenthesized_expression_list
+ (parser, /*is_attribute_list=*/false,
+ /*cast_p=*/false,
+ /*non_constant_p=*/NULL));
+ if (is_builtin_constant_p)
+ {
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
+ }
if (args == error_mark_node)
{
non_constant_p = (unary_operator == PREINCREMENT_EXPR
? "`++'" : "`--'");
/* Fall through. */
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
expression = finish_unary_op_expr (unary_operator, cast_expression);
return ADDR_EXPR;
case CPP_PLUS:
- return CONVERT_EXPR;
+ return UNARY_PLUS_EXPR;
case CPP_MINUS:
return NEGATE_EXPR;
argument. */
default_argument = make_node (DEFAULT_ARG);
DEFARG_TOKENS (default_argument)
- = cp_token_cache_new (first_token, token);
+ = cp_token_cache_new (first_token, token);
+ DEFARG_INSTANTIATIONS (default_argument) = NULL;
}
/* Outside of a class definition, we can just parse the
assignment-expression. */
/* Look for an identifier. */
identifier = cp_parser_identifier (parser);
- /* Declare it as a lobel. */
+ /* If we failed, stop. */
+ if (identifier == error_mark_node)
+ break;
+ /* Declare it as a label. */
finish_label_decl (identifier);
/* If the next token is a `;', stop. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
parm = TREE_CHAIN (parm))
{
cp_token_cache *tokens;
+ tree default_arg = TREE_PURPOSE (parm);
+ tree parsed_arg;
+ VEC(tree,gc) *insts;
+ tree copy;
+ unsigned ix;
+
+ if (!default_arg)
+ continue;
- if (!TREE_PURPOSE (parm)
- || TREE_CODE (TREE_PURPOSE (parm)) != DEFAULT_ARG)
+ if (TREE_CODE (default_arg) != DEFAULT_ARG)
+ /* This can happen for a friend declaration for a function
+ already declared with default arguments. */
continue;
/* Push the saved tokens for the default argument onto the parser's
lexer stack. */
- tokens = DEFARG_TOKENS (TREE_PURPOSE (parm));
+ tokens = DEFARG_TOKENS (default_arg);
cp_parser_push_lexer_for_tokens (parser, tokens);
/* Parse the assignment-expression. */
- TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser,
- /*cast_p=*/false);
+ parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+
+ TREE_PURPOSE (parm) = parsed_arg;
+
+ /* Update any instantiations we've already created. */
+ for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
+ VEC_iterate (tree, insts, ix, copy); ix++)
+ TREE_PURPOSE (copy) = parsed_arg;
/* If the token stream has not been completely used up, then
there was extra junk after the end of the default