X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fparser.c;h=05b5b661758411b0b2940cffc0c290cc8444f73e;hb=1577e1c17a0e33424963d1dee28d9f819522eab6;hp=18d62cc49ca350e05fbe9be0ad6c69aaa44b7fb5;hpb=ccc5f70da5eb810f09be63d4e92b57bb38121050;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 18d62cc49ca..05b5b661758 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -24,10 +24,10 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "dyn-string.h" -#include "varray.h" #include "cpplib.h" #include "tree.h" #include "cp-tree.h" +#include "intl.h" #include "c-pragma.h" #include "decl.h" #include "flags.h" @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "c-common.h" +#include "plugin.h" /* The lexer. */ @@ -47,8 +48,7 @@ along with GCC; see the file COPYING3. If not see /* A token's value and its associated deferred access checks and qualifying scope. */ -struct tree_check GTY(()) -{ +struct GTY(()) tree_check { /* The value associated with the token. */ tree value; /* The checks that have been associated with value. */ @@ -60,8 +60,7 @@ struct tree_check GTY(()) /* A C++ token. */ -typedef struct cp_token GTY (()) -{ +typedef struct GTY (()) cp_token { /* The kind of token. */ ENUM_BITFIELD (cpp_ttype) type : 8; /* If this token is a keyword, this value indicates which keyword. @@ -103,8 +102,7 @@ static cp_token eof_token = it to the parser. Tokens are never added to the cp_lexer after it is created. */ -typedef struct cp_lexer GTY (()) -{ +typedef struct GTY (()) cp_lexer { /* The memory allocated for the buffer. NULL if this lexer does not own the token buffer. */ cp_token * GTY ((length ("%h.buffer_length"))) buffer; @@ -143,8 +141,7 @@ typedef struct cp_lexer GTY (()) a cp_token_cache, since everything in here is referenced through a lexer. */ -typedef struct cp_token_cache GTY(()) -{ +typedef struct GTY(()) cp_token_cache { /* The beginning of the token range. */ cp_token * GTY((skip)) first; @@ -250,6 +247,10 @@ static void cp_parser_initial_pragma static FILE *cp_lexer_debug_stream; #endif /* ENABLE_CHECKING */ +/* Nonzero if we are parsing an unevaluated operand: an operand to + sizeof, typeof, or alignof. */ +int cp_unevaluated_operand; + /* Create a new main C++ lexer, the lexer that gets tokens from the preprocessor. */ @@ -401,7 +402,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) /* Get a new token from the preprocessor. */ token->type = c_lex_with_flags (&token->u.value, &token->location, &token->flags, - lexer == NULL ? 0 : C_LEX_RAW_STRINGS); + lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN); token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; @@ -421,11 +422,6 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) token->type = CPP_KEYWORD; /* Record which keyword. */ token->keyword = C_RID_CODE (token->u.value); - /* Update the value. Some keywords are mapped to particular - entities, rather than simply having the value of the - corresponding IDENTIFIER_NODE. For example, `__const' is - mapped to `const'. */ - token->u.value = ridpointers[token->keyword]; } else { @@ -436,8 +432,8 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) /* Warn about the C++0x keyword (but still treat it as an identifier). */ warning (OPT_Wc__0x_compat, - "identifier %<%s%> will become a keyword in C++0x", - IDENTIFIER_POINTER (token->u.value)); + "identifier %qE will become a keyword in C++0x", + token->u.value); /* Clear out the C_RID_CODE so we don't warn about this particular identifier-turned-keyword again. */ @@ -468,7 +464,8 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) else if (token->type == CPP_PRAGMA) { /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ - token->pragma_kind = TREE_INT_CST_LOW (token->u.value); + token->pragma_kind = ((enum pragma_kind) + TREE_INT_CST_LOW (token->u.value)); token->u.value = NULL_TREE; } } @@ -795,6 +792,7 @@ cp_lexer_print_token (FILE * stream, cp_token *token) case CPP_STRING16: case CPP_STRING32: case CPP_WSTRING: + case CPP_UTF8STRING: fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value)); break; @@ -891,6 +889,7 @@ make_declarator (cp_declarator_kind kind) declarator->attributes = NULL_TREE; declarator->declarator = NULL; declarator->parameter_pack_p = false; + declarator->id_loc = UNKNOWN_LOCATION; return declarator; } @@ -1190,16 +1189,24 @@ function_declarator_p (const cp_declarator *declarator) /* Flags that are passed to some parsing functions. These values can be bitwise-ored together. */ -typedef enum cp_parser_flags +enum { /* No flags. */ CP_PARSER_FLAGS_NONE = 0x0, /* The construct is optional. If it is not present, then no error should be issued. */ CP_PARSER_FLAGS_OPTIONAL = 0x1, - /* When parsing a type-specifier, do not allow user-defined types. */ - CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2 -} cp_parser_flags; + /* When parsing a type-specifier, treat user-defined type-names + as non-type identifiers. */ + CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2, + /* When parsing a type-specifier, do not try to parse a class-specifier + or enum-specifier. */ + CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4 +}; + +/* This type is used for parameters and variables which hold + combinations of the above flags. */ +typedef int cp_parser_flags; /* The different kinds of declarators we want to parse. */ @@ -1271,7 +1278,7 @@ typedef struct cp_parser_expression_stack_entry /* Tree code for the binary operation we are parsing. */ enum tree_code tree_type; /* Precedence of the binary operation we are parsing. */ - int prec; + enum cp_parser_prec prec; } cp_parser_expression_stack_entry; /* The stack for storing partial expressions. We only need NUM_PREC_VALUES @@ -1281,8 +1288,7 @@ typedef struct cp_parser_expression_stack_entry cp_parser_expression_stack[NUM_PREC_VALUES]; /* Context that is saved and restored when parsing tentatively. */ -typedef struct cp_parser_context GTY (()) -{ +typedef struct GTY (()) cp_parser_context { /* If this is a tentative parsing context, the status of the tentative parse. */ enum cp_parser_status_kind status; @@ -1388,8 +1394,7 @@ cp_parser_context_new (cp_parser_context* next) /* The cp_parser structure represents the C++ parser. */ -typedef struct cp_parser GTY(()) -{ +typedef struct GTY(()) cp_parser { /* The lexer from which we are obtaining tokens. */ cp_lexer *lexer; @@ -1589,8 +1594,10 @@ static tree cp_parser_postfix_open_square_expression (cp_parser *, tree, bool); static tree cp_parser_postfix_dot_deref_expression (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t); -static tree cp_parser_parenthesized_expression_list - (cp_parser *, bool, bool, bool, bool *); +static VEC(tree,gc) *cp_parser_parenthesized_expression_list + (cp_parser *, int, bool, bool, bool *); +/* Values for the second parameter of cp_parser_parenthesized_expression_list. */ +enum { non_attr = 0, normal_attr = 1, id_attr = 2 }; static void cp_parser_pseudo_destructor_name (cp_parser *, tree *, tree *); static tree cp_parser_unary_expression @@ -1599,7 +1606,7 @@ static enum tree_code cp_parser_unary_operator (cp_token *); static tree cp_parser_new_expression (cp_parser *); -static tree cp_parser_new_placement +static VEC(tree,gc) *cp_parser_new_placement (cp_parser *); static tree cp_parser_new_type_id (cp_parser *, tree *); @@ -1607,7 +1614,7 @@ static cp_declarator *cp_parser_new_declarator_opt (cp_parser *); static cp_declarator *cp_parser_direct_new_declarator (cp_parser *); -static tree cp_parser_new_initializer +static VEC(tree,gc) *cp_parser_new_initializer (cp_parser *); static tree cp_parser_delete_expression (cp_parser *); @@ -1627,6 +1634,14 @@ static tree cp_parser_constant_expression (cp_parser *, bool, bool *); static tree cp_parser_builtin_offsetof (cp_parser *); +static tree cp_parser_lambda_expression + (cp_parser *); +static void cp_parser_lambda_introducer + (cp_parser *, tree); +static void cp_parser_lambda_declarator_opt + (cp_parser *, tree); +static void cp_parser_lambda_body + (cp_parser *, tree); /* Statements [gram.stmt.stmt] */ @@ -1734,10 +1749,11 @@ static tree cp_parser_type_id (cp_parser *); static tree cp_parser_template_type_arg (cp_parser *); +static tree cp_parser_trailing_type_id (cp_parser *); static tree cp_parser_type_id_1 - (cp_parser *, bool); + (cp_parser *, bool, bool); static void cp_parser_type_specifier_seq - (cp_parser *, bool, cp_decl_specifier_seq *); + (cp_parser *, bool, bool, cp_decl_specifier_seq *); static tree cp_parser_parameter_declaration_clause (cp_parser *); static tree cp_parser_parameter_declaration_list @@ -1860,6 +1876,8 @@ static tree cp_parser_asm_operand_list (cp_parser *); static tree cp_parser_asm_clobber_list (cp_parser *); +static tree cp_parser_asm_label_list + (cp_parser *); static tree cp_parser_attributes_opt (cp_parser *); static tree cp_parser_attribute_list @@ -1913,7 +1931,7 @@ static tree cp_parser_maybe_treat_template_as_class static bool cp_parser_check_declarator_template_parameters (cp_parser *, cp_declarator *, location_t); static bool cp_parser_check_template_parameters - (cp_parser *, unsigned, location_t); + (cp_parser *, unsigned, location_t, cp_declarator *); static tree cp_parser_simple_cast_expression (cp_parser *); static tree cp_parser_global_scope_opt @@ -2051,7 +2069,8 @@ cp_parser_is_string_literal (cp_token* token) return (token->type == CPP_STRING || token->type == CPP_STRING16 || token->type == CPP_STRING32 || - token->type == CPP_WSTRING); + token->type == CPP_WSTRING || + token->type == CPP_UTF8STRING); } /* Returns nonzero if TOKEN is the indicated KEYWORD. */ @@ -2080,7 +2099,8 @@ cp_parser_error (cp_parser* parser, const char* message) if (token->type == CPP_PRAGMA) { - error ("%H%<#pragma%> is not allowed here", &token->location); + error_at (token->location, + "%<#pragma%> is not allowed here"); cp_parser_skip_to_pragma_eol (parser, token); return; } @@ -2090,7 +2110,7 @@ cp_parser_error (cp_parser* parser, const char* message) CPP_KEYWORD, keywords are treated like identifiers. */ (token->type == CPP_KEYWORD ? CPP_NAME : token->type), - token->u.value); + token->u.value, token->flags); } } @@ -2111,26 +2131,26 @@ cp_parser_name_lookup_error (cp_parser* parser, if (decl == error_mark_node) { if (parser->scope && parser->scope != global_namespace) - error ("%H%<%E::%E%> has not been declared", - &location, parser->scope, name); + error_at (location, "%<%E::%E%> has not been declared", + parser->scope, name); else if (parser->scope == global_namespace) - error ("%H%<::%E%> has not been declared", &location, name); + error_at (location, "%<::%E%> has not been declared", name); else if (parser->object_scope && !CLASS_TYPE_P (parser->object_scope)) - error ("%Hrequest for member %qE in non-class type %qT", - &location, name, parser->object_scope); + error_at (location, "request for member %qE in non-class type %qT", + name, parser->object_scope); else if (parser->object_scope) - error ("%H%<%T::%E%> has not been declared", - &location, parser->object_scope, name); + error_at (location, "%<%T::%E%> has not been declared", + parser->object_scope, name); else - error ("%H%qE has not been declared", &location, name); + error_at (location, "%qE has not been declared", name); } else if (parser->scope && parser->scope != global_namespace) - error ("%H%<%E::%E%> %s", &location, parser->scope, name, desired); + error_at (location, "%<%E::%E%> %s", parser->scope, name, desired); else if (parser->scope == global_namespace) - error ("%H%<::%E%> %s", &location, name, desired); + error_at (location, "%<::%E%> %s", name, desired); else - error ("%H%qE %s", &location, name, desired); + error_at (location, "%qE %s", name, desired); } /* If we are parsing tentatively, remember that an error has occurred @@ -2154,22 +2174,21 @@ static void cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs, location_t location) { - cp_decl_spec ds; + int ds; for (ds = ds_first; ds != ds_last; ++ds) { - unsigned count = decl_specs->specs[(int)ds]; + unsigned count = decl_specs->specs[ds]; if (count < 2) continue; /* The "long" specifier is a special case because of "long long". */ if (ds == ds_long) { if (count > 2) - error ("%H% is too long for GCC", &location); - else if (pedantic && !in_system_header && warn_long_long - && cxx_dialect == cxx98) - pedwarn (location, OPT_Wlong_long, - "ISO C++ 1998 does not support %"); + error_at (location, "% is too long for GCC"); + else + pedwarn_cxx98 (location, OPT_Wlong_long, + "ISO C++ 1998 does not support %"); } else if (count > 1) { @@ -2186,10 +2205,11 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs, "explicit", "friend", "typedef", + "constexpr", "__complex", "__thread" }; - error ("%Hduplicate %qs", &location, decl_spec_names[(int)ds]); + error_at (location, "duplicate %qs", decl_spec_names[ds]); } } } @@ -2233,7 +2253,8 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, if (declarator && declarator->kind == cdk_function) { - error ("%Hnew types may not be defined in a return type", &type_location); + error_at (type_location, + "new types may not be defined in a return type"); inform (type_location, "(perhaps a semicolon is missing after the definition of %qT)", type); @@ -2255,11 +2276,11 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) { if (TYPE_P (type)) - error ("%H%qT is not a template", &location, type); + error_at (location, "%qT is not a template", type); else if (TREE_CODE (type) == IDENTIFIER_NODE) - error ("%H%qE is not a template", &location, type); + error_at (location, "%qE is not a template", type); else - error ("%Hinvalid template-id", &location); + error_at (location, "invalid template-id"); /* Remember the location of the invalid "<". */ if (cp_parser_uncommitted_to_tentative_parse_p (parser)) start = cp_lexer_token_position (parser->lexer, true); @@ -2321,18 +2342,18 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, /* If the lookup found a template-name, it means that the user forgot to specify an argument list. Emit a useful error message. */ if (TREE_CODE (decl) == TEMPLATE_DECL) - error ("%Hinvalid use of template-name %qE without an argument list", - &location, decl); + error_at (location, + "invalid use of template-name %qE without an argument list", + decl); else if (TREE_CODE (id) == BIT_NOT_EXPR) - error ("%Hinvalid use of destructor %qD as a type", &location, id); + error_at (location, "invalid use of destructor %qD as a type", id); else if (TREE_CODE (decl) == TYPE_DECL) /* Something like 'unsigned A a;' */ - error ("%Hinvalid combination of multiple type-specifiers", - &location); + error_at (location, "invalid combination of multiple type-specifiers"); else if (!parser->scope) { /* Issue an error message. */ - error ("%H%qE does not name a type", &location, id); + error_at (location, "%qE does not name a type", id); /* If we're in a template class, it's possible that the user was referring to a type from a base class. For example: @@ -2380,11 +2401,26 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, else if (parser->scope != error_mark_node) { if (TREE_CODE (parser->scope) == NAMESPACE_DECL) - error ("%H%qE in namespace %qE does not name a type", - &location, id, parser->scope); + error_at (location, "%qE in namespace %qE does not name a type", + id, parser->scope); + else if (CLASS_TYPE_P (parser->scope) + && constructor_name_p (id, parser->scope)) + { + /* A::A() */ + error_at (location, "%<%T::%E%> names the constructor, not" + " the type", parser->scope, id); + if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + error_at (location, "and %qT has no template constructors", + parser->scope); + } + else if (TYPE_P (parser->scope) + && dependent_scope_p (parser->scope)) + error_at (location, "need % before %<%T::%E%> because " + "%qT is a dependent scope", + parser->scope, id, parser->scope); else if (TYPE_P (parser->scope)) - error ("%H%qE in class %qT does not name a type", - &location, id, parser->scope); + error_at (location, "%qE in class %qT does not name a type", + id, parser->scope); else gcc_unreachable (); } @@ -2407,6 +2443,14 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) tree id; cp_token *token = cp_lexer_peek_token (parser->lexer); + /* Avoid duplicate error about ambiguous lookup. */ + if (token->type == CPP_NESTED_NAME_SPECIFIER) + { + cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2); + if (next->type == CPP_NAME && next->ambiguous_p) + goto out; + } + cp_parser_parse_tentatively (parser); id = cp_parser_id_expression (parser, /*template_keyword_p=*/false, @@ -2414,12 +2458,9 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) /*template_p=*/NULL, /*declarator_p=*/true, /*optional_p=*/false); - /* After the id-expression, there should be a plain identifier, - otherwise this is not a simple variable declaration. Also, if - the scope is dependent, we cannot do much. */ - if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME) - || (parser->scope && TYPE_P (parser->scope) - && dependent_type_p (parser->scope)) + /* If the next token is a (, this is a function with no explicit return + type, i.e. constructor, destructor or conversion op. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) || TREE_CODE (id) == TYPE_DECL) { cp_parser_abort_tentative_parse (parser); @@ -2431,9 +2472,12 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) /* Emit a diagnostic for the invalid type. */ cp_parser_diagnose_invalid_type_name (parser, parser->scope, id, token->location); - /* Skip to the end of the declaration; there's no point in - trying to process it. */ - cp_parser_skip_to_end_of_block_or_statement (parser); + out: + /* If we aren't in the middle of a declarator (i.e. in a + parameter-declaration-clause), skip to the end of the declaration; + there's no point in trying to process it. */ + if (!parser->in_declarator_p) + cp_parser_skip_to_end_of_block_or_statement (parser); return true; } @@ -2450,6 +2494,7 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser, { unsigned paren_depth = 0; unsigned brace_depth = 0; + unsigned square_depth = 0; if (recovering && !or_comma && cp_parser_uncommitted_to_tentative_parse_p (parser)) @@ -2466,6 +2511,15 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser, /* If we've run out of tokens, then there is no closing `)'. */ return 0; + /* This is good for lambda expression capture-lists. */ + case CPP_OPEN_SQUARE: + ++square_depth; + break; + case CPP_CLOSE_SQUARE: + if (!square_depth--) + return 0; + break; + case CPP_SEMICOLON: /* This matches the processing in skip_to_end_of_statement. */ if (!brace_depth) @@ -2481,7 +2535,8 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser, break; case CPP_COMMA: - if (recovering && or_comma && !brace_depth && !paren_depth) + if (recovering && or_comma && !brace_depth && !paren_depth + && !square_depth) return -1; break; @@ -2623,6 +2678,8 @@ cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser) /* Stop if this is an unnested '}', or closes the outermost nesting level. */ nesting_depth--; + if (nesting_depth < 0) + return; if (!nesting_depth) nesting_depth = -1; break; @@ -2945,8 +3002,9 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) if (type == CPP_STRING) type = tok->type; else if (tok->type != CPP_STRING) - error ("%Hunsupported non-standard concatenation " - "of string literals", &tok->location); + error_at (tok->location, + "unsupported non-standard concatenation " + "of string literals"); } obstack_grow (&str_ob, &str, sizeof (cpp_string)); @@ -2974,6 +3032,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) { default: case CPP_STRING: + case CPP_UTF8STRING: TREE_TYPE (value) = char_array_type_node; break; case CPP_STRING16: @@ -3148,8 +3207,8 @@ cp_parser_primary_expression (cp_parser *parser, token = cp_lexer_consume_token (parser->lexer); if (TREE_CODE (token->u.value) == FIXED_CST) { - error ("%Hfixed-point types not supported in C++", - &token->location); + error_at (token->location, + "fixed-point types not supported in C++"); return error_mark_node; } /* Floating-point literals are only allowed in an integral @@ -3203,6 +3262,7 @@ cp_parser_primary_expression (cp_parser *parser, case CPP_STRING16: case CPP_STRING32: case CPP_WSTRING: + case CPP_UTF8STRING: /* ??? Should wide strings be allowed when parser->translate_strings_p is false (i.e. in attributes)? If not, we can kill the third argument to cp_parser_string_literal. */ @@ -3240,9 +3300,9 @@ cp_parser_primary_expression (cp_parser *parser, if (!parser->in_function_body || parser->in_template_argument_list_p) { - error ("%Hstatement-expressions are not allowed outside " - "functions nor in template-argument lists", - &token->location); + error_at (token->location, + "statement-expressions are not allowed outside " + "functions nor in template-argument lists"); cp_parser_skip_to_end_of_block_or_statement (parser); expr = error_mark_node; } @@ -3278,6 +3338,20 @@ cp_parser_primary_expression (cp_parser *parser, return expr; } + case CPP_OPEN_SQUARE: + if (c_dialect_objc ()) + /* We have an Objective-C++ message. */ + return cp_parser_objc_expression (parser); + maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR); + return cp_parser_lambda_expression (parser); + + case CPP_OBJC_STRING: + if (c_dialect_objc ()) + /* We have an Objective-C++ string literal. */ + return cp_parser_objc_expression (parser); + cp_parser_error (parser, "expected primary-expression"); + return error_mark_node; + case CPP_KEYWORD: switch (token->keyword) { @@ -3294,13 +3368,18 @@ cp_parser_primary_expression (cp_parser *parser, cp_lexer_consume_token (parser->lexer); return null_node; + /* The `nullptr' literal. */ + case RID_NULLPTR: + cp_lexer_consume_token (parser->lexer); + return nullptr_node; + /* Recognize the `this' keyword. */ case RID_THIS: cp_lexer_consume_token (parser->lexer); if (parser->local_variables_forbidden_p) { - error ("%H% may not be used in this context", - &token->location); + error_at (token->location, + "% may not be used in this context"); return error_mark_node; } /* Pointers cannot appear in constant-expressions. */ @@ -3396,6 +3475,8 @@ cp_parser_primary_expression (cp_parser *parser, case RID_IS_ENUM: case RID_IS_POD: case RID_IS_POLYMORPHIC: + case RID_IS_STD_LAYOUT: + case RID_IS_TRIVIAL: case RID_IS_UNION: return cp_parser_trait_expr (parser, token->keyword); @@ -3455,6 +3536,16 @@ cp_parser_primary_expression (cp_parser *parser, { tree ambiguous_decls; + /* If we already know that this lookup is ambiguous, then + we've already issued an error message; there's no reason + to check again. */ + if (id_expr_token->type == CPP_NAME + && id_expr_token->ambiguous_p) + { + cp_parser_simulate_error (parser); + return error_mark_node; + } + decl = cp_parser_lookup_name (parser, id_expression, none_type, template_p, @@ -3508,8 +3599,9 @@ cp_parser_primary_expression (cp_parser *parser, decl = check_for_out_of_scope_variable (decl); if (local_variable_p (decl)) { - error ("%Hlocal variable %qD may not appear in this context", - &id_expr_token->location, decl); + error_at (id_expr_token->location, + "local variable %qD may not appear in this context", + decl); return error_mark_node; } } @@ -3532,13 +3624,6 @@ cp_parser_primary_expression (cp_parser *parser, /* Anything else is an error. */ default: - /* ...unless we have an Objective-C++ message or string literal, - that is. */ - if (c_dialect_objc () - && (token->type == CPP_OPEN_SQUARE - || token->type == CPP_OBJC_STRING)) - return cp_parser_objc_expression (parser); - cp_parser_error (parser, "expected primary-expression"); return error_mark_node; } @@ -3808,8 +3893,9 @@ cp_parser_unqualified_id (cp_parser* parser, if (scope && TREE_CODE (scope) == NAMESPACE_DECL) { if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("%Hscope %qT before %<~%> is not a class-name", - &token->location, scope); + error_at (token->location, + "scope %qT before %<~%> is not a class-name", + scope); cp_parser_simulate_error (parser); if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) cp_lexer_consume_token (parser->lexer); @@ -3817,20 +3903,26 @@ cp_parser_unqualified_id (cp_parser* parser, } gcc_assert (!scope || TYPE_P (scope)); - /* If the name is of the form "X::~X" it's OK. */ + /* If the name is of the form "X::~X" it's OK even if X is a + typedef. */ token = cp_lexer_peek_token (parser->lexer); if (scope && token->type == CPP_NAME && (cp_lexer_peek_nth_token (parser->lexer, 2)->type - == CPP_OPEN_PAREN) - && constructor_name_p (token->u.value, scope)) + != CPP_LESS) + && (token->u.value == TYPE_IDENTIFIER (scope) + || constructor_name_p (token->u.value, scope))) { cp_lexer_consume_token (parser->lexer); return build_nt (BIT_NOT_EXPR, scope); } /* If there was an explicit qualification (S::~T), first look - in the scope given by the qualification (i.e., S). */ + in the scope given by the qualification (i.e., S). + + Note: in the calls to cp_parser_class_name below we pass + typename_type so that lookup finds the injected-class-name + rather than the constructor. */ done = false; type_decl = NULL_TREE; if (scope) @@ -3839,7 +3931,7 @@ cp_parser_unqualified_id (cp_parser* parser, type_decl = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - none_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3857,7 +3949,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - none_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3875,7 +3967,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - none_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3894,7 +3986,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - none_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3922,8 +4014,9 @@ cp_parser_unqualified_id (cp_parser* parser, if (declarator_p && scope && !check_dtor_name (scope, type_decl)) { if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("%Hdeclaration of %<~%T%> as member of %qT", - &token->location, type_decl, scope); + error_at (token->location, + "declaration of %<~%T%> as member of %qT", + type_decl, scope); cp_parser_simulate_error (parser); return error_mark_node; } @@ -3936,8 +4029,9 @@ cp_parser_unqualified_id (cp_parser* parser, && !DECL_IMPLICIT_TYPEDEF_P (type_decl) && !DECL_SELF_REFERENCE_P (type_decl) && !cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("%Htypedef-name %qD used as destructor declarator", - &token->location, type_decl); + error_at (token->location, + "typedef-name %qD used as destructor declarator", + type_decl); return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); } @@ -4150,12 +4244,14 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, &ambiguous_decls, token->location); if (TREE_CODE (decl) == TEMPLATE_DECL) - error ("%H%qD used without template parameters", - &token->location, decl); + error_at (token->location, + "%qD used without template parameters", + decl); else if (ambiguous_decls) { - error ("%Hreference to %qD is ambiguous", - &token->location, token->u.value); + error_at (token->location, + "reference to %qD is ambiguous", + token->u.value); print_candidates (ambiguous_decls); decl = error_mark_node; } @@ -4353,6 +4449,16 @@ cp_parser_qualifying_entity (cp_parser *parser, /* Parse a typedef-name or enum-name. */ scope = cp_parser_nonclass_name (parser); + + /* "If the name found does not designate a namespace or a class, + enumeration, or dependent type, the program is ill-formed." + + We cover classes and dependent types above and namespaces below, + so this code is only looking for enums. */ + if (!scope || TREE_CODE (scope) != TYPE_DECL + || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE) + cp_parser_simulate_error (parser); + successful_parse_p = cp_parser_parse_definitely (parser); } /* If that didn't work, try for a namespace-name. */ @@ -4451,7 +4557,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* New types cannot be defined in the cast. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in casts"; + = G_("types may not be defined in casts"); /* Look for the opening `<'. */ cp_parser_require (parser, CPP_LESS, "%<<%>"); @@ -4514,7 +4620,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Types cannot be defined in a `typeid' expression. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in a % expression"; + = G_("types may not be defined in a % expression"); /* We can't be sure yet whether we're looking at a type-id or an expression. */ cp_parser_parse_tentatively (parser); @@ -4689,7 +4795,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, bool is_builtin_constant_p; bool saved_integral_constant_expression_p = false; bool saved_non_integral_constant_expression_p = false; - tree args; + VEC(tree,gc) *args; is_member_access = false; @@ -4706,7 +4812,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, parser->integral_constant_expression_p = false; } args = (cp_parser_parenthesized_expression_list - (parser, /*is_attribute_list=*/false, + (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); if (is_builtin_constant_p) @@ -4717,7 +4823,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, = saved_non_integral_constant_expression_p; } - if (args == error_mark_node) + if (args == NULL) { postfix_expression = error_mark_node; break; @@ -4730,6 +4836,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, "a function call")) { postfix_expression = error_mark_node; + release_tree_vector (args); break; } @@ -4739,7 +4846,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, { if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) { - if (args) + if (!VEC_empty (tree, args)) { koenig_p = true; if (!any_type_dependent_arguments_p (args)) @@ -4753,17 +4860,17 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* We do not perform argument-dependent lookup if normal lookup finds a non-function, in accordance with the expected resolution of DR 218. */ - else if (args && is_overloaded_fn (postfix_expression)) + else if (!VEC_empty (tree, args) + && is_overloaded_fn (postfix_expression)) { tree fn = get_first_fn (postfix_expression); + fn = STRIP_TEMPLATE (fn); - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = OVL_CURRENT (TREE_OPERAND (fn, 0)); - - /* Only do argument dependent lookup if regular - lookup does not find a set of member functions. - [basic.lookup.koenig]/2a */ - if (!DECL_FUNCTION_MEMBER_P (fn)) + /* Do not do argument dependent lookup if regular + lookup finds a member function or a block-scope + function declaration. [basic.lookup.argdep]/3 */ + if (!DECL_FUNCTION_MEMBER_P (fn) + && !DECL_LOCAL_FUNCTION_P (fn)) { koenig_p = true; if (!any_type_dependent_arguments_p (args)) @@ -4786,7 +4893,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, || any_type_dependent_arguments_p (args))) { postfix_expression - = build_nt_call_list (postfix_expression, args); + = build_nt_call_vec (postfix_expression, args); + release_tree_vector (args); break; } @@ -4794,7 +4902,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, { postfix_expression = (build_new_method_call - (instance, fn, args, NULL_TREE, + (instance, fn, &args, NULL_TREE, (idk == CP_ID_KIND_QUALIFIED ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL), /*fn_p=*/NULL, @@ -4802,7 +4910,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } else postfix_expression - = finish_call_expr (postfix_expression, args, + = finish_call_expr (postfix_expression, &args, /*disallow_virtual=*/false, /*koenig_p=*/false, tf_warning_or_error); @@ -4811,25 +4919,27 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, || TREE_CODE (postfix_expression) == MEMBER_REF || TREE_CODE (postfix_expression) == DOTSTAR_EXPR) postfix_expression = (build_offset_ref_call_from_tree - (postfix_expression, args)); + (postfix_expression, &args)); else if (idk == CP_ID_KIND_QUALIFIED) /* A call to a static class member, or a namespace-scope function. */ postfix_expression - = finish_call_expr (postfix_expression, args, + = finish_call_expr (postfix_expression, &args, /*disallow_virtual=*/true, koenig_p, tf_warning_or_error); else /* All other function calls. */ postfix_expression - = finish_call_expr (postfix_expression, args, + = finish_call_expr (postfix_expression, &args, /*disallow_virtual=*/false, koenig_p, tf_warning_or_error); /* The POSTFIX_EXPRESSION is certainly no longer an id. */ idk = CP_ID_KIND_NONE; + + release_tree_vector (args); } break; @@ -4997,7 +5107,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, /* The type of the POSTFIX_EXPRESSION must be complete. */ if (scope == unknown_type_node) { - error ("%H%qE does not have class type", &location, postfix_expression); + error_at (location, "%qE does not have class type", + postfix_expression); scope = NULL_TREE; } else @@ -5081,7 +5192,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, TYPE_DECL here. That is invalid code. */ if (TREE_CODE (name) == TYPE_DECL) { - error ("%Hinvalid use of %qD", &token->location, name); + error_at (token->location, "invalid use of %qD", name); postfix_expression = error_mark_node; } else @@ -5136,25 +5247,25 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ALLOW_EXPANSION_P is true if this expression allows expansion of an argument pack. - Returns a TREE_LIST. The TREE_VALUE of each node is a - representation of an assignment-expression. Note that a TREE_LIST - is returned even if there is only a single expression in the list. - error_mark_node is returned if the ( and or ) are - missing. NULL_TREE is returned on no expressions. The parentheses - are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute - list being parsed. If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P - indicates whether or not all of the expressions in the list were - constant. */ - -static tree + Returns a vector of trees. Each element is a representation of an + assignment-expression. NULL is returned if the ( and or ) are + missing. An empty, but allocated, vector is returned on no + expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr + if we are parsing an attribute list for an attribute that wants a + plain identifier argument, normal_attr for an attribute that wants + an expression, or non_attr if we aren't parsing an attribute list. If + NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or + not all of the expressions in the list were constant. */ + +static VEC(tree,gc) * cp_parser_parenthesized_expression_list (cp_parser* parser, - bool is_attribute_list, + int is_attribute_list, bool cast_p, bool allow_expansion_p, bool *non_constant_p) { - tree expression_list = NULL_TREE; - bool fold_expr_p = is_attribute_list; + VEC(tree,gc) *expression_list; + bool fold_expr_p = is_attribute_list != non_attr; tree identifier = NULL_TREE; bool saved_greater_than_is_operator_p; @@ -5163,7 +5274,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, *non_constant_p = false; if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) - return error_mark_node; + return NULL; + + expression_list = make_tree_vector (); /* Within a parenthesized expression, a `>' token is always the greater-than operator. */ @@ -5179,7 +5292,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, /* At the beginning of attribute lists, check to see if the next token is an identifier. */ - if (is_attribute_list + if (is_attribute_list == id_attr && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME) { cp_token *token; @@ -5197,7 +5310,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { /* A braced-init-list. */ - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); expr = cp_parser_braced_list (parser, &expr_non_constant_p); if (non_constant_p && expr_non_constant_p) *non_constant_p = true; @@ -5232,7 +5345,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, expressions to the list, so that we can still tell if the correct form for a parenthesized expression-list is found. That gives better errors. */ - expression_list = tree_cons (NULL_TREE, expr, expression_list); + VEC_safe_push (tree, gc, expression_list, expr); if (expr == error_mark_node) goto skip_comma; @@ -5240,7 +5353,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, /* After the first item, attribute lists look the same as expression lists. */ - is_attribute_list = false; + is_attribute_list = non_attr; get_comma:; /* If the next token isn't a `,', then we are done. */ @@ -5268,17 +5381,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, { parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; - return error_mark_node; + return NULL; } } 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) - expression_list = tree_cons (NULL_TREE, identifier, expression_list); + VEC_safe_insert (tree, gc, expression_list, 0, identifier); return expression_list; } @@ -5539,7 +5650,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, { case INDIRECT_REF: non_constant_p = "%<*%>"; - expression = build_x_indirect_ref (cast_expression, "unary *", + expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR, tf_warning_or_error); break; @@ -5622,10 +5733,11 @@ static tree cp_parser_new_expression (cp_parser* parser) { bool global_scope_p; - tree placement; + VEC(tree,gc) *placement; tree type; - tree initializer; + VEC(tree,gc) *initializer; tree nelts; + tree ret; /* Look for the optional `::' operator. */ global_scope_p @@ -5641,7 +5753,11 @@ cp_parser_new_expression (cp_parser* parser) placement = cp_parser_new_placement (parser); /* If that didn't work out, there's no new-placement. */ if (!cp_parser_parse_definitely (parser)) - placement = NULL_TREE; + { + if (placement != NULL) + release_tree_vector (placement); + placement = NULL; + } /* If the next token is a `(', then we have a parenthesized type-id. */ @@ -5660,8 +5776,8 @@ cp_parser_new_expression (cp_parser* parser) message for this case. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { - error ("%Harray bound forbidden after parenthesized type-id", - &token->location); + error_at (token->location, + "array bound forbidden after parenthesized type-id"); inform (token->location, "try removing the parentheses around the type-id"); cp_parser_direct_new_declarator (parser); @@ -5677,16 +5793,25 @@ cp_parser_new_expression (cp_parser* parser) || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) initializer = cp_parser_new_initializer (parser); else - initializer = NULL_TREE; + initializer = NULL; /* A new-expression may not appear in an integral constant expression. */ if (cp_parser_non_integral_constant_expression (parser, "%")) - return error_mark_node; + ret = error_mark_node; + else + { + /* Create a representation of the new-expression. */ + ret = build_new (&placement, type, nelts, &initializer, global_scope_p, + tf_warning_or_error); + } - /* Create a representation of the new-expression. */ - return build_new (placement, type, nelts, initializer, global_scope_p, - tf_warning_or_error); + if (placement != NULL) + release_tree_vector (placement); + if (initializer != NULL) + release_tree_vector (initializer); + + return ret; } /* Parse a new-placement. @@ -5696,14 +5821,15 @@ cp_parser_new_expression (cp_parser* parser) Returns the same representation as for an expression-list. */ -static tree +static VEC(tree,gc) * cp_parser_new_placement (cp_parser* parser) { - tree expression_list; + VEC(tree,gc) *expression_list; /* Parse the expression-list. */ expression_list = (cp_parser_parenthesized_expression_list - (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, + (parser, non_attr, /*cast_p=*/false, + /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); return expression_list; @@ -5734,9 +5860,10 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts) complete.) */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in a new-type-id"; + = G_("types may not be defined in a new-type-id"); /* Parse the type-specifier-seq. */ - cp_parser_type_specifier_seq (parser, /*is_condition=*/false, + cp_parser_type_specifier_seq (parser, /*is_declaration=*/false, + /*is_trailing_return=*/false, &type_specifier_seq); /* Restore the old message. */ parser->type_definition_forbidden_message = saved_message; @@ -5856,8 +5983,9 @@ cp_parser_direct_new_declarator (cp_parser* parser) /*complain=*/true); if (!expression) { - error ("%Hexpression in new-declarator must have integral " - "or enumeration type", &token->location); + error_at (token->location, + "expression in new-declarator must have integral " + "or enumeration type"); expression = error_mark_node; } } @@ -5889,28 +6017,27 @@ cp_parser_direct_new_declarator (cp_parser* parser) ( expression-list [opt] ) braced-init-list - Returns a representation of the expression-list. If there is no - expression-list, VOID_ZERO_NODE is returned. */ + Returns a representation of the expression-list. */ -static tree +static VEC(tree,gc) * cp_parser_new_initializer (cp_parser* parser) { - tree expression_list; + VEC(tree,gc) *expression_list; if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { + tree t; bool expr_non_constant_p; - maybe_warn_cpp0x ("extended initializer lists"); - expression_list = cp_parser_braced_list (parser, &expr_non_constant_p); - CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1; - expression_list = build_tree_list (NULL_TREE, expression_list); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); + t = cp_parser_braced_list (parser, &expr_non_constant_p); + CONSTRUCTOR_IS_DIRECT_INIT (t) = 1; + expression_list = make_tree_vector_single (t); } else expression_list = (cp_parser_parenthesized_expression_list - (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, + (parser, non_attr, /*cast_p=*/false, + /*allow_expansion_p=*/true, /*non_constant_p=*/NULL)); - if (!expression_list) - expression_list = void_zero_node; return expression_list; } @@ -6047,7 +6174,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, /* Types may not be defined in a cast. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in casts"; + = G_("types may not be defined in casts"); /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); /* A very tricky bit is that `(struct S) { 3 }' is a @@ -6124,7 +6251,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, return error_mark_node; /* Perform the cast. */ - expr = build_c_cast (type, expr); + expr = build_c_cast (input_location, type, expr); return expr; } else @@ -6242,11 +6369,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, && token->type == CPP_RSHIFT && !parser->greater_than_is_operator_p) { - warning (OPT_Wc__0x_compat, - "%H%<>>%> operator will be treated as two right angle brackets in C++0x", - &token->location); - warning (OPT_Wc__0x_compat, - "suggest parentheses around %<>>%> expression"); + if (warning_at (token->location, OPT_Wc__0x_compat, + "%<>>%> operator will be treated as" + " two right angle brackets in C++0x")) + inform (token->location, + "suggest parentheses around %<>>%> expression"); } new_prec = TOKEN_PRECEDENCE (token); @@ -6272,6 +6399,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, /* We used the operator token. */ cp_lexer_consume_token (parser->lexer); + /* For "false && x" or "true || x", x will never be executed; + disable warnings while evaluating it. */ + if (tree_type == TRUTH_ANDIF_EXPR) + c_inhibit_evaluation_warnings += lhs == truthvalue_false_node; + else if (tree_type == TRUTH_ORIF_EXPR) + c_inhibit_evaluation_warnings += lhs == truthvalue_true_node; + /* Extract another operand. It may be the RHS of this expression or the LHS of a new, higher priority expression. */ rhs = cp_parser_simple_cast_expression (parser); @@ -6317,6 +6451,12 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, lhs_type = sp->lhs_type; } + /* Undo the disabling of warnings done above. */ + if (tree_type == TRUTH_ANDIF_EXPR) + c_inhibit_evaluation_warnings -= lhs == truthvalue_false_node; + else if (tree_type == TRUTH_ORIF_EXPR) + c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node; + overloaded_p = false; /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type == ERROR_MARK for everything that is not a binary expression. @@ -6374,16 +6514,26 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) cp_lexer_consume_token (parser->lexer); if (cp_parser_allow_gnu_extensions_p (parser) && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - /* Implicit true clause. */ - expr = NULL_TREE; + { + /* Implicit true clause. */ + expr = NULL_TREE; + c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node; + } else - /* Parse the expression. */ - expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + { + /* Parse the expression. */ + c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node; + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + c_inhibit_evaluation_warnings += + ((logical_or_expr == truthvalue_true_node) + - (logical_or_expr == truthvalue_false_node)); + } /* The next token should be a `:'. */ cp_parser_require (parser, CPP_COLON, "%<:%>"); /* Parse the assignment-expression. */ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); + c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node; /* Build the conditional-expression. */ return build_x_conditional_expr (logical_or_expr, @@ -6440,7 +6590,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, tree rhs = cp_parser_initializer_clause (parser, &non_constant_p); if (BRACE_ENCLOSED_INITIALIZER_P (rhs)) - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); /* An assignment may not appear in a constant-expression. */ @@ -6816,6 +6966,12 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case RID_IS_POLYMORPHIC: kind = CPTK_IS_POLYMORPHIC; break; + case RID_IS_STD_LAYOUT: + kind = CPTK_IS_STD_LAYOUT; + break; + case RID_IS_TRIVIAL: + kind = CPTK_IS_TRIVIAL; + break; case RID_IS_UNION: kind = CPTK_IS_UNION; break; @@ -6866,6 +7022,523 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) return finish_trait_expr (kind, type1, type2); } +/* Lambdas that appear in variable initializer or default argument scope + get that in their mangling, so we need to record it. We might as well + use the count for function and namespace scopes as well. */ +static GTY(()) tree lambda_scope; +static GTY(()) int lambda_count; +typedef struct GTY(()) tree_int +{ + tree t; + int i; +} tree_int; +DEF_VEC_O(tree_int); +DEF_VEC_ALLOC_O(tree_int,gc); +static GTY(()) VEC(tree_int,gc) *lambda_scope_stack; + +static void +start_lambda_scope (tree decl) +{ + tree_int ti; + gcc_assert (decl); + /* Once we're inside a function, we ignore other scopes and just push + the function again so that popping works properly. */ + if (current_function_decl && TREE_CODE (decl) != FUNCTION_DECL) + decl = current_function_decl; + ti.t = lambda_scope; + ti.i = lambda_count; + VEC_safe_push (tree_int, gc, lambda_scope_stack, &ti); + if (lambda_scope != decl) + { + /* Don't reset the count if we're still in the same function. */ + lambda_scope = decl; + lambda_count = 0; + } +} + +static void +record_lambda_scope (tree lambda) +{ + LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope; + LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++; +} + +static void +finish_lambda_scope (void) +{ + tree_int *p = VEC_last (tree_int, lambda_scope_stack); + if (lambda_scope != p->t) + { + lambda_scope = p->t; + lambda_count = p->i; + } + VEC_pop (tree_int, lambda_scope_stack); +} + +/* Parse a lambda expression. + + lambda-expression: + lambda-introducer lambda-declarator [opt] compound-statement + + Returns a representation of the expression. */ + +static tree +cp_parser_lambda_expression (cp_parser* parser) +{ + tree lambda_expr = build_lambda_expr (); + tree type; + + LAMBDA_EXPR_LOCATION (lambda_expr) + = cp_lexer_peek_token (parser->lexer)->location; + + if (cp_unevaluated_operand) + error_at (LAMBDA_EXPR_LOCATION (lambda_expr), + "lambda-expression in unevaluated context"); + + /* We may be in the middle of deferred access check. Disable + it now. */ + push_deferring_access_checks (dk_no_deferred); + + cp_parser_lambda_introducer (parser, lambda_expr); + + type = begin_lambda_type (lambda_expr); + + record_lambda_scope (lambda_expr); + + /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ + determine_visibility (TYPE_NAME (type)); + + /* Now that we've started the type, add the capture fields for any + explicit captures. */ + register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)); + + { + /* Inside the class, surrounding template-parameter-lists do not apply. */ + unsigned int saved_num_template_parameter_lists + = parser->num_template_parameter_lists; + + parser->num_template_parameter_lists = 0; + + /* By virtue of defining a local class, a lambda expression has access to + the private variables of enclosing classes. */ + + cp_parser_lambda_declarator_opt (parser, lambda_expr); + + cp_parser_lambda_body (parser, lambda_expr); + + /* The capture list was built up in reverse order; fix that now. */ + { + tree newlist = NULL_TREE; + tree elt, next; + + for (elt = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); + elt; elt = next) + { + tree field = TREE_PURPOSE (elt); + char *buf; + + next = TREE_CHAIN (elt); + TREE_CHAIN (elt) = newlist; + newlist = elt; + + /* Also add __ to the beginning of the field name so that code + outside the lambda body can't see the captured name. We could + just remove the name entirely, but this is more useful for + debugging. */ + if (field == LAMBDA_EXPR_THIS_CAPTURE (lambda_expr)) + /* The 'this' capture already starts with __. */ + continue; + + buf = (char *) alloca (IDENTIFIER_LENGTH (DECL_NAME (field)) + 3); + buf[1] = buf[0] = '_'; + memcpy (buf + 2, IDENTIFIER_POINTER (DECL_NAME (field)), + IDENTIFIER_LENGTH (DECL_NAME (field)) + 1); + DECL_NAME (field) = get_identifier (buf); + } + LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist; + } + + maybe_add_lambda_conv_op (type); + + type = finish_struct (type, /*attributes=*/NULL_TREE); + + parser->num_template_parameter_lists = saved_num_template_parameter_lists; + } + + pop_deferring_access_checks (); + + return build_lambda_object (lambda_expr); +} + +/* Parse the beginning of a lambda expression. + + lambda-introducer: + [ lambda-capture [opt] ] + + LAMBDA_EXPR is the current representation of the lambda expression. */ + +static void +cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) +{ + /* Need commas after the first capture. */ + bool first = true; + + /* Eat the leading `['. */ + cp_parser_require (parser, CPP_OPEN_SQUARE, "%<[%>"); + + /* Record default capture mode. "[&" "[=" "[&," "[=," */ + if (cp_lexer_next_token_is (parser->lexer, CPP_AND) + && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_NAME) + LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE; + else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) + LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY; + + if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE) + { + cp_lexer_consume_token (parser->lexer); + first = false; + } + + while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE)) + { + cp_token* capture_token; + tree capture_id; + tree capture_init_expr; + cp_id_kind idk = CP_ID_KIND_NONE; + bool explicit_init_p = false; + + enum capture_kind_type + { + BY_COPY, + BY_REFERENCE + }; + enum capture_kind_type capture_kind = BY_COPY; + + if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) + { + error ("expected end of capture-list"); + return; + } + + if (first) + first = false; + else + cp_parser_require (parser, CPP_COMMA, "%<,%>"); + + /* Possibly capture `this'. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS)) + { + cp_lexer_consume_token (parser->lexer); + add_capture (lambda_expr, + /*id=*/get_identifier ("__this"), + /*initializer=*/finish_this_expr(), + /*by_reference_p=*/false, + explicit_init_p); + continue; + } + + /* Remember whether we want to capture as a reference or not. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_AND)) + { + capture_kind = BY_REFERENCE; + cp_lexer_consume_token (parser->lexer); + } + + /* Get the identifier. */ + capture_token = cp_lexer_peek_token (parser->lexer); + capture_id = cp_parser_identifier (parser); + + if (capture_id == error_mark_node) + /* Would be nice to have a cp_parser_skip_to_closing_x for general + delimiters, but I modified this to stop on unnested ']' as well. It + was already changed to stop on unnested '}', so the + "closing_parenthesis" name is no more misleading with my change. */ + { + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/true, + /*consume_paren=*/true); + break; + } + + /* Find the initializer for this capture. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) + { + /* An explicit expression exists. */ + cp_lexer_consume_token (parser->lexer); + pedwarn (input_location, OPT_pedantic, + "ISO C++ does not allow initializers " + "in lambda expression capture lists"); + capture_init_expr = cp_parser_assignment_expression (parser, + /*cast_p=*/true, + &idk); + explicit_init_p = true; + } + else + { + const char* error_msg; + + /* Turn the identifier into an id-expression. */ + capture_init_expr + = cp_parser_lookup_name + (parser, + capture_id, + none_type, + /*is_template=*/false, + /*is_namespace=*/false, + /*check_dependency=*/true, + /*ambiguous_decls=*/NULL, + capture_token->location); + + capture_init_expr + = finish_id_expression + (capture_id, + capture_init_expr, + parser->scope, + &idk, + /*integral_constant_expression_p=*/false, + /*allow_non_integral_constant_expression_p=*/false, + /*non_integral_constant_expression_p=*/NULL, + /*template_p=*/false, + /*done=*/true, + /*address_p=*/false, + /*template_arg_p=*/false, + &error_msg, + capture_token->location); + } + + if (TREE_CODE (capture_init_expr) == IDENTIFIER_NODE) + capture_init_expr + = unqualified_name_lookup_error (capture_init_expr); + + add_capture (lambda_expr, + capture_id, + capture_init_expr, + /*by_reference_p=*/capture_kind == BY_REFERENCE, + explicit_init_p); + } + + cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"); +} + +/* Parse the (optional) middle of a lambda expression. + + lambda-declarator: + ( parameter-declaration-clause [opt] ) + attribute-specifier [opt] + mutable [opt] + exception-specification [opt] + lambda-return-type-clause [opt] + + LAMBDA_EXPR is the current representation of the lambda expression. */ + +static void +cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) +{ + /* 5.1.1.4 of the standard says: + If a lambda-expression does not include a lambda-declarator, it is as if + the lambda-declarator were (). + This means an empty parameter list, no attributes, and no exception + specification. */ + tree param_list = void_list_node; + tree attributes = NULL_TREE; + tree exception_spec = NULL_TREE; + tree t; + + /* The lambda-declarator is optional, but must begin with an opening + parenthesis if present. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + + begin_scope (sk_function_parms, /*entity=*/NULL_TREE); + + /* Parse parameters. */ + param_list = cp_parser_parameter_declaration_clause (parser); + + /* Default arguments shall not be specified in the + parameter-declaration-clause of a lambda-declarator. */ + for (t = param_list; t; t = TREE_CHAIN (t)) + if (TREE_PURPOSE (t)) + pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_pedantic, + "default argument specified for lambda parameter"); + + cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + + attributes = cp_parser_attributes_opt (parser); + + /* Parse optional `mutable' keyword. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_MUTABLE)) + { + cp_lexer_consume_token (parser->lexer); + LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1; + } + + /* Parse optional exception specification. */ + exception_spec = cp_parser_exception_specification_opt (parser); + + /* Parse optional trailing return type. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF)) + { + cp_lexer_consume_token (parser->lexer); + LAMBDA_EXPR_RETURN_TYPE (lambda_expr) = cp_parser_type_id (parser); + } + + /* The function parameters must be in scope all the way until after the + trailing-return-type in case of decltype. */ + for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) + pop_binding (DECL_NAME (t), t); + + leave_scope (); + } + + /* Create the function call operator. + + Messing with declarators like this is no uglier than building up the + FUNCTION_DECL by hand, and this is less likely to get out of sync with + other code. */ + { + cp_decl_specifier_seq return_type_specs; + cp_declarator* declarator; + tree fco; + int quals; + void *p; + + clear_decl_specs (&return_type_specs); + if (LAMBDA_EXPR_RETURN_TYPE (lambda_expr)) + return_type_specs.type = LAMBDA_EXPR_RETURN_TYPE (lambda_expr); + else + /* Maybe we will deduce the return type later, but we can use void + as a placeholder return type anyways. */ + return_type_specs.type = void_type_node; + + p = obstack_alloc (&declarator_obstack, 0); + + declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR), + sfk_none); + + quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr) + ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST); + declarator = make_call_declarator (declarator, param_list, quals, + exception_spec, + /*late_return_type=*/NULL_TREE); + declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr); + + fco = grokmethod (&return_type_specs, + declarator, + attributes); + DECL_INITIALIZED_IN_CLASS_P (fco) = 1; + DECL_ARTIFICIAL (fco) = 1; + + finish_member_declaration (fco); + + obstack_free (&declarator_obstack, p); + } +} + +/* Parse the body of a lambda expression, which is simply + + compound-statement + + but which requires special handling. + LAMBDA_EXPR is the current representation of the lambda expression. */ + +static void +cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) +{ + bool nested = (current_function_decl != NULL_TREE); + if (nested) + push_function_context (); + + /* Finish the function call operator + - class_specifier + + late_parsing_for_member + + function_definition_after_declarator + + ctor_initializer_opt_and_function_body */ + { + tree fco = lambda_function (lambda_expr); + tree body; + bool done = false; + + /* Let the front end know that we are going to be defining this + function. */ + start_preparsed_function (fco, + NULL_TREE, + SF_PRE_PARSED | SF_INCLASS_INLINE); + + start_lambda_scope (fco); + body = begin_function_body (); + + /* 5.1.1.4 of the standard says: + If a lambda-expression does not include a trailing-return-type, it + is as if the trailing-return-type denotes the following type: + * if the compound-statement is of the form + { return attribute-specifier [opt] expression ; } + the type of the returned expression after lvalue-to-rvalue + conversion (_conv.lval_ 4.1), array-to-pointer conversion + (_conv.array_ 4.2), and function-to-pointer conversion + (_conv.func_ 4.3); + * otherwise, void. */ + + /* In a lambda that has neither a lambda-return-type-clause + nor a deducible form, errors should be reported for return statements + in the body. Since we used void as the placeholder return type, parsing + the body as usual will give such desired behavior. */ + if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr) + && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) + && cp_lexer_peek_nth_token (parser->lexer, 2)->keyword == RID_RETURN + && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_SEMICOLON) + { + tree compound_stmt; + tree expr = NULL_TREE; + cp_id_kind idk = CP_ID_KIND_NONE; + + /* Parse tentatively in case there's more after the initial return + statement. */ + cp_parser_parse_tentatively (parser); + + cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"); + cp_parser_require_keyword (parser, RID_RETURN, "%"); + + expr = cp_parser_expression (parser, /*cast_p=*/false, &idk); + + cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); + cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); + + if (cp_parser_parse_definitely (parser)) + { + apply_lambda_return_type (lambda_expr, lambda_return_type (expr)); + + compound_stmt = begin_compound_stmt (0); + /* Will get error here if type not deduced yet. */ + finish_return_stmt (expr); + finish_compound_stmt (compound_stmt); + + done = true; + } + } + + if (!done) + { + if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)) + LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = true; + /* TODO: does begin_compound_stmt want BCS_FN_BODY? + cp_parser_compound_stmt does not pass it. */ + cp_parser_function_body (parser); + LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false; + } + + finish_function_body (body); + finish_lambda_scope (); + + /* Finish the function and generate code for it if necessary. */ + expand_or_defer_fn (finish_function (/*inline*/2)); + } + + if (nested) + pop_function_context(); +} + /* Statements [gram.stmt.stmt] */ /* Parse a statement. @@ -7041,6 +7714,7 @@ static void cp_parser_label_for_labeled_statement (cp_parser* parser) { cp_token *token; + tree label = NULL_TREE; /* The next token should be an identifier. */ token = cp_lexer_peek_token (parser->lexer); @@ -7081,10 +7755,11 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) expr_hi = NULL_TREE; if (parser->in_switch_statement_p) - finish_case_label (expr, expr_hi); + finish_case_label (token->location, expr, expr_hi); else - error ("%Hcase label %qE not within a switch statement", - &token->location, expr); + error_at (token->location, + "case label %qE not within a switch statement", + expr); } break; @@ -7093,19 +7768,41 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) cp_lexer_consume_token (parser->lexer); if (parser->in_switch_statement_p) - finish_case_label (NULL_TREE, NULL_TREE); + finish_case_label (token->location, NULL_TREE, NULL_TREE); else - error ("%Hcase label not within a switch statement", &token->location); + error_at (token->location, "case label not within a switch statement"); break; default: /* Anything else must be an ordinary label. */ - finish_label_stmt (cp_parser_identifier (parser)); + label = finish_label_stmt (cp_parser_identifier (parser)); break; } /* Require the `:' token. */ cp_parser_require (parser, CPP_COLON, "%<:%>"); + + /* An ordinary label may optionally be followed by attributes. + However, this is only permitted if the attributes are then + followed by a semicolon. This is because, for backward + compatibility, when parsing + lab: __attribute__ ((unused)) int i; + we want the attribute to attach to "i", not "lab". */ + if (label != NULL_TREE + && cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)) + { + tree attrs; + + cp_parser_parse_tentatively (parser); + attrs = cp_parser_attributes_opt (parser); + if (attrs == NULL_TREE + || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + cp_parser_abort_tentative_parse (parser); + else if (!cp_parser_parse_definitely (parser)) + ; + else + cplus_decl_attributes (&label, attrs, 0); + } } /* Parse an expression-statement. @@ -7122,12 +7819,32 @@ static tree cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) { tree statement = NULL_TREE; + cp_token *token = cp_lexer_peek_token (parser->lexer); /* If the next token is a ';', then there is no expression statement. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) statement = cp_parser_expression (parser, /*cast_p=*/false, NULL); + /* Give a helpful message for "A::type t;" and the like. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON) + && !cp_parser_uncommitted_to_tentative_parse_p (parser)) + { + if (TREE_CODE (statement) == SCOPE_REF) + error_at (token->location, "need % before %qE because " + "%qT is a dependent scope", + statement, TREE_OPERAND (statement, 0)); + else if (is_overloaded_fn (statement) + && DECL_CONSTRUCTOR_P (get_first_fn (statement))) + { + /* A::A a; */ + tree fn = get_first_fn (statement); + error_at (token->location, + "%<%T::%D%> names the constructor, not the type", + DECL_CONTEXT (fn), DECL_NAME (fn)); + } + } + /* Consume the final `;'. */ cp_parser_consume_semicolon_at_end_of_statement (parser); @@ -7213,7 +7930,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr) else { token = cp_lexer_consume_token (parser->lexer); - error ("%H% without a previous %", &token->location); + error_at (token->location, "% without a previous %"); } } @@ -7292,7 +8009,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) { location_t loc = cp_lexer_peek_token (parser->lexer)->location; - add_stmt (build_empty_stmt ()); + add_stmt (build_empty_stmt (loc)); cp_lexer_consume_token (parser->lexer); if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE)) warning_at (loc, OPT_Wempty_body, "suggest braces around " @@ -7315,10 +8032,12 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) /* Parse the else-clause. */ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) { - warning_at (cp_lexer_peek_token (parser->lexer)->location, + location_t loc; + loc = cp_lexer_peek_token (parser->lexer)->location; + warning_at (loc, OPT_Wempty_body, "suggest braces around " "empty body in an % statement"); - add_stmt (build_empty_stmt ()); + add_stmt (build_empty_stmt (loc)); cp_lexer_consume_token (parser->lexer); } else @@ -7341,10 +8060,9 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p) statement which does have an else clause. We warn about the potential ambiguity. */ if (nested_if) - warning (OPT_Wparentheses, - ("%Hsuggest explicit braces " - "to avoid ambiguous %"), - EXPR_LOCUS (statement)); + warning_at (EXPR_LOCATION (statement), OPT_Wparentheses, + "suggest explicit braces to avoid ambiguous" + " %"); } /* Now we're all done with the if-statement. */ @@ -7408,9 +8126,10 @@ cp_parser_condition (cp_parser* parser) condition. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in conditions"; + = G_("types may not be defined in conditions"); /* Parse the type-specifier-seq. */ - cp_parser_type_specifier_seq (parser, /*is_condition==*/true, + cp_parser_type_specifier_seq (parser, /*is_declaration==*/true, + /*is_trailing_return=*/false, &type_specifiers); /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; @@ -7471,7 +8190,7 @@ cp_parser_condition (cp_parser* parser) initializer = cp_parser_initializer_clause (parser, &non_constant_p); } if (BRACE_ENCLOSED_INITIALIZER_P (initializer)) - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); if (!non_constant_p) initializer = fold_non_dependent_expr (initializer); @@ -7651,7 +8370,7 @@ cp_parser_for_init_statement (cp_parser* parser) return; } - cp_parser_expression_statement (parser, false); + cp_parser_expression_statement (parser, NULL_TREE); } /* Parse a jump-statement. @@ -7692,7 +8411,7 @@ cp_parser_jump_statement (cp_parser* parser) switch (in_statement) { case 0: - error ("%Hbreak statement not within loop or switch", &token->location); + error_at (token->location, "break statement not within loop or switch"); break; default: gcc_assert ((in_statement & IN_SWITCH_STMT) @@ -7700,10 +8419,10 @@ cp_parser_jump_statement (cp_parser* parser) statement = finish_break_stmt (); break; case IN_OMP_BLOCK: - error ("%Hinvalid exit from OpenMP structured block", &token->location); + error_at (token->location, "invalid exit from OpenMP structured block"); break; case IN_OMP_FOR: - error ("%Hbreak statement used with OpenMP for loop", &token->location); + error_at (token->location, "break statement used with OpenMP for loop"); break; } cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); @@ -7713,14 +8432,14 @@ cp_parser_jump_statement (cp_parser* parser) switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT)) { case 0: - error ("%Hcontinue statement not within a loop", &token->location); + error_at (token->location, "continue statement not within a loop"); break; case IN_ITERATION_STMT: case IN_OMP_FOR: statement = finish_continue_stmt (); break; case IN_OMP_BLOCK: - error ("%Hinvalid exit from OpenMP structured block", &token->location); + error_at (token->location, "invalid exit from OpenMP structured block"); break; default: gcc_unreachable (); @@ -7735,7 +8454,7 @@ cp_parser_jump_statement (cp_parser* parser) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); expr = cp_parser_braced_list (parser, &expr_non_constant_p); } else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) @@ -7826,8 +8545,9 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p) /* Mark if () ; with a special NOP_EXPR. */ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) { + location_t loc = cp_lexer_peek_token (parser->lexer)->location; cp_lexer_consume_token (parser->lexer); - statement = add_stmt (build_empty_stmt ()); + statement = add_stmt (build_empty_stmt (loc)); } /* if a compound is opened, we simply parse the statement directly. */ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) @@ -8121,7 +8841,7 @@ cp_parser_block_declaration (cp_parser *parser, else if (token1->keyword == RID_LABEL) { cp_lexer_consume_token (parser->lexer); - error ("%H%<__label__%> not at the beginning of a block", &token1->location); + error_at (token1->location, "%<__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)) @@ -8194,7 +8914,7 @@ cp_parser_simple_declaration (cp_parser* parser, T t; where "T" should name a type -- but does not. */ - if (!decl_specifiers.type + if (!decl_specifiers.any_type_specifiers_p && cp_parser_parse_and_diagnose_invalid_type_name (parser)) { /* If parsing tentatively, we should commit; we really are @@ -8258,8 +8978,9 @@ cp_parser_simple_declaration (cp_parser* parser, if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) { cp_token *token = cp_lexer_peek_token (parser->lexer); - error ("%Hmixing declarations and function-definitions is forbidden", - &token->location); + error_at (token->location, + "mixing" + " declarations and function-definitions is forbidden"); } /* Otherwise, we're done with the list of declarators. */ else @@ -8394,11 +9115,12 @@ cp_parser_decl_specifier_seq (cp_parser* parser, switch (token->keyword) { /* decl-specifier: - friend */ + friend + constexpr */ case RID_FRIEND: if (!at_class_scope_p ()) { - error ("%H% used outside of class", &token->location); + error_at (token->location, "% used outside of class"); cp_lexer_purge_token (parser->lexer); } else @@ -8409,6 +9131,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser, } break; + case RID_CONSTEXPR: + ++decl_specs->specs[(int) ds_constexpr]; + cp_lexer_consume_token (parser->lexer); + break; + /* function-specifier: inline virtual @@ -8452,10 +9179,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, /* Complain about `auto' as a storage specifier, if we're complaining about C++0x compatibility. */ - warning - (OPT_Wc__0x_compat, - "%H% will change meaning in C++0x; please remove it", - &token->location); + warning_at (token->location, OPT_Wc__0x_compat, "%" + " will change meaning in C++0x; please remove it"); /* Set the storage class anyway. */ cp_parser_set_storage_class (parser, decl_specs, RID_AUTO, @@ -8554,6 +9279,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, { constructor_possible_p = false; found_decl_spec = true; + if (!is_cv_qualifier) + decl_specs->any_type_specifiers_p = true; } } @@ -8573,8 +9300,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, /* Don't allow a friend specifier with a class definition. */ if (decl_specs->specs[(int) ds_friend] != 0 && (*declares_class_or_enum & 2)) - error ("%Hclass definition may not be declared a friend", - &start_token->location); + error_at (start_token->location, + "class definition may not be declared a friend"); } /* Parse an (optional) storage-class-specifier. @@ -8643,7 +9370,7 @@ cp_parser_function_specifier_opt (cp_parser* parser, A member function template shall not be virtual. */ if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - error ("%Htemplates may not be %", &token->location); + error_at (token->location, "templates may not be %"); else if (decl_specs) ++decl_specs->specs[(int) ds_virtual]; break; @@ -8809,7 +9536,7 @@ cp_parser_decltype (cp_parser *parser) /* And create the new one. */ parser->type_definition_forbidden_message - = "types may not be defined in % expressions"; + = G_("types may not be defined in % expressions"); /* The restrictions on constant-expressions do not apply inside decltype expressions. */ @@ -8820,7 +9547,10 @@ cp_parser_decltype (cp_parser *parser) parser->integral_constant_expression_p = false; /* Do not actually evaluate the expression. */ - ++skip_evaluation; + ++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, "%<(%>")) @@ -8915,16 +9645,30 @@ 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, 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; } /* Go back to evaluating expressions. */ - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; /* Restore the old message and the integral constant expression flags. */ @@ -9028,7 +9772,8 @@ cp_parser_conversion_type_id (cp_parser* parser) /* Parse the attributes. */ attributes = cp_parser_attributes_opt (parser); /* Parse the type-specifiers. */ - cp_parser_type_specifier_seq (parser, /*is_condition=*/false, + cp_parser_type_specifier_seq (parser, /*is_declaration=*/false, + /*is_trailing_return=*/false, &type_specifiers); /* If that didn't work, stop. */ if (type_specifiers.type == error_mark_node) @@ -9130,8 +9875,8 @@ cp_parser_mem_initializer_list (cp_parser* parser) /* Let the semantic analysis code know that we are starting the mem-initializer-list. */ if (!DECL_CONSTRUCTOR_P (current_function_decl)) - error ("%Honly constructors take base initializers", - &token->location); + error_at (token->location, + "only constructors take base initializers"); /* Loop through the list. */ while (true) @@ -9152,8 +9897,9 @@ cp_parser_mem_initializer_list (cp_parser* parser) if (mem_initializer != error_mark_node && !TYPE_P (TREE_PURPOSE (mem_initializer))) { - error ("%Hcannot expand initializer for member %<%D%>", - &token->location, TREE_PURPOSE (mem_initializer)); + error_at (token->location, + "cannot expand initializer for member %<%D%>", + TREE_PURPOSE (mem_initializer)); mem_initializer = error_mark_node; } @@ -9223,17 +9969,24 @@ cp_parser_mem_initializer (cp_parser* parser) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { bool expr_non_constant_p; - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); expression_list = cp_parser_braced_list (parser, &expr_non_constant_p); CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1; expression_list = build_tree_list (NULL_TREE, expression_list); } else - expression_list - = cp_parser_parenthesized_expression_list (parser, false, - /*cast_p=*/false, - /*allow_expansion_p=*/true, - /*non_constant_p=*/NULL); + { + VEC(tree,gc)* vec; + vec = cp_parser_parenthesized_expression_list (parser, non_attr, + /*cast_p=*/false, + /*allow_expansion_p=*/true, + /*non_constant_p=*/NULL); + if (vec == NULL) + return error_mark_node; + expression_list = build_tree_list_vec (vec); + release_tree_vector (vec); + } + if (expression_list == error_mark_node) return error_mark_node; if (!expression_list) @@ -9267,9 +10020,9 @@ cp_parser_mem_initializer_id (cp_parser* parser) /* `typename' is not allowed in this context ([temp.res]). */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) { - error ("%Hkeyword % not allowed in this context (a qualified " - "member initializer is implicitly a type)", - &token->location); + error_at (token->location, + "keyword % not allowed in this context (a qualified " + "member initializer is implicitly a type)"); cp_lexer_consume_token (parser->lexer); } /* Look for the optional `::' operator. */ @@ -9304,7 +10057,7 @@ cp_parser_mem_initializer_id (cp_parser* parser) return cp_parser_class_name (parser, /*typename_keyword_p=*/true, /*template_keyword_p=*/template_p, - none_type, + typename_type, /*check_dependency_p=*/true, /*class_head_p=*/false, /*is_declaration=*/true); @@ -9639,14 +10392,17 @@ cp_parser_template_parameter_list (cp_parser* parser) tree parameter; bool is_non_type; bool is_parameter_pack; + location_t parm_loc; /* Parse the template-parameter. */ + parm_loc = cp_lexer_peek_token (parser->lexer)->location; parameter = cp_parser_template_parameter (parser, &is_non_type, &is_parameter_pack); /* Add it to the list. */ if (parameter != error_mark_node) parameter_list = process_template_parm (parameter_list, + parm_loc, parameter, is_non_type, is_parameter_pack); @@ -9795,11 +10551,12 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, id_declarator = id_declarator->declarator; if (id_declarator && id_declarator->kind == cdk_id) - error ("%Htemplate parameter pack %qD cannot have a default argument", - &start_token->location, id_declarator->u.id.unqualified_name); + error_at (start_token->location, + "template parameter pack %qD cannot have a default argument", + id_declarator->u.id.unqualified_name); else - error ("%Htemplate parameter pack cannot have a default argument", - &start_token->location); + error_at (start_token->location, + "template parameter pack cannot have a default argument"); /* Parse the default argument, but throw away the result. */ cp_parser_default_argument (parser, /*template_parm_p=*/true); @@ -9807,7 +10564,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, parm = grokdeclarator (parameter_declarator->declarator, ¶meter_declarator->decl_specifiers, - PARM, /*initialized=*/0, + TPARM, /*initialized=*/0, /*attrlist=*/NULL); if (parm == error_mark_node) return error_mark_node; @@ -9893,11 +10650,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) if (*is_parameter_pack) { if (identifier) - error ("%Htemplate parameter pack %qD cannot have a " - "default argument", &token->location, identifier); + error_at (token->location, + "template parameter pack %qD cannot have a " + "default argument", identifier); else - error ("%Htemplate parameter packs cannot have " - "default arguments", &token->location); + error_at (token->location, + "template parameter packs cannot have " + "default arguments"); default_argument = NULL_TREE; } pop_deferring_access_checks (); @@ -9913,14 +10672,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) case RID_TEMPLATE: { - tree parameter_list; tree identifier; tree default_argument; /* Look for the `<'. */ cp_parser_require (parser, CPP_LESS, "%<<%>"); /* Parse the template-parameter-list. */ - parameter_list = cp_parser_template_parameter_list (parser); + cp_parser_template_parameter_list (parser); /* Look for the `>'. */ cp_parser_require (parser, CPP_GREATER, "%<>%>"); /* Look for the `class' keyword. */ @@ -9999,13 +10757,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) if (*is_parameter_pack) { if (identifier) - error ("%Htemplate parameter pack %qD cannot " - "have a default argument", - &token->location, identifier); + error_at (token->location, + "template parameter pack %qD cannot " + "have a default argument", + identifier); else - error ("%Htemplate parameter packs cannot " - "have default arguments", - &token->location); + error_at (token->location, "template parameter packs cannot " + "have default arguments"); default_argument = NULL_TREE; } pop_deferring_access_checks (); @@ -10054,7 +10812,7 @@ cp_parser_template_id (cp_parser *parser, cp_token_position start_of_id = 0; deferred_access_check *chk; VEC (deferred_access_check,gc) *access_check; - cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL; + cp_token *next_token = NULL, *next_token_2 = NULL; bool is_identifier; /* If the next token corresponds to a template-id, there is no need @@ -10102,7 +10860,6 @@ cp_parser_template_id (cp_parser *parser, /* Parse the template-name. */ is_identifier = false; - token = cp_lexer_peek_token (parser->lexer); templ = cp_parser_template_name (parser, template_keyword_p, check_dependency_p, is_declaration, @@ -10227,8 +10984,7 @@ cp_parser_template_id (cp_parser *parser, user, as opposed to simply marking the tentative parse as failed? */ if (cp_parser_error_occurred (parser) && template_id != error_mark_node) - error ("%Hparse error in template argument list", - &token->location); + error_at (token->location, "parse error in template argument list"); } pop_deferring_access_checks (); @@ -10342,9 +11098,9 @@ cp_parser_template_name (cp_parser* parser, cp_token_position start = 0; /* Explain what went wrong. */ - error ("%Hnon-template %qD used as template", - &token->location, identifier); - inform (input_location, "use %<%T::template %D%> to indicate that it is a template", + error_at (token->location, "non-template %qD used as template", + identifier); + inform (token->location, "use %<%T::template %D%> to indicate that it is a template", parser->scope, identifier); /* If parsing tentatively, find the location of the "<" token. */ if (cp_parser_simulate_error (parser)) @@ -10384,12 +11140,11 @@ cp_parser_template_name (cp_parser* parser, /* Look up the name. */ decl = cp_parser_lookup_name (parser, identifier, none_type, - /*is_template=*/false, + /*is_template=*/true, /*is_namespace=*/false, check_dependency_p, /*ambiguous_decls=*/NULL, token->location); - decl = maybe_get_template_decl_from_type_decl (decl); /* If DECL is a template, then the name was a template-name. */ if (TREE_CODE (decl) == TEMPLATE_DECL) @@ -10474,6 +11229,12 @@ cp_parser_template_argument_list (cp_parser* parser) argument pack. */ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { + if (argument == error_mark_node) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + error_at (token->location, + "expected parameter pack before %<...%>"); + } /* Consume the `...' token. */ cp_lexer_consume_token (parser->lexer); @@ -10508,6 +11269,9 @@ cp_parser_template_argument_list (cp_parser* parser) parser->non_integral_constant_expression_p = saved_non_ice_p; parser->integral_constant_expression_p = saved_ice_p; parser->in_template_argument_list_p = saved_in_template_argument_list_p; +#ifdef ENABLE_CHECKING + SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec)); +#endif return vec; } @@ -10670,18 +11434,26 @@ cp_parser_template_argument (cp_parser* parser) cp_parser_abort_tentative_parse (parser); else { + tree probe; + if (TREE_CODE (argument) == INDIRECT_REF) { gcc_assert (REFERENCE_REF_P (argument)); argument = TREE_OPERAND (argument, 0); } - if (TREE_CODE (argument) == VAR_DECL) + /* If we're in a template, we represent a qualified-id referring + to a static data member as a SCOPE_REF even if the scope isn't + dependent so that we can check access control later. */ + probe = argument; + if (TREE_CODE (probe) == SCOPE_REF) + probe = TREE_OPERAND (probe, 1); + if (TREE_CODE (probe) == VAR_DECL) { /* A variable without external linkage might still be a valid constant-expression, so no error is issued here if the external-linkage check fails. */ - if (!address_p && !DECL_EXTERNAL_LINKAGE_P (argument)) + if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe)) cp_parser_simulate_error (parser); } else if (is_overloaded_fn (argument)) @@ -10767,7 +11539,6 @@ cp_parser_explicit_instantiation (cp_parser* parser) int declares_class_or_enum; cp_decl_specifier_seq decl_specifiers; tree extension_specifier = NULL_TREE; - cp_token *token; /* Look for an (optional) storage-class-specifier or function-specifier. */ @@ -10790,7 +11561,6 @@ cp_parser_explicit_instantiation (cp_parser* parser) control while processing explicit instantiation directives. */ push_deferring_access_checks (dk_no_check); /* Parse a decl-specifier-seq. */ - token = cp_lexer_peek_token (parser->lexer); cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_OPTIONAL, &decl_specifiers, @@ -10881,7 +11651,7 @@ cp_parser_explicit_specialization (cp_parser* parser) linkage. */ if (current_lang_name == lang_name_c) { - error ("%Htemplate specialization with C linkage", &token->location); + error_at (token->location, "template specialization with C linkage"); /* Give it C++ linkage to avoid confusing other parts of the front end. */ push_lang_context (lang_name_cplusplus); @@ -10985,6 +11755,9 @@ cp_parser_type_specifier (cp_parser* parser, switch (keyword) { case RID_ENUM: + if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS)) + goto elaborated_type_specifier; + /* Look for the enum-specifier. */ type_spec = cp_parser_enum_specifier (parser); /* If that worked, we're done. */ @@ -11007,11 +11780,15 @@ cp_parser_type_specifier (cp_parser* parser, case RID_CLASS: case RID_STRUCT: case RID_UNION: + if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS)) + goto elaborated_type_specifier; + /* Parse tentatively so that we can back up if we don't find a class-specifier. */ cp_parser_parse_tentatively (parser); /* Look for the class-specifier. */ type_spec = cp_parser_class_specifier (parser); + invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec); /* If that worked, we're done. */ if (cp_parser_parse_definitely (parser)) { @@ -11202,7 +11979,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, break; case RID_AUTO: - maybe_warn_cpp0x ("C++0x auto"); + maybe_warn_cpp0x (CPP0X_AUTO); type = make_auto (); break; @@ -11240,8 +12017,6 @@ cp_parser_simple_type_specifier (cp_parser* parser, /* If the type-specifier was for a built-in type, we're done. */ if (type) { - tree id; - /* Record the type. */ if (decl_specs && (token->keyword != RID_SIGNED @@ -11256,7 +12031,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, decl_specs->any_specifiers_p = true; /* Consume the token. */ - id = cp_lexer_consume_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); /* There is no valid C++ program where a non-template type is followed by a "<". That usually indicates that the user thought @@ -11493,6 +12268,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, tree identifier; tree type = NULL_TREE; tree attributes = NULL_TREE; + tree globalscope; cp_token *token = NULL; /* See if we're looking at the `enum' keyword. */ @@ -11508,7 +12284,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT)) { if (cxx_dialect == cxx98) - maybe_warn_cpp0x ("scoped enums"); + maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS); /* Consume the `struct' or `class'. */ cp_lexer_consume_token (parser->lexer); @@ -11524,9 +12300,6 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, cp_lexer_consume_token (parser->lexer); /* Remember that it's a `typename' type. */ tag_type = typename_type; - /* The `typename' keyword is only allowed in templates. */ - if (!processing_template_decl) - permerror (input_location, "using % outside of template"); } /* Otherwise it must be a class-key. */ else @@ -11539,10 +12312,10 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, } /* Look for the `::' operator. */ - cp_parser_global_scope_opt (parser, - /*current_scope_valid_p=*/false); + globalscope = cp_parser_global_scope_opt (parser, + /*current_scope_valid_p=*/false); /* Look for the nested-name-specifier. */ - if (tag_type == typename_type) + if (tag_type == typename_type && !globalscope) { if (!cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/true, @@ -11765,7 +12538,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, there were no qualifying templates. */ if (!cp_parser_check_template_parameters (parser, /*num_templates=*/0, - token->location)) + token->location, + /*declarator=*/NULL)) return error_mark_node; type = xref_tag (tag_type, identifier, ts, template_p); } @@ -11847,7 +12621,7 @@ cp_parser_enum_specifier (cp_parser* parser) || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT)) { if (cxx_dialect == cxx98) - maybe_warn_cpp0x ("scoped enums"); + maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS); /* Consume the `struct' or `class' token. */ cp_lexer_consume_token (parser->lexer); @@ -11862,27 +12636,29 @@ cp_parser_enum_specifier (cp_parser* parser) else identifier = make_anon_name (); - /* Check for the `:' that denotes a specified underlying type in C++0x. */ + /* Check for the `:' that denotes a specified underlying type in C++0x. + Note that a ':' could also indicate a bitfield width, however. */ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { cp_decl_specifier_seq type_specifiers; + /* Consume the `:'. */ + cp_lexer_consume_token (parser->lexer); + + /* Parse the type-specifier-seq. */ + cp_parser_type_specifier_seq (parser, /*is_declaration=*/false, + /*is_trailing_return=*/false, + &type_specifiers); + /* At this point this is surely not elaborated type specifier. */ if (!cp_parser_parse_definitely (parser)) return NULL_TREE; if (cxx_dialect == cxx98) - maybe_warn_cpp0x ("scoped enums"); - - /* Consume the `:'. */ - cp_lexer_consume_token (parser->lexer); + maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS); has_underlying_type = true; - /* Parse the type-specifier-seq. */ - cp_parser_type_specifier_seq (parser, /*is_condition=*/false, - &type_specifiers); - /* If that didn't work, stop. */ if (type_specifiers.type != error_mark_node) { @@ -12071,7 +12847,7 @@ cp_parser_namespace_name (cp_parser* parser) || TREE_CODE (namespace_decl) != NAMESPACE_DECL) { if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("%H%qD is not a namespace-name", &token->location, identifier); + error_at (token->location, "%qD is not a namespace-name", identifier); cp_parser_error (parser, "expected namespace-name"); namespace_decl = error_mark_node; } @@ -12155,7 +12931,7 @@ cp_parser_namespace_definition (cp_parser* parser) #ifdef HANDLE_PRAGMA_VISIBILITY if (has_visibility) - pop_visibility (); + pop_visibility (1); #endif /* Finish the namespace. */ @@ -12198,7 +12974,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser) if (!cp_parser_uncommitted_to_tentative_parse_p (parser) && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { - error ("%H% definition is not allowed here", &token->location); + error_at (token->location, "% definition is not allowed here"); /* Skip the definition. */ cp_lexer_consume_token (parser->lexer); if (cp_parser_skip_to_closing_brace (parser)) @@ -12338,8 +13114,8 @@ cp_parser_using_declaration (cp_parser* parser, /* [namespace.udecl] A using declaration shall not name a template-id. */ - error ("%Ha template-id may not appear in a using-declaration", - &token->location); + error_at (token->location, + "a template-id may not appear in a using-declaration"); else { if (at_class_scope_p ()) @@ -12425,7 +13201,10 @@ cp_parser_using_directive (cp_parser* parser) : asm-operand-list [opt] ) ; asm volatile [opt] ( string-literal : asm-operand-list [opt] : asm-operand-list [opt] - : asm-operand-list [opt] ) ; */ + : asm-clobber-list [opt] ) ; + asm volatile [opt] goto ( string-literal : : asm-operand-list [opt] + : asm-clobber-list [opt] + : asm-goto-list ) ; */ static void cp_parser_asm_definition (cp_parser* parser) @@ -12434,11 +13213,14 @@ cp_parser_asm_definition (cp_parser* parser) tree outputs = NULL_TREE; tree inputs = NULL_TREE; tree clobbers = NULL_TREE; + tree labels = NULL_TREE; tree asm_stmt; bool volatile_p = false; bool extended_p = false; bool invalid_inputs_p = false; bool invalid_outputs_p = false; + bool goto_p = false; + const char *missing = NULL; /* Look for the `asm' keyword. */ cp_parser_require_keyword (parser, RID_ASM, "%"); @@ -12451,6 +13233,15 @@ cp_parser_asm_definition (cp_parser* parser) /* Consume the token. */ cp_lexer_consume_token (parser->lexer); } + if (cp_parser_allow_gnu_extensions_p (parser) + && parser->in_function_body + && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO)) + { + /* Remember that we saw the `goto' keyword. */ + goto_p = true; + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + } /* Look for the opening `('. */ if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) return; @@ -12475,6 +13266,7 @@ cp_parser_asm_definition (cp_parser* parser) { bool inputs_p = false; bool clobbers_p = false; + bool labels_p = false; /* The extended syntax was used. */ extended_p = true; @@ -12490,7 +13282,8 @@ cp_parser_asm_definition (cp_parser* parser) && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE) && cp_lexer_next_token_is_not (parser->lexer, - CPP_CLOSE_PAREN)) + CPP_CLOSE_PAREN) + && !goto_p) outputs = cp_parser_asm_operand_list (parser); if (outputs == error_mark_node) @@ -12512,6 +13305,8 @@ cp_parser_asm_definition (cp_parser* parser) if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON) && cp_lexer_next_token_is_not (parser->lexer, + CPP_SCOPE) + && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) inputs = cp_parser_asm_operand_list (parser); @@ -12526,16 +13321,41 @@ cp_parser_asm_definition (cp_parser* parser) if (clobbers_p || cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { + clobbers_p = true; /* Consume the `:' or `::'. */ cp_lexer_consume_token (parser->lexer); /* Parse the clobbers. */ if (cp_lexer_next_token_is_not (parser->lexer, - CPP_CLOSE_PAREN)) + CPP_COLON) + && cp_lexer_next_token_is_not (parser->lexer, + CPP_CLOSE_PAREN)) clobbers = cp_parser_asm_clobber_list (parser); } + else if (goto_p + && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) + /* The labels are coming next. */ + labels_p = true; + + /* Look for labels. */ + if (labels_p + || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON))) + { + labels_p = true; + /* Consume the `:' or `::'. */ + cp_lexer_consume_token (parser->lexer); + /* Parse the labels. */ + labels = cp_parser_asm_label_list (parser); + } + + if (goto_p && !labels_p) + missing = clobbers_p ? "%<:%>" : "%<:%> or %<::%>"; } + else if (goto_p) + missing = "%<:%> or %<::%>"; + /* Look for the closing `)'. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>")) + if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN, + missing ? missing : "%<)%>")) cp_parser_skip_to_closing_parenthesis (parser, true, false, /*consume_paren=*/true); cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); @@ -12546,7 +13366,7 @@ cp_parser_asm_definition (cp_parser* parser) if (parser->in_function_body) { asm_stmt = finish_asm_stmt (volatile_p, string, outputs, - inputs, clobbers); + inputs, clobbers, labels); /* If the extended syntax was not used, mark the ASM_EXPR. */ if (!extended_p) { @@ -12675,6 +13495,11 @@ cp_parser_init_declarator (cp_parser* parser, we compute it now. */ scope = get_scope_of_declarator (declarator); + /* Perform any lookups in the declared type which were thought to be + dependent, but are not in the scope of the declarator. */ + decl_specifiers->type + = maybe_update_decl_type (decl_specifiers->type, scope); + /* If we're allowing GNU extensions, look for an asm-specification and attributes. */ if (cp_parser_allow_gnu_extensions_p (parser)) @@ -12715,12 +13540,12 @@ cp_parser_init_declarator (cp_parser* parser, /* Neither attributes nor an asm-specification are allowed on a function-definition. */ if (asm_specification) - error ("%Han asm-specification is not allowed " - "on a function-definition", - &asm_spec_start_token->location); + error_at (asm_spec_start_token->location, + "an asm-specification is not allowed " + "on a function-definition"); if (attributes) - error ("%Hattributes are not allowed on a function-definition", - &attributes_start_token->location); + error_at (attributes_start_token->location, + "attributes are not allowed on a function-definition"); /* This is a function-definition. */ *function_definition_p = true; @@ -12872,8 +13697,8 @@ cp_parser_init_declarator (cp_parser* parser, know what the user intended, so just silently consume the initializer. */ if (decl != error_mark_node) - error ("%Hinitializer provided for function", - &initializer_start_token->location); + error_at (initializer_start_token->location, + "initializer provided for function"); cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, @@ -12881,9 +13706,21 @@ cp_parser_init_declarator (cp_parser* parser, } } else - initializer = cp_parser_initializer (parser, - &is_direct_init, - &is_non_constant_init); + { + /* We want to record the extra mangling scope for in-class + initializers of class members and initializers of static data + member templates. The former is a C++0x feature which isn't + implemented yet, and I expect it will involve deferring + parsing of the initializer until end of class as with default + arguments. So right here we only handle the latter. */ + if (!member_p && processing_template_decl) + start_lambda_scope (decl); + initializer = cp_parser_initializer (parser, + &is_direct_init, + &is_non_constant_init); + if (!member_p && processing_template_decl) + finish_lambda_scope (); + } } /* The old parser allows attributes to appear after a parenthesized @@ -12987,7 +13824,6 @@ cp_parser_declarator (cp_parser* parser, bool* parenthesized_p, bool member_p) { - cp_token *token; cp_declarator *declarator; enum tree_code code; cp_cv_quals cv_quals; @@ -13002,9 +13838,6 @@ cp_parser_declarator (cp_parser* parser, if (cp_parser_allow_gnu_extensions_p (parser)) attributes = cp_parser_attributes_opt (parser); - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* Check for the ptr-operator production. */ cp_parser_parse_tentatively (parser); /* Parse the ptr-operator. */ @@ -13287,22 +14120,23 @@ cp_parser_direct_declarator (cp_parser* parser, &non_constant_p); if (!non_constant_p) bounds = fold_non_dependent_expr (bounds); - else if (processing_template_decl) - { - /* Remember this wasn't a constant-expression. */ - bounds = build_nop (TREE_TYPE (bounds), bounds); - TREE_SIDE_EFFECTS (bounds) = 1; - } - /* Normally, the array bound must be an integral constant expression. However, as an extension, we allow VLAs - in function scopes. */ - else if (!parser->in_function_body) + in function scopes as long as they aren't part of a + parameter declaration. */ + else if (!parser->in_function_body + || current_binding_level->kind == sk_function_parms) { - error ("%Harray bound is not an integer constant", - &token->location); + cp_parser_error (parser, + "array bound is not an integer constant"); bounds = error_mark_node; } + else if (processing_template_decl && !error_operand_p (bounds)) + { + /* Remember this wasn't a constant-expression. */ + bounds = build_nop (TREE_TYPE (bounds), bounds); + TREE_SIDE_EFFECTS (bounds) = 1; + } } else bounds = NULL_TREE; @@ -13317,181 +14151,195 @@ cp_parser_direct_declarator (cp_parser* parser, } else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { - tree qualifying_scope; - tree unqualified_name; - special_function_kind sfk; - bool abstract_ok; - bool pack_expansion_p = false; - cp_token *declarator_id_start_token; - - /* Parse a declarator-id */ - abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); - if (abstract_ok) - { - cp_parser_parse_tentatively (parser); + { + tree qualifying_scope; + tree unqualified_name; + special_function_kind sfk; + bool abstract_ok; + bool pack_expansion_p = false; + cp_token *declarator_id_start_token; + + /* Parse a declarator-id */ + abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); + if (abstract_ok) + { + cp_parser_parse_tentatively (parser); - /* If we see an ellipsis, we should be looking at a - parameter pack. */ - if (token->type == CPP_ELLIPSIS) - { - /* Consume the `...' */ - cp_lexer_consume_token (parser->lexer); + /* If we see an ellipsis, we should be looking at a + parameter pack. */ + if (token->type == CPP_ELLIPSIS) + { + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); - pack_expansion_p = true; - } - } + pack_expansion_p = true; + } + } - declarator_id_start_token = cp_lexer_peek_token (parser->lexer); - unqualified_name - = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); - qualifying_scope = parser->scope; - if (abstract_ok) - { - bool okay = false; - - if (!unqualified_name && pack_expansion_p) - { - /* Check whether an error occurred. */ - okay = !cp_parser_error_occurred (parser); - - /* We already consumed the ellipsis to mark a - parameter pack, but we have no way to report it, - so abort the tentative parse. We will be exiting - immediately anyway. */ - cp_parser_abort_tentative_parse (parser); - } - else - okay = cp_parser_parse_definitely (parser); - - if (!okay) - unqualified_name = error_mark_node; - else if (unqualified_name - && (qualifying_scope - || (TREE_CODE (unqualified_name) - != IDENTIFIER_NODE))) - { - cp_parser_error (parser, "expected unqualified-id"); + declarator_id_start_token = cp_lexer_peek_token (parser->lexer); + unqualified_name + = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); + qualifying_scope = parser->scope; + if (abstract_ok) + { + bool okay = false; + + if (!unqualified_name && pack_expansion_p) + { + /* Check whether an error occurred. */ + okay = !cp_parser_error_occurred (parser); + + /* We already consumed the ellipsis to mark a + parameter pack, but we have no way to report it, + so abort the tentative parse. We will be exiting + immediately anyway. */ + cp_parser_abort_tentative_parse (parser); + } + else + okay = cp_parser_parse_definitely (parser); + + if (!okay) unqualified_name = error_mark_node; - } - } + else if (unqualified_name + && (qualifying_scope + || (TREE_CODE (unqualified_name) + != IDENTIFIER_NODE))) + { + cp_parser_error (parser, "expected unqualified-id"); + unqualified_name = error_mark_node; + } + } - if (!unqualified_name) - return NULL; - if (unqualified_name == error_mark_node) - { - declarator = cp_error_declarator; - pack_expansion_p = false; - declarator->parameter_pack_p = false; - break; - } + if (!unqualified_name) + return NULL; + if (unqualified_name == error_mark_node) + { + declarator = cp_error_declarator; + pack_expansion_p = false; + declarator->parameter_pack_p = false; + break; + } - if (qualifying_scope && at_namespace_scope_p () - && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) - { - /* In the declaration of a member of a template class - outside of the class itself, the SCOPE will sometimes - be a TYPENAME_TYPE. For example, given: - - template - int S::R::i = 3; - - the SCOPE will be a TYPENAME_TYPE for `S::R'. In - this context, we must resolve S::R to an ordinary - type, rather than a typename type. - - The reason we normally avoid resolving TYPENAME_TYPEs - is that a specialization of `S' might render - `S::R' not a type. However, if `S' is - specialized, then this `i' will not be used, so there - is no harm in resolving the types here. */ - tree type; + if (qualifying_scope && at_namespace_scope_p () + && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) + { + /* In the declaration of a member of a template class + outside of the class itself, the SCOPE will sometimes + be a TYPENAME_TYPE. For example, given: + + template + int S::R::i = 3; + + the SCOPE will be a TYPENAME_TYPE for `S::R'. In + this context, we must resolve S::R to an ordinary + type, rather than a typename type. + + The reason we normally avoid resolving TYPENAME_TYPEs + is that a specialization of `S' might render + `S::R' not a type. However, if `S' is + specialized, then this `i' will not be used, so there + is no harm in resolving the types here. */ + tree type; + + /* Resolve the TYPENAME_TYPE. */ + type = resolve_typename_type (qualifying_scope, + /*only_current_p=*/false); + /* If that failed, the declarator is invalid. */ + if (TREE_CODE (type) == TYPENAME_TYPE) + { + if (typedef_variant_p (type)) + error_at (declarator_id_start_token->location, + "cannot define member of dependent typedef " + "%qT", type); + else + error_at (declarator_id_start_token->location, + "%<%T::%E%> is not a type", + TYPE_CONTEXT (qualifying_scope), + TYPE_IDENTIFIER (qualifying_scope)); + } + qualifying_scope = type; + } - /* Resolve the TYPENAME_TYPE. */ - type = resolve_typename_type (qualifying_scope, - /*only_current_p=*/false); - /* If that failed, the declarator is invalid. */ - if (TREE_CODE (type) == TYPENAME_TYPE) - error ("%H%<%T::%E%> is not a type", - &declarator_id_start_token->location, - TYPE_CONTEXT (qualifying_scope), - TYPE_IDENTIFIER (qualifying_scope)); - qualifying_scope = type; - } + sfk = sfk_none; - sfk = sfk_none; + if (unqualified_name) + { + tree class_type; - if (unqualified_name) - { - tree class_type; + if (qualifying_scope + && CLASS_TYPE_P (qualifying_scope)) + class_type = qualifying_scope; + else + class_type = current_class_type; - if (qualifying_scope - && CLASS_TYPE_P (qualifying_scope)) - class_type = qualifying_scope; - else - class_type = current_class_type; + if (TREE_CODE (unqualified_name) == TYPE_DECL) + { + tree name_type = TREE_TYPE (unqualified_name); + if (class_type && same_type_p (name_type, class_type)) + { + if (qualifying_scope + && CLASSTYPE_USE_TEMPLATE (name_type)) + { + error_at (declarator_id_start_token->location, + "invalid use of constructor as a template"); + inform (declarator_id_start_token->location, + "use %<%T::%D%> instead of %<%T::%D%> to " + "name the constructor in a qualified name", + class_type, + DECL_NAME (TYPE_TI_TEMPLATE (class_type)), + class_type, name_type); + declarator = cp_error_declarator; + break; + } + else + unqualified_name = constructor_name (class_type); + } + else + { + /* We do not attempt to print the declarator + here because we do not have enough + information about its original syntactic + form. */ + cp_parser_error (parser, "invalid declarator"); + declarator = cp_error_declarator; + break; + } + } - if (TREE_CODE (unqualified_name) == TYPE_DECL) - { - tree name_type = TREE_TYPE (unqualified_name); - if (class_type && same_type_p (name_type, class_type)) - { - if (qualifying_scope - && CLASSTYPE_USE_TEMPLATE (name_type)) - { - error ("%Hinvalid use of constructor as a template", - &declarator_id_start_token->location); - inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to " - "name the constructor in a qualified name", - class_type, - DECL_NAME (TYPE_TI_TEMPLATE (class_type)), - class_type, name_type); - declarator = cp_error_declarator; - break; - } - else + if (class_type) + { + if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) + sfk = sfk_destructor; + else if (IDENTIFIER_TYPENAME_P (unqualified_name)) + sfk = sfk_conversion; + else if (/* There's no way to declare a constructor + for an anonymous type, even if the type + got a name for linkage purposes. */ + !TYPE_WAS_ANONYMOUS (class_type) + && constructor_name_p (unqualified_name, + class_type)) + { unqualified_name = constructor_name (class_type); - } - else - { - /* We do not attempt to print the declarator - here because we do not have enough - information about its original syntactic - form. */ - cp_parser_error (parser, "invalid declarator"); - declarator = cp_error_declarator; - break; - } - } - - if (class_type) - { - if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) - sfk = sfk_destructor; - else if (IDENTIFIER_TYPENAME_P (unqualified_name)) - sfk = sfk_conversion; - else if (/* There's no way to declare a constructor - for an anonymous type, even if the type - got a name for linkage purposes. */ - !TYPE_WAS_ANONYMOUS (class_type) - && constructor_name_p (unqualified_name, - class_type)) - { - unqualified_name = constructor_name (class_type); + sfk = sfk_constructor; + } + else if (is_overloaded_fn (unqualified_name) + && DECL_CONSTRUCTOR_P (get_first_fn + (unqualified_name))) sfk = sfk_constructor; - } - - if (ctor_dtor_or_conv_p && sfk != sfk_none) - *ctor_dtor_or_conv_p = -1; - } - } - declarator = make_id_declarator (qualifying_scope, - unqualified_name, - sfk); - declarator->id_loc = token->location; - declarator->parameter_pack_p = pack_expansion_p; - if (pack_expansion_p) - maybe_warn_variadic_templates (); + if (ctor_dtor_or_conv_p && sfk != sfk_none) + *ctor_dtor_or_conv_p = -1; + } + } + declarator = make_id_declarator (qualifying_scope, + unqualified_name, + sfk); + declarator->id_loc = token->location; + declarator->parameter_pack_p = pack_expansion_p; + + if (pack_expansion_p) + maybe_warn_variadic_templates (); + } handle_declarator:; scope = get_scope_of_declarator (declarator); @@ -13613,7 +14461,7 @@ cp_parser_ptr_operator (cp_parser* parser, code = INDIRECT_REF; if (TREE_CODE (parser->scope) == NAMESPACE_DECL) - error ("%H%qD is a namespace", &token->location, parser->scope); + error_at (token->location, "%qD is a namespace", parser->scope); else { /* The type of which the member is a member is given by the @@ -13688,7 +14536,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) if (cv_quals & cv_qualifier) { - error ("%Hduplicate cv-qualifier", &token->location); + error_at (token->location, "duplicate cv-qualifier"); cp_lexer_purge_token (parser->lexer); } else @@ -13704,7 +14552,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) /* Parse a late-specified return type, if any. This is not a separate non-terminal, but part of a function declarator, which looks like - -> type-id + -> trailing-type-specifier-seq abstract-declarator(opt) Returns the type indicated by the type-id. */ @@ -13722,7 +14570,7 @@ cp_parser_late_return_type_opt (cp_parser* parser) /* Consume the ->. */ cp_lexer_consume_token (parser->lexer); - return cp_parser_type_id (parser); + return cp_parser_trailing_type_id (parser); } /* Parse a declarator-id. @@ -13775,13 +14623,15 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p) Returns the TYPE specified. */ static tree -cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg) +cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg, + bool is_trailing_return) { cp_decl_specifier_seq type_specifier_seq; cp_declarator *abstract_declarator; /* Parse the type-specifier-seq. */ - cp_parser_type_specifier_seq (parser, /*is_condition=*/false, + cp_parser_type_specifier_seq (parser, /*is_declaration=*/false, + is_trailing_return, &type_specifier_seq); if (type_specifier_seq.type == error_mark_node) return error_mark_node; @@ -13800,8 +14650,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg) if (type_specifier_seq.type && type_uses_auto (type_specifier_seq.type)) { - error ("invalid use of %"); - return error_mark_node; + /* A type-id with type 'auto' is only ok if the abstract declarator + is a function declarator with a late-specified return type. */ + if (abstract_declarator + && abstract_declarator->kind == cdk_function + && abstract_declarator->u.function.late_return_type) + /* OK */; + else + { + error ("invalid use of %"); + return error_mark_node; + } } return groktypename (&type_specifier_seq, abstract_declarator, @@ -13810,12 +14669,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg) static tree cp_parser_type_id (cp_parser *parser) { - return cp_parser_type_id_1 (parser, false); + return cp_parser_type_id_1 (parser, false, false); } static tree cp_parser_template_type_arg (cp_parser *parser) { - return cp_parser_type_id_1 (parser, true); + return cp_parser_type_id_1 (parser, true, false); +} + +static tree cp_parser_trailing_type_id (cp_parser *parser) +{ + return cp_parser_type_id_1 (parser, false, true); } /* Parse a type-specifier-seq. @@ -13828,14 +14692,18 @@ static tree cp_parser_template_type_arg (cp_parser *parser) type-specifier-seq: attributes type-specifier-seq [opt] - If IS_CONDITION is true, we are at the start of a "condition", - e.g., we've just seen "if (". + If IS_DECLARATION is true, we are at the start of a "condition" or + exception-declaration, so we might be followed by a declarator-id. + + If IS_TRAILING_RETURN is true, we are in a trailing-return-type, + i.e. we've just seen "->". Sets *TYPE_SPECIFIER_SEQ to represent the sequence. */ static void cp_parser_type_specifier_seq (cp_parser* parser, - bool is_condition, + bool is_declaration, + bool is_trailing_return, cp_decl_specifier_seq *type_specifier_seq) { bool seen_type_specifier = false; @@ -13845,6 +14713,12 @@ cp_parser_type_specifier_seq (cp_parser* parser, /* Clear the TYPE_SPECIFIER_SEQ. */ clear_decl_specs (type_specifier_seq); + /* In the context of a trailing return type, enum E { } is an + elaborated-type-specifier followed by a function-body, not an + enum-specifier. */ + if (is_trailing_return) + flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS; + /* Parse the type-specifiers and attributes. */ while (true) { @@ -13904,7 +14778,7 @@ cp_parser_type_specifier_seq (cp_parser* parser, would be clearer just to allow a decl-specifier-seq here, and then add a semantic restriction that if any decl-specifiers that are not type-specifiers appear, the program is invalid. */ - if (is_condition && !is_cv_qualifier) + if (is_declaration && !is_cv_qualifier) flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; } @@ -14015,6 +14889,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) tree parameters = NULL_TREE; tree *tail = ¶meters; bool saved_in_unbraced_linkage_specification_p; + int index = 0; /* Assume all will go well. */ *is_error = false; @@ -14066,6 +14941,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) if (DECL_NAME (decl)) decl = pushdecl (decl); + if (decl != error_mark_node) + { + retrofit_lang_decl (decl); + DECL_PARM_INDEX (decl) = ++index; + } + /* Add the new parameter to the list. */ *tail = build_tree_list (parameter->default_argument, decl); tail = &TREE_CHAIN (*tail); @@ -14153,7 +15034,6 @@ cp_parser_parameter_declaration (cp_parser *parser, bool *parenthesized_p) { int declares_class_or_enum; - bool greater_than_is_operator_p; cp_decl_specifier_seq decl_specifiers; cp_declarator *declarator; tree default_argument; @@ -14168,18 +15048,22 @@ cp_parser_parameter_declaration (cp_parser *parser, template-parameter, the first non-nested `>' is taken as the end of the template parameter-list rather than a greater-than operator. */ - greater_than_is_operator_p = !template_parm_p; /* Type definitions may not appear in parameter types. */ saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message - = "types may not be defined in parameter types"; + = G_("types may not be defined in parameter types"); /* Parse the declaration-specifiers. */ cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_NONE, &decl_specifiers, &declares_class_or_enum); + + /* Complain about missing 'typename' or other invalid type names. */ + if (!decl_specifiers.any_type_specifiers_p) + cp_parser_parse_and_diagnose_invalid_type_name (parser); + /* If an error occurred, there's no reason to attempt to parse the rest of the declaration. */ if (cp_parser_error_occurred (parser)) @@ -14283,7 +15167,8 @@ cp_parser_parameter_declaration (cp_parser *parser, /* If we are defining a class, then the tokens that make up the default argument must be saved and processed later. */ if (!template_parm_p && at_class_scope_p () - && TYPE_BEING_DEFINED (current_class_type)) + && TYPE_BEING_DEFINED (current_class_type) + && !LAMBDA_TYPE_P (current_class_type)) { unsigned depth = 0; int maybe_template_id = 0; @@ -14385,7 +15270,7 @@ cp_parser_parameter_declaration (cp_parser *parser, /* If we run out of tokens, issue an error message. */ case CPP_EOF: case CPP_PRAGMA_EOL: - error ("%Hfile ends in default argument", &token->location); + error_at (token->location, "file ends in default argument"); done = true; break; @@ -14434,9 +15319,9 @@ cp_parser_parameter_declaration (cp_parser *parser, warning (0, "deprecated use of default argument for parameter of non-function"); else { - error ("%Hdefault arguments are only " - "permitted for function parameters", - &token->location); + error_at (token->location, + "default arguments are only " + "permitted for function parameters"); default_argument = NULL_TREE; } } @@ -14444,20 +15329,23 @@ cp_parser_parameter_declaration (cp_parser *parser, || (decl_specifiers.type && PACK_EXPANSION_P (decl_specifiers.type))) { - const char* kind = template_parm_p? "template " : ""; - /* Find the name of the parameter pack. */ cp_declarator *id_declarator = declarator; while (id_declarator && id_declarator->kind != cdk_id) id_declarator = id_declarator->declarator; if (id_declarator && id_declarator->kind == cdk_id) - error ("%H%sparameter pack %qD cannot have a default argument", - &declarator_token_start->location, - kind, id_declarator->u.id.unqualified_name); + error_at (declarator_token_start->location, + template_parm_p + ? "template parameter pack %qD" + " cannot have a default argument" + : "parameter pack %qD cannot have a default argument", + id_declarator->u.id.unqualified_name); else - error ("%H%sparameter pack cannot have a default argument", - &declarator_token_start->location, kind); + error_at (declarator_token_start->location, + template_parm_p + ? "template parameter pack cannot have a default argument" + : "parameter pack cannot have a default argument"); default_argument = NULL_TREE; } @@ -14489,12 +15377,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) appear in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; - /* The default argument expression may cause implicitly - defined member functions to be synthesized, which will - result in garbage collection. We must treat this - situation as if we were within the body of function so as - to avoid collecting live data on the stack. */ - ++function_depth; /* Parse the assignment-expression. */ if (template_parm_p) push_deferring_access_checks (dk_no_deferred); @@ -14502,8 +15384,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); if (template_parm_p) pop_deferring_access_checks (); - /* Restore saved state. */ - --function_depth; parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; @@ -14581,13 +15461,20 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, init = cp_parser_initializer_clause (parser, non_constant_p); } else if (token->type == CPP_OPEN_PAREN) - init = cp_parser_parenthesized_expression_list (parser, false, - /*cast_p=*/false, - /*allow_expansion_p=*/true, - non_constant_p); + { + VEC(tree,gc) *vec; + vec = cp_parser_parenthesized_expression_list (parser, non_attr, + /*cast_p=*/false, + /*allow_expansion_p=*/true, + non_constant_p); + if (vec == NULL) + return error_mark_node; + init = build_tree_list_vec (vec); + release_tree_vector (vec); + } else if (token->type == CPP_OPEN_BRACE) { - maybe_warn_cpp0x ("extended initializer lists"); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); init = cp_parser_braced_list (parser, non_constant_p); CONSTRUCTOR_IS_DIRECT_INIT (init) = 1; } @@ -14872,14 +15759,8 @@ cp_parser_class_name (cp_parser *parser, identifier_token->location); if (ambiguous_decls) { - error ("%Hreference to %qD is ambiguous", - &identifier_token->location, identifier); - print_candidates (ambiguous_decls); if (cp_parser_parsing_tentatively (parser)) - { - identifier_token->ambiguous_p = true; - cp_parser_simulate_error (parser); - } + cp_parser_simulate_error (parser); return error_mark_node; } } @@ -14947,10 +15828,8 @@ cp_parser_class_name (cp_parser *parser, static tree cp_parser_class_specifier (cp_parser* parser) { - cp_token *token; tree type; tree attributes = NULL_TREE; - int has_trailing_semicolon; bool nested_name_specifier_p; unsigned saved_num_template_parameter_lists; bool saved_in_function_body; @@ -15028,10 +15907,6 @@ cp_parser_class_specifier (cp_parser* parser) /* Look for the trailing `}'. */ cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>"); - /* We get better error messages by noticing a common problem: a - missing trailing `;'. */ - token = cp_lexer_peek_token (parser->lexer); - has_trailing_semicolon = (token->type == CPP_SEMICOLON); /* Look for trailing attributes to apply to this class. */ if (cp_parser_allow_gnu_extensions_p (parser)) attributes = cp_parser_attributes_opt (parser); @@ -15344,8 +16219,9 @@ cp_parser_class_head (cp_parser* parser, /* Reject typedef-names in class heads. */ if (!DECL_IMPLICIT_TYPEDEF_P (type)) { - error ("%Hinvalid class name in declaration of %qD", - &type_start_token->location, type); + error_at (type_start_token->location, + "invalid class name in declaration of %qD", + type); type = NULL_TREE; goto done; } @@ -15357,14 +16233,14 @@ cp_parser_class_head (cp_parser* parser, if (scope && !is_ancestor (scope, nested_name_specifier)) { if (at_namespace_scope_p ()) - error ("%Hdeclaration of %qD in namespace %qD which does not " - "enclose %qD", - &type_start_token->location, - type, scope, nested_name_specifier); + error_at (type_start_token->location, + "declaration of %qD in namespace %qD which does not " + "enclose %qD", + type, scope, nested_name_specifier); else - error ("%Hdeclaration of %qD in %qD which does not enclose %qD", - &type_start_token->location, - type, scope, nested_name_specifier); + error_at (type_start_token->location, + "declaration of %qD in %qD which does not enclose %qD", + type, scope, nested_name_specifier); type = NULL_TREE; goto done; } @@ -15376,8 +16252,8 @@ cp_parser_class_head (cp_parser* parser, class member of a namespace outside of its namespace. */ if (scope == nested_name_specifier) { - permerror (input_location, "%Hextra qualification not allowed", - &nested_name_specifier_token_start->location); + permerror (nested_name_specifier_token_start->location, + "extra qualification not allowed"); nested_name_specifier = NULL_TREE; num_templates = 0; } @@ -15388,8 +16264,8 @@ cp_parser_class_head (cp_parser* parser, && parser->num_template_parameter_lists == 0 && template_id_p) { - error ("%Han explicit specialization must be preceded by %