c-common.h (enum rid): Add RID_CXX_COMPAT_WARN.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 11 Jul 2008 18:16:26 +0000 (18:16 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 11 Jul 2008 18:16:26 +0000 (18:16 +0000)
./: * 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
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/lex.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wcxx-compat-2.c [new file with mode: 0644]

index 6db32ef25b3dc88cd8a0e1b5e7788d174fc79e2b..0a3ff2570569de8e53fd9e2efe440ffc79ed35bc 100644 (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):
index 2224a21f0efec9521d752ec15be683cf63bc1c9b..1af2120f84b3666cc0265aed4b61e4abc9a8dc87 100644 (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[] =
 {
index 7fd2242c35220951e965ceb350e80de45d0061bc..7edb4a67afda1524ab972bea7c90539acea18883 100644 (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]
index 18ad11901f97962da9b9b42e50121cd51ed607ca..0f190e12be88b62dcafb80b5ddc6ee795092b143 100644 (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)
index 4ca06fec414e22404e9133f05919c44ed66a60ac..aba007c9bc2c1b47e33f2a330a69b3004b230d17 100644 (file)
@@ -59,131 +59,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 
 \f
-/* 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;
     }
 }
 \f
@@ -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)
+             {
+               warning (OPT_Wc___compat,
+                        "%Hidentifier %qs conflicts with C++ keyword",
+                        &token->location,
+                        IDENTIFIER_POINTER (token->value));
+             }
+           else if (c_dialect_objc ())
              {
-               if (!OBJC_IS_AT_KEYWORD (rid_code)
+               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);
index 7b73ee1e8a113be29ffecc7cf947d9b22028ef4c..ac33477482d56d1bba6f4eb28f38ee141108d153 100644 (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
index 233011b85d9e84107aee4b7e62b092b077d6a828..890640e912a7455e50b8ab7d9885400521a264de 100644 (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;
     }
 }
index f5869b3bca97c13672eaf21b3ec3e7db65424ba1..18a548da635a0a0ab23059ee352a23b1bfb64517 100644 (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,
index 4aef9a02017ef50f6ef63a0a3dfe17d48d745abb..822dd35eb8d6f8619f1a2cd686698a3e47dd8254 100644 (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'.  */
index cf57c77a0c2e9b8f5217c38fafbdd0b8caf6323c..c246c5f6aec2d18ded80ccf6a81712214d25c9dd 100644 (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
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-2.c b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
new file mode 100644 (file)
index 0000000..5a46fbe
--- /dev/null
@@ -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;