[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
This revision was automatically updated to reflect the committed changes. Closed by commit rC340301: [Parser] Support alternative operator token keyword args in Objective-C++ (authored by epilk, committed by ). Changed prior to commit: https://reviews.llvm.org/D50527?vs=159995=161748#toc Repository: rC Clang https://reviews.llvm.org/D50527 Files: lib/Parse/ParseExpr.cpp test/Parser/message-expr-alt-op.mm Index: test/Parser/message-expr-alt-op.mm === --- test/Parser/message-expr-alt-op.mm +++ test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { Index: test/Parser/message-expr-alt-op.mm === --- test/Parser/message-expr-alt-op.mm +++ test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. In https://reviews.llvm.org/D50527#1206460, @erik.pilkington wrote: > Ping! If the build came back clean, then I think our combination of previous sign-offs is good enough. :) https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
erik.pilkington added a comment. Ping! https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
erik.pilkington added a comment. The build came back clean! https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
erik.pilkington added a comment. In https://reviews.llvm.org/D50527#1194660, @rjmccall wrote: > Assuming you've done enough source-compatibility testing to say with > reasonable confidence that this won't break anything, I think this is fine. > It's a core goal of Objective-C/C++ to allow the base language as a complete > subset if at all possible. I don't really see how this could break source-compatibility, I don't believe there is a way to start a binary operator's RHS with a colon[1] or a r_square, so this change can only affect programs that were previously ill-formed. I'll run some internal builds and report back though, just to be paranoid. [1] excluding the GNU conditional expr, which is handled because getIdentifierInfo will always return nullptr for '?'. https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
rjmccall added a comment. Assuming you've done enough source-compatibility testing to say with reasonable confidence that this won't break anything, I think this is fine. It's a core goal of Objective-C/C++ to allow the base language as a complete subset if at all possible. https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
erik.pilkington updated this revision to Diff 159995. erik.pilkington added a comment. Remove `isBinaryCXXAlternativeOperatorToken`, this check can be done using `OpToken.getAsIdentifierInfo()`. Thanks! FWIW, I can't imagine this being anything but an oversight, we go out of our way to support these tokens in `ParseObjCSelectorPiece`, and we already happen to support unary alternative operators, such as `[foo not]`. https://reviews.llvm.org/D50527 Files: clang/lib/Parse/ParseExpr.cpp clang/test/Parser/message-expr-alt-op.mm Index: clang/test/Parser/message-expr-alt-op.mm === --- /dev/null +++ clang/test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: clang/lib/Parse/ParseExpr.cpp === --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { Index: clang/test/Parser/message-expr-alt-op.mm === --- /dev/null +++ clang/test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: clang/lib/Parse/ParseExpr.cpp === --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
rsmith added a comment. One comment, but otherwise the code change looks mechanically correct. Not accepting only because I don't know whether this is the intended language rule for Objective-C++ or not (please get someone else to sign off on that). Comment at: clang/lib/Parse/ParseExpr.cpp:278 + case tok::caretequal: +return isLetter(PP.getSpelling(Tok).front()); + default: Just check `Tok.getIdentifierInfo()`. That will be null for a punctuation token and non-null for a token spelled as an identifier. (I don't think you even need the `switch`, because we already only get here for operators.) Repository: rC Clang https://reviews.llvm.org/D50527 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
erik.pilkington created this revision. erik.pilkington added reviewers: rjmccall, arphaman. Herald added a subscriber: dexonsmith. This fixes rdar://30741878 Thanks! Erik Repository: rC Clang https://reviews.llvm.org/D50527 Files: clang/lib/Parse/ParseExpr.cpp clang/test/Parser/message-expr-alt-op.mm Index: clang/test/Parser/message-expr-alt-op.mm === --- /dev/null +++ clang/test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: clang/lib/Parse/ParseExpr.cpp === --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -263,6 +263,24 @@ return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); } +static bool isBinaryCXXAlternativeOperatorToken(Preprocessor , +const Token ) { + switch (Tok.getKind()) { + case tok::ampamp: + case tok::ampequal: + case tok::amp: + case tok::pipe: + case tok::exclaimequal: + case tok::pipepipe: + case tok::pipeequal: + case tok::caret: + case tok::caretequal: +return isLetter(PP.getSpelling(Tok).front()); + default: +return false; + } +} + /// Parse a binary expression that starts with \p LHS and has a /// precedence of at least \p MinPrec. ExprResult @@ -315,6 +333,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +isBinaryCXXAlternativeOperatorToken(PP, OpToken)) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { Index: clang/test/Parser/message-expr-alt-op.mm === --- /dev/null +++ clang/test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: clang/lib/Parse/ParseExpr.cpp === --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -263,6 +263,24 @@ return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); } +static bool isBinaryCXXAlternativeOperatorToken(Preprocessor , +const Token ) { + switch (Tok.getKind()) { + case tok::ampamp: + case tok::ampequal: + case tok::amp: + case tok::pipe: + case tok::exclaimequal: + case tok::pipepipe: + case tok::pipeequal: + case tok::caret: + case tok::caretequal: +return isLetter(PP.getSpelling(Tok).front()); + default: +return false; + } +} + /// Parse a binary expression that starts with \p LHS and has a /// precedence of at least \p MinPrec. ExprResult @@ -315,6 +333,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can