From patchwork Fri Jul 19 09:00:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adam Butcher X-Patchwork-Id: 260213 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 171062C0091 for ; Fri, 19 Jul 2013 19:01:44 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=J3CQyKFILNX5yrHbCZzMhGl7BnwhXQyE+icFRmJccYAqdNxKfbarE 2JzQnDICJzT1ZH9EAUbl2S2+rOK5JUjz6cthQyLf6CFPyo23/10OoYGa4HlhNxW0 xaQgtfoc4CtySwjplFooym7jHxMp2Axwx1/BS0QYm0VNRQgnaDcbbM= 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 :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=sJ/3JmXZYX2+dPe3Vqir+e+V5Fc=; b=EruIFyPWZ2/8Q4kvWdYs llYtbPPqpUF1+JS9nKe/qA7G2r8vZ17OvKZYEBPqHGjNn3QkuMOF7irbsGDKDT/F afKpUD9JJOBwsytUL9Vk8bGI5aOnBqSnYOaFGSqmzH3H9+7qfASRc6G6EnTmwNum 2i+y/vSmPnmUdgDYHY9kyvg= Received: (qmail 29848 invoked by alias); 19 Jul 2013 09:01:26 -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 29782 invoked by uid 89); 19 Jul 2013 09:01:26 -0000 X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS autolearn=ham version=3.3.1 Received: from Unknown (HELO mail-we0-f173.google.com) (74.125.82.173) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 19 Jul 2013 09:01:24 +0000 Received: by mail-we0-f173.google.com with SMTP id x54so3755673wes.4 for ; Fri, 19 Jul 2013 02:01:16 -0700 (PDT) X-Received: by 10.194.84.205 with SMTP id b13mr11058868wjz.92.1374224476008; Fri, 19 Jul 2013 02:01:16 -0700 (PDT) Received: from archbang.lan (munkyhouse.force9.co.uk. [84.92.244.81]) by mx.google.com with ESMTPSA id i1sm46950413wiz.6.2013.07.19.02.01.14 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 19 Jul 2013 02:01:15 -0700 (PDT) From: Adam Butcher To: Jason Merrill Cc: gcc-patches@gcc.gnu.org, Andrew Sutton , Adam Butcher Subject: [PATCH 1/3] [lambda] Support template-parameter-list in lambda-declarator. Date: Fri, 19 Jul 2013 10:00:40 +0100 Message-Id: <1374224442-9360-2-git-send-email-adam@jessamine.co.uk> In-Reply-To: <1374224442-9360-1-git-send-email-adam@jessamine.co.uk> References: <51DE19EC.10300@redhat.com> <1374224442-9360-1-git-send-email-adam@jessamine.co.uk> --- gcc/cp/decl2.c | 5 +++-- gcc/cp/lambda.c | 9 ++++++++- gcc/cp/parser.c | 36 ++++++++++++++++++++++++++++++++++-- gcc/cp/pt.c | 4 +++- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1573ced..c166f6e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -507,8 +507,9 @@ check_member_template (tree tmpl) || (TREE_CODE (decl) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)))) { - /* The parser rejects template declarations in local classes. */ - gcc_assert (!current_function_decl); + /* The parser rejects template declarations in local classes + (with the exception of generic lambdas). */ + gcc_assert (!current_function_decl || LAMBDA_FUNCTION_P (decl)); /* The parser rejects any use of virtual in a function template. */ gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index a53e692..98a7925 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -196,7 +196,7 @@ lambda_function (tree lambda) /*protect=*/0, /*want_type=*/false, tf_warning_or_error); if (lambda) - lambda = BASELINK_FUNCTIONS (lambda); + lambda = STRIP_TEMPLATE (get_first_fn (lambda)); return lambda; } @@ -759,6 +759,13 @@ maybe_add_lambda_conv_op (tree type) if (processing_template_decl) return; + if (DECL_TEMPLATE_INFO (callop) && DECL_TEMPLATE_RESULT + (DECL_TI_TEMPLATE (callop)) == callop) + { + warning (0, "Conversion of a generic lambda to a function pointer is not currently implemented."); + return; + } + if (DECL_INITIAL (callop) == NULL_TREE) { /* If the op() wasn't instantiated due to errors, give up. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4b683bf..48c95e6 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8790,6 +8790,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) /* Parse the (optional) middle of a lambda expression. lambda-declarator: + < template-parameter-list [opt] > ( parameter-declaration-clause [opt] ) attribute-specifier [opt] mutable [opt] @@ -8809,10 +8810,32 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) tree param_list = void_list_node; tree attributes = NULL_TREE; tree exception_spec = NULL_TREE; + tree template_param_list = NULL_TREE; tree t; - /* The lambda-declarator is optional, but must begin with an opening - parenthesis if present. */ + /* The template-parameter-list is optional, but must begin with + an opening angle if present. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + { + cp_lexer_consume_token (parser->lexer); + + if (cxx_dialect < cxx1y) + cp_parser_error (parser, + "Generic lambdas are only supported in C++1y mode."); + + push_deferring_access_checks (dk_deferred); + + template_param_list = cp_parser_template_parameter_list (parser); + + cp_parser_skip_to_end_of_template_parameter_list (parser); + + /* We just processed one more parameter list. */ + ++parser->num_template_parameter_lists; + } + + /* The parameter-declaration-clause is optional (unless + template-parameter-list was given), but must begin with an + opening parenthesis if present. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { cp_lexer_consume_token (parser->lexer); @@ -8858,6 +8881,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) leave_scope (); } + else if (template_param_list != NULL_TREE) // generate diagnostic + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Create the function call operator. @@ -8901,6 +8926,13 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) DECL_ARTIFICIAL (fco) = 1; /* Give the object parameter a different name. */ DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure"); + if (template_param_list) + { + pop_deferring_access_checks (); + fco = finish_member_template_decl (fco); + finish_template_decl (template_param_list); + --parser->num_template_parameter_lists; + } } finish_member_declaration (fco); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index de054ac..3694ccc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9028,7 +9028,9 @@ instantiate_class_template_1 (tree type) tree decl = lambda_function (type); if (decl) { - instantiate_decl (decl, false, false); + if (!DECL_TEMPLATE_INFO (decl) || DECL_TEMPLATE_RESULT + (DECL_TI_TEMPLATE (decl)) != decl) + instantiate_decl (decl, false, false); /* We need to instantiate the capture list from the template after we've instantiated the closure members, but before we