X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fparser.c;h=120360a4d9235668f0f38edcf16494679a35ed55;hb=0958a641e614f832728291f512df7a293137f784;hp=a0aa2a1a4f7c6535b7a4c634e4668fed404aca75;hpb=f770bf539d878932610b858b44971478cb8c3825;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a0aa2a1a4f7..120360a4d92 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1,6 +1,6 @@ /* C++ Parser. Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + 2005, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Written by Mark Mitchell . This file is part of GCC. @@ -2007,7 +2007,7 @@ static tree cp_parser_class_name static tree cp_parser_class_specifier (cp_parser *); static tree cp_parser_class_head - (cp_parser *, bool *, tree *, tree *); + (cp_parser *, bool *); static enum tag_types cp_parser_class_key (cp_parser *); static void cp_parser_member_specification_opt @@ -2249,6 +2249,8 @@ static void cp_parser_pre_parsed_nested_name_specifier (cp_parser *); static bool cp_parser_cache_group (cp_parser *, enum cpp_ttype, unsigned); +static tree cp_parser_cache_defarg + (cp_parser *parser, bool nsdmi); static void cp_parser_parse_tentatively (cp_parser *); static void cp_parser_commit_to_tentative_parse @@ -3579,7 +3581,13 @@ lookup_literal_operator (tree name, VEC(tree,gc) *args) TREE_TYPE (tparm)))) found = false; } - if (found) + if (found + && ix == VEC_length (tree, args) + /* May be this should be sufficient_parms_p instead, + depending on how exactly should user-defined literals + work in presence of default arguments on the literal + operator parameters. */ + && argtypes == void_list_node) return fn; } } @@ -3854,6 +3862,7 @@ cp_parser_translation_unit (cp_parser* parser) __is_convertible_to ( type-id , type-id ) __is_empty ( type-id ) __is_enum ( type-id ) + __is_final ( type-id ) __is_literal_type ( type-id ) __is_pod ( type-id ) __is_polymorphic ( type-id ) @@ -4199,6 +4208,7 @@ cp_parser_primary_expression (cp_parser *parser, case RID_IS_CONVERTIBLE_TO: case RID_IS_EMPTY: case RID_IS_ENUM: + case RID_IS_FINAL: case RID_IS_LITERAL_TYPE: case RID_IS_POD: case RID_IS_POLYMORPHIC: @@ -5827,6 +5837,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, by cp_parser_builtin_offsetof. We're looking for postfix-expression [ expression ] + postfix-expression [ braced-init-list ] (C++11) FOR_OFFSETOF is set if we're being called in that context, which changes how we deal with integer constant expressions. */ @@ -5852,7 +5863,16 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, if (for_offsetof) index = cp_parser_constant_expression (parser, false, NULL); else - index = cp_parser_expression (parser, /*cast_p=*/false, NULL); + { + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + { + bool expr_nonconst_p; + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); + index = cp_parser_braced_list (parser, &expr_nonconst_p); + } + else + index = cp_parser_expression (parser, /*cast_p=*/false, NULL); + } /* Look for the closing `]'. */ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); @@ -6031,9 +6051,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } - if (scope && name && BASELINK_P (name)) + if (parser->scope && name && BASELINK_P (name)) adjust_result_of_qualified_name_lookup - (name, BINFO_TYPE (BASELINK_ACCESS_BINFO (name)), scope); + (name, parser->scope, scope); postfix_expression = finish_class_member_access_expr (postfix_expression, name, template_p, @@ -6297,10 +6317,6 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, /* Look for the `~'. */ cp_parser_require (parser, CPP_COMPL, RT_COMPL); - /* Once we see the ~, this has to be a pseudo-destructor. */ - if (!processing_template_decl && !cp_parser_error_occurred (parser)) - cp_parser_commit_to_tentative_parse (parser); - /* Look for the type-name again. We are not responsible for checking that it matches the first type-name. */ *type = cp_parser_nonclass_name (parser); @@ -6654,10 +6670,17 @@ cp_parser_new_expression (cp_parser* parser) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { cp_token *token; + const char *saved_message = parser->type_definition_forbidden_message; + /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); + /* Parse the type-id. */ + parser->type_definition_forbidden_message + = G_("types may not be defined in a new-expression"); type = cp_parser_type_id (parser); + parser->type_definition_forbidden_message = saved_message; + /* Look for the closing `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); token = cp_lexer_peek_token (parser->lexer); @@ -6983,8 +7006,9 @@ cp_parser_delete_expression (cp_parser* parser) otherwise. */ static bool -cp_parser_token_starts_cast_expression (cp_token *token) +cp_parser_tokens_start_cast_expression (cp_parser *parser) { + cp_token *token = cp_lexer_peek_token (parser->lexer); switch (token->type) { case CPP_COMMA: @@ -7025,6 +7049,12 @@ cp_parser_token_starts_cast_expression (cp_token *token) case CPP_EOF: return false; + case CPP_OPEN_PAREN: + /* In ((type ()) () the last () isn't a valid cast-expression, + so the whole must be parsed as postfix-expression. */ + return cp_lexer_peek_nth_token (parser->lexer, 2)->type + != CPP_CLOSE_PAREN; + /* '[' may start a primary-expression in obj-c++. */ case CPP_OPEN_SQUARE: return c_dialect_objc (); @@ -7117,8 +7147,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, parenthesized ctor such as `(T ())' that looks like a cast to function returning T. */ if (!cp_parser_error_occurred (parser) - && cp_parser_token_starts_cast_expression (cp_lexer_peek_token - (parser->lexer))) + && cp_parser_tokens_start_cast_expression (parser)) { cp_parser_parse_definitely (parser); expr = cp_parser_cast_expression (parser, @@ -7249,6 +7278,9 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk); lhs_type = ERROR_MARK; + if (cp_parser_error_occurred (parser)) + return error_mark_node; + for (;;) { /* Get an operator token. */ @@ -7868,6 +7900,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case RID_IS_ENUM: kind = CPTK_IS_ENUM; break; + case RID_IS_FINAL: + kind = CPTK_IS_FINAL; + break; case RID_IS_LITERAL_TYPE: kind = CPTK_IS_LITERAL_TYPE; break; @@ -8033,6 +8068,8 @@ cp_parser_lambda_expression (cp_parser* parser) cp_parser_lambda_introducer (parser, lambda_expr); type = begin_lambda_type (lambda_expr); + if (type == error_mark_node) + return error_mark_node; record_lambda_scope (lambda_expr); @@ -9323,7 +9360,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl) range_expr = error_mark_node; stmt = begin_range_for_stmt (scope, init); finish_range_for_decl (stmt, range_decl, range_expr); - if (!type_dependent_expression_p (range_expr) + if (range_expr != error_mark_node + && !type_dependent_expression_p (range_expr) + /* The length of an array might be dependent. */ + && COMPLETE_TYPE_P (TREE_TYPE (range_expr)) /* do_auto_deduction doesn't mess with template init-lists. */ && !BRACE_ENCLOSED_INITIALIZER_P (range_expr)) do_range_for_auto_deduction (range_decl, range_expr); @@ -11932,8 +11972,7 @@ cp_parser_template_parameter_list (cp_parser* parser) parm_loc, parameter, is_non_type, - is_parameter_pack, - 0); + is_parameter_pack); else { tree err_parm = build_tree_list (parameter, parameter); @@ -12696,7 +12735,7 @@ cp_parser_template_name (cp_parser* parser, its name; we will look it up again during template instantiation. */ if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl)) { - tree scope = CP_DECL_CONTEXT (get_first_fn (decl)); + tree scope = ovl_scope (decl); if (TYPE_P (scope) && dependent_type_p (scope)) return identifier; } @@ -13807,9 +13846,8 @@ cp_parser_nonclass_name (cp_parser* parser) /* Look up the type-name. */ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location); - /* If it is a using decl, use its underlying decl. */ type_decl = strip_using_decl (type_decl); - + if (TREE_CODE (type_decl) != TYPE_DECL && (objc_is_id (identifier) || objc_is_class_name (identifier))) { @@ -13978,12 +14016,14 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, typename_type, /*complain=*/tf_error); /* If the `typename' keyword is in effect and DECL is not a type - decl. Then type is non existant. */ + decl, then type is non existent. */ else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) - type = NULL_TREE; - else - type = check_elaborated_type_specifier (tag_type, decl, + ; + else if (TREE_CODE (decl) == TYPE_DECL) + type = check_elaborated_type_specifier (tag_type, decl, /*allow_template_p=*/true); + else if (decl == error_mark_node) + type = error_mark_node; } if (!type) @@ -14863,9 +14903,14 @@ cp_parser_using_declaration (cp_parser* parser, tree decl; tree identifier; tree qscope; + int oldcount = errorcount; + cp_token *diag_token = NULL; if (access_declaration_p) - cp_parser_parse_tentatively (parser); + { + diag_token = cp_lexer_peek_token (parser->lexer); + cp_parser_parse_tentatively (parser); + } else { /* Look for the `using' keyword. */ @@ -14947,9 +14992,12 @@ cp_parser_using_declaration (cp_parser* parser, /* Create the USING_DECL. */ decl = do_class_using_decl (parser->scope, identifier); + if (decl && typename_p) + USING_DECL_TYPENAME_P (decl) = 1; + if (check_for_bare_parameter_packs (decl)) return false; - else + else /* Add it to the list of members in this class. */ finish_member_declaration (decl); } @@ -14973,7 +15021,13 @@ cp_parser_using_declaration (cp_parser* parser, /* Look for the final `;'. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); - + + if (access_declaration_p && errorcount == oldcount) + warning_at (diag_token->location, OPT_Wdeprecated, + "access declarations are deprecated " + "in favour of using-declarations; " + "suggestion: add the % keyword"); + return true; } @@ -14996,9 +15050,18 @@ cp_parser_alias_declaration (cp_parser* parser) cp_parser_require_keyword (parser, RID_USING, RT_USING); id_location = cp_lexer_peek_token (parser->lexer)->location; id = cp_parser_identifier (parser); + if (id == error_mark_node) + return error_mark_node; + attributes = cp_parser_attributes_opt (parser); + if (attributes == error_mark_node) + return error_mark_node; + cp_parser_require (parser, CPP_EQ, RT_EQ); + if (cp_parser_error_occurred (parser)) + return error_mark_node; + /* Now we are going to parse the type-id of the declaration. */ /* @@ -15661,8 +15724,7 @@ cp_parser_init_declarator (cp_parser* parser, { /* 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 + member templates. The former involves 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) @@ -16421,6 +16483,9 @@ cp_parser_ptr_operator (cp_parser* parser, if (TREE_CODE (parser->scope) == NAMESPACE_DECL) error_at (token->location, "%qD is a namespace", parser->scope); + else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE) + error_at (token->location, "cannot form pointer to member of " + "non-class %q#T", parser->scope); else { /* The type of which the member is a member is given by the @@ -16604,7 +16669,7 @@ static tree cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals) { cp_token *token; - tree type; + tree type, save_ccp, save_ccr; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -16615,17 +16680,21 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals) /* Consume the ->. */ cp_lexer_consume_token (parser->lexer); + save_ccp = current_class_ptr; + save_ccr = current_class_ref; if (quals >= 0) { /* DR 1207: 'this' is in scope in the trailing return type. */ - gcc_assert (current_class_ptr == NULL_TREE); inject_this_parameter (current_class_type, quals); } type = cp_parser_trailing_type_id (parser); if (quals >= 0) - current_class_ptr = current_class_ref = NULL_TREE; + { + current_class_ptr = save_ccp; + current_class_ref = save_ccr; + } return type; } @@ -17226,159 +17295,18 @@ cp_parser_parameter_declaration (cp_parser *parser, /* If the next token is `=', then process a default argument. */ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) { + token = cp_lexer_peek_token (parser->lexer); /* 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) && !LAMBDA_TYPE_P (current_class_type)) - { - unsigned depth = 0; - int maybe_template_id = 0; - cp_token *first_token; - cp_token *token; - - /* Add tokens until we have processed the entire default - argument. We add the range [first_token, token). */ - first_token = cp_lexer_peek_token (parser->lexer); - while (true) - { - bool done = false; - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* What we do depends on what token we have. */ - switch (token->type) - { - /* In valid code, a default argument must be - immediately followed by a `,' `)', or `...'. */ - case CPP_COMMA: - if (depth == 0 && maybe_template_id) - { - /* If we've seen a '<', we might be in a - template-argument-list. Until Core issue 325 is - resolved, we don't know how this situation ought - to be handled, so try to DTRT. We check whether - what comes after the comma is a valid parameter - declaration list. If it is, then the comma ends - the default argument; otherwise the default - argument continues. */ - bool error = false; - tree t; - - /* Set ITALP so cp_parser_parameter_declaration_list - doesn't decide to commit to this parse. */ - bool saved_italp = parser->in_template_argument_list_p; - parser->in_template_argument_list_p = true; - - cp_parser_parse_tentatively (parser); - cp_lexer_consume_token (parser->lexer); - begin_scope (sk_function_parms, NULL_TREE); - cp_parser_parameter_declaration_list (parser, &error); - for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) - pop_binding (DECL_NAME (t), t); - leave_scope (); - if (!cp_parser_error_occurred (parser) && !error) - done = true; - cp_parser_abort_tentative_parse (parser); - - parser->in_template_argument_list_p = saved_italp; - break; - } - case CPP_CLOSE_PAREN: - case CPP_ELLIPSIS: - /* If we run into a non-nested `;', `}', or `]', - then the code is invalid -- but the default - argument is certainly over. */ - case CPP_SEMICOLON: - case CPP_CLOSE_BRACE: - case CPP_CLOSE_SQUARE: - if (depth == 0) - done = true; - /* Update DEPTH, if necessary. */ - else if (token->type == CPP_CLOSE_PAREN - || token->type == CPP_CLOSE_BRACE - || token->type == CPP_CLOSE_SQUARE) - --depth; - break; - - case CPP_OPEN_PAREN: - case CPP_OPEN_SQUARE: - case CPP_OPEN_BRACE: - ++depth; - break; - - case CPP_LESS: - if (depth == 0) - /* This might be the comparison operator, or it might - start a template argument list. */ - ++maybe_template_id; - break; - - case CPP_RSHIFT: - if (cxx_dialect == cxx98) - break; - /* Fall through for C++0x, which treats the `>>' - operator like two `>' tokens in certain - cases. */ - - case CPP_GREATER: - if (depth == 0) - { - /* This might be an operator, or it might close a - template argument list. But if a previous '<' - started a template argument list, this will have - closed it, so we can't be in one anymore. */ - maybe_template_id -= 1 + (token->type == CPP_RSHIFT); - if (maybe_template_id < 0) - maybe_template_id = 0; - } - break; - - /* If we run out of tokens, issue an error message. */ - case CPP_EOF: - case CPP_PRAGMA_EOL: - error_at (token->location, "file ends in default argument"); - done = true; - break; - - case CPP_NAME: - case CPP_SCOPE: - /* In these cases, we should look for template-ids. - For example, if the default argument is - `X()', we need to do name lookup to - figure out whether or not `X' is a template; if - so, the `,' does not end the default argument. - - That is not yet done. */ - break; - - default: - break; - } - - /* If we've reached the end, stop. */ - if (done) - break; - - /* Add the token to the token block. */ - token = cp_lexer_consume_token (parser->lexer); - } - - /* Create a DEFAULT_ARG to represent the unparsed default - argument. */ - default_argument = make_node (DEFAULT_ARG); - DEFARG_TOKENS (default_argument) - = cp_token_cache_new (first_token, token); - DEFARG_INSTANTIATIONS (default_argument) = NULL; - } + default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false); /* Outside of a class definition, we can just parse the assignment-expression. */ else - { - token = cp_lexer_peek_token (parser->lexer); - default_argument - = cp_parser_default_argument (parser, template_parm_p); - } + default_argument + = cp_parser_default_argument (parser, template_parm_p); if (!parser->default_arg_ok_p) { @@ -17500,11 +17428,8 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser) cp_parser_function_body changed its state. */ if (check_body_p) { - list = body; - if (TREE_CODE (list) == BIND_EXPR) - list = BIND_EXPR_BODY (list); - if (TREE_CODE (list) == STATEMENT_LIST - && STATEMENT_LIST_TAIL (list) != NULL) + list = cur_stmt_list; + if (STATEMENT_LIST_TAIL (list)) last = STATEMENT_LIST_TAIL (list)->stmt; } /* Parse the function-body. */ @@ -17732,13 +17657,17 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p) && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { /* In C++11, [ could start a lambda-introducer. */ + bool non_const = false; + cp_parser_parse_tentatively (parser); cp_lexer_consume_token (parser->lexer); - designator = cp_parser_constant_expression (parser, false, NULL); + designator = cp_parser_constant_expression (parser, true, &non_const); cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); cp_parser_require (parser, CPP_EQ, RT_EQ); if (!cp_parser_parse_definitely (parser)) designator = NULL_TREE; + else if (non_const) + require_potential_rvalue_constant_expression (designator); } else designator = NULL_TREE; @@ -17914,6 +17843,8 @@ cp_parser_class_name (cp_parser *parser, decl = TYPE_NAME (decl); } + decl = strip_using_decl (decl); + /* Check to see that it is really the name of a class. */ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE @@ -17971,16 +17902,13 @@ cp_parser_class_specifier_1 (cp_parser* parser) bool saved_in_unbraced_linkage_specification_p; tree old_scope = NULL_TREE; tree scope = NULL_TREE; - tree bases; cp_token *closing_brace; push_deferring_access_checks (dk_no_deferred); /* Parse the class-head. */ type = cp_parser_class_head (parser, - &nested_name_specifier_p, - &attributes, - &bases); + &nested_name_specifier_p); /* If the class-head was a semantic disaster, skip the entire body of the class. */ if (!type) @@ -17997,18 +17925,6 @@ cp_parser_class_specifier_1 (cp_parser* parser) return error_mark_node; } - /* Process the base classes. If they're invalid, skip the - entire class body. */ - if (!xref_basetypes (type, bases)) - { - /* Consuming the closing brace yields better error messages - later on. */ - if (cp_parser_skip_to_closing_brace (parser)) - cp_lexer_consume_token (parser->lexer); - pop_deferring_access_checks (); - return error_mark_node; - } - /* Issue an error message if type-definitions are forbidden here. */ cp_parser_check_type_definition (parser); /* Remember that we are defining one more class. */ @@ -18038,7 +17954,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)); old_scope = push_inner_scope (scope); } - type = begin_class_definition (type, attributes); + type = begin_class_definition (type); if (type == error_mark_node) /* If the type is erroneous, skip the entire body of the class. */ @@ -18294,15 +18210,14 @@ cp_parser_class_specifier (cp_parser* parser) static tree cp_parser_class_head (cp_parser* parser, - bool* nested_name_specifier_p, - tree *attributes_p, - tree *bases) + bool* nested_name_specifier_p) { tree nested_name_specifier; enum tag_types class_key; tree id = NULL_TREE; tree type = NULL_TREE; tree attributes; + tree bases; cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED; bool template_id_p = false; bool qualified_p = false; @@ -18319,8 +18234,6 @@ cp_parser_class_head (cp_parser* parser, num_templates = 0; parser->colon_corrects_to_scope_p = false; - *bases = NULL_TREE; - /* Look for the class-key. */ class_key = cp_parser_class_key (parser); if (class_key == none_type) @@ -18663,6 +18576,14 @@ cp_parser_class_head (cp_parser* parser, else if (type == error_mark_node) type = NULL_TREE; + if (type) + { + /* Apply attributes now, before any use of the class as a template + argument in its base list. */ + cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE); + fixup_attribute_variants (type); + } + /* We will have entered the scope containing the class; the names of base classes should be looked up in that context. For example: @@ -18673,7 +18594,15 @@ cp_parser_class_head (cp_parser* parser, /* Get the list of base-classes, if there is one. */ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - *bases = cp_parser_base_clause (parser); + bases = cp_parser_base_clause (parser); + else + bases = NULL_TREE; + + /* If we're really defining a class, process the base classes. + If they're invalid, fail. */ + if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) + && !xref_basetypes (type, bases)) + type = NULL_TREE; done: /* Leave the scope given by the nested-name-specifier. We will @@ -18689,7 +18618,6 @@ cp_parser_class_head (cp_parser* parser, if (type) DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location; - *attributes_p = attributes; if (type && (virt_specifiers & VIRT_SPEC_FINAL)) CLASSTYPE_FINAL (type) = 1; out: @@ -18900,7 +18828,7 @@ cp_parser_member_declaration (cp_parser* parser) parser->colon_corrects_to_scope_p = false; if (cp_parser_using_declaration (parser, /*access_declaration=*/true)) - goto out; + goto out; /* Parse the decl-specifier-seq. */ decl_spec_token_start = cp_lexer_peek_token (parser->lexer); @@ -19176,7 +19104,7 @@ cp_parser_member_declaration (cp_parser* parser) possible that this fact is an oversight in the standard, since a pure function may be defined outside of the class-specifier. */ - if (initializer) + if (initializer && initializer_token_start) error_at (initializer_token_start->location, "pure-specifier on function-definition"); decl = cp_parser_save_member_function_body (parser, @@ -21202,7 +21130,6 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) { /* Parse the template parameters. */ parameter_list = cp_parser_template_parameter_list (parser); - fixup_template_parms (); } /* Get the deferred access checks from the parameter list. These @@ -21474,6 +21401,9 @@ cp_parser_functional_cast (cp_parser* parser, tree type) tree cast; bool nonconst_p; + if (!type) + type = error_mark_node; + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); @@ -21589,25 +21519,9 @@ cp_parser_save_member_function_body (cp_parser* parser, static tree cp_parser_save_nsdmi (cp_parser* parser) { - /* Save away the tokens that make up the body of the - function. */ - cp_token *first = parser->lexer->next_token; - cp_token *last; - tree node; - - /* Save tokens until the next comma or semicolon. */ - cp_parser_cache_group (parser, CPP_COMMA, /*depth=*/0); - - last = parser->lexer->next_token; - - node = make_node (DEFAULT_ARG); - DEFARG_TOKENS (node) = cp_token_cache_new (first, last); - DEFARG_INSTANTIATIONS (node) = NULL; - - return node; + return cp_parser_cache_defarg (parser, /*nsdmi=*/true); } - /* Parse a template-argument-list, as well as the trailing ">" (but not the opening "<"). See cp_parser_template_argument_list for the return value. */ @@ -21826,6 +21740,9 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl, tree parsed_arg; bool dummy; + if (default_arg == error_mark_node) + return error_mark_node; + /* Push the saved tokens for the default argument onto the parser's lexer stack. */ tokens = DEFARG_TOKENS (default_arg); @@ -22594,6 +22511,8 @@ cp_parser_token_is_class_key (cp_token* token) static void cp_parser_check_class_key (enum tag_types class_key, tree type) { + if (type == error_mark_node) + return; if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type)) { permerror (input_location, "%qs tag used in naming %q#T", @@ -22712,12 +22631,6 @@ cp_parser_cache_group (cp_parser *parser, kind of syntax error. */ return true; - /* If we're caching something finished by a comma (or semicolon), - such as an NSDMI, don't consume the comma. */ - if (end == CPP_COMMA - && (token->type == CPP_SEMICOLON || token->type == CPP_COMMA)) - return false; - /* Consume the token. */ cp_lexer_consume_token (parser->lexer); /* See if it starts a new group. */ @@ -22743,6 +22656,178 @@ cp_parser_cache_group (cp_parser *parser, } } +/* Like above, for caching a default argument or NSDMI. Both of these are + terminated by a non-nested comma, but it can be unclear whether or not a + comma is nested in a template argument list unless we do more parsing. + In order to handle this ambiguity, when we encounter a ',' after a '<' + we try to parse what follows as a parameter-declaration-list (in the + case of a default argument) or a member-declarator (in the case of an + NSDMI). If that succeeds, then we stop caching. */ + +static tree +cp_parser_cache_defarg (cp_parser *parser, bool nsdmi) +{ + unsigned depth = 0; + int maybe_template_id = 0; + cp_token *first_token; + cp_token *token; + tree default_argument; + + /* Add tokens until we have processed the entire default + argument. We add the range [first_token, token). */ + first_token = cp_lexer_peek_token (parser->lexer); + if (first_token->type == CPP_OPEN_BRACE) + { + /* For list-initialization, this is straightforward. */ + cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); + token = cp_lexer_peek_token (parser->lexer); + } + else while (true) + { + bool done = false; + + /* Peek at the next token. */ + token = cp_lexer_peek_token (parser->lexer); + /* What we do depends on what token we have. */ + switch (token->type) + { + /* In valid code, a default argument must be + immediately followed by a `,' `)', or `...'. */ + case CPP_COMMA: + if (depth == 0 && maybe_template_id) + { + /* If we've seen a '<', we might be in a + template-argument-list. Until Core issue 325 is + resolved, we don't know how this situation ought + to be handled, so try to DTRT. We check whether + what comes after the comma is a valid parameter + declaration list. If it is, then the comma ends + the default argument; otherwise the default + argument continues. */ + bool error = false; + tree t; + + /* Set ITALP so cp_parser_parameter_declaration_list + doesn't decide to commit to this parse. */ + bool saved_italp = parser->in_template_argument_list_p; + parser->in_template_argument_list_p = true; + + cp_parser_parse_tentatively (parser); + cp_lexer_consume_token (parser->lexer); + + if (nsdmi) + { + int ctor_dtor_or_conv_p; + cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, + &ctor_dtor_or_conv_p, + /*parenthesized_p=*/NULL, + /*member_p=*/true); + } + else + { + begin_scope (sk_function_parms, NULL_TREE); + cp_parser_parameter_declaration_list (parser, &error); + for (t = current_binding_level->names; t; t = DECL_CHAIN (t)) + pop_binding (DECL_NAME (t), t); + leave_scope (); + } + if (!cp_parser_error_occurred (parser) && !error) + done = true; + cp_parser_abort_tentative_parse (parser); + + parser->in_template_argument_list_p = saved_italp; + break; + } + case CPP_CLOSE_PAREN: + case CPP_ELLIPSIS: + /* If we run into a non-nested `;', `}', or `]', + then the code is invalid -- but the default + argument is certainly over. */ + case CPP_SEMICOLON: + case CPP_CLOSE_BRACE: + case CPP_CLOSE_SQUARE: + if (depth == 0) + done = true; + /* Update DEPTH, if necessary. */ + else if (token->type == CPP_CLOSE_PAREN + || token->type == CPP_CLOSE_BRACE + || token->type == CPP_CLOSE_SQUARE) + --depth; + break; + + case CPP_OPEN_PAREN: + case CPP_OPEN_SQUARE: + case CPP_OPEN_BRACE: + ++depth; + break; + + case CPP_LESS: + if (depth == 0) + /* This might be the comparison operator, or it might + start a template argument list. */ + ++maybe_template_id; + break; + + case CPP_RSHIFT: + if (cxx_dialect == cxx98) + break; + /* Fall through for C++0x, which treats the `>>' + operator like two `>' tokens in certain + cases. */ + + case CPP_GREATER: + if (depth == 0) + { + /* This might be an operator, or it might close a + template argument list. But if a previous '<' + started a template argument list, this will have + closed it, so we can't be in one anymore. */ + maybe_template_id -= 1 + (token->type == CPP_RSHIFT); + if (maybe_template_id < 0) + maybe_template_id = 0; + } + break; + + /* If we run out of tokens, issue an error message. */ + case CPP_EOF: + case CPP_PRAGMA_EOL: + error_at (token->location, "file ends in default argument"); + done = true; + break; + + case CPP_NAME: + case CPP_SCOPE: + /* In these cases, we should look for template-ids. + For example, if the default argument is + `X()', we need to do name lookup to + figure out whether or not `X' is a template; if + so, the `,' does not end the default argument. + + That is not yet done. */ + break; + + default: + break; + } + + /* If we've reached the end, stop. */ + if (done) + break; + + /* Add the token to the token block. */ + token = cp_lexer_consume_token (parser->lexer); + } + + /* Create a DEFAULT_ARG to represent the unparsed default + argument. */ + default_argument = make_node (DEFAULT_ARG); + DEFARG_TOKENS (default_argument) + = cp_token_cache_new (first_token, token); + DEFARG_INSTANTIATIONS (default_argument) = NULL; + + return default_argument; +} + /* Begin parsing tentatively. We always save tokens while parsing tentatively so that if the tentative parsing fails we can restore the tokens. */ @@ -26354,11 +26439,11 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) { /* If decl is an iterator, preserve the operator on decl until finish_omp_for. */ - if (decl + if (real_decl && ((processing_template_decl - && !POINTER_TYPE_P (TREE_TYPE (decl))) - || CLASS_TYPE_P (TREE_TYPE (decl)))) - incr = cp_parser_omp_for_incr (parser, decl); + && !POINTER_TYPE_P (TREE_TYPE (real_decl))) + || CLASS_TYPE_P (TREE_TYPE (real_decl)))) + incr = cp_parser_omp_for_incr (parser, real_decl); else incr = cp_parser_expression (parser, false, NULL); }