aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Smith-Rowland <3dw4rd@verizon.net>2013-04-17 01:05:43 +0000
committerEdward Smith-Rowland <emsr@gcc.gnu.org>2013-04-17 01:05:43 +0000
commit3a8d9ab15448911199ac24e7e23206e0a7e12696 (patch)
treed59c0e3121b34946be580a8f99242f2fac75e83f /gcc
parenta0d079a44311217d7727bd45ceaca4d6e5a65c23 (diff)
downloadgcc-3a8d9ab15448911199ac24e7e23206e0a7e12696.zip
gcc-3a8d9ab15448911199ac24e7e23206e0a7e12696.tar.gz
gcc-3a8d9ab15448911199ac24e7e23206e0a7e12696.tar.bz2
Implement n3599 String literal operator templates.
From-SVN: r198018
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/parser.c71
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/udlit-char-template-neg.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/udlit-char-template.C12
5 files changed, 101 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b7df0d5..94e29af 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6b5020e..6560852 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 02cb947..7182088 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..71fc973
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/udlit-char-template-neg.C
@@ -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
index 0000000..42d25c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/udlit-char-template.C
@@ -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;