Skip to content

Commit 07e44e0

Browse files
committed
Remove the need for string comparisons
If this ends up performing significantly better, I'll rip out the changes to IdentifierTable.
1 parent 20dcdae commit 07e44e0

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

clang/include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ ANNOTATION(embed)
10421042
#undef TYPE_TRAIT_2
10431043
#undef TYPE_TRAIT_1
10441044
#undef TYPE_TRAIT
1045+
#undef MODULES_KEYWORD
10451046
#undef CXX20_KEYWORD
10461047
#undef CXX11_KEYWORD
10471048
#undef KEYWORD

clang/lib/Sema/SemaDecl.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include "clang/Sema/SemaWasm.h"
6060
#include "clang/Sema/Template.h"
6161
#include "llvm/ADT/STLForwardCompat.h"
62+
#include "llvm/ADT/SmallPtrSet.h"
6263
#include "llvm/ADT/SmallString.h"
6364
#include "llvm/ADT/StringExtras.h"
6465
#include "llvm/ADT/StringSwitch.h"
@@ -6112,17 +6113,23 @@ static bool isKeywordInCPlusPlus(const Sema &S, const IdentifierInfo *II) {
61126113
if (!II)
61136114
return false;
61146115

6115-
// Clear all the C language options, set all the C++ language options, but
6116-
// otherwise leave all the defaults alone. This isn't ideal because some
6117-
// feature flags are language-specific, but this is a reasonable
6118-
// approximation.
6119-
LangOptions LO = S.getLangOpts();
6120-
LO.CPlusPlus = LO.CPlusPlus11 = LO.CPlusPlus14 = LO.CPlusPlus17 =
6121-
LO.CPlusPlus20 = LO.CPlusPlus23 = LO.CPlusPlus26 = 1;
6122-
LO.C99 = LO.C11 = LO.C17 = LO.C23 = LO.C2y = 0;
6123-
LO.Char8 = 1; // Presume this is always a keyword in C++.
6124-
LO.WChar = 1; // Presume this is always a keyword in C++.
6125-
return II->isNameKeyword(LO);
6116+
// Build a static map of identifiers for all of the keywords in C++ that are
6117+
// not keywords in C. This allows us to do pointer comparisons instead of
6118+
// string comparisons when deciding whether the given identifier is a keyword
6119+
// or not. Note, this treats all keywords as being enabled, regardless of the
6120+
// setting of other language options. It intentionally disables the modules
6121+
// keywords because those are conditional keywords, so may be safe to use.
6122+
static llvm::SmallPtrSet<IdentifierInfo *, 32> Keywords;
6123+
if (Keywords.empty()) {
6124+
#define MODULES_KEYWORD(NAME)
6125+
#define KEYWORD(NAME, FLAGS) \
6126+
Keywords.insert(&S.getPreprocessor().getIdentifierTable().get(#NAME));
6127+
#define CXX_KEYWORD_OPERATOR(NAME, TOK) \
6128+
Keywords.insert(&S.getPreprocessor().getIdentifierTable().get(#NAME));
6129+
#include "clang/Basic/TokenKinds.def"
6130+
}
6131+
6132+
return Keywords.contains(II);
61266133
}
61276134

61286135
void Sema::warnOnReservedIdentifier(const NamedDecl *D) {

0 commit comments

Comments
 (0)