[cfe-commits] r141700 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Basic/IdentifierTable.h include/clang/Lex/Preprocessor.h lib/Basic/IdentifierTable.cpp lib/Lex/Preprocessor.cpp test/Lexer/cxx0x_keyword_as_cxx98.cpp test/SemaCXX/decltype-crash.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Oct 11 12:57:52 PDT 2011


Author: rsmith
Date: Tue Oct 11 14:57:52 2011
New Revision: 141700

URL: http://llvm.org/viewvc/llvm-project?rev=141700&view=rev
Log:
Add a -Wc++0x-compat warning for C++11 keywords used as identifiers when in
C++98 mode. Only the first occurrence of each keyword will produce a warning.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp
    cfe/trunk/test/SemaCXX/decltype-crash.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Oct 11 14:57:52 2011
@@ -46,6 +46,9 @@
 def ext_token_used : Extension<"extension used">,
   InGroup<DiagGroup<"language-extension-token">>;
 
+def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
+  InGroup<CXX0xCompat>;
+
 def warn_unterminated_string : ExtWarn<"missing terminating '\"' character">;
 def warn_unterminated_char : ExtWarn<"missing terminating ' character">;
 def err_empty_character : Error<"empty character constant">;

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Tue Oct 11 14:57:52 2011
@@ -58,6 +58,7 @@
   unsigned ObjCOrBuiltinID    :11;
   bool HasMacro               : 1; // True if there is a #define for this.
   bool IsExtension            : 1; // True if identifier is a lang extension.
+  bool IsCXX11CompatKeyword   : 1; // True if identifier is a keyword in C++11.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
   bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
   bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
@@ -199,6 +200,19 @@
       RecomputeNeedsHandleIdentifier();
   }
 
+  /// is/setIsCXX11CompatKeyword - Initialize information about whether or not
+  /// this language token is a keyword in C++11. This controls compatibility
+  /// warnings, and is only true when not parsing C++11. Once a compatibility
+  /// problem has been diagnosed with this keyword, the flag will be cleared.
+  bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; }
+  void setIsCXX11CompatKeyword(bool Val) {
+    IsCXX11CompatKeyword = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
   /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
   /// Preprocessor will emit an error every time this token is used.
   void setIsPoisoned(bool Value = true) {
@@ -252,7 +266,8 @@
   void RecomputeNeedsHandleIdentifier() {
     NeedsHandleIdentifier =
       (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
-       isExtensionToken() || (getTokenID() == tok::kw___import_module__));
+       isExtensionToken() | isCXX11CompatKeyword() ||
+       (getTokenID() == tok::kw___import_module__));
   }
 };
 

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Oct 11 14:57:52 2011
@@ -752,11 +752,11 @@
   /// Diag - Forwarding function for diagnostics.  This emits a diagnostic at
   /// the specified Token's location, translating the token's start
   /// position in the current buffer into a SourcePosition object for rendering.
-  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
     return Diags->Report(Loc, DiagID);
   }
 
-  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
     return Diags->Report(Tok.getLocation(), DiagID);
   }
 

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Tue Oct 11 14:57:52 2011
@@ -32,6 +32,7 @@
   ObjCOrBuiltinID = 0;
   HasMacro = false;
   IsExtension = false;
+  IsCXX11CompatKeyword = false;
   IsPoisoned = false;
   IsCPPOperatorKeyword = false;
   NeedsHandleIdentifier = false;
@@ -102,10 +103,10 @@
 /// identifiers because they are language keywords.  This causes the lexer to
 /// automatically map matching identifiers to specialized token codes.
 ///
