From patchwork Tue Apr 16 20:34:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ed Smith-Rowland <3dw4rd@verizon.net> X-Patchwork-Id: 237082 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 98DA12C0144 for ; Wed, 17 Apr 2013 06:34:20 +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 :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=VVcRpfISBJXEz6KNqy0A5OrJmuzswJa+iRsrHDfaVVjlCb eh4PuQAtjMWXJF1hEmv5QsIU2u5xUJi9JjyKUaR7zW6paY2jveLJ+rkFw7Scmu2c ljLzwl2nErOMoDC1X/TEOLAJgctOrAQps85ozlNaVZnhUOyG8FOHBEn5YCkgY= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=7M8UoPHAJ9z8IH8dZf2UVBuO7Bc=; b=IeLI1UwOv0rsUOg2mQTS zaJdxei2FA9zO+RYDqgd+zZYv+7+z1Fp/dUc5+zxGeE4cxL7bKKHbYacbthg50o5 PWvwewM8tvwpFbEgoF6jLOv4rfcrdVzSMW1GI0Afw2nu2k+Reg+BrTnpEhyuWFna nsGnRTFnLr3KuKP6P0SI0UA= Received: (qmail 1583 invoked by alias); 16 Apr 2013 20:34:13 -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 1574 invoked by uid 89); 16 Apr 2013 20:34:13 -0000 X-Spam-SWARE-Status: No, score=1.8 required=5.0 tests=AWL, BAYES_00, BOTNET, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD, TW_CX, TW_RG, T_MANY_HDRS_LCASE autolearn=no version=3.3.1 Received: from vms173005pub.verizon.net (HELO vms173005pub.verizon.net) (206.46.173.5) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 16 Apr 2013 20:34:11 +0000 Received: from [192.168.1.4] ([unknown] [96.244.50.87]) by vms173005.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0MLD00DPI7SU9A30@vms173005.mailsrvcs.net> for gcc-patches@gcc.gnu.org; Tue, 16 Apr 2013 15:34:08 -0500 (CDT) Message-id: <516DB5C3.2030906@verizon.net> Date: Tue, 16 Apr 2013 16:34:11 -0400 From: Ed Smith-Rowland <3dw4rd@verizon.net> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-version: 1.0 To: gcc-patches , Jason Merrill Subject: [C++1y] Support n3599 - Literal operator templates for strings for C++1y Content-type: multipart/mixed; boundary=------------090008050704090107090108 X-Virus-Found: No Here is a small patch which fixes a derp in the C++11 standard up for repair in c+14 or so. It allows you to have things like template constexpr int operator"" _crypto() {...} ... int i = "hi there!"_crypto; And many other things. The string literal operator template can examine the string at compile time. This is enabled with -std=c++1y. Testing slight tweaks now. gcc/cp: 2013-04-17 Ed Smith-Rowland <3dw4rd@verizon.net> Implement n3599 - Literal operator templates for strings. * parser.c (make_string_pack (tree value)): New function. (cp_parser_userdef_string_literal (cp_token *)): Use it to construct calls to character string literal operator templates. (cp_parser_template_declaration_after_export): Check for new string literal operator template parameter form. gcc/testsuite: 2013-04-17 Ed Smith-Rowland <3dw4rd@verizon.net> Implement n3599 - Literal operator templates for strings. * g++.dg/cpp1y/udlit-char-template.C: New test. * g++.dg/cpp1y/udlit-char-template-neg.C: New test. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 197945) +++ cp/parser.c (working copy) @@ -3702,6 +3702,37 @@ return argvec; } +/* A subroutine of cp_parser_userdef_numeric_literal to + create a char... template parameter pack from a string node. */ + +static tree +make_string_pack (tree value) +{ + tree charvec; + tree argpack = make_node (NONTYPE_ARGUMENT_PACK); + const char *str = TREE_STRING_POINTER (value); + int i, len = TREE_STRING_LENGTH (value) - 1; + tree argvec = make_tree_vec (2); + + tree string_char_type_node = TREE_TYPE (TREE_TYPE (value)); + + /* First template parm is character type. */ + TREE_VEC_ELT (argvec, 0) = string_char_type_node; + + /* Fill in CHARVEC with all of the parameters. */ + charvec = make_tree_vec (len); + for (i = 0; i < len; ++i) + TREE_VEC_ELT (charvec, i) = build_int_cst (string_char_type_node, str[i]); + + /* Build the argument packs. */ + SET_ARGUMENT_PACK_ARGS (argpack, charvec); + TREE_TYPE (argpack) = string_char_type_node; + + TREE_VEC_ELT (argvec, 1) = argpack; + + return argvec; +} + /* Parse a user-defined numeric constant. returns a call to a user-defined literal operator. */ @@ -3801,10 +3832,29 @@ int len = TREE_STRING_LENGTH (value) / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1; tree decl, result; + vec *args; + /* Look for a template function with typename parameter CharT + and parameter pack CharT... Call the function with + template parameter characters representing the string. */ + args = make_tree_vector (); + decl = lookup_literal_operator (name, args); + if (decl && decl != error_mark_node) + { + tree tmpl_args = make_string_pack (value); + decl = lookup_template_function (decl, tmpl_args); + result = finish_call_expr (decl, &args, false, true, tf_none); + if (result != error_mark_node) + { + release_tree_vector (args); + return result; + } + } + release_tree_vector (args); + /* Build up a call to the user-defined operator */ /* Lookup the name we got back from the id-expression. */ - vec *args = make_tree_vector (); + args = make_tree_vector (); vec_safe_push (args, value); vec_safe_push (args, build_int_cst (size_type_node, len)); decl = lookup_name (name); @@ -22101,9 +22151,7 @@ else { int num_parms = TREE_VEC_LENGTH (parameter_list); - if (num_parms != 1) - ok = false; - else + if (num_parms == 1) { tree parm_list = TREE_VEC_ELT (parameter_list, 0); tree parm = INNERMOST_TEMPLATE_PARMS (parm_list); @@ -22111,10 +22159,23 @@ || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))) ok = false; } + else if (num_parms == 2 && cxx_dialect >= cxx1y) + { + tree parm_type = TREE_VEC_ELT (parameter_list, 0); + tree type = INNERMOST_TEMPLATE_PARMS (parm_type); + tree parm_list = TREE_VEC_ELT (parameter_list, 1); + tree parm = INNERMOST_TEMPLATE_PARMS (parm_list); + if (TREE_TYPE (parm) != TREE_TYPE (type) + || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))) + ok = false; + } + else + ok = false; } if (!ok) error ("literal operator template %qD has invalid parameter list." - " Expected non-type template argument pack ", + " Expected non-type template argument pack " + " or ", decl); } /* Register member declarations. */ Index: testsuite/g++.dg/cpp1y/udlit-char-template.C =================================================================== --- testsuite/g++.dg/cpp1y/udlit-char-template.C (revision 0) +++ testsuite/g++.dg/cpp1y/udlit-char-template.C (revision 0) @@ -0,0 +1,12 @@ +// { dg-options -std=c++1y } + +template + int + operator"" _script() + { return 42; } + +int i = "hi!"_script; +int i8 = u8"hi!"_script; +int iw = L"hi!"_script; +int i16 = u"hi!"_script; +int i32 = U"hi!"_script; Index: testsuite/g++.dg/cpp1y/udlit-char-template-neg.C =================================================================== --- testsuite/g++.dg/cpp1y/udlit-char-template-neg.C (revision 0) +++ testsuite/g++.dg/cpp1y/udlit-char-template-neg.C (revision 0) @@ -0,0 +1,8 @@ +// { dg-options -std=c++11 } + +template + int + operator"" _script() + { return 42; } // { dg-error "literal operator template|has invalid parameter list" } + +int i = "hi!"_script;