@@ -4441,10 +4441,17 @@ cp_parser_primary_expression (cp_parser *parser,
}
case CPP_OPEN_SQUARE:
- if (c_dialect_objc ())
- /* We have an Objective-C++ message. */
- return cp_parser_objc_expression (parser);
{
+ if (c_dialect_objc ())
+ {
+ /* We might have an Objective-C++ message. */
+ cp_parser_parse_tentatively (parser);
+ tree msg = cp_parser_objc_message_expression (parser);
+ /* If that works out, we're done ... */
+ if (cp_parser_parse_definitely (parser))
+ return msg;
+ /* ... else, fall though to see if it's a lambda. */
+ }
tree lam = cp_parser_lambda_expression (parser);
/* Don't warn about a failed tentative parse. */
if (cp_parser_error_occurred (parser))
@@ -25630,14 +25637,20 @@ cp_parser_objc_message_receiver (cp_parser* parser)
cp_parser_parse_tentatively (parser);
rcv = cp_parser_expression (parser);
+ /* If that worked out, fine. */
if (cp_parser_parse_definitely (parser))
return rcv;
+ cp_parser_parse_tentatively (parser);
rcv = cp_parser_simple_type_specifier (parser,
/*decl_specs=*/NULL,
CP_PARSER_FLAGS_NONE);
- return objc_get_class_reference (rcv);
+ if (cp_parser_parse_definitely (parser))
+ return objc_get_class_reference (rcv);
+
+ cp_parser_error (parser, "objective-c++ message receiver expected");
+ return error_mark_node;
}
/* Parse the arguments and selectors comprising an Objective-C message.
new file mode 100644
@@ -0,0 +1,22 @@
+// Contributed by Iain Sandoe <iain@codesourcery.com>, December 2014. */
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+
+template<class Function>
+Function thing(Function fn, int a)
+{
+ fn(a);
+ return fn;
+}
+
+int
+test (int *arr, unsigned n)
+{
+ int total = 0;
+ for (unsigned i=0; i<n; i++) {
+ int a = arr[i];
+ thing ([&total] (int a) { total += a; }, a);
+ }
+ return total;
+}
new file mode 100644
@@ -0,0 +1,13 @@
+// Contributed by Iain Sandoe <iain@codesourcery.com>, December 2014. */
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+extern "C" {
+ int printf (const char *,...);
+}
+
+int main ()
+{
+ auto f = [] (const char *msg) -> int { printf("%s", msg); return 0; };
+ return f("Some test\n");
+}
@@ -8,5 +8,8 @@ void FOO()
{
NSButton * mCopyAcrobatCB;
- [ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "objective\\-c\\+\\+" } */
+ [ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "expected identifier before ... token" } */
+/* { dg-error "expected \\\'\\\{\\\' before \\\'!=\\\' token" "" { target *-*-* } 11 } */
+/* { dg-error "lambda expressions only available with" "" { target *-*-* } 11 } */
+/* { dg-error "no match for \\\'operator!=\\\' in" "" { target *-*-* } 11 } */
}
Hi, The principle of Objective-c/c++ is that they should be supersets of the parent language. Thus, it is intended that valid c++ (or c) should be parsed by the relevant objective-c/c++ FE. While trying to build some external code, I found that lambdas confuse things at present for objcp. When we find "[" and we're in objcp mode, and the "[" introduces a lambda, we try to parse a message expression and if that fails we punt (thus we are unable to recognise lambdas). The attached patch tries "[" as a message expression introducer, if that fails it drops through to try for a lambda (no change intended for the non-objective-c++ path). I guess it's a bit of a nuisance that the diagnostics from a failed message expression are likely to end up as mentioning a lambda. Perhaps we might decide to punt early if we are both ObjC and < c++11. This allows me to parse some necessary lldb headers with gcc objcp. Thoughts / OK for trunk? (I can raise a formal PR if you like). Iain gcc/cp: * parser.c (cp_parser_primary_expression): If parsing an objective-c++ message expression fails, see if a lambda is present. (cp_parser_objc_message_reciever): Don't assume that if a message reciever expression fails it is a hard error. gcc/testsuite: * obj-c++.dg/lambda-0.mm New file. * obj-c++.dg/lambda-1.mm New file. From e8038ba3cb16095e53d09e23ff15f4682cb5bd0c Mon Sep 17 00:00:00 2001 From: Iain Sandoe <iain@codesourcery.com> Date: Mon, 22 Dec 2014 10:50:45 +0000 Subject: [PATCH] Modify objective-c++ parse to check for lambdas when a message construct isn't matched after a [ --- gcc/cp/parser.c | 21 +++++++++++++++++---- gcc/testsuite/obj-c++.dg/lambda-0.mm | 22 ++++++++++++++++++++++ gcc/testsuite/obj-c++.dg/lambda-1.mm | 13 +++++++++++++ gcc/testsuite/obj-c++.dg/syntax-error-6.mm | 5 ++++- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/obj-c++.dg/lambda-0.mm create mode 100644 gcc/testsuite/obj-c++.dg/lambda-1.mm