aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
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/cp
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/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/parser.c71
2 files changed, 75 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. */