+2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/26151
+ * parser.c (cp_parser_decl_specifier_seq): Check for duplicate
+ decl-specifiers. Remove extra check for duplicate 'friend'.
+ * decl.c (grokdeclarator): Remove check for duplicate
+ decl-specifiers. Set longlong together with long_p.
+
2006-02-12 Jason Merrill <jason@redhat.com>
PR c++/24996
this value will be NULL_TREE, even if the entity is located at
namespace scope. */
tree in_namespace = NULL_TREE;
- cp_decl_spec ds;
cp_storage_class storage_class;
bool unsigned_p, signed_p, short_p, long_p, thread_p;
bool type_was_error_mark_node = false;
unsigned_p = declspecs->specs[(int)ds_unsigned];
short_p = declspecs->specs[(int)ds_short];
long_p = declspecs->specs[(int)ds_long];
+ longlong = declspecs->specs[(int)ds_long] >= 2;
thread_p = declspecs->specs[(int)ds_thread];
if (decl_context == FUNCDEF)
explicit_int = declspecs->explicit_int_p;
explicit_char = declspecs->explicit_char_p;
- /* Check for repeated decl-specifiers. */
- for (ds = ds_first; ds != ds_last; ++ds)
- {
- unsigned count = declspecs->specs[(int)ds];
- if (count < 2)
- continue;
- /* The "long" specifier is a special case because of
- "long long". */
- if (ds == ds_long)
- {
- if (count > 2)
- error ("%<long long long%> is too long for GCC");
- else if (pedantic && !in_system_header && warn_long_long)
- pedwarn ("ISO C++ does not support %<long long%>");
- else
- longlong = 1;
- }
- else if (declspecs->specs[(int)ds] > 1)
- {
- static const char *const decl_spec_names[] = {
- "signed",
- "unsigned",
- "short",
- "long",
- "const",
- "volatile",
- "restrict",
- "inline",
- "virtual",
- "explicit",
- "friend",
- "typedef",
- "__complex",
- "__thread"
- };
- error ("duplicate %qs", decl_spec_names[(int)ds]);
- }
- }
-
#if 0
/* See the code below that used this. */
if (typedef_decl)
int* declares_class_or_enum)
{
bool constructor_possible_p = !parser->in_declarator_p;
+ cp_decl_spec ds;
/* Clear DECL_SPECS. */
clear_decl_specs (decl_specs);
/* decl-specifier:
friend */
case RID_FRIEND:
- if (decl_specs->specs[(int) ds_friend]++)
- error ("duplicate %<friend%>");
+ ++decl_specs->specs[(int) ds_friend];
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
break;
flags |= CP_PARSER_FLAGS_OPTIONAL;
}
+ /* Check for repeated decl-specifiers. */
+ for (ds = ds_first; ds != ds_last; ++ds)
+ {
+ unsigned count = decl_specs->specs[(int)ds];
+ if (count < 2)
+ continue;
+ /* The "long" specifier is a special case because of "long long". */
+ if (ds == ds_long)
+ {
+ if (count > 2)
+ error ("%<long long long%> is too long for GCC");
+ else if (pedantic && !in_system_header && warn_long_long)
+ pedwarn ("ISO C++ does not support %<long long%>");
+ }
+ else if (count > 1)
+ {
+ static const char *const decl_spec_names[] = {
+ "signed",
+ "unsigned",
+ "short",
+ "long",
+ "const",
+ "volatile",
+ "restrict",
+ "inline",
+ "virtual",
+ "explicit",
+ "friend",
+ "typedef",
+ "__complex",
+ "__thread"
+ };
+ error ("duplicate %qs", decl_spec_names[(int)ds]);
+ }
+ }
+
/* Don't allow a friend specifier with a class definition. */
if (decl_specs->specs[(int) ds_friend] != 0
&& (*declares_class_or_enum & 2))