[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++

2018-08-21 Thread Phabricator via Phabricator via cfe-commits
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++

2018-08-20 Thread John McCall via Phabricator via cfe-commits
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++

2018-08-20 Thread Erik Pilkington via Phabricator via cfe-commits
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++

2018-08-13 Thread Erik Pilkington via Phabricator via cfe-commits
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++

2018-08-09 Thread Erik Pilkington via Phabricator via cfe-commits
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++

2018-08-09 Thread John McCall via Phabricator via cfe-commits
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++

2018-08-09 Thread Erik Pilkington via Phabricator via cfe-commits
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++

2018-08-09 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
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++

2018-08-09 Thread Erik Pilkington via Phabricator via cfe-commits
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