{
if (count > 2)
error ("%<long long long%> is too long for GCC");
- else if (pedantic && !in_system_header && warn_long_long)
- pedwarn ("ISO C++ does not support %<long long%>");
+ else if (pedantic && !in_system_header && warn_long_long
+ && cxx_dialect == cxx98)
+ pedwarn ("ISO C++ 1998 does not support %<long long%>");
}
else if (count > 1)
{
&& !COMPLETE_TYPE_P (new_scope)
/* Do not try to complete dependent types. */
&& !dependent_type_p (new_scope))
- new_scope = complete_type (new_scope);
+ {
+ new_scope = complete_type (new_scope);
+ /* If it is a typedef to current class, use the current
+ class instead, as the typedef won't have any names inside
+ it yet. */
+ if (!COMPLETE_TYPE_P (new_scope)
+ && currently_open_class (new_scope))
+ new_scope = TYPE_MAIN_VARIANT (new_scope);
+ }
/* Make sure we look in the right scope the next time through
the loop. */
parser->scope = new_scope;
pseudo_destructor_p = false;
/* If the SCOPE is a scalar type, then, if this is a valid program,
- we must be looking at a pseudo-destructor-name. */
- if (scope && SCALAR_TYPE_P (scope))
+ we must be looking at a pseudo-destructor-name. If POSTFIX_EXPRESSION
+ is type dependent, it can be pseudo-destructor-name or something else.
+ Try to parse it as pseudo-destructor-name first. */
+ if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
{
tree s;
tree type;
/* Parse the pseudo-destructor-name. */
s = NULL_TREE;
cp_parser_pseudo_destructor_name (parser, &s, &type);
- if (cp_parser_parse_definitely (parser))
+ if (dependent_p
+ && (cp_parser_error_occurred (parser)
+ || TREE_CODE (type) != TYPE_DECL
+ || !SCALAR_TYPE_P (TREE_TYPE (type))))
+ cp_parser_abort_tentative_parse (parser);
+ else if (cp_parser_parse_definitely (parser))
{
pseudo_destructor_p = true;
postfix_expression
tree expression_list = NULL_TREE;
bool fold_expr_p = is_attribute_list;
tree identifier = NULL_TREE;
+ bool saved_greater_than_is_operator_p;
/* Assume all the expressions will be constant. */
if (non_constant_p)
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
return error_mark_node;
+ /* 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;
+
/* Consume expressions until there are no more. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
while (true)
if (ending < 0)
goto get_comma;
if (!ending)
- return error_mark_node;
+ {
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ return error_mark_node;
+ }
}
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+
/* We built up the list in reverse order so we must reverse it now. */
expression_list = nreverse (expression_list);
if (identifier)
&& token->type == CPP_AND_AND)
{
tree identifier;
+ tree expression;
/* Consume the '&&' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the identifier. */
identifier = cp_parser_identifier (parser);
/* Create an expression representing the address. */
- return finish_label_address_expr (identifier);
+ expression = finish_label_address_expr (identifier);
+ if (cp_parser_non_integral_constant_expression (parser,
+ "the address of a label"))
+ expression = error_mark_node;
+ return expression;
}
}
if (unary_operator != ERROR_MARK)
compound-statement:
{ statement-seq [opt] }
+ GNU extension:
+
+ compound-statement:
+ { label-declaration-seq [opt] statement-seq [opt] }
+
+ label-declaration-seq:
+ label-declaration
+ label-declaration-seq label-declaration
+
Returns a tree representing the statement. */
static tree
return error_mark_node;
/* Begin the compound-statement. */
compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0);
+ /* If the next keyword is `__label__' we have a label declaration. */
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+ cp_parser_label_declaration (parser);
/* Parse an (optional) statement-seq. */
cp_parser_statement_seq_opt (parser, in_statement_expr);
/* Finish the compound-statement. */
block-declaration:
__extension__ block-declaration
- label-declaration
C++0x Extension:
cp_parser_using_declaration (parser,
/*access_declaration_p=*/false);
}
- /* If the next keyword is `__label__' we have a label declaration. */
+ /* If the next keyword is `__label__' we have a misplaced label
+ declaration. */
else if (token1->keyword == RID_LABEL)
{
- if (statement_p)
- cp_parser_commit_to_tentative_parse (parser);
- cp_parser_label_declaration (parser);
+ cp_lexer_consume_token (parser->lexer);
+ error ("%<__label__%> not at the beginning of a block");
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
}
/* If the next token is `static_assert' we have a static assertion. */
else if (token1->keyword == RID_STATIC_ASSERT)
++skip_evaluation;
/* Parse the opening `('. */
- cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
+ return error_mark_node;
/* First, try parsing an id-expression. */
cp_parser_parse_tentatively (parser);
cp_id_kind idk;
const char *error_msg;
- /* Lookup the name we got back from the id-expression. */
- expr = cp_parser_lookup_name (parser, expr,
- none_type,
- /*is_template=*/false,
- /*is_namespace=*/false,
- /*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
-
- if (expr
+ if (TREE_CODE (expr) == IDENTIFIER_NODE)
+ /* Lookup the name we got back from the id-expression. */
+ expr = cp_parser_lookup_name (parser, expr,
+ none_type,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ /*ambiguous_decls=*/NULL);
+
+ if (expr
&& expr != error_mark_node
&& TREE_CODE (expr) != TEMPLATE_ID_EXPR
&& TREE_CODE (expr) != TYPE_DECL
+ && (TREE_CODE (expr) != BIT_NOT_EXPR
+ || !TYPE_P (TREE_OPERAND (expr, 0)))
&& cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
{
/* Complete lookup of the id-expression. */
/* Parse to the closing `)'. */
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
- cp_parser_skip_to_closing_parenthesis (parser, true, false,
- /*consume_paren=*/true);
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ return error_mark_node;
+ }
return finish_decltype_type (expr, id_expression_or_member_access_p);
}
token = cp_lexer_consume_token (parser->lexer);
}
- /* Create a DEFAULT_ARG to represented the unparsed default
+ /* Create a DEFAULT_ARG to represent the unparsed default
argument. */
default_argument = make_node (DEFAULT_ARG);
DEFARG_TOKENS (default_argument)
/* Look up the type. */
if (template_id_p)
{
- type = TREE_TYPE (id);
- type = maybe_process_partial_specialization (type);
+ if (TREE_CODE (id) == TEMPLATE_ID_EXPR
+ && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
+ || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
+ {
+ error ("function template %qD redeclared as a class template", id);
+ type = error_mark_node;
+ }
+ else
+ {
+ type = TREE_TYPE (id);
+ type = maybe_process_partial_specialization (type);
+ }
if (nested_name_specifier)
pushed_scope = push_scope (nested_name_specifier);
}
/* Make this a pack expansion type. */
TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
else
- check_for_bare_parameter_packs (TREE_VALUE (base));
+ check_for_bare_parameter_packs (&TREE_VALUE (base));
TREE_CHAIN (base) = bases;
bases = base;
static void
cp_parser_check_access_in_redeclaration (tree decl)
{
- if (!CLASS_TYPE_P (TREE_TYPE (decl)))
+ if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl)))
return;
if ((TREE_PRIVATE (decl)
const char *where, cp_token *pragma_tok)
{
tree clauses = NULL;
+ bool first = true;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- pragma_omp_clause c_kind = cp_parser_omp_clause_name (parser);
+ pragma_omp_clause c_kind;
const char *c_name;
tree prev = clauses;
+ if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+
+ c_kind = cp_parser_omp_clause_name (parser);
+ first = false;
+
switch (c_kind)
{
case PRAGMA_OMP_CLAUSE_COPYIN:
switch (p_kind)
{
case PRAGMA_OMP_PARALLEL:
- cp_parser_already_scoped_statement (parser);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
par_clause = clauses;
break;