diff options
author | Muhammad Usman Shahid <codesbyusman@gmail.com> | 2022-08-26 09:17:14 -0400 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2022-08-26 09:20:05 -0400 |
commit | 41667a8b9b624e282e7c08fadf7091223728d1c1 (patch) | |
tree | fd845d5f127d655f70888e733fe832ad70e77534 /clang/lib/Basic/IdentifierTable.cpp | |
parent | 5af06ba7dc26f614989a9a9e16e69f6ecc811519 (diff) | |
download | llvm-41667a8b9b624e282e7c08fadf7091223728d1c1.zip llvm-41667a8b9b624e282e7c08fadf7091223728d1c1.tar.gz llvm-41667a8b9b624e282e7c08fadf7091223728d1c1.tar.bz2 |
Diagnosing the Future Keywords
The patch diagnoses an identifier as a future keyword if it exists in a
future language mode, such as:
int restrict;
in C modes earlier than C99. We now give a warning to the user that
such an identifier is a future keyword. Handles keywords from C as well
as C++.
Differential Revision: https://reviews.llvm.org/D131683
Diffstat (limited to 'clang/lib/Basic/IdentifierTable.cpp')
-rw-r--r-- | clang/lib/Basic/IdentifierTable.cpp | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 06f0850..5d413a8 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -88,26 +88,25 @@ namespace { KEYCXX11 = 0x4, KEYGNU = 0x8, KEYMS = 0x10, - BOOLSUPPORT = 0x20, - KEYALTIVEC = 0x40, - KEYNOCXX = 0x80, - KEYBORLAND = 0x100, - KEYOPENCLC = 0x200, - KEYC11 = 0x400, - KEYNOMS18 = 0x800, - KEYNOOPENCL = 0x1000, - WCHARSUPPORT = 0x2000, - HALFSUPPORT = 0x4000, - CHAR8SUPPORT = 0x8000, - KEYOBJC = 0x10000, - KEYZVECTOR = 0x20000, - KEYCOROUTINES = 0x40000, - KEYMODULES = 0x80000, - KEYCXX20 = 0x100000, - KEYOPENCLCXX = 0x200000, - KEYMSCOMPAT = 0x400000, - KEYSYCL = 0x800000, - KEYCUDA = 0x1000000, + KEYALTIVEC = 0x20, + KEYNOCXX = 0x40, + KEYBORLAND = 0x80, + KEYOPENCLC = 0x100, + KEYC2X = 0x200, + KEYNOMS18 = 0x400, + KEYNOOPENCL = 0x800, + WCHARSUPPORT = 0x1000, + HALFSUPPORT = 0x2000, + CHAR8SUPPORT = 0x4000, + KEYOBJC = 0x8000, + KEYZVECTOR = 0x10000, + KEYCOROUTINES = 0x20000, + KEYMODULES = 0x40000, + KEYCXX20 = 0x80000, + KEYOPENCLCXX = 0x100000, + KEYMSCOMPAT = 0x200000, + KEYSYCL = 0x400000, + KEYCUDA = 0x800000, KEYMAX = KEYCUDA, // The maximum key KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20, KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 & @@ -140,15 +139,13 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts, 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; - 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.C99) + return KS_Enabled; + return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown; + case KEYC2X: + if (LangOpts.C2x) + return KS_Enabled; + return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown; case KEYCXX: return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown; case KEYCXX11: @@ -163,8 +160,6 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts, return LangOpts.GNUKeywords ? KS_Extension : KS_Unknown; case KEYMS: return LangOpts.MicrosoftExt ? KS_Extension : KS_Unknown; - case BOOLSUPPORT: - return LangOpts.Bool ? KS_Enabled : KS_Unknown; case KEYALTIVEC: return LangOpts.AltiVec ? KS_Enabled : KS_Unknown; case KEYBORLAND: @@ -845,3 +840,35 @@ StringRef clang::getNullabilitySpelling(NullabilityKind kind, } llvm_unreachable("Unknown nullability kind."); } + +diag::kind +IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo &II, + const LangOptions &LangOpts) { + assert(II.isFutureCompatKeyword() && "diagnostic should not be needed"); + + unsigned Flags = llvm::StringSwitch<unsigned>(II.getName()) +#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS) +#include "clang/Basic/TokenKinds.def" +#undef KEYWORD + ; + + if (LangOpts.CPlusPlus) { + if ((Flags & KEYCXX11) == KEYCXX11) + return diag::warn_cxx11_keyword; + + // 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.) + if (((Flags & KEYCXX20) == KEYCXX20) || + ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT)) + return diag::warn_cxx20_keyword; + } else { + if ((Flags & KEYC99) == KEYC99) + return diag::warn_c99_keyword; + if ((Flags & KEYC2X) == KEYC2X) + return diag::warn_c2x_keyword; + } + + llvm_unreachable( + "Keyword not known to come from a newer Standard or proposed Standard"); +} |