Codesbyusman updated this revision to Diff 453110.
Codesbyusman edited the summary of this revision.
Codesbyusman added a comment.

updated.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131683/new/

https://reviews.llvm.org/D131683

Files:
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/test/Lexer/keywords_test.c
  clang/test/Lexer/keywords_test.cpp

Index: clang/test/Lexer/keywords_test.cpp
===================================================================
--- clang/test/Lexer/keywords_test.cpp
+++ clang/test/Lexer/keywords_test.cpp
@@ -15,6 +15,8 @@
 // RUN: %clang -std=c++03 -target i686-windows-msvc -DMS -fno-declspec -fsyntax-only %s
 // RUN: %clang -std=c++03 -target x86_64-scei-ps4 -fno-declspec -fsyntax-only %s
 
+// RUN: %clang_cc1 -std=c++98 -DFutureKeyword -fsyntax-only %s
+
 #define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME)
 #define NOT_KEYWORD(NAME) _Static_assert(__is_identifier(NAME), #NAME)
 #define IS_TYPE(NAME) void is_##NAME##_type() { int f(NAME); }
@@ -61,6 +63,11 @@
 // Concepts keywords
 CXX20_KEYWORD(concept);
 CXX20_KEYWORD(requires);
+CXX20_KEYWORD(consteval);
+CXX20_KEYWORD(constinit);
+CXX20_KEYWORD(co_await);
+CXX20_KEYWORD(co_return);
+CXX20_KEYWORD(co_yield);
 
 // __declspec extension
 DECLSPEC_KEYWORD(__declspec);
@@ -70,3 +77,27 @@
 IS_TYPE(__char16_t);
 IS_KEYWORD(__char32_t);
 IS_TYPE(__char32_t);
+
+#ifdef FutureKeyword
+
+int nullptr; // expected-warning {{'nullptr' is a keyword in C++11}}
+int decltype;  // expected-warning {{'decltype' is a keyword in C++11}}
+int alignof;  // expected-warning {{'alignof' is a keyword in C++11}}
+int alignas;  // expected-warning {{'alignas' is a keyword in C++11}}
+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 noexcept;  // expected-warning {{'noexcept' is a keyword in C++11}}
+int static_assert; // expected-warning {{'static_assert' is a keyword in C++11}}
+char thread_local; // expected-warning {{'thread_local' is a keyword in C++11}}
+
+int co_await; // expected-warning {{'co_await' is a keyword in C++20}}
+char co_return; // expected-warning {{'co_return' is a keyword in C++20}}
+char co_yield; // expected-warning {{'co_yield' is a keyword in C++20}}
+float align; // expected-warning {{'align' is a keyword in C++20}}
+int constinit; // expected-warning {{'constinit' is a keyword in C++20}}
+int consteval; // expected-warning {{'alignas' is a keyword in C++20}}
+int requires; // expected-warning {{'requires' is a keyword in C++20}}
+int concept; // expected-warning {{'concept' is a keyword in C++20}}
+
+#endif
Index: clang/test/Lexer/keywords_test.c
===================================================================
--- clang/test/Lexer/keywords_test.c
+++ clang/test/Lexer/keywords_test.c
@@ -14,6 +14,41 @@
 // RUN: %clang_cc1 -std=c99 -fms-extensions -fno-declspec -E %s -o - \
 // RUN:     | FileCheck --check-prefix=CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC %s
 
