From patchwork Mon Dec 22 12:50:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 423388 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E43DB1400E2 for ; Mon, 22 Dec 2014 23:51:07 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :content-type:subject:date:message-id:cc:to:mime-version; q=dns; s=default; b=WknrHLoifYDeIjQ+odSderjhftSpniFLKBKSesmVurVTqvpULj ESO01zfWpXpDYJEJg+9xGS1dtCsrM8n4MouTYl+p5xjMbD5C9FQu6zAYqhgfTHSK cYF0kfHPMm9RGjs18xVFpaKNgLI73ugTSvxtTUVjdcceHbudpBnCfXwzk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :content-type:subject:date:message-id:cc:to:mime-version; s= default; bh=aC4dGUfHJRWTgy9vdeyT9APvxEE=; b=Ry2AvXToqsGUrgHs/k6q +NFdNu6Fmb8sB4NrMIFQjEgL97W9zwKKOkw24AE4dcWzsWfyVaCf3yycDoDqG0iM 5EdMz5G/qB//7BgMV99D4s19WR5dUUTLinqhIJPppr5afqMHgMAvDrqtwYZr9+ae icGvxKNZAgmAPDM2JIPJe3k= Received: (qmail 31192 invoked by alias); 22 Dec 2014 12:50:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31180 invoked by uid 89); 22 Dec 2014 12:50:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 22 Dec 2014 12:50:56 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1Y32Rn-0002en-Ki from Iain_Sandoe@mentor.com ; Mon, 22 Dec 2014 04:50:52 -0800 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.3.181.6; Mon, 22 Dec 2014 12:50:49 +0000 From: Iain Sandoe Subject: [PATCH c++/objc++] Make Objective-c++ recognise lambdas. Date: Mon, 22 Dec 2014 12:50:47 +0000 Message-ID: <29BB8A79-F3DA-4FC8-9CDE-9B3151F04B7A@mentor.com> CC: gcc-patches Patches , Mike Stump To: Jason Merrill MIME-Version: 1.0 (Apple Message framework v1283) 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 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 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8ff16ed..1409bef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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. 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 0000000..41482fd --- /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 21423ec..36a444f 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 } */ }