aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-11-07 22:47:36 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-11-07 22:47:36 -0500
commit67dc1f24dceea8dca4b2810f2cb9d9b7775d2b98 (patch)
treedd1b28a0105b37143349e8a0082a6894d5afb12c /gcc/cp
parent5241b7e4a17c23a94b85b16850febad8eaf6bcdf (diff)
downloadgcc-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/ChangeLog18
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/parser.c38
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