+// RUN: %clang_cc1 -std=c99 -DC99 -fsyntax-only %s
+// RUN: %clang_cc1 -std=c2x -DC99 -DC23 -fsyntax-only %s
+
+// RUN: %clang_cc1 -std=c89 -DFutureKeyword -fsyntax-only %s
+
+#define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME)
+#define NOT_KEYWORD(NAME) _Static_assert(__is_identifier(NAME), #NAME)
+
+#if defined(C99)
+#define C99_KEYWORD(NAME)  IS_KEYWORD(NAME)
+#else
+#define C99_KEYWORD(NAME)  NOT_KEYWORD(NAME)
+#endif
+
+#if defined(C23)
+#define C23_KEYWORD(NAME)  IS_KEYWORD(NAME)
+#else
+#define C23_KEYWORD(NAME)  NOT_KEYWORD(NAME)
+#endif
+
+// C99 Keywords.
+C99_KEYWORD(restrict);
+C99_KEYWORD(inline);
+
+// C23 Keywords.
+C23_KEYWORD(bool);
+C23_KEYWORD(true);
+C23_KEYWORD(false);
+C23_KEYWORD(remove_quals);
+C23_KEYWORD(static_assert);
+C23_KEYWORD(typeof);
+C23_KEYWORD(thread_local);
+C23_KEYWORD(alignas);
+C23_KEYWORD(alignof);
+
 void f() {
 // CHECK-NONE: int asm
 // CHECK-GNU-KEYWORDS: asm ("ret" : :)
@@ -52,3 +87,19 @@
 #else
 void has_static_assert();
 #endif
+
+#ifdef FutureKeyword
+
+  int restrict; // expected-warning {{'restrict' is a keyword in C99}}
+  int inline;  // expected-warning {{'inline' is a keyword in C99}}
+
+  int bool; // expected-warning {{'bool' is a keyword in C23}}
+  char true; // expected-warning {{'true' is a keyword in C23}}
+  char false; // expected-warning {{'false' is a keyword in C23}}
+  float align; // expected-warning {{'align' is a keyword in C23}}
+  int typeof; // expected-warning {{'typeof' is a keyword in C23}}
+    int alignas; // expected-warning {{'alignas' is a keyword in C23}}
+  int remove_quals; // expected-warning {{'remove_quals' is a keyword in C23}}
+  int static_assert; // expected-warning {{'static_assert' is a keyword in C23}}
+
+#endif
Index: clang/lib/Lex/Preprocessor.cpp
===================================================================
--- clang/lib/Lex/Preprocessor.cpp
+++ clang/lib/Lex/Preprocessor.cpp
@@ -773,29 +773,6 @@
     Diag(Identifier,it->second) << Identifier.getIdentifierInfo();
 }
 
