static tree cp_parser_init_declarator
(cp_parser *, cp_decl_specifier_seq *, bool, bool, int, bool *);
static cp_declarator *cp_parser_declarator
- (cp_parser *, cp_parser_declarator_kind, int *, bool *);
+ (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
static cp_declarator *cp_parser_direct_declarator
- (cp_parser *, cp_parser_declarator_kind, int *);
+ (cp_parser *, cp_parser_declarator_kind, int *, bool);
static enum tree_code cp_parser_ptr_operator
(cp_parser *, tree *, cp_cv_quals *);
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
/* Parse the declarator. */
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
/*ctor_dtor_or_conv_p=*/NULL,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
/* Parse the attributes. */
attributes = cp_parser_attributes_opt (parser);
/* Parse the asm-specification. */
declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
/*ctor_dtor_or_conv_p=*/NULL,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
cp_parser_check_for_definition_in_return_type (declarator,
declares_class_or_enum);
if (declarator != cp_error_declarator)
declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
&ctor_dtor_or_conv_p,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
/* Gather up the deferred checks. */
stop_deferring_access_checks ();
expression, not a declaration.)
If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
- the declarator is a direct-declarator of the form "(...)". */
+ the declarator is a direct-declarator of the form "(...)".
+
+ MEMBER_P is true iff this declarator is a member-declarator. */
static cp_declarator *
cp_parser_declarator (cp_parser* parser,
cp_parser_declarator_kind dcl_kind,
int* ctor_dtor_or_conv_p,
- bool* parenthesized_p)
+ bool* parenthesized_p,
+ bool member_p)
{
cp_token *token;
cp_declarator *declarator;
/* Parse the dependent declarator. */
declarator = cp_parser_declarator (parser, dcl_kind,
/*ctor_dtor_or_conv_p=*/NULL,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
/* If we are parsing an abstract-declarator, we must handle the
case where the dependent declarator is absent. */
*parenthesized_p = cp_lexer_next_token_is (parser->lexer,
CPP_OPEN_PAREN);
declarator = cp_parser_direct_declarator (parser, dcl_kind,
- ctor_dtor_or_conv_p);
+ ctor_dtor_or_conv_p,
+ member_p);
}
if (attributes && declarator != cp_error_declarator)
we are parsing a direct-declarator. It is
CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
of ambiguity we prefer an abstract declarator, as per
- [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P is as for
+ [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P and MEMBER_P are as for
cp_parser_declarator. */
static cp_declarator *
cp_parser_direct_declarator (cp_parser* parser,
cp_parser_declarator_kind dcl_kind,
- int* ctor_dtor_or_conv_p)
+ int* ctor_dtor_or_conv_p,
+ bool member_p)
{
cp_token *token;
cp_declarator *declarator = NULL;
cp_parameter_declarator *params;
unsigned saved_num_template_parameter_lists;
- cp_parser_parse_tentatively (parser);
+ /* In a member-declarator, the only valid interpretation
+ of a parenthesis is the start of a
+ parameter-declaration-clause. (It is invalid to
+ initialize a static data member with a parenthesized
+ initializer; only the "=" form of initialization is
+ permitted.) */
+ if (!member_p)
+ cp_parser_parse_tentatively (parser);
/* Consume the `('. */
cp_lexer_consume_token (parser->lexer);
/* If all went well, parse the cv-qualifier-seq and the
exception-specification. */
- if (cp_parser_parse_definitely (parser))
+ if (member_p || cp_parser_parse_definitely (parser))
{
cp_cv_quals cv_quals;
tree exception_specification;
parser->in_type_id_in_expr_p = true;
declarator
= cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ member_p);
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
first = false;
/* Expect a `)'. */
/* Look for the declarator. */
abstract_declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
/* Check to see if there really was a declarator. */
if (!cp_parser_parse_definitely (parser))
abstract_declarator = NULL;
declarator = cp_parser_declarator (parser,
CP_PARSER_DECLARATOR_EITHER,
/*ctor_dtor_or_conv_p=*/NULL,
- parenthesized_p);
+ parenthesized_p,
+ /*member_p=*/false);
parser->default_arg_ok_p = saved_default_arg_ok_p;
/* After the declarator, allow more attributes. */
decl_specifiers.attributes
declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
&ctor_dtor_or_conv_p,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/true);
/* If something went wrong parsing the declarator, make sure
that we at least consume some tokens. */
else
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
/*ctor_dtor_or_conv_p=*/NULL,
- /*parenthesized_p=*/NULL);
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;