aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanak@gmail.com>2025-05-13 16:25:21 -0700
committerGitHub <noreply@github.com>2025-05-13 16:25:21 -0700
commit7460056a81fbf897fecfaaae7aa8cc515599ea97 (patch)
tree205d522a8ba3077a07ac1604bc2a3e1ae2f418ae
parente9ce7527691ec2b3748895598cd5ee31ac644f3a (diff)
downloadllvm-7460056a81fbf897fecfaaae7aa8cc515599ea97.zip
llvm-7460056a81fbf897fecfaaae7aa8cc515599ea97.tar.gz
llvm-7460056a81fbf897fecfaaae7aa8cc515599ea97.tar.bz2
[ObjC] Stop hard-coding the list of keywords that are allowed in selectors (#138952)
The design intent is that ObjC selector pieces can be arbitrary keywords, including basic C keywords like `if`, and the grammar permits this and makes it unambiguous. Allow any token that has an identifier (except `__attribute__`) to be part of a selector. rdar://150383689
-rw-r--r--clang/lib/Parse/ParseObjc.cpp78
-rw-r--r--clang/test/SemaObjCXX/cxxoperator-selector.mm5
2 files changed, 11 insertions, 72 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 6496b4f..f4b0016 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -1067,8 +1067,6 @@ Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
switch (Tok.getKind()) {
- default:
- return nullptr;
case tok::colon:
// Empty selector piece uses the location of the ':'.
SelectorLoc = Tok.getLocation();
@@ -1094,77 +1092,13 @@ IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
return nullptr;
}
- case tok::identifier:
- case tok::kw_asm:
- case tok::kw_auto:
- case tok::kw_bool:
- case tok::kw_break:
- case tok::kw_case:
- case tok::kw_catch:
- case tok::kw_char:
- case tok::kw_class:
- case tok::kw_const:
- case tok::kw_const_cast:
- case tok::kw_continue:
- case tok::kw_default:
- case tok::kw_delete:
- case tok::kw_do:
- case tok::kw_double:
- case tok::kw_dynamic_cast:
- case tok::kw_else:
- case tok::kw_enum:
- case tok::kw_explicit:
- case tok::kw_export:
- case tok::kw_extern:
- case tok::kw_false:
- case tok::kw_float:
- case tok::kw_for:
- case tok::kw_friend:
- case tok::kw_goto:
- case tok::kw_if:
- case tok::kw_inline:
- case tok::kw_int:
- case tok::kw_long:
- case tok::kw_mutable:
- case tok::kw_namespace:
- case tok::kw_new:
- case tok::kw_operator:
- case tok::kw_private:
- case tok::kw_protected:
- case tok::kw_public:
- case tok::kw_register:
- case tok::kw_reinterpret_cast:
- case tok::kw_restrict:
- case tok::kw_return:
- case tok::kw_short:
- case tok::kw_signed:
- case tok::kw_sizeof:
- case tok::kw_static:
- case tok::kw_static_cast:
- case tok::kw_struct:
- case tok::kw_switch:
- case tok::kw_template:
- case tok::kw_this:
- case tok::kw_throw:
- case tok::kw_true:
- case tok::kw_try:
- case tok::kw_typedef:
- case tok::kw_typeid:
- case tok::kw_typename:
- case tok::kw_typeof:
- case tok::kw_union:
- case tok::kw_unsigned:
- case tok::kw_using:
- case tok::kw_virtual:
- case tok::kw_void:
- case tok::kw_volatile:
- case tok::kw_wchar_t:
- case tok::kw_while:
- case tok::kw__Bool:
- case tok::kw__Complex:
- case tok::kw___alignof:
- case tok::kw___auto_type:
+ case tok::kw___attribute:
+ return nullptr;
+
+ default:
IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (!II)
+ return nullptr;
SelectorLoc = ConsumeToken();
return II;
}
diff --git a/clang/test/SemaObjCXX/cxxoperator-selector.mm b/clang/test/SemaObjCXX/cxxoperator-selector.mm
index 8134b82..2348bd7 100644
--- a/clang/test/SemaObjCXX/cxxoperator-selector.mm
+++ b/clang/test/SemaObjCXX/cxxoperator-selector.mm
@@ -19,5 +19,10 @@
- (id) xor{return 0; };
- (id) or{return 0; };
+- (void)decltype {}
+- (void)constexpr {}
+- (void)noexcept {}
+- (void)nullptr {}
+
- (void)dataSetForValuesBetween:(NSDate *)startDate and:(NSDate *)endDate { return; }
@end