-/// Returns a diagnostic message kind for reporting a future keyword as
-/// appropriate for the identifier and specified language.
-static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
-                                          const LangOptions &LangOpts) {
-  assert(II.isFutureCompatKeyword() && "diagnostic should not be needed");
-
-  if (LangOpts.CPlusPlus)
-    return llvm::StringSwitch<diag::kind>(II.getName())
-#define CXX11_KEYWORD(NAME, FLAGS)                                             \
-        .Case(#NAME, diag::warn_cxx11_keyword)
-#define CXX20_KEYWORD(NAME, FLAGS)                                             \
-        .Case(#NAME, diag::warn_cxx20_keyword)
-#include "clang/Basic/TokenKinds.def"
-        // char8_t is not modeled as a CXX20_KEYWORD because it's not
-        // unconditionally enabled in C++20 mode. (It can be disabled
-        // by -fno-char8_t.)
-        .Case("char8_t", diag::warn_cxx20_keyword)
-        ;
-
-  llvm_unreachable(
-      "Keyword not known to come from a newer Standard or proposed Standard");
-}
-
 void Preprocessor::updateOutOfDateIdentifier(IdentifierInfo &II) const {
   assert(II.isOutOfDate() && "not out of date");
   getExternalSource()->updateOutOfDateIdentifier(II);
@@ -867,7 +844,8 @@
   // FIXME: This warning is disabled in cases where it shouldn't be, like
   //   "#define constexpr constexpr", "int constexpr;"
   if (II.isFutureCompatKeyword() && !DisableMacroExpansion) {
-    Diag(Identifier, getFutureCompatDiagKind(II, getLangOpts()))
+    IdentifierTable IT;
+    Diag(Identifier, IT.getFutureCompatDiagKind(II, getLangOpts()))
         << II.getName();
     // Don't diagnose this keyword again in this translation unit.
     II.setIsFutureCompatKeyword(false);
Index: clang/lib/Basic/IdentifierTable.cpp
===================================================================
--- clang/lib/Basic/IdentifierTable.cpp
+++ clang/lib/Basic/IdentifierTable.cpp
@@ -107,7 +107,8 @@
     KEYOPENCLCXX  = 0x200000,
     KEYMSCOMPAT   = 0x400000,
     KEYSYCL       = 0x800000,
-    KEYCUDA       = 0x1000000,
+    KEYC23        = 0x1000000,
+    KEYCUDA       = 0x2000000,
     KEYMAX        = KEYCUDA, // The maximum key
     KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
     KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 &
@@ -140,15 +141,17 @@
 
   switch (Flag) {
   case KEYC99:
-    // FIXME: This should have KS_Future logic here, but that can only happen if
-    // getFutureCompatDiagKind ALSO gets updated. This is safe, since C mode is
-    // ALWAYS implied.
-    return LangOpts.C99 ? KS_Enabled : KS_Unknown;
+    if (LangOpts.C99)
+      return KS_Enabled;
+    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
   case KEYC11:
-    // FIXME: This should have KS_Future logic here, but that can only happen if
-    // getFutureCompatDiagKind ALSO gets updated. This is safe, since C mode is
-    // ALWAYS implied.
-    return LangOpts.C11 ? KS_Enabled : KS_Unknown;
+    if (LangOpts.C11)
+      return KS_Enabled;
+    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+  case KEYC23:
+    if (LangOpts.C2x)
+      return KS_Enabled;
+    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
   case KEYCXX:
     return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown;
   case KEYCXX11:
@@ -845,3 +848,46 @@
   }
   llvm_unreachable("Unknown nullability kind.");
 }
+
+//===----------------------------------------------------------------------===//
+// IdentifierTable Implementation
+//===----------------------------------------------------------------------===//
+
+/// Returns a diagnostic message kind for reporting a future keyword as
+/// appropriate for the identifier and specified language.
+diag::kind
+IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo &II,
+                                         const LangOptions &LangOpts) {
+  assert(II.isFutureCompatKeyword() && "diagnostic should not be needed");
+
+  // Getting the flag value. i.e bool keyword passing it name to the function
+  // and will return the flag value that which keys are used then will use for
+  // mapping the keywords to the languages.
+  unsigned Flags = llvm::StringSwitch<unsigned>(II.getName())
+#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
+#include "clang/Basic/TokenKinds.def"
+#undef KEYWORD
+      ;
+
+  // Checking the Language mode and then for the diagnostics.
+
+  // If C++.
+  if (LangOpts.CPlusPlus) {
+    if ((Flags & KEYCXX11) == KEYCXX11)
+      return diag::warn_cxx11_keyword;
+    if (((Flags & KEYCXX20) == KEYCXX20) ||
+        ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT))
+      return diag::warn_cxx20_keyword;
+  }
+
+  // If C.
+  if (!LangOpts.CPlusPlus) {
+    if ((Flags & KEYC99) == KEYC99)
+      return diag::warn_c99_keyword;
+    if ((Flags & KEYC23) == KEYC23)
+      return diag::warn_c23_keyword;
+  }
+
+  llvm_unreachable(
+      "Keyword not known to come from a newer Standard or proposed Standard");
+}
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -79,6 +79,12 @@
 #ifndef PRAGMA_ANNOTATION
 #define PRAGMA_ANNOTATION(X) ANNOTATION(X)
 #endif
+#ifndef C99_KEYWORD
+#define C99_KEYWORD(X,Y) KEYWORD(X,KEYC99|(Y))
+#endif
+#ifndef C23_KEYWORD
+#define C23_KEYWORD(X,Y) KEYWORD(X,KEYC23|(Y))
+#endif
 
 //===----------------------------------------------------------------------===//
 // Preprocessor keywords.
@@ -250,6 +256,7 @@
 //              always be treated as a keyword
 //   KEYC99   - This is a keyword introduced to C in C99
 //   KEYC11   - This is a keyword introduced to C in C11
+//   KEYC23   - This is a keyword introduced to C in C23
 //   KEYCXX   - This is a C++ keyword, or a C++-specific keyword in the
 //              implementation namespace
 //   KEYNOCXX - This is a keyword in every non-C++ dialect.
@@ -291,13 +298,11 @@
 KEYWORD(for                         , KEYALL)
 KEYWORD(goto                        , KEYALL)
 KEYWORD(if                          , KEYALL)
-KEYWORD(inline                      , KEYC99|KEYCXX|KEYGNU)
 KEYWORD(int                         , KEYALL)
 KEYWORD(_ExtInt                     , KEYALL)
 KEYWORD(_BitInt                     , KEYALL)
 KEYWORD(long                        , KEYALL)
 KEYWORD(register                    , KEYALL)
-KEYWORD(restrict                    , KEYC99)
 KEYWORD(return                      , KEYALL)
 KEYWORD(short                       , KEYALL)
 KEYWORD(signed                      , KEYALL)
@@ -328,7 +333,6 @@
 
 // C++ 2.11p1: Keywords.
 KEYWORD(asm                         , KEYCXX|KEYGNU)
-KEYWORD(bool                        , BOOLSUPPORT)
 KEYWORD(catch                       , KEYCXX)
 KEYWORD(class                       , KEYCXX)
 KEYWORD(const_cast                  , KEYCXX)
@@ -336,7 +340,6 @@
 KEYWORD(dynamic_cast                , KEYCXX)
 KEYWORD(explicit                    , KEYCXX)
 KEYWORD(export                      , KEYCXX)
-KEYWORD(false                       , BOOLSUPPORT)
 KEYWORD(friend                      , KEYCXX)
 KEYWORD(mutable                     , KEYCXX)
 KEYWORD(namespace                   , KEYCXX)
@@ -350,7 +353,6 @@
 KEYWORD(template                    , KEYCXX)
 KEYWORD(this                        , KEYCXX)
 KEYWORD(throw                       , KEYCXX)
-KEYWORD(true                        , BOOLSUPPORT)
 KEYWORD(try                         , KEYCXX)
 KEYWORD(typename                    , KEYCXX)
 KEYWORD(typeid                      , KEYCXX)
@@ -371,18 +373,28 @@
 CXX_KEYWORD_OPERATOR(xor     , caret)
 CXX_KEYWORD_OPERATOR(xor_eq  , caretequal)
 
+// C99 Keywords.
+C99_KEYWORD(restrict                    , 0)
+C99_KEYWORD(inline                      , KEYCXX|KEYGNU)
+
+// C23 Keywords.
+C23_KEYWORD(bool                        , BOOLSUPPORT)
+C23_KEYWORD(false                       , BOOLSUPPORT)
+C23_KEYWORD(true                        , BOOLSUPPORT)
+C23_KEYWORD(remove_quals                , 0)
+
 // C++11 keywords
-CXX11_KEYWORD(alignas               , 0)
+CXX11_KEYWORD(alignas               , KEYC23)
 // alignof and _Alignof return the required ABI alignment
-CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, 0)
+CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, KEYC23)
 CXX11_KEYWORD(char16_t              , KEYNOMS18)
 CXX11_KEYWORD(char32_t              , KEYNOMS18)
 CXX11_KEYWORD(constexpr             , 0)
 CXX11_KEYWORD(decltype              , 0)
 CXX11_KEYWORD(noexcept              , 0)
 CXX11_KEYWORD(nullptr               , 0)
-CXX11_KEYWORD(static_assert         , KEYMSCOMPAT)
-CXX11_KEYWORD(thread_local          , 0)
+CXX11_KEYWORD(static_assert         , KEYMSCOMPAT|KEYC23)
+CXX11_KEYWORD(thread_local          , KEYC23)
 
 // C++20 / coroutines TS keywords
 COROUTINES_KEYWORD(co_await)
@@ -444,7 +456,7 @@
 KEYWORD(__auto_type                 , KEYALL)
 
 // GNU Extensions (outside impl-reserved namespace)
-KEYWORD(typeof                      , KEYGNU)
+KEYWORD(typeof                      , KEYGNU|KEYC23)
 
 // MS Extensions
 KEYWORD(__FUNCDNAME__               , KEYMS)
@@ -933,3 +945,5 @@
 #undef KEYWORD
 #undef PUNCTUATOR
 #undef TOK
+#undef C99_KEYWORD
+#undef C23_KEYWORD
Index: clang/include/clang/Basic/IdentifierTable.h
===================================================================
--- clang/include/clang/Basic/IdentifierTable.h
+++ clang/include/clang/Basic/IdentifierTable.h
@@ -17,6 +17,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/LexDiagnostic.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
@@ -668,6 +669,9 @@
   /// Populate the identifier table with info about the language keywords
   /// for the language specified by \p LangOpts.
   void AddKeywords(const LangOptions &LangOpts);
+
+  diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
+                                     const LangOptions &LangOpts);
 };
 
 /// A family of Objective-C methods.
Index: clang/include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticLexKinds.td
+++ clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -80,6 +80,10 @@
   InGroup<CXX11Compat>, DefaultIgnore;
 def warn_cxx20_keyword : Warning<"'%0' is a keyword in C++20">,
   InGroup<CXX20Compat>, DefaultIgnore;
+def warn_c99_keyword : Warning<"'%0' is a keyword in C99">,
+  InGroup<C99Compat>, DefaultIgnore;
+def warn_c23_keyword : Warning<"'%0' is a keyword in C23">,
+  InGroup<CPre2xCompat>, DefaultIgnore;
 
 def ext_unterminated_char_or_string : ExtWarn<
   "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to