From e8ef82d74f40e216b3a1c9707a79a3bd0b6c953d Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Wed, 31 Dec 2014 13:58:16 +0000 Subject: [PATCH] Allow Objective-c++ to recognise lambdas. 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_receiver): Don't assume that, if a message receiver expression fails, it is a hard error. gcc/testsuite: * obj-c++.dg/lambda-0.mm New. * obj-c++.dg/lambda-1.mm New. * obj-c++.dg/syntax-error-6.mm Adjust for revised error messages. From-SVN: r219125 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/parser.c | 21 +++++++++++++++++---- gcc/testsuite/ChangeLog | 6 ++++++ 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 ++++- 6 files changed, 69 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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bd5dd495595..a6ce50bc685 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-12-31 Iain Sandoe + + * parser.c (cp_parser_primary_expression): If parsing an + objective-c++ message expression fails, see if a lambda is present. + (cp_parser_objc_message_receiver): Don't assume that, if a message + receiver expression fails, it is a hard error. + 2014-12-25 Jason Merrill * pt.c (check_default_tmpl_args): Uses the parameter source diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2af15763ce3..68940aab1c9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4442,10 +4442,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)) @@ -25657,14 +25664,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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6e7a99e01d1..03531d386fc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-12-31 Iain Sandoe + + * obj-c++.dg/lambda-0.mm New. + * obj-c++.dg/lambda-1.mm New. + * obj-c++.dg/syntax-error-6.mm Adjust for revised error messages. + 2014-12-31 Iain Sandoe * obj-c++.dg/standard-headers.mm New. diff --git a/gcc/testsuite/obj-c++.dg/lambda-0.mm b/gcc/testsuite/obj-c++.dg/lambda-0.mm new file mode 100644 index 00000000000..41482fdba88 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/lambda-0.mm @@ -0,0 +1,22 @@ +// Contributed by Iain Sandoe , December 2014. */ +// { dg-do compile } +// { dg-options "-std=c++11" } + + +template +Function thing(Function fn, int a) +{ + fn(a); + return fn; +} + +int +test (int *arr, unsigned n) +{ + int total = 0; + for (unsigned i=0; i, 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"); +} diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-6.mm b/gcc/testsuite/obj-c++.dg/syntax-error-6.mm index 21423ec7eb7..36a444f784d 100644 --- a/gcc/testsuite/obj-c++.dg/syntax-error-6.mm +++ b/gcc/testsuite/obj-c++.dg/syntax-error-6.mm @@ -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 } */ } -- 2.30.2