-/// The C90/C99/CPP/CPP0x flags are set to 2 if the token should be
-/// enabled in the specified langauge, set to 1 if it is an extension
-/// in the specified language, and set to 0 if disabled in the
-/// specified language.
+/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a
+/// future language standard, set to 2 if the token should be enabled in the
+/// specified langauge, set to 1 if it is an extension in the specified
+/// language, and set to 0 if disabled in the specified language.
 static void AddKeyword(StringRef Keyword,
                        tok::TokenKind TokenCode, unsigned Flags,
                        const LangOptions &LangOpts, IdentifierTable &Table) {
@@ -123,12 +124,15 @@
   else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2;
   else if (LangOpts.C1X && (Flags & KEYC1X)) AddResult = 2;
   else if (LangOpts.ObjCAutoRefCount && (Flags & KEYARC)) AddResult = 2;
-           
+  else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3;
+
   // Don't add this keyword if disabled in this language.
   if (AddResult == 0) return;
 
-  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
+  IdentifierInfo &Info =
+      Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode);
   Info.setIsExtensionToken(AddResult == 1);
+  Info.setIsCXX11CompatKeyword(AddResult == 3);
 }
 
 /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
@@ -493,4 +497,3 @@
 
   return 0;
 }
-

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Oct 11 14:57:52 2011
@@ -513,6 +513,17 @@
     }
   }
 
+  // If this identifier is a keyword in C++11, produce a warning. Don't warn if
+  // we're not considering macro expansion, since this identifier might be the
+  // name of a macro.
+  // FIXME: This warning is disabled in cases where it shouldn't be, like
+  //   "#define constexpr constexpr", "int constexpr;"
+  if (II.isCXX11CompatKeyword() & !DisableMacroExpansion) {
+    Diag(Identifier, diag::warn_cxx11_keyword) << II.getName();
+    // Don't diagnose this keyword again in this translation unit.
+    II.setIsCXX11CompatKeyword(false);
+  }
+
   // C++ 2.11p2: If this is an alternative representation of a C++ operator,
   // then we act as if it is the actual operator and not the textual
   // representation of it.

Modified: cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp (original)
+++ cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp Tue Oct 11 14:57:52 2011
@@ -1,3 +1,36 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
-int static_assert;
-int char16_t;
+
+#define thread_local __thread
+thread_local int x;
+#undef thread_local
+
+namespace lib {
+  struct nullptr_t;
+  typedef nullptr_t nullptr; // expected-warning {{'nullptr' is a keyword in C++11}}
+}
+
+#define CONCAT(X,Y) CONCAT2(X,Y)
+#define CONCAT2(X,Y) X ## Y
+int CONCAT(constexpr,ession);
+
+#define ID(X) X
+extern int ID(decltype); // expected-warning {{'decltype' is a keyword in C++11}}
+
+extern int CONCAT(align,of); // expected-warning {{'alignof' is a keyword in C++11}}
+
+#define static_assert(b, s) int CONCAT(check, __LINE__)[(b) ? 1 : 0];
+static_assert(1 > 0, "hello"); // ok
+
+#define IF_CXX11(CXX11, CXX03) CXX03
+typedef IF_CXX11(char16_t, wchar_t) my_wide_char_t; // ok
+
+int alignas; // expected-warning {{'alignas' is a keyword in C++11}}
+int alignof; // already diagnosed in this TU
+int char16_t; // expected-warning {{'char16_t' is a keyword in C++11}}
+int char32_t; // expected-warning {{'char32_t' is a keyword in C++11}}
+int constexpr; // expected-warning {{'constexpr' is a keyword in C++11}}
+int decltype; // already diagnosed in this TU
+int noexcept; // expected-warning {{'noexcept' is a keyword in C++11}}
+int nullptr; // already diagnosed in this TU
+int static_assert; // expected-warning {{'static_assert' is a keyword in C++11}}
+int thread_local; // expected-warning {{'thread_local' is a keyword in C++11}}

Modified: cfe/trunk/test/SemaCXX/decltype-crash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype-crash.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decltype-crash.cpp (original)
+++ cfe/trunk/test/SemaCXX/decltype-crash.cpp Tue Oct 11 14:57:52 2011
@@ -3,5 +3,5 @@
 int& a();
 
 void f() {
-  decltype(a()) c; // expected-error {{use of undeclared identifier 'decltype'}}
+  decltype(a()) c; // expected-warning {{'decltype' is a keyword in C++11}} expected-error {{use of undeclared identifier 'decltype'}}
 }





More information about the cfe-commits mailing list