c-common.h (enum rid): Add RID_CXX_COMPAT_WARN.

./:	* c-common.h (enum rid): Add RID_CXX_COMPAT_WARN.
	(struct c_common_resword): Define.
	(D_CONLY, D_CXXONLY, D_C99, D_CXX0X, D_EXT, D_EXT89): Define.
	(D_ASM, D_OBJC, D_CXX_OBJC, D_CXXWARN): Define.
	(c_common_reswords, num_c_common_reswords): Declare.
	* c-common.c (c_common_reswords): New global const array.
	(num_c_common_reswords): New const int.
	* c-parser.c (struct resword, reswords): Don't define.
	(D_C89, D_EXT, D_EXT89, D_OBJC): Don't define.
	(c_parse_init): Clarify mask code.  Use c_common_reswords rather
	than reswords.  If warning about C++ keywords, give them a special
	RID code.
	(c_lex_one_token): Warn about C++ keywords.  Call
	objc_is_reserved_word rather than OBJC_IS_AT_KEYWORD.
	(c_parser_external_declaration): Look for RID_xxx rather than
	RID_AT_xxx, for ObjC++ keywords which are also C++ keywords.
	(c_parser_statement_after_labels): Likewise.
	(c_parser_objc_class_instance_variables): Likewise.
	(c_parser_objc_class_declaration): Likewise.
	(c_parser_objc_try_catch_statement): Likewise.
	* c-decl.c (c_print_identifier): Ignore RID_CXX_COMPAT_WARN.
	(declspecs_add_type): Likewise.
cp/:
	* lex.c (struct resword, reswords): Don't define.
	(D_EXT, D_ASM, D_OBJC, D_CXX0X): Don't define.
	(init_reswords): Clarify mask code.  Use c_common_reswords rather
	than reswords.
objc/:
	* objc-act.c (objc_is_reserved_word): Always check for RID_CLASS,
	etc., not just when OBJCPLUS is defined.
testsuite/:
	* gcc.dg/Wcxx-compat-2.c: New test.

From-SVN: r137724
This commit is contained in:
Ian Lance Taylor 2008-07-11 18:16:26 +00:00
parent 94eeabbe19
commit eea1139b26
11 changed files with 351 additions and 326 deletions

View File

@ -1,3 +1,29 @@
2008-07-11 Tom Tromey <tromey@redhat.com>
Ian Lance Taylor <iant@google.com>
* c-common.h (enum rid): Add RID_CXX_COMPAT_WARN.
(struct c_common_resword): Define.
(D_CONLY, D_CXXONLY, D_C99, D_CXX0X, D_EXT, D_EXT89): Define.
(D_ASM, D_OBJC, D_CXX_OBJC, D_CXXWARN): Define.
(c_common_reswords, num_c_common_reswords): Declare.
* c-common.c (c_common_reswords): New global const array.
(num_c_common_reswords): New const int.
* c-parser.c (struct resword, reswords): Don't define.
(D_C89, D_EXT, D_EXT89, D_OBJC): Don't define.
(c_parse_init): Clarify mask code. Use c_common_reswords rather
than reswords. If warning about C++ keywords, give them a special
RID code.
(c_lex_one_token): Warn about C++ keywords. Call
objc_is_reserved_word rather than OBJC_IS_AT_KEYWORD.
(c_parser_external_declaration): Look for RID_xxx rather than
RID_AT_xxx, for ObjC++ keywords which are also C++ keywords.
(c_parser_statement_after_labels): Likewise.
(c_parser_objc_class_instance_variables): Likewise.
(c_parser_objc_class_declaration): Likewise.
(c_parser_objc_try_catch_statement): Likewise.
* c-decl.c (c_print_identifier): Ignore RID_CXX_COMPAT_WARN.
(declspecs_add_type): Likewise.
2008-07-11 Angelo Graziosi <angelo.graziosi@alice.it>
* ggc-page.c (alloc_page):

View File

@ -581,6 +581,179 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
static int resort_field_decl_cmp (const void *, const void *);
/* Reserved words. The third field is a mask: keywords are disabled
if they match the mask.
Masks for languages:
C --std=c89: D_C99 | D_CXXONLY | D_OBJC | D_CXX_OBJC
C --std=c99: D_CXXONLY | D_OBJC
ObjC is like C except that D_OBJC and D_CXX_OBJC are not set
C++ --std=c98: D_CONLY | D_CXXOX | D_OBJC
C++ --std=c0x: D_CONLY | D_OBJC
ObjC++ is like C++ except that D_OBJC is not set
If -fno-asm is used, D_ASM is added to the mask. If
-fno-gnu-keywords is used, D_EXT is added. If -fno-asm and C in
C89 mode, D_EXT89 is added for both -fno-asm and -fno-gnu-keywords.
In C with -Wcxx-compat, we warn if D_CXXWARN is set. */
const struct c_common_resword c_common_reswords[] =
{
{ "_Bool", RID_BOOL, D_CONLY },
{ "_Complex", RID_COMPLEX, 0 },
{ "_Decimal32", RID_DFLOAT32, D_CONLY | D_EXT },
{ "_Decimal64", RID_DFLOAT64, D_CONLY | D_EXT },
{ "_Decimal128", RID_DFLOAT128, D_CONLY | D_EXT },
{ "_Fract", RID_FRACT, D_CONLY | D_EXT },
{ "_Accum", RID_ACCUM, D_CONLY | D_EXT },
{ "_Sat", RID_SAT, D_CONLY | D_EXT },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
{ "__alignof__", RID_ALIGNOF, 0 },
{ "__asm", RID_ASM, 0 },
{ "__asm__", RID_ASM, 0 },
{ "__attribute", RID_ATTRIBUTE, 0 },
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
{ "__const", RID_CONST, 0 },
{ "__const__", RID_CONST, 0 },
{ "__decltype", RID_DECLTYPE, D_CXXONLY },
{ "__extension__", RID_EXTENSION, 0 },
{ "__func__", RID_C99_FUNCTION_NAME, 0 },
{ "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, D_CXXONLY },
{ "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, D_CXXONLY },
{ "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, D_CXXONLY },
{ "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, D_CXXONLY },
{ "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, D_CXXONLY },
{ "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, D_CXXONLY },
{ "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY },
{ "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY },
{ "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY },
{ "__is_base_of", RID_IS_BASE_OF, D_CXXONLY },
{ "__is_class", RID_IS_CLASS, D_CXXONLY },
{ "__is_convertible_to", RID_IS_CONVERTIBLE_TO, D_CXXONLY },
{ "__is_empty", RID_IS_EMPTY, D_CXXONLY },
{ "__is_enum", RID_IS_ENUM, D_CXXONLY },
{ "__is_pod", RID_IS_POD, D_CXXONLY },
{ "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY },
{ "__is_union", RID_IS_UNION, D_CXXONLY },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
{ "__inline__", RID_INLINE, 0 },
{ "__label__", RID_LABEL, 0 },
{ "__null", RID_NULL, 0 },
{ "__real", RID_REALPART, 0 },
{ "__real__", RID_REALPART, 0 },
{ "__restrict", RID_RESTRICT, 0 },
{ "__restrict__", RID_RESTRICT, 0 },
{ "__signed", RID_SIGNED, 0 },
{ "__signed__", RID_SIGNED, 0 },
{ "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
{ "asm", RID_ASM, D_ASM },
{ "auto", RID_AUTO, 0 },
{ "bool", RID_BOOL, D_CXXONLY },
{ "break", RID_BREAK, 0 },
{ "case", RID_CASE, 0 },
{ "catch", RID_CATCH, D_CXX_OBJC },
{ "char", RID_CHAR, 0 },
{ "char16_t", RID_CHAR16, D_CXXONLY | D_CXX0X },
{ "char32_t", RID_CHAR32, D_CXXONLY | D_CXX0X },
{ "class", RID_CLASS, D_CXX_OBJC },
{ "const", RID_CONST, 0 },
{ "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN },
{ "continue", RID_CONTINUE, 0 },
{ "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX0X },
{ "default", RID_DEFAULT, 0 },
{ "delete", RID_DELETE, D_CXXONLY },
{ "do", RID_DO, 0 },
{ "double", RID_DOUBLE, 0 },
{ "dynamic_cast", RID_DYNCAST, D_CXXONLY | D_CXXWARN },
{ "else", RID_ELSE, 0 },
{ "enum", RID_ENUM, 0 },
{ "explicit", RID_EXPLICIT, D_CXXONLY },
{ "export", RID_EXPORT, D_CXXONLY },
{ "extern", RID_EXTERN, 0 },
{ "false", RID_FALSE, D_CXXONLY },
{ "float", RID_FLOAT, 0 },
{ "for", RID_FOR, 0 },
{ "friend", RID_FRIEND, D_CXXONLY },
{ "goto", RID_GOTO, 0 },
{ "if", RID_IF, 0 },
{ "inline", RID_INLINE, D_EXT89 },
{ "int", RID_INT, 0 },
{ "long", RID_LONG, 0 },
{ "mutable", RID_MUTABLE, D_CXXONLY | D_CXXWARN },
{ "namespace", RID_NAMESPACE, D_CXXONLY },
{ "new", RID_NEW, D_CXXONLY },
{ "operator", RID_OPERATOR, D_CXXONLY },
{ "private", RID_PRIVATE, D_CXX_OBJC },
{ "protected", RID_PROTECTED, D_CXX_OBJC },
{ "public", RID_PUBLIC, D_CXX_OBJC },
{ "register", RID_REGISTER, 0 },
{ "reinterpret_cast", RID_REINTCAST, D_CXXONLY | D_CXXWARN },
{ "restrict", RID_RESTRICT, D_CONLY | D_C99 },
{ "return", RID_RETURN, 0 },
{ "short", RID_SHORT, 0 },
{ "signed", RID_SIGNED, 0 },
{ "sizeof", RID_SIZEOF, 0 },
{ "static", RID_STATIC, 0 },
{ "static_assert", RID_STATIC_ASSERT, D_CXXONLY | D_CXX0X | D_CXXWARN },
{ "static_cast", RID_STATCAST, D_CXXONLY | D_CXXWARN },
{ "struct", RID_STRUCT, 0 },
{ "switch", RID_SWITCH, 0 },
{ "template", RID_TEMPLATE, D_CXXONLY },
{ "this", RID_THIS, D_CXXONLY },
{ "throw", RID_THROW, D_CXX_OBJC },
{ "true", RID_TRUE, D_CXXONLY },
{ "try", RID_TRY, D_CXX_OBJC },
{ "typedef", RID_TYPEDEF, 0 },
{ "typename", RID_TYPENAME, D_CXXONLY },
{ "typeid", RID_TYPEID, D_CXXONLY },
{ "typeof", RID_TYPEOF, D_ASM | D_EXT },
{ "union", RID_UNION, 0 },
{ "unsigned", RID_UNSIGNED, 0 },
{ "using", RID_USING, D_CXXONLY },
{ "virtual", RID_VIRTUAL, D_CXXONLY },
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "wchar_t", RID_WCHAR, D_CXXONLY },
{ "while", RID_WHILE, 0 },
/* These Objective-C keywords are recognized only immediately after
an '@'. */
{ "compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "defs", RID_AT_DEFS, D_OBJC },
{ "encode", RID_AT_ENCODE, D_OBJC },
{ "end", RID_AT_END, D_OBJC },
{ "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "interface", RID_AT_INTERFACE, D_OBJC },
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
{ "finally", RID_AT_FINALLY, D_OBJC },
{ "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
/* These are recognized only in protocol-qualifier context
(see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
};
const unsigned int num_c_common_reswords =
sizeof c_common_reswords / sizeof (struct c_common_resword);
/* Table of machine-independent attributes common to all C-like languages. */
const struct attribute_spec c_common_attribute_table[] =
{

View File

@ -74,6 +74,10 @@ enum rid
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
RID_FRACT, RID_ACCUM,
/* This means to warn that this is a C++ keyword, and then treat it
as a normal identifier. */
RID_CXX_COMPAT_WARN,
/* Too many ways of getting the name of a function as a string */
RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
@ -197,6 +201,36 @@ struct c_common_identifier GTY(())
struct cpp_hashnode node;
};
/* An entry in the reserved keyword table. */
struct c_common_resword
{
const char *const word;
ENUM_BITFIELD(rid) const rid : 16;
const unsigned int disable : 16;
};
/* Disable mask. Keywords are disabled if (reswords[i].disable &
mask) is _true_. Thus for keywords which are present in all
languages the disable field is zero. */
#define D_CONLY 0x001 /* C only (not in C++). */
#define D_CXXONLY 0x002 /* C++ only (not in C). */
#define D_C99 0x004 /* In C, C99 only. */
#define D_CXX0X 0x008 /* In C++, C++0X only. */
#define D_EXT 0x010 /* GCC extension. */
#define D_EXT89 0x020 /* GCC extension incorporated in C99. */
#define D_ASM 0x040 /* Disabled by -fno-asm. */
#define D_OBJC 0x080 /* In Objective C and neither C nor C++. */
#define D_CXX_OBJC 0x100 /* In Objective C, and C++, but not C. */
#define D_CXXWARN 0x200 /* In C warn with -Wcxx-compat. */
/* The reserved keyword table. */
extern const struct c_common_resword c_common_reswords[];
/* The number of items in the reserved keyword table. */
extern const unsigned int num_c_common_reswords;
#define char16_type_node c_global_trees[CTI_CHAR16_TYPE]
#define char32_type_node c_global_trees[CTI_CHAR32_TYPE]
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]

View File

@ -445,7 +445,7 @@ c_print_identifier (FILE *file, tree node, int indent)
print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
print_node (file, "tag", I_TAG_DECL (node), indent + 4);
print_node (file, "label", I_LABEL_DECL (node), indent + 4);
if (C_IS_RESERVED_WORD (node))
if (C_IS_RESERVED_WORD (node) && C_RID_CODE (node) != RID_CXX_COMPAT_WARN)
{
tree rid = ridpointers[C_RID_CODE (node)];
indent_to (file, indent + 4);
@ -7177,7 +7177,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->deprecated_p = true;
/* Handle type specifier keywords. */
if (TREE_CODE (type) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (type))
if (TREE_CODE (type) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (type)
&& C_RID_CODE (type) != RID_CXX_COMPAT_WARN)
{
enum rid i = C_RID_CODE (type);
if (specs->type)

View File

@ -59,131 +59,6 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
/* The reserved keyword table. */
struct resword
{
const char *word;
ENUM_BITFIELD(rid) rid : 16;
unsigned int disable : 16;
};
/* Disable mask. Keywords are disabled if (reswords[i].disable &
mask) is _true_. */
#define D_C89 0x01 /* not in C89 */
#define D_EXT 0x02 /* GCC extension */
#define D_EXT89 0x04 /* GCC extension incorporated in C99 */
#define D_OBJC 0x08 /* Objective C only */
static const struct resword reswords[] =
{
{ "_Bool", RID_BOOL, 0 },
{ "_Complex", RID_COMPLEX, 0 },
{ "_Decimal32", RID_DFLOAT32, D_EXT },
{ "_Decimal64", RID_DFLOAT64, D_EXT },
{ "_Decimal128", RID_DFLOAT128, D_EXT },
{ "_Fract", RID_FRACT, D_EXT },
{ "_Accum", RID_ACCUM, D_EXT },
{ "_Sat", RID_SAT, D_EXT },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
{ "__alignof__", RID_ALIGNOF, 0 },
{ "__asm", RID_ASM, 0 },
{ "__asm__", RID_ASM, 0 },
{ "__attribute", RID_ATTRIBUTE, 0 },
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
{ "__const", RID_CONST, 0 },
{ "__const__", RID_CONST, 0 },
{ "__extension__", RID_EXTENSION, 0 },
{ "__func__", RID_C99_FUNCTION_NAME, 0 },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
{ "__inline__", RID_INLINE, 0 },
{ "__label__", RID_LABEL, 0 },
{ "__real", RID_REALPART, 0 },
{ "__real__", RID_REALPART, 0 },
{ "__restrict", RID_RESTRICT, 0 },
{ "__restrict__", RID_RESTRICT, 0 },
{ "__signed", RID_SIGNED, 0 },
{ "__signed__", RID_SIGNED, 0 },
{ "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
{ "asm", RID_ASM, D_EXT },
{ "auto", RID_AUTO, 0 },
{ "break", RID_BREAK, 0 },
{ "case", RID_CASE, 0 },
{ "char", RID_CHAR, 0 },
{ "const", RID_CONST, 0 },
{ "continue", RID_CONTINUE, 0 },
{ "default", RID_DEFAULT, 0 },
{ "do", RID_DO, 0 },
{ "double", RID_DOUBLE, 0 },
{ "else", RID_ELSE, 0 },
{ "enum", RID_ENUM, 0 },
{ "extern", RID_EXTERN, 0 },
{ "float", RID_FLOAT, 0 },
{ "for", RID_FOR, 0 },
{ "goto", RID_GOTO, 0 },
{ "if", RID_IF, 0 },
{ "inline", RID_INLINE, D_EXT89 },
{ "int", RID_INT, 0 },
{ "long", RID_LONG, 0 },
{ "register", RID_REGISTER, 0 },
{ "restrict", RID_RESTRICT, D_C89 },
{ "return", RID_RETURN, 0 },
{ "short", RID_SHORT, 0 },
{ "signed", RID_SIGNED, 0 },
{ "sizeof", RID_SIZEOF, 0 },
{ "static", RID_STATIC, 0 },
{ "struct", RID_STRUCT, 0 },
{ "switch", RID_SWITCH, 0 },
{ "typedef", RID_TYPEDEF, 0 },
{ "typeof", RID_TYPEOF, D_EXT },
{ "union", RID_UNION, 0 },
{ "unsigned", RID_UNSIGNED, 0 },
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "while", RID_WHILE, 0 },
/* These Objective-C keywords are recognized only immediately after
an '@'. */
{ "class", RID_AT_CLASS, D_OBJC },
{ "compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "defs", RID_AT_DEFS, D_OBJC },
{ "encode", RID_AT_ENCODE, D_OBJC },
{ "end", RID_AT_END, D_OBJC },
{ "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "interface", RID_AT_INTERFACE, D_OBJC },
{ "private", RID_AT_PRIVATE, D_OBJC },
{ "protected", RID_AT_PROTECTED, D_OBJC },
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "public", RID_AT_PUBLIC, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
{ "throw", RID_AT_THROW, D_OBJC },
{ "try", RID_AT_TRY, D_OBJC },
{ "catch", RID_AT_CATCH, D_OBJC },
{ "finally", RID_AT_FINALLY, D_OBJC },
{ "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
/* These are recognized only in protocol-qualifier context
(see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
};
#define N_reswords (sizeof reswords / sizeof (struct resword))
/* Initialization routine for this file. */
void
@ -193,24 +68,41 @@ c_parse_init (void)
identifiers. */
unsigned int i;
tree id;
int mask = (flag_isoc99 ? 0 : D_C89)
| (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0);
int mask = 0;
mask |= D_CXXONLY;
if (!flag_isoc99)
mask |= D_C99;
if (flag_no_asm)
{
mask |= D_ASM | D_EXT;
if (!flag_isoc99)
mask |= D_EXT89;
}
if (!c_dialect_objc ())
mask |= D_OBJC;
mask |= D_OBJC | D_CXX_OBJC;
ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
for (i = 0; i < N_reswords; i++)
for (i = 0; i < num_c_common_reswords; i++)
{
/* If a keyword is disabled, do not enter it into the table
and so create a canonical spelling that isn't a keyword. */
if (reswords[i].disable & mask)
continue;
if (c_common_reswords[i].disable & mask)
{
if (warn_cxx_compat
&& (c_common_reswords[i].disable & D_CXXWARN))
{
id = get_identifier (c_common_reswords[i].word);
C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
C_IS_RESERVED_WORD (id) = 1;
}
continue;
}
id = get_identifier (reswords[i].word);
C_SET_RID_CODE (id, reswords[i].rid);
id = get_identifier (c_common_reswords[i].word);
C_SET_RID_CODE (id, c_common_reswords[i].rid);
C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) reswords[i].rid] = id;
ridpointers [(int) c_common_reswords[i].rid] = id;
}
}
@ -330,9 +222,16 @@ c_lex_one_token (c_parser *parser, c_token *token)
{
enum rid rid_code = C_RID_CODE (token->value);
if (c_dialect_objc ())
if (rid_code == RID_CXX_COMPAT_WARN)
{
if (!OBJC_IS_AT_KEYWORD (rid_code)
warning (OPT_Wc___compat,
"%Hidentifier %qs conflicts with C++ keyword",
&token->location,
IDENTIFIER_POINTER (token->value));
}
else if (c_dialect_objc ())
{
if (!objc_is_reserved_word (token->value)
&& (!OBJC_IS_PQ_KEYWORD (rid_code)
|| parser->objc_pq_context))
{
@ -1129,7 +1028,7 @@ c_parser_external_declaration (c_parser *parser)
gcc_assert (c_dialect_objc ());
c_parser_objc_class_definition (parser);
break;
case RID_AT_CLASS:
case RID_CLASS:
gcc_assert (c_dialect_objc ());
c_parser_objc_class_declaration (parser);
break;
@ -3830,7 +3729,7 @@ c_parser_statement_after_labels (c_parser *parser)
case RID_ASM:
stmt = c_parser_asm_statement (parser);
break;
case RID_AT_THROW:
case RID_THROW:
gcc_assert (c_dialect_objc ());
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@ -3845,7 +3744,7 @@ c_parser_statement_after_labels (c_parser *parser)
goto expect_semicolon;
}
break;
case RID_AT_TRY:
case RID_TRY:
gcc_assert (c_dialect_objc ());
c_parser_objc_try_catch_statement (parser);
break;
@ -5906,19 +5805,19 @@ c_parser_objc_class_instance_variables (c_parser *parser)
break;
}
/* Parse any objc-visibility-spec. */
if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
if (c_parser_next_token_is_keyword (parser, RID_PRIVATE))
{
c_parser_consume_token (parser);
objc_set_visibility (2);
continue;
}
else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
else if (c_parser_next_token_is_keyword (parser, RID_PROTECTED))
{
c_parser_consume_token (parser);
objc_set_visibility (0);
continue;
}
else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
else if (c_parser_next_token_is_keyword (parser, RID_PUBLIC))
{
c_parser_consume_token (parser);
objc_set_visibility (1);
@ -5953,7 +5852,7 @@ static void
c_parser_objc_class_declaration (c_parser *parser)
{
tree list = NULL_TREE;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
gcc_assert (c_parser_next_token_is_keyword (parser, RID_CLASS));
c_parser_consume_token (parser);
/* Any identifiers, including those declared as type names, are OK
here. */
@ -6390,12 +6289,12 @@ c_parser_objc_try_catch_statement (c_parser *parser)
{
location_t loc;
tree stmt;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRY));
c_parser_consume_token (parser);
loc = c_parser_peek_token (parser)->location;
stmt = c_parser_compound_statement (parser);
objc_begin_try_stmt (loc, stmt);
while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
while (c_parser_next_token_is_keyword (parser, RID_CATCH))
{
struct c_parm *parm;
c_parser_consume_token (parser);

View File

@ -1,3 +1,11 @@
2008-07-11 Tom Tromey <tromey@redhat.com>
Ian Lance Taylor <iant@google.com>
* lex.c (struct resword, reswords): Don't define.
(D_EXT, D_ASM, D_OBJC, D_CXX0X): Don't define.
(init_reswords): Clarify mask code. Use c_common_reswords rather
than reswords.
2008-07-11 Dodji Seketeli <dseketel@redhat.com>
PR c++/13101

View File

@ -163,190 +163,32 @@ init_operators (void)
= "(round %=)";
}
/* The reserved keyword table. */
struct resword
{
const char *const word;
ENUM_BITFIELD(rid) const rid : 16;
const unsigned int disable : 16;
};
/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is
_true_. */
#define D_EXT 0x01 /* GCC extension */
#define D_ASM 0x02 /* in C99, but has a switch to turn it off */
#define D_OBJC 0x04 /* Objective C++ only */
#define D_CXX0X 0x08 /* C++0x only */
CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
static const struct resword reswords[] =
{
{ "_Complex", RID_COMPLEX, 0 },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
{ "__alignof__", RID_ALIGNOF, 0 },
{ "__asm", RID_ASM, 0 },
{ "__asm__", RID_ASM, 0 },
{ "__attribute", RID_ATTRIBUTE, 0 },
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
{ "__const", RID_CONST, 0 },
{ "__const__", RID_CONST, 0 },
{ "__decltype", RID_DECLTYPE, 0 },
{ "__extension__", RID_EXTENSION, 0 },
{ "__func__", RID_C99_FUNCTION_NAME, 0 },
{ "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, 0 },
{ "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, 0 },
{ "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, 0 },
{ "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, 0 },
{ "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, 0 },
{ "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, 0 },
{ "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, 0 },
{ "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, 0 },
{ "__is_abstract", RID_IS_ABSTRACT, 0 },
{ "__is_base_of", RID_IS_BASE_OF, 0 },
{ "__is_class", RID_IS_CLASS, 0 },
{ "__is_convertible_to", RID_IS_CONVERTIBLE_TO, 0 },
{ "__is_empty", RID_IS_EMPTY, 0 },
{ "__is_enum", RID_IS_ENUM, 0 },
{ "__is_pod", RID_IS_POD, 0 },
{ "__is_polymorphic", RID_IS_POLYMORPHIC, 0 },
{ "__is_union", RID_IS_UNION, 0 },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
{ "__inline__", RID_INLINE, 0 },
{ "__label__", RID_LABEL, 0 },
{ "__null", RID_NULL, 0 },
{ "__real", RID_REALPART, 0 },
{ "__real__", RID_REALPART, 0 },
{ "__restrict", RID_RESTRICT, 0 },
{ "__restrict__", RID_RESTRICT, 0 },
{ "__signed", RID_SIGNED, 0 },
{ "__signed__", RID_SIGNED, 0 },
{ "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
{ "asm", RID_ASM, D_ASM },
{ "auto", RID_AUTO, 0 },
{ "bool", RID_BOOL, 0 },
{ "break", RID_BREAK, 0 },
{ "case", RID_CASE, 0 },
{ "catch", RID_CATCH, 0 },
{ "char", RID_CHAR, 0 },
{ "char16_t", RID_CHAR16, D_CXX0X },
{ "char32_t", RID_CHAR32, D_CXX0X },
{ "class", RID_CLASS, 0 },
{ "const", RID_CONST, 0 },
{ "const_cast", RID_CONSTCAST, 0 },
{ "continue", RID_CONTINUE, 0 },
{ "decltype", RID_DECLTYPE, D_CXX0X },
{ "default", RID_DEFAULT, 0 },
{ "delete", RID_DELETE, 0 },
{ "do", RID_DO, 0 },
{ "double", RID_DOUBLE, 0 },
{ "dynamic_cast", RID_DYNCAST, 0 },
{ "else", RID_ELSE, 0 },
{ "enum", RID_ENUM, 0 },
{ "explicit", RID_EXPLICIT, 0 },
{ "export", RID_EXPORT, 0 },
{ "extern", RID_EXTERN, 0 },
{ "false", RID_FALSE, 0 },
{ "float", RID_FLOAT, 0 },
{ "for", RID_FOR, 0 },
{ "friend", RID_FRIEND, 0 },
{ "goto", RID_GOTO, 0 },
{ "if", RID_IF, 0 },
{ "inline", RID_INLINE, 0 },
{ "int", RID_INT, 0 },
{ "long", RID_LONG, 0 },
{ "mutable", RID_MUTABLE, 0 },
{ "namespace", RID_NAMESPACE, 0 },
{ "new", RID_NEW, 0 },
{ "operator", RID_OPERATOR, 0 },
{ "private", RID_PRIVATE, 0 },
{ "protected", RID_PROTECTED, 0 },
{ "public", RID_PUBLIC, 0 },
{ "register", RID_REGISTER, 0 },
{ "reinterpret_cast", RID_REINTCAST, 0 },
{ "return", RID_RETURN, 0 },
{ "short", RID_SHORT, 0 },
{ "signed", RID_SIGNED, 0 },
{ "sizeof", RID_SIZEOF, 0 },
{ "static", RID_STATIC, 0 },
{ "static_assert", RID_STATIC_ASSERT, D_CXX0X },
{ "static_cast", RID_STATCAST, 0 },
{ "struct", RID_STRUCT, 0 },
{ "switch", RID_SWITCH, 0 },
{ "template", RID_TEMPLATE, 0 },
{ "this", RID_THIS, 0 },
{ "throw", RID_THROW, 0 },
{ "true", RID_TRUE, 0 },
{ "try", RID_TRY, 0 },
{ "typedef", RID_TYPEDEF, 0 },
{ "typename", RID_TYPENAME, 0 },
{ "typeid", RID_TYPEID, 0 },
{ "typeof", RID_TYPEOF, D_ASM|D_EXT },
{ "union", RID_UNION, 0 },
{ "unsigned", RID_UNSIGNED, 0 },
{ "using", RID_USING, 0 },
{ "virtual", RID_VIRTUAL, 0 },
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "wchar_t", RID_WCHAR, 0 },
{ "while", RID_WHILE, 0 },
/* The remaining keywords are specific to Objective-C++. NB:
All of them will remain _disabled_, since they are context-
sensitive. */
/* These ObjC keywords are recognized only immediately after
an '@'. NB: The following C++ keywords double as
ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH. */
{ "compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "defs", RID_AT_DEFS, D_OBJC },
{ "encode", RID_AT_ENCODE, D_OBJC },
{ "end", RID_AT_END, D_OBJC },
{ "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "interface", RID_AT_INTERFACE, D_OBJC },
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
{ "finally", RID_AT_FINALLY, D_OBJC },
{ "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
/* These are recognized only in protocol-qualifier context. */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
};
/* Initialize the reserved words. */
void
init_reswords (void)
{
unsigned int i;
tree id;
int mask = ((flag_no_asm ? D_ASM : 0)
| D_OBJC
| (flag_no_gnu_keywords ? D_EXT : 0)
| ((cxx_dialect == cxx0x) ? 0 : D_CXX0X));
int mask = 0;
mask |= D_CONLY;
if (cxx_dialect != cxx0x)
mask |= D_CXX0X;
if (flag_no_asm)
mask |= D_ASM | D_EXT;
if (flag_no_gnu_keywords)
mask |= D_EXT;
if (!c_dialect_objc())
mask |= D_OBJC;
ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
for (i = 0; i < ARRAY_SIZE (reswords); i++)
for (i = 0; i < num_c_common_reswords; i++)
{
id = get_identifier (reswords[i].word);
C_SET_RID_CODE (id, reswords[i].rid);
ridpointers [(int) reswords[i].rid] = id;
if (! (reswords[i].disable & mask))
id = get_identifier (c_common_reswords[i].word);
C_SET_RID_CODE (id, c_common_reswords[i].rid);
ridpointers [(int) c_common_reswords[i].rid] = id;
if (! (c_common_reswords[i].disable & mask))
C_IS_RESERVED_WORD (id) = 1;
}
}

View File

@ -1,3 +1,8 @@
2008-07-11 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_is_reserved_word): Always check for RID_CLASS,
etc., not just when OBJCPLUS is defined.
2008-06-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* objc-act.c (setup_string_decl, objc_build_string_object,

View File

@ -760,12 +760,9 @@ objc_is_reserved_word (tree ident)
unsigned char code = C_RID_CODE (ident);
return (OBJC_IS_AT_KEYWORD (code)
#ifdef OBJCPLUS
|| code == RID_CLASS || code == RID_PUBLIC
|| code == RID_PROTECTED || code == RID_PRIVATE
|| code == RID_TRY || code == RID_THROW || code == RID_CATCH
#endif
);
|| code == RID_TRY || code == RID_THROW || code == RID_CATCH);
}
/* Return true if TYPE is 'id'. */

View File

@ -1,3 +1,7 @@
2008-07-11 Ian Lance Taylor <iant@google.com>
* gcc.dg/Wcxx-compat-2.c: New test.
2008-07-11 Dodji Seketeli <dseketel@redhat.com>
PR c++/13101

View File

@ -0,0 +1,35 @@
/* { dg-options "-Wc++-compat" } */
int bool;
int catch;
int char16_t;
int char32_t;
int class;
int const_cast; /* { dg-warning "keyword" } */
int decltype;
int delete;
int dynamic_cast; /* { dg-warning "keyword" } */
int explicit;
int export;
int false;
int friend;
int mutable; /* { dg-warning "keyword" } */
int namespace;
int new;
int operator;
int private;
int protected;
int public;
int reinterpret_cast; /* { dg-warning "keyword" } */
int static_assert; /* { dg-warning "keyword" } */
int static_cast; /* { dg-warning "keyword" } */
int template;
int this;
int throw;
int true;
int try;
int typename;
int typeid;
int using;
int virtual;
int wchar_t;