X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fparser.c;h=8a1bb9f600ed0ddfbb99b1f5bba6bc41f37cbf32;hp=f3122bc76fd9f6a70d2149491a77b72d4c2e81f4;hb=cb84e3260f2c8971ed840a90546cfebf87bfae78;hpb=32d008d96c324cc44d8a92b38cb67ed33e24f040 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f3122bc76fd..8a1bb9f600e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "cpplib.h" #include "tree.h" #include "cp-tree.h" +#include "intl.h" #include "c-pragma.h" #include "decl.h" #include "flags.h" @@ -402,7 +403,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; @@ -792,6 +793,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; @@ -888,6 +890,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; } @@ -1194,8 +1197,12 @@ enum /* 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 + /* 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 @@ -1626,6 +1633,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] */ @@ -1733,10 +1748,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 @@ -1859,6 +1875,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 @@ -2050,7 +2068,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. */ @@ -2079,7 +2098,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; } @@ -2110,26 +2130,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 @@ -2164,7 +2184,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs, if (ds == ds_long) { if (count > 2) - error ("%H% is too long for GCC", &location); + error_at (location, "% is too long for GCC"); else pedwarn_cxx98 (location, OPT_Wlong_long, "ISO C++ 1998 does not support %"); @@ -2184,10 +2204,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[ds]); + error_at (location, "duplicate %qs", decl_spec_names[ds]); } } } @@ -2231,7 +2252,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); @@ -2253,11 +2275,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); @@ -2319,18 +2341,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: @@ -2378,11 +2400,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 (); } @@ -2405,6 +2442,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, @@ -2412,12 +2457,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); @@ -2429,9 +2471,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; } @@ -2448,6 +2493,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)) @@ -2464,6 +2510,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) @@ -2479,7 +2534,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; @@ -2945,8 +3001,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 +3031,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 +3206,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 +3261,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 +3299,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 +3337,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) { @@ -3299,8 +3372,8 @@ cp_parser_primary_expression (cp_parser *parser, 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 +3469,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 +3530,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 +3593,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 +3618,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 +3887,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 +3897,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 +3925,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 +3943,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 +3961,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 +3980,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 +4008,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 +4023,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 +4238,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 +4443,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 +4551,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 +4614,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); @@ -4758,14 +4858,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, && 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)) @@ -5002,7 +5101,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 @@ -5086,7 +5186,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 @@ -5202,7 +5302,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; @@ -5542,7 +5642,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; @@ -5668,8 +5768,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); @@ -5751,9 +5851,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; @@ -5873,8 +5974,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; } } @@ -5917,7 +6019,7 @@ cp_parser_new_initializer (cp_parser* parser) { tree t; bool expr_non_constant_p; - maybe_warn_cpp0x ("extended initializer lists"); + 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); @@ -6062,7 +6164,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 @@ -6257,11 +6359,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); @@ -6478,7 +6580,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. */ @@ -6854,6 +6956,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; @@ -6904,6 +7012,519 @@ 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; + + /* 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. @@ -7122,8 +7743,9 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) if (parser->in_switch_statement_p) 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; @@ -7134,7 +7756,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) if (parser->in_switch_statement_p) 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: @@ -7183,12 +7805,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); @@ -7274,7 +7916,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 %"); } } @@ -7404,10 +8046,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. */ @@ -7471,9 +8112,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; @@ -7534,7 +8176,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); @@ -7714,7 +8356,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. @@ -7755,7 +8397,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) @@ -7763,10 +8405,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, "%<;%>"); @@ -7776,14 +8418,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 (); @@ -7798,7 +8440,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)) @@ -8185,7 +8827,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)) @@ -8258,7 +8900,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 @@ -8322,8 +8964,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 @@ -8458,11 +9101,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 @@ -8473,6 +9117,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 @@ -8516,10 +9165,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, @@ -8618,6 +9265,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; } } @@ -8637,8 +9286,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. @@ -8707,7 +9356,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; @@ -8873,7 +9522,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. */ @@ -8982,12 +9631,25 @@ 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. */ @@ -9096,7 +9758,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) @@ -9198,8 +9861,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) @@ -9220,8 +9883,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; } @@ -9291,7 +9955,7 @@ 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); @@ -9342,9 +10006,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. */ @@ -9379,7 +10043,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); @@ -9873,11 +10537,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); @@ -9885,7 +10550,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; @@ -9971,11 +10636,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 (); @@ -9991,14 +10658,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. */ @@ -10077,13 +10743,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 (); @@ -10132,7 +10798,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 @@ -10180,7 +10846,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, @@ -10305,8 +10970,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 (); @@ -10420,9 +11084,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)) @@ -10462,12 +11126,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) @@ -10555,8 +11218,8 @@ cp_parser_template_argument_list (cp_parser* parser) if (argument == error_mark_node) { cp_token *token = cp_lexer_peek_token (parser->lexer); - error ("%Hexpected parameter pack before %<...%>", - &token->location); + error_at (token->location, + "expected parameter pack before %<...%>"); } /* Consume the `...' token. */ cp_lexer_consume_token (parser->lexer); @@ -10592,6 +11255,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; } @@ -10754,18 +11420,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)) @@ -10851,7 +11525,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. */ @@ -10874,7 +11547,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, @@ -10965,7 +11637,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); @@ -11069,6 +11741,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. */ @@ -11091,6 +11766,9 @@ 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); @@ -11287,7 +11965,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; @@ -11325,8 +12003,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 @@ -11341,7 +12017,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 @@ -11578,6 +12254,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. */ @@ -11593,7 +12270,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); @@ -11609,9 +12286,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 @@ -11624,10 +12298,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, @@ -11933,7 +12607,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); @@ -11948,27 +12622,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) { @@ -12157,7 +12833,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; } @@ -12241,7 +12917,7 @@ cp_parser_namespace_definition (cp_parser* parser) #ifdef HANDLE_PRAGMA_VISIBILITY if (has_visibility) - pop_visibility (); + pop_visibility (1); #endif /* Finish the namespace. */ @@ -12284,7 +12960,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)) @@ -12424,8 +13100,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 ()) @@ -12511,7 +13187,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) @@ -12520,11 +13199,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, "%"); @@ -12537,6 +13219,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; @@ -12561,6 +13252,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; @@ -12576,7 +13268,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) @@ -12598,6 +13291,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); @@ -12612,16 +13307,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, "%<;%>"); @@ -12632,7 +13352,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) { @@ -12761,6 +13481,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)) @@ -12801,12 +13526,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; @@ -12958,8 +13683,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, @@ -12967,9 +13692,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 @@ -13073,7 +13810,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; @@ -13088,9 +13824,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. */ @@ -13375,11 +14108,13 @@ cp_parser_direct_declarator (cp_parser* parser, bounds = fold_non_dependent_expr (bounds); /* 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)) @@ -13497,10 +14232,17 @@ cp_parser_direct_declarator (cp_parser* parser, /*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)); + { + 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; } @@ -13524,9 +14266,10 @@ cp_parser_direct_declarator (cp_parser* parser, 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 " + 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)), @@ -13565,6 +14308,10 @@ cp_parser_direct_declarator (cp_parser* parser, 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; @@ -13700,7 +14447,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 @@ -13775,7 +14522,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 @@ -13791,7 +14538,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. */ @@ -13809,7 +14556,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. @@ -13862,13 +14609,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; @@ -13906,12 +14655,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. @@ -13924,14 +14678,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; @@ -13941,6 +14699,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) { @@ -14000,7 +14764,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; } @@ -14256,7 +15020,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; @@ -14271,18 +15034,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)) @@ -14386,7 +15153,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; @@ -14488,7 +15256,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; @@ -14537,9 +15305,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; } } @@ -14547,20 +15315,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; } @@ -14592,12 +15363,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); @@ -14605,8 +15370,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; @@ -14697,7 +15460,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, } 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; } @@ -14982,14 +15745,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; } } @@ -15448,8 +16205,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; } @@ -15461,14 +16219,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; } @@ -15480,8 +16238,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; } @@ -15492,8 +16250,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 %