diff options
author | Ed Smith-Rowland <3dw4rd@verizon.net> | 2013-04-17 01:05:43 +0000 |
---|---|---|
committer | Edward Smith-Rowland <emsr@gcc.gnu.org> | 2013-04-17 01:05:43 +0000 |
commit | 3a8d9ab15448911199ac24e7e23206e0a7e12696 (patch) | |
tree | d59c0e3121b34946be580a8f99242f2fac75e83f /gcc/cp | |
parent | a0d079a44311217d7727bd45ceaca4d6e5a65c23 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/parser.c | 71 |
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. */ |