From eea1139b26437bb71fd5ee838d8d0b5f2473a16a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 11 Jul 2008 18:16:26 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 26 ++++ gcc/c-common.c | 173 ++++++++++++++++++++++++ gcc/c-common.h | 34 +++++ gcc/c-decl.c | 6 +- gcc/c-parser.c | 189 ++++++-------------------- gcc/cp/ChangeLog | 8 ++ gcc/cp/lex.c | 192 +++------------------------ gcc/objc/ChangeLog | 5 + gcc/objc/objc-act.c | 5 +- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/Wcxx-compat-2.c | 35 +++++ 11 files changed, 351 insertions(+), 326 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wcxx-compat-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6db32ef25b3..0a3ff257056 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2008-07-11 Tom Tromey + Ian Lance Taylor + + * 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 * ggc-page.c (alloc_page): diff --git a/gcc/c-common.c b/gcc/c-common.c index 2224a21f0ef..1af2120f84b 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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[] = { diff --git a/gcc/c-common.h b/gcc/c-common.h index 7fd2242c352..7edb4a67afd 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -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] diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 18ad11901f9..0f190e12be8 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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) diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 4ca06fec414..aba007c9bc2 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7b73ee1e8a1..ac33477482d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2008-07-11 Tom Tromey + Ian Lance Taylor + + * 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 PR c++/13101 diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 233011b85d9..890640e912a 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -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; } } diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index f5869b3bca9..18a548da635 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,8 @@ +2008-07-11 Ian Lance Taylor + + * 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 * objc-act.c (setup_string_decl, objc_build_string_object, diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 4aef9a02017..822dd35eb8d 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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'. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf57c77a0c2..c246c5f6aec 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-07-11 Ian Lance Taylor + + * gcc.dg/Wcxx-compat-2.c: New test. + 2008-07-11 Dodji Seketeli PR c++/13101 diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-2.c b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c new file mode 100644 index 00000000000..5a46fbe4bd5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c @@ -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;