-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C] Diagnose use of C++ keywords in C #137234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
56a3f3c
3b0732e
55350f0
52fe07b
fb976c2
972a5fa
81ac3ce
6c5d838
20dcdae
07e44e0
908162e
c8b6f48
1308a4e
6bd0c2f
b07e0fd
5bf4006
ac746fa
d0551ca
205aa3c
16594b3
6b12e5e
49c7db0
485c548
c0fbe17
c3547f9
082d94c
f00bd69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -250,6 +250,32 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, | |
return CurStatus; | ||
} | ||
|
||
static bool IsKeywordInCpp(unsigned Flags) { | ||
while (Flags != 0) { | ||
unsigned CurFlag = Flags & ~(Flags - 1); | ||
Flags = Flags & ~CurFlag; | ||
switch (static_cast<TokenKey>(CurFlag)) { | ||
case KEYCXX: | ||
case KEYCXX11: | ||
case KEYCXX20: | ||
case BOOLSUPPORT: | ||
case WCHARSUPPORT: | ||
case CHAR8SUPPORT: | ||
return true; | ||
default: | ||
break; // Go to the next flag, try again. | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
static void MarkIdentifierAsKeywordInCpp(IdentifierTable &Table, | ||
StringRef Name) { | ||
IdentifierInfo &II = Table.get(Name, tok::identifier); | ||
II.setIsKeywordInCPlusPlus(); | ||
II.setHandleIdentifierCase(); | ||
} | ||
|
||
/// AddKeyword - This method is used to associate a token ID with specific | ||
/// identifiers because they are language keywords. This causes the lexer to | ||
/// automatically map matching identifiers to specialized token codes. | ||
|
@@ -258,8 +284,18 @@ static void AddKeyword(StringRef Keyword, | |
const LangOptions &LangOpts, IdentifierTable &Table) { | ||
KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags); | ||
|
||
// Don't add this keyword if disabled in this language. | ||
if (AddResult == KS_Disabled) return; | ||
// Don't add this keyword if disabled in this language and isn't otherwise | ||
// special. | ||
if (AddResult == KS_Disabled) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: It'd be more consistent with the existing code to add an extra KeywordStatus value for this case, analogous to KS_Future. To do that, maybe we'd need to also replace the special macro for C++ operator keywords with a normal flag so that it can be taken into account when computing the KeywordStatus too. I don't think it's necessary to be consistent here, though; we can always refactor later. |
||
// We do not consider any identifiers to be C++ keywords when in | ||
// Objective-C because @ effectively introduces a custom grammar where C++ | ||
// keywords can be used (and similar for selectors). We could enable this | ||
// for Objective-C, but it would require more logic to ensure we do not | ||
// issue compatibility diagnostics in these cases. | ||
if (!LangOpts.ObjC && IsKeywordInCpp(Flags)) | ||
MarkIdentifierAsKeywordInCpp(Table, Keyword); | ||
return; | ||
} | ||
|
||
IdentifierInfo &Info = | ||
Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode); | ||
|
@@ -304,9 +340,11 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { | |
#define ALIAS(NAME, TOK, FLAGS) \ | ||
AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \ | ||
FLAGS, LangOpts, *this); | ||
#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ | ||
if (LangOpts.CXXOperatorNames) \ | ||
AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); | ||
#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ | ||
if (LangOpts.CXXOperatorNames) \ | ||
AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); \ | ||
else \ | ||
MarkIdentifierAsKeywordInCpp(*this, StringRef(#NAME)); | ||
#define OBJC_AT_KEYWORD(NAME) \ | ||
if (LangOpts.ObjC) \ | ||
AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused by this function. Why does this go through all bits in a loop instead of directly checking them? I'd have expected this whole function to be something like
return Flags & (KEYALLCXX|BOOLSUPPORT|WCHARSUPPORT|CHAR8SUPPORT);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code was lifted from
llvm-project/clang/lib/Basic/IdentifierTable.cpp
Line 240 in a4ceac7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated in 0b2ab11 thank you for the catch!