]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Implement n3599 String literal operator templates.
authorEd Smith-Rowland <3dw4rd@verizon.net>
Wed, 17 Apr 2013 01:05:43 +0000 (01:05 +0000)
committerEdward Smith-Rowland <emsr@gcc.gnu.org>
Wed, 17 Apr 2013 01:05:43 +0000 (01:05 +0000)
From-SVN: r198018

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/udlit-char-template-neg.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/udlit-char-template.C [new file with mode: 0644]

index b7df0d56782c8b2914e3ae3ee923ee9981f8fee2..94e29afae07bc34259c3124504c5970064f6152f 100644 (file)
@@ -1,3 +1,12 @@
+2013-04-16  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.
+
 2013-04-15  Jason Merrill  <jason@redhat.com>
 
        * pt.c (tsubst) [DECLTYPE_TYPE]: Use tsubst_copy_and_build.
index 6b5020eefb6045daefcf4838e2cf8ca9b15cc7d5..6560852e470be794a50284ee92ca18038b0fdc15 100644 (file)
@@ -3702,6 +3702,37 @@ make_char_string_pack (tree value)
   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 @@ cp_parser_userdef_string_literal (cp_token *token)
   int len = TREE_STRING_LENGTH (value)
        / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
   tree decl, result;
+  vec<tree, va_gc> *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<tree, va_gc> *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 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
       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 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
                  || !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 <char...>",
+              "  Expected non-type template argument pack <char...>"
+              " or <typename CharT, CharT...>",
               decl);
     }
   /* Register member declarations.  */
index 02cb9473ef6dc44ba5f8a63a70993a20ceec199e..7182088806b7f17d7132608c1a631ee8b66e5c29 100644 (file)
@@ -1,3 +1,9 @@
+2013-04-16  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.
+
 2013-04-16  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/39505
diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-char-template-neg.C b/gcc/testsuite/g++.dg/cpp1y/udlit-char-template-neg.C
new file mode 100644 (file)
index 0000000..71fc973
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-options -std=c++11 }
+
+template<typename CharT, CharT... String>
+  int
+  operator"" _script()
+  { return 42; } // { dg-error "literal operator template|has invalid parameter list" }
+
+int i = "hi!"_script;
diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-char-template.C b/gcc/testsuite/g++.dg/cpp1y/udlit-char-template.C
new file mode 100644 (file)
index 0000000..42d25c0
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-options -std=c++1y }
+
+template<typename CharT, CharT... String>
+  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;