diff options
author | Jason Merrill <jason@redhat.com> | 2009-11-07 22:47:36 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-11-07 22:47:36 -0500 |
commit | 67dc1f24dceea8dca4b2810f2cb9d9b7775d2b98 (patch) | |
tree | dd1b28a0105b37143349e8a0082a6894d5afb12c /gcc/cp | |
parent | 5241b7e4a17c23a94b85b16850febad8eaf6bcdf (diff) | |
download | gcc-67dc1f24dceea8dca4b2810f2cb9d9b7775d2b98.zip gcc-67dc1f24dceea8dca4b2810f2cb9d9b7775d2b98.tar.gz gcc-67dc1f24dceea8dca4b2810f2cb9d9b7775d2b98.tar.bz2 |
re PR c++/18451 (C++ error message regression)
PR c++/18451
PR c++/40738
* cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p.
* parser.c (cp_parser_single_declaration): Call
cp_parser_parse_and_diagnose_invalid_type_name here, too.
(cp_parser_parameter_declaration): And here.
(cp_parser_parse_and_diagnose_invalid_type_name): Be
less picky about declarator form. Don't skip to
the end of the block if we're in a declarator.
(cp_parser_decl_specifier_seq): Set any_type_specifiers_p.
(cp_parser_simple_declaration): Check it.
(cp_parser_member_declaration): Likewise.
(cp_parser_diagnose_invalid_type_name): Tweak error message.
(cp_parser_expression_statement): Likewise.
* decl2.c (grokfield): Mention decltype instead of typeof.
From-SVN: r154006
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 38 |
4 files changed, 47 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b63977b..7dc1587 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2009-11-07 Jason Merrill <jason@redhat.com> + + PR c++/18451 + PR c++/40738 + * cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p. + * parser.c (cp_parser_single_declaration): Call + cp_parser_parse_and_diagnose_invalid_type_name here, too. + (cp_parser_parameter_declaration): And here. + (cp_parser_parse_and_diagnose_invalid_type_name): Be + less picky about declarator form. Don't skip to + the end of the block if we're in a declarator. + (cp_parser_decl_specifier_seq): Set any_type_specifiers_p. + (cp_parser_simple_declaration): Check it. + (cp_parser_member_declaration): Likewise. + (cp_parser_diagnose_invalid_type_name): Tweak error message. + (cp_parser_expression_statement): Likewise. + * decl2.c (grokfield): Mention decltype instead of typeof. + 2009-11-06 Jason Merrill <jason@redhat.com> PR c++/15946 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c4b088b..68be934 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4267,6 +4267,8 @@ typedef struct cp_decl_specifier_seq { BOOL_BITFIELD conflicting_specifiers_p : 1; /* True iff at least one decl-specifier was found. */ BOOL_BITFIELD any_specifiers_p : 1; + /* True iff at least one type-specifier was found. */ + BOOL_BITFIELD any_type_specifiers_p : 1; /* True iff "int" was explicitly provided. */ BOOL_BITFIELD explicit_int_p : 1; /* True iff "char" was explicitly provided. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 53f66ad..ba987f7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -789,7 +789,7 @@ grokfield (const cp_declarator *declarator, if (TREE_CODE (value) == TYPE_DECL && init) { - error ("typedef %qD is initialized (use __typeof__ instead)", value); + error ("typedef %qD is initialized (use decltype instead)", value); init = NULL_TREE; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 47f5f13..7bafb67 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2402,8 +2402,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, id, parser->scope); else if (TYPE_P (parser->scope) && dependent_scope_p (parser->scope)) - error_at (location, "need %<typename%> before %<%T::%E%> to name " - "a type in dependent scope %qT", + error_at (location, "need %<typename%> before %<%T::%E%> because " + "%qT is a dependent scope", parser->scope, id, parser->scope); else if (TYPE_P (parser->scope)) error_at (location, "%qE in class %qT does not name a type", @@ -2437,9 +2437,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. */ - if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME) + /* 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); @@ -2451,9 +2451,11 @@ 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); + /* 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; } @@ -7773,8 +7775,8 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON) && !cp_parser_uncommitted_to_tentative_parse_p (parser) && TREE_CODE (statement) == SCOPE_REF) - error_at (token->location, "need %<typename%> before %qE to name " - "a type in dependent scope %qT", + error_at (token->location, "need %<typename%> before %qE because " + "%qT is a dependent scope", statement, TREE_OPERAND (statement, 0)); /* Consume the final `;'. */ @@ -8846,7 +8848,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 @@ -9211,6 +9213,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; } } @@ -14973,6 +14977,11 @@ cp_parser_parameter_declaration (cp_parser *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)) @@ -16523,7 +16532,7 @@ cp_parser_member_declaration (cp_parser* parser) prefix_attributes = decl_specifiers.attributes; decl_specifiers.attributes = NULL_TREE; /* Check for an invalid type-name. */ - if (!decl_specifiers.type + if (!decl_specifiers.any_type_specifiers_p && cp_parser_parse_and_diagnose_invalid_type_name (parser)) return; /* If there is no declarator, then the decl-specifier-seq should @@ -18775,6 +18784,11 @@ cp_parser_single_declaration (cp_parser* parser, cp_parser_perform_template_parameter_access_checks (checks); } } + + /* 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 it's not a template class, try for a template function. If the next token is a `;', then this declaration does not declare anything. But, if there were errors in the decl-specifiers, then |