X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=47f3c0de05b2cc1aa09e7ba23f47ba7d6680225d;hb=08cc44e74d28ab49958b246b6d1f3ee827c21d24;hp=f7bc7ce59a5cc04b380b7024c950c22241d9d01d;hpb=475963b02ecf4e138f7ef03d7ad321de3f40c6af;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f7bc7ce59a5..c609bd0cc3a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,6 +1,6 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -8,7 +8,7 @@ This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -17,9 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ /* Known bugs or deficiencies include: @@ -53,12 +52,14 @@ typedef int (*tree_fn_t) (tree, void*); /* The PENDING_TEMPLATES is a TREE_LIST of templates whose instantiations have been deferred, either because their definitions - were not yet available, or because we were putting off doing the work. - The TREE_PURPOSE of each entry is either a DECL (for a function or - static data member), or a TYPE (for a class) indicating what we are - hoping to instantiate. The TREE_VALUE is not used. */ -static GTY(()) tree pending_templates; -static GTY(()) tree last_pending_template; + were not yet available, or because we were putting off doing the work. */ +struct pending_template GTY (()) { + struct pending_template *next; + struct tinst_level *tinst; +}; + +static GTY(()) struct pending_template *pending_templates; +static GTY(()) struct pending_template *last_pending_template; int processing_template_parmlist; static int template_header_count; @@ -66,7 +67,7 @@ static int template_header_count; static GTY(()) tree saved_trees; static VEC(int,heap) *inline_parm_levels; -static GTY(()) tree current_tinst_level; +static GTY(()) struct tinst_level *current_tinst_level; static GTY(()) tree saved_access_scope; @@ -80,6 +81,12 @@ static tree cur_stmt_expr; local variables. */ static htab_t local_specializations; +/* Contains canonical template parameter types. The vector is indexed by + the TEMPLATE_TYPE_IDX of the template parameter. Each element is a + TREE_LIST, whose TREE_VALUEs contain the canonical template + parameters of various types and levels. */ +static GTY(()) VEC(tree,gc) *canonical_template_parms; + #define UNIFY_ALLOW_NONE 0 #define UNIFY_ALLOW_MORE_CV_QUAL 1 #define UNIFY_ALLOW_LESS_CV_QUAL 2 @@ -91,17 +98,15 @@ static htab_t local_specializations; static void push_access_scope (tree); static void pop_access_scope (tree); -static int resolve_overloaded_unification (tree, tree, tree, tree, - unification_kind_t, int); +static bool resolve_overloaded_unification (tree, tree, tree, tree, + unification_kind_t, int); static int try_one_overload (tree, tree, tree, tree, tree, unification_kind_t, int, bool); static int unify (tree, tree, tree, tree, int); static void add_pending_template (tree); static int push_tinst_level (tree); static void pop_tinst_level (void); -static void reopen_tinst_level (tree); -static tree classtype_mangled_name (tree); -static char* mangle_class_name_for_template (const char *, tree, tree); +static tree reopen_tinst_level (struct tinst_level *); static tree tsubst_initializer_list (tree, tree); static tree get_class_bindings (tree, tree, tree); static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, @@ -110,7 +115,8 @@ static void tsubst_enum (tree, tree, tree); static tree add_to_template_args (tree, tree); static tree add_outermost_template_args (tree, tree); static bool check_instantiated_args (tree, tree, tsubst_flags_t); -static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*); +static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*, + tree); static int type_unification_real (tree, tree, tree, tree, int, unification_kind_t, int); static void note_template_header (int); @@ -119,13 +125,14 @@ static tree convert_nontype_argument (tree, tree); static tree convert_template_argument (tree, tree, tree, tsubst_flags_t, int, tree); static int for_each_template_parm (tree, tree_fn_t, void*, - struct pointer_set_t*); + struct pointer_set_t*, bool); +static tree expand_template_argument_pack (tree); static tree build_template_parm_index (int, int, int, tree, tree); -static int inline_needs_template_parms (tree); +static bool inline_needs_template_parms (tree); static void push_inline_template_parms_recursive (tree, int); static tree retrieve_local_specialization (tree); static void register_local_specialization (tree, tree); -static tree reduce_template_parm_level (tree, tree, int); +static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t); static int mark_template_parm (tree, void *); static int template_parm_this_level_p (tree, void *); static tree tsubst_friend_function (tree, tree); @@ -134,6 +141,8 @@ static int can_complete_type_without_circularity (tree); static tree get_bindings (tree, tree, tree, bool); static int template_decl_level (tree); static int check_cv_quals_for_unify (int, tree, tree); +static void template_parm_level_and_index (tree, int*, int*); +static int unify_pack_expansion (tree, tree, tree, tree, int, bool, bool); static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); @@ -142,14 +151,14 @@ static tree most_specialized_class (tree, tree); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); -static void check_specialization_scope (void); +static bool check_specialization_scope (void); static tree process_partial_specialization (tree); static void set_current_access_from_decl (tree); -static void check_default_tmpl_args (tree, tree, int, int); static tree get_template_base (tree, tree, tree, tree); static tree try_class_unification (tree, tree, tree, tree); static int coerce_template_template_parms (tree, tree, tsubst_flags_t, tree, tree); +static bool template_template_parm_bindings_ok_p (tree, tree); static int template_args_equal (tree, tree); static void tsubst_default_arguments (tree); static tree for_each_template_parm_r (tree *, int *, void *); @@ -157,10 +166,13 @@ static tree copy_default_args_to_explicit_spec_1 (tree, tree); static void copy_default_args_to_explicit_spec (tree); static int invalid_nontype_parm_type_p (tree, tsubst_flags_t); static int eq_local_specializations (const void *, const void *); +static bool dependent_template_arg_p (tree); +static bool any_template_arguments_need_structural_equality_p (tree); static bool dependent_type_p_r (tree); static tree tsubst (tree, tree, tsubst_flags_t, tree); -static tree tsubst_expr (tree, tree, tsubst_flags_t, tree); +static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); +static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -224,7 +236,9 @@ finish_member_template_decl (tree decl) tree type; type = TREE_TYPE (decl); - if (IS_AGGR_TYPE (type) + if (type == error_mark_node) + return error_mark_node; + if (MAYBE_CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) { @@ -252,6 +266,25 @@ finish_member_template_decl (tree decl) return error_mark_node; } +/* Return the template info node corresponding to T, whatever T is. */ + +tree +get_template_info (tree t) +{ + tree tinfo = NULL_TREE; + + if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) + tinfo = DECL_TEMPLATE_INFO (t); + + if (!tinfo && TREE_CODE (t) == TYPE_DECL) + t = TREE_TYPE (t); + + if (TAGGED_TYPE_P (t)) + tinfo = TYPE_TEMPLATE_INFO (t); + + return tinfo; +} + /* Returns the template nesting level of the indicated class TYPE. For example, in: @@ -280,33 +313,24 @@ template_class_depth (tree type) type = (TREE_CODE (type) == FUNCTION_DECL) ? CP_DECL_CONTEXT (type) : TYPE_CONTEXT (type)) { - if (TREE_CODE (type) != FUNCTION_DECL) - { - if (CLASSTYPE_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) - && uses_template_parms (CLASSTYPE_TI_ARGS (type))) - ++depth; - } - else - { - if (DECL_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) - && uses_template_parms (DECL_TI_ARGS (type))) - ++depth; - } + tree tinfo = get_template_info (type); + + if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) + && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)))) + ++depth; } return depth; } -/* Returns 1 if processing DECL as part of do_pending_inlines - needs us to push template parms. */ +/* Subroutine of maybe_begin_member_template_processing. + Returns true if processing DECL needs us to push template parms. */ -static int +static bool inline_needs_template_parms (tree decl) { if (! DECL_TEMPLATE_INFO (decl)) - return 0; + return false; return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl))) > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl))); @@ -337,6 +361,10 @@ push_inline_template_parms_recursive (tree parmlist, int levels) for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + + if (parm == error_mark_node) + continue; + gcc_assert (DECL_P (parm)); switch (TREE_CODE (parm)) @@ -356,7 +384,6 @@ push_inline_template_parms_recursive (tree parmlist, int levels) TREE_TYPE (parm)); DECL_ARTIFICIAL (decl) = 1; TREE_CONSTANT (decl) = 1; - TREE_INVARIANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (decl) = DECL_INITIAL (parm); SET_DECL_TEMPLATE_PARM_P (decl); @@ -504,6 +531,37 @@ get_innermost_template_args (tree args, int n) return new_args; } +/* The inverse of get_innermost_template_args: Return all but the innermost + EXTRA_LEVELS levels of template arguments from the ARGS. */ + +static tree +strip_innermost_template_args (tree args, int extra_levels) +{ + tree new_args; + int n = TMPL_ARGS_DEPTH (args) - extra_levels; + int i; + + gcc_assert (n >= 0); + + /* If N is 1, just return the outermost set of template arguments. */ + if (n == 1) + return TMPL_ARGS_LEVEL (args, 1); + + /* If we're not removing anything, just return the arguments we were + given. */ + gcc_assert (extra_levels >= 0); + if (extra_levels == 0) + return args; + + /* Make a new set of arguments, not containing the inner arguments. */ + new_args = make_tree_vec (n); + for (i = 1; i <= n; ++i) + SET_TMPL_ARGS_LEVEL (new_args, i, + TMPL_ARGS_LEVEL (args, i)); + + return new_args; +} + /* We've got a template header coming up; push to a new level for storing the parms. */ @@ -531,9 +589,10 @@ begin_template_parm_list (void) } /* This routine is called when a specialization is declared. If it is - invalid to declare a specialization here, an error is reported. */ + invalid to declare a specialization here, an error is reported and + false is returned, otherwise this routine will return true. */ -static void +static bool check_specialization_scope (void) { tree scope = current_scope (); @@ -548,7 +607,10 @@ check_specialization_scope (void) shall be declared in the namespace of which the class template is a member. */ if (scope && TREE_CODE (scope) != NAMESPACE_DECL) - error ("explicit specialization in non-namespace scope %qD", scope); + { + error ("explicit specialization in non-namespace scope %qD", scope); + return false; + } /* [temp.expl.spec] @@ -559,17 +621,22 @@ check_specialization_scope (void) explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. */ if (current_template_parms) - error ("enclosing class templates are not explicitly specialized"); + { + error ("enclosing class templates are not explicitly specialized"); + return false; + } + + return true; } /* We've just seen template <>. */ -void +bool begin_specialization (void) { begin_scope (sk_template_spec, NULL); note_template_header (1); - check_specialization_scope (); + return check_specialization_scope (); } /* Called at then end of processing a declaration preceded by @@ -643,8 +710,8 @@ check_specialization_namespace (tree tmpl) return true; else { - pedwarn ("specialization of %qD in different namespace", tmpl); - pedwarn (" from definition of %q+#D", tmpl); + permerror ("specialization of %qD in different namespace", tmpl); + permerror (" from definition of %q+#D", tmpl); return false; } } @@ -661,21 +728,28 @@ check_explicit_instantiation_namespace (tree spec) namespace of its template. */ ns = decl_namespace_context (spec); if (!is_ancestor (current_namespace, ns)) - pedwarn ("explicit instantiation of %qD in namespace %qD " - "(which does not enclose namespace %qD)", - spec, current_namespace, ns); + permerror ("explicit instantiation of %qD in namespace %qD " + "(which does not enclose namespace %qD)", + spec, current_namespace, ns); } /* The TYPE is being declared. If it is a template type, that means it is a partial specialization. Do appropriate error-checking. */ -void +tree maybe_process_partial_specialization (tree type) { tree context; if (type == error_mark_node) - return; + return error_mark_node; + + if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + { + error ("name of class shadows template template parameter %qD", + TYPE_NAME (type)); + return error_mark_node; + } context = TYPE_CONTEXT (type); @@ -698,7 +772,11 @@ maybe_process_partial_specialization (tree type) check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type)); SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL (type)); + { + if (push_template_decl (TYPE_MAIN_DECL (type)) + == error_mark_node) + return error_mark_node; + } } else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) error ("specialization of %qT after instantiation", type); @@ -733,9 +811,9 @@ maybe_process_partial_specialization (tree type) if (current_namespace != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) { - pedwarn ("specializing %q#T in different namespace", type); - pedwarn (" from definition of %q+#D", - CLASSTYPE_TI_TEMPLATE (type)); + permerror ("specializing %q#T in different namespace", type); + permerror (" from definition of %q+#D", + CLASSTYPE_TI_TEMPLATE (type)); } /* Check for invalid specialization after instantiation: @@ -760,7 +838,12 @@ maybe_process_partial_specialization (tree type) } } else if (processing_specialization) - error ("explicit specialization of non-template %qT", type); + { + error ("explicit specialization of non-template %qT", type); + return error_mark_node; + } + + return type; } /* Returns nonzero if we can optimize the retrieval of specializations @@ -811,6 +894,9 @@ static tree retrieve_specialization (tree tmpl, tree args, bool class_specializations_p) { + if (args == error_mark_node) + return NULL_TREE; + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); /* There should be as many levels of arguments as there are @@ -860,7 +946,8 @@ retrieve_specialization (tree tmpl, tree args, DECL_TEMPLATE_INSTANTIATIONS list; other templates use the DECL_TEMPLATE_SPECIALIZATIONS list. */ if (!class_specializations_p - && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL) + && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL + && TAGGED_TYPE_P (TREE_TYPE (tmpl))) sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl); else sp = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); @@ -894,8 +981,13 @@ retrieve_specialization (tree tmpl, tree args, static tree retrieve_local_specialization (tree tmpl) { - tree spec = (tree) htab_find_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl)); + tree spec; + + if (local_specializations == NULL) + return NULL_TREE; + + spec = (tree) htab_find_with_hash (local_specializations, tmpl, + htab_hash_pointer (tmpl)); return spec ? TREE_PURPOSE (spec) : NULL_TREE; } @@ -930,10 +1022,10 @@ is_specialization_of (tree decl, tree tmpl) } /* Returns nonzero iff DECL is a specialization of friend declaration - FRIEND according to [temp.friend]. */ + FRIEND_DECL according to [temp.friend]. */ bool -is_specialization_of_friend (tree decl, tree friend) +is_specialization_of_friend (tree decl, tree friend_decl) { bool need_template = true; int template_depth; @@ -941,26 +1033,26 @@ is_specialization_of_friend (tree decl, tree friend) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == TYPE_DECL); - /* For [temp.friend/6] when FRIEND is an ordinary member function + /* For [temp.friend/6] when FRIEND_DECL is an ordinary member function of a template class, we want to check if DECL is a specialization if this. */ - if (TREE_CODE (friend) == FUNCTION_DECL - && DECL_TEMPLATE_INFO (friend) - && !DECL_USE_TEMPLATE (friend)) + if (TREE_CODE (friend_decl) == FUNCTION_DECL + && DECL_TEMPLATE_INFO (friend_decl) + && !DECL_USE_TEMPLATE (friend_decl)) { /* We want a TEMPLATE_DECL for `is_specialization_of'. */ - friend = DECL_TI_TEMPLATE (friend); + friend_decl = DECL_TI_TEMPLATE (friend_decl); need_template = false; } - else if (TREE_CODE (friend) == TEMPLATE_DECL - && !PRIMARY_TEMPLATE_P (friend)) + else if (TREE_CODE (friend_decl) == TEMPLATE_DECL + && !PRIMARY_TEMPLATE_P (friend_decl)) need_template = false; /* There is nothing to do if this is not a template friend. */ - if (TREE_CODE (friend) != TEMPLATE_DECL) + if (TREE_CODE (friend_decl) != TEMPLATE_DECL) return false; - if (is_specialization_of (decl, friend)) + if (is_specialization_of (decl, friend_decl)) return true; /* [temp.friend/6] @@ -983,14 +1075,14 @@ is_specialization_of_friend (tree decl, tree friend) nonzero. To determine if DECL is a friend of FRIEND, we first check if the enclosing class is a specialization of another. */ - template_depth = template_class_depth (DECL_CONTEXT (friend)); + template_depth = template_class_depth (DECL_CONTEXT (friend_decl)); if (template_depth && DECL_CLASS_SCOPE_P (decl) && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)), - CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend)))) + CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend_decl)))) { /* Next, we check the members themselves. In order to handle - a few tricky cases, such as when FRIEND's are + a few tricky cases, such as when FRIEND_DECL's are template friend void A::g(T t); template template friend void A::h(); @@ -1030,7 +1122,7 @@ is_specialization_of_friend (tree decl, tree friend) tree friend_args_type; tree decl_args_type; - /* Make sure that both DECL and FRIEND are templates or + /* Make sure that both DECL and FRIEND_DECL are templates or non-templates. */ is_template = DECL_TEMPLATE_INFO (decl) && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)); @@ -1040,7 +1132,7 @@ is_specialization_of_friend (tree decl, tree friend) { /* If both are templates, check template parameter list. */ tree friend_parms - = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend), + = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl), args, tf_none); if (!comp_template_parms (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)), @@ -1052,7 +1144,7 @@ is_specialization_of_friend (tree decl, tree friend) else decl_type = TREE_TYPE (decl); - friend_type = tsubst_function_type (TREE_TYPE (friend), args, + friend_type = tsubst_function_type (TREE_TYPE (friend_decl), args, tf_none, NULL_TREE); if (friend_type == error_mark_node) return false; @@ -1065,7 +1157,7 @@ is_specialization_of_friend (tree decl, tree friend) `this' parameter. */ friend_args_type = TYPE_ARG_TYPES (friend_type); decl_args_type = TYPE_ARG_TYPES (decl_type); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend)) + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend_decl)) friend_args_type = TREE_CHAIN (friend_args_type); if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) decl_args_type = TREE_CHAIN (decl_args_type); @@ -1078,7 +1170,7 @@ is_specialization_of_friend (tree decl, tree friend) bool is_template; tree decl_type = TREE_TYPE (decl); - /* Make sure that both DECL and FRIEND are templates or + /* Make sure that both DECL and FRIEND_DECL are templates or non-templates. */ is_template = CLASSTYPE_TEMPLATE_INFO (decl_type) @@ -1092,12 +1184,12 @@ is_specialization_of_friend (tree decl, tree friend) /* If both are templates, check the name of the two TEMPLATE_DECL's first because is_friend didn't. */ if (DECL_NAME (CLASSTYPE_TI_TEMPLATE (decl_type)) - != DECL_NAME (friend)) + != DECL_NAME (friend_decl)) return false; /* Now check template parameter list. */ friend_parms - = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend), + = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl), args, tf_none); return comp_template_parms (DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (decl_type)), @@ -1105,7 +1197,7 @@ is_specialization_of_friend (tree decl, tree friend) } else return (DECL_NAME (decl) - == DECL_NAME (friend)); + == DECL_NAME (friend_decl)); } } return false; @@ -1156,7 +1248,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) { error ("specialization of %qD after instantiation", fn); - return spec; + return error_mark_node; } else { @@ -1224,7 +1316,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) template it is specializing. */ if (DECL_TEMPLATE_SPECIALIZATION (spec) && !check_specialization_namespace (tmpl)) - DECL_CONTEXT (spec) = decl_namespace_context (tmpl); + DECL_CONTEXT (spec) = FROB_CONTEXT (decl_namespace_context (tmpl)); if (!optimize_specialization_lookup_p (tmpl)) DECL_TEMPLATE_SPECIALIZATIONS (tmpl) @@ -1264,7 +1356,7 @@ reregister_specialization (tree spec, tree tmpl, tree new_spec) static int eq_local_specializations (const void *p1, const void *p2) { - return TREE_VALUE ((tree) p1) == (tree) p2; + return TREE_VALUE ((const_tree) p1) == (const_tree) p2; } /* Hash P1, an entry in the local specializations table. */ @@ -1272,7 +1364,7 @@ eq_local_specializations (const void *p1, const void *p2) static hashval_t hash_local_specialization (const void* p1) { - return htab_hash_pointer (TREE_VALUE ((tree) p1)); + return htab_hash_pointer (TREE_VALUE ((const_tree) p1)); } /* Like register_specialization, but for local declarations. We are @@ -1288,6 +1380,17 @@ register_local_specialization (tree spec, tree tmpl) *slot = build_tree_list (spec, tmpl); } +/* TYPE is a class type. Returns true if TYPE is an explicitly + specialized class. */ + +bool +explicit_class_specialization_p (tree type) +{ + if (!CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) + return false; + return !uses_template_parms (CLASSTYPE_TI_ARGS (type)); +} + /* Print the list of candidate FNS in an error message. */ void @@ -1354,7 +1457,7 @@ determine_specialization (tree template_id, *targs_out = NULL_TREE; - if (template_id == error_mark_node) + if (template_id == error_mark_node || decl == error_mark_node) return error_mark_node; fns = TREE_OPERAND (template_id, 0); @@ -1390,33 +1493,6 @@ determine_specialization (tree template_id, tree decl_arg_types; tree fn_arg_types; - /* DECL might be a specialization of FN. */ - - /* Adjust the type of DECL in case FN is a static member. */ - decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - if (DECL_STATIC_FUNCTION_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) - decl_arg_types = TREE_CHAIN (decl_arg_types); - - /* Check that the number of function parameters matches. - For example, - template void f(int i = 0); - template <> void f(); - The specialization f is invalid but is not caught - by get_bindings below. */ - - fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); - if (list_length (fn_arg_types) != list_length (decl_arg_types)) - continue; - - /* For a non-static member function, we need to make sure that - the const qualification is the same. This can be done by - checking the 'this' in the argument list. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) - && !same_type_p (TREE_VALUE (fn_arg_types), - TREE_VALUE (decl_arg_types))) - continue; - /* In case of explicit specialization, we need to check if the number of template headers appearing in the specialization is correct. This is usually done in check_explicit_specialization, @@ -1455,14 +1531,44 @@ determine_specialization (tree template_id, (current_template_parms)))) continue; + /* DECL might be a specialization of FN. */ + decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); + fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); + + /* For a non-static member function, we need to make sure + that the const qualification is the same. Since + get_bindings does not try to merge the "this" parameter, + we must do the comparison explicitly. */ + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && !same_type_p (TREE_VALUE (fn_arg_types), + TREE_VALUE (decl_arg_types))) + continue; + + /* Skip the "this" parameter and, for constructors of + classes with virtual bases, the VTT parameter. A + full specialization of a constructor will have a VTT + parameter, but a template never will. */ + decl_arg_types + = skip_artificial_parms_for (decl, decl_arg_types); + fn_arg_types + = skip_artificial_parms_for (fn, fn_arg_types); + + /* Check that the number of function parameters matches. + For example, + template void f(int i = 0); + template <> void f(); + The specialization f is invalid but is not caught + by get_bindings below. */ + if (list_length (fn_arg_types) != list_length (decl_arg_types)) + continue; + /* Function templates cannot be specializations; there are no partial specializations of functions. Therefore, if the type of DECL does not match FN, there is no match. */ if (tsk == tsk_template) { - if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), - decl_arg_types)) + if (compparms (fn_arg_types, decl_arg_types)) candidates = tree_cons (NULL_TREE, fn, candidates); continue; } @@ -1562,7 +1668,7 @@ determine_specialization (tree template_id, This extension can only serve to make invalid programs valid, so it's safe. And, there is strong anecdotal evidence that the committee intended the partial ordering rules to apply; - the EDG front-end has that behavior, and John Spicer claims + the EDG front end has that behavior, and John Spicer claims that the committee simply forgot to delete the wording in [temp.expl.spec]. */ tree tmpl = most_specialized_instantiation (templates); @@ -1900,7 +2006,7 @@ check_explicit_specialization (tree declarator, for (; t; t = TREE_CHAIN (t)) if (TREE_PURPOSE (t)) { - pedwarn + permerror ("default argument specified in explicit specialization"); break; } @@ -1929,7 +2035,7 @@ check_explicit_specialization (tree declarator, context. */ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, false, true); - if (!fns || !is_overloaded_fn (fns)) + if (fns == error_mark_node || !is_overloaded_fn (fns)) { error ("%qD is not a template function", dname); fns = error_mark_node; @@ -1990,7 +2096,7 @@ check_explicit_specialization (tree declarator, { int is_constructor = DECL_CONSTRUCTOR_P (decl); - if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype) + if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype) : !CLASSTYPE_DESTRUCTORS (ctype)) { /* From [temp.expl.spec]: @@ -2140,13 +2246,43 @@ check_explicit_specialization (tree declarator, template it specializes. */ TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl); TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl); - /* The specialization has the same visibility as the - template it specializes. */ - if (DECL_VISIBILITY_SPECIFIED (gen_tmpl)) - { - DECL_VISIBILITY_SPECIFIED (decl) = 1; - DECL_VISIBILITY (decl) = DECL_VISIBILITY (gen_tmpl); - } + + /* 7.1.1-1 [dcl.stc] + + A storage-class-specifier shall not be specified in an + explicit specialization... + + The parser rejects these, so unless action is taken here, + explicit function specializations will always appear with + global linkage. + + The action recommended by the C++ CWG in response to C++ + defect report 605 is to make the storage class and linkage + of the explicit specialization match the templated function: + + http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#605 + */ + if (tsk == tsk_expl_spec && DECL_FUNCTION_TEMPLATE_P (gen_tmpl)) + { + tree tmpl_func = DECL_TEMPLATE_RESULT (gen_tmpl); + gcc_assert (TREE_CODE (tmpl_func) == FUNCTION_DECL); + + /* This specialization has the same linkage and visibility as + the function template it specializes. */ + TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func); + if (! TREE_PUBLIC (decl)) + { + DECL_INTERFACE_KNOWN (decl) = 1; + DECL_NOT_REALLY_EXTERN (decl) = 1; + } + DECL_THIS_STATIC (decl) = DECL_THIS_STATIC (tmpl_func); + if (DECL_VISIBILITY_SPECIFIED (tmpl_func)) + { + DECL_VISIBILITY_SPECIFIED (decl) = 1; + DECL_VISIBILITY (decl) = DECL_VISIBILITY (tmpl_func); + } + } + /* If DECL is a friend declaration, declared using an unqualified name, the namespace associated with DECL may have been set incorrectly. For example, in: @@ -2186,10 +2322,10 @@ check_explicit_specialization (tree declarator, DECL_TEMPLATE_PARMS. */ int -comp_template_parms (tree parms1, tree parms2) +comp_template_parms (const_tree parms1, const_tree parms2) { - tree p1; - tree p2; + const_tree p1; + const_tree p2; if (parms1 == parms2) return 1; @@ -2210,13 +2346,20 @@ comp_template_parms (tree parms1, tree parms2) for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) { - tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); - tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); + tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); + tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); + + /* If either of the template parameters are invalid, assume + they match for the sake of error recovery. */ + if (parm1 == error_mark_node || parm2 == error_mark_node) + return 1; if (TREE_CODE (parm1) != TREE_CODE (parm2)) return 0; - if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM) + if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM + && (TEMPLATE_TYPE_PARAMETER_PACK (parm1) + == TEMPLATE_TYPE_PARAMETER_PACK (parm2))) continue; else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2))) return 0; @@ -2231,131 +2374,609 @@ comp_template_parms (tree parms1, tree parms2) return 1; } -/* Complain if DECL shadows a template parameter. - - [temp.local]: A template-parameter shall not be redeclared within its - scope (including nested scopes). */ - -void -check_template_shadow (tree decl) +/* Determine whether PARM is a parameter pack. */ +bool +template_parameter_pack_p (const_tree parm) { - tree olddecl; + /* Determine if we have a non-type template parameter pack. */ + if (TREE_CODE (parm) == PARM_DECL) + return (DECL_TEMPLATE_PARM_P (parm) + && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))); + + /* If this is a list of template parameters, we could get a + TYPE_DECL or a TEMPLATE_DECL. */ + if (TREE_CODE (parm) == TYPE_DECL || TREE_CODE (parm) == TEMPLATE_DECL) + parm = TREE_TYPE (parm); + + return ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM + || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM) + && TEMPLATE_TYPE_PARAMETER_PACK (parm)); +} - /* If we're not in a template, we can't possibly shadow a template - parameter. */ - if (!current_template_parms) - return; +/* Determine whether ARGS describes a variadic template args list, + i.e., one that is terminated by a template argument pack. */ +static bool +template_args_variadic_p (tree args) +{ + int nargs; + tree last_parm; - /* Figure out what we're shadowing. */ - if (TREE_CODE (decl) == OVERLOAD) - decl = OVL_CURRENT (decl); - olddecl = innermost_non_namespace_value (DECL_NAME (decl)); + if (args == NULL_TREE) + return false; - /* If there's no previous binding for this name, we're not shadowing - anything, let alone a template parameter. */ - if (!olddecl) - return; + args = INNERMOST_TEMPLATE_ARGS (args); + nargs = TREE_VEC_LENGTH (args); - /* If we're not shadowing a template parameter, we're done. Note - that OLDDECL might be an OVERLOAD (or perhaps even an - ERROR_MARK), so we can't just blithely assume it to be a _DECL - node. */ - if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl)) - return; + if (nargs == 0) + return false; - /* We check for decl != olddecl to avoid bogus errors for using a - name inside a class. We check TPFI to avoid duplicate errors for - inline member templates. */ - if (decl == olddecl - || TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) - return; + last_parm = TREE_VEC_ELT (args, nargs - 1); - error ("declaration of %q+#D", decl); - error (" shadows template parm %q+#D", olddecl); + return ARGUMENT_PACK_P (last_parm); } -/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, - ORIG_LEVEL, DECL, and TYPE. */ - +/* Generate a new name for the parameter pack name NAME (an + IDENTIFIER_NODE) that incorporates its */ static tree -build_template_parm_index (int index, - int level, - int orig_level, - tree decl, - tree type) +make_ith_pack_parameter_name (tree name, int i) { - tree t = make_node (TEMPLATE_PARM_INDEX); - TEMPLATE_PARM_IDX (t) = index; - TEMPLATE_PARM_LEVEL (t) = level; - TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level; - TEMPLATE_PARM_DECL (t) = decl; - TREE_TYPE (t) = type; - TREE_CONSTANT (t) = TREE_CONSTANT (decl); - TREE_INVARIANT (t) = TREE_INVARIANT (decl); - TREE_READONLY (t) = TREE_READONLY (decl); - - return t; + /* Munge the name to include the parameter index. */ + char numbuf[128]; + char* newname; + + sprintf(numbuf, "%i", i); + newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2); + sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i); + return get_identifier (newname); } -/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose - TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a - TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a - new one is created. */ +/* Structure used to track the progress of find_parameter_packs_r. */ +struct find_parameter_pack_data +{ + /* TREE_LIST that will contain all of the parameter packs found by + the traversal. */ + tree* parameter_packs; + + /* Set of AST nodes that have been visited by the traversal. */ + struct pointer_set_t *visited; +}; +/* Identifies all of the argument packs that occur in a template + argument and appends them to the TREE_LIST inside DATA, which is a + find_parameter_pack_data structure. This is a subroutine of + make_pack_expansion and uses_parameter_packs. */ static tree -reduce_template_parm_level (tree index, tree type, int levels) +find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) { - if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE - || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) - != TEMPLATE_PARM_LEVEL (index) - levels)) + tree t = *tp; + struct find_parameter_pack_data* ppd = + (struct find_parameter_pack_data*)data; + bool parameter_pack_p = false; + + /* Identify whether this is a parameter pack or not. */ + switch (TREE_CODE (t)) { - tree orig_decl = TEMPLATE_PARM_DECL (index); - tree decl, t; + case TEMPLATE_PARM_INDEX: + if (TEMPLATE_PARM_PARAMETER_PACK (t)) + parameter_pack_p = true; + break; - decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type); - TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl); - TREE_INVARIANT (decl) = TREE_INVARIANT (orig_decl); - TREE_READONLY (decl) = TREE_READONLY (orig_decl); - DECL_ARTIFICIAL (decl) = 1; - SET_DECL_TEMPLATE_PARM_P (decl); + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + if (TEMPLATE_TYPE_PARAMETER_PACK (t)) + parameter_pack_p = true; + break; - t = build_template_parm_index (TEMPLATE_PARM_IDX (index), - TEMPLATE_PARM_LEVEL (index) - levels, - TEMPLATE_PARM_ORIG_LEVEL (index), - decl, type); - TEMPLATE_PARM_DESCENDANTS (index) = t; + case PARM_DECL: + if (FUNCTION_PARAMETER_PACK_P (t)) + { + /* We don't want to walk into the type of a PARM_DECL, + because we don't want to see the type parameter pack. */ + *walk_subtrees = 0; + parameter_pack_p = true; + } + break; - /* Template template parameters need this. */ - if (TREE_CODE (decl) != CONST_DECL) - DECL_TEMPLATE_PARMS (decl) - = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); + default: + /* Not a parameter pack. */ + break; } - return TEMPLATE_PARM_DESCENDANTS (index); -} - -/* Process information from new template parameter PARM and append it to the - LIST being built. This new parameter is a non-type parameter iff - IS_NON_TYPE is true. */ + if (parameter_pack_p) + { + /* Add this parameter pack to the list. */ + *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs); + } -tree -process_template_parm (tree list, tree parm, bool is_non_type) -{ - tree decl = 0; - tree defval; - int idx; + if (TYPE_P (t)) + cp_walk_tree (&TYPE_CONTEXT (t), + &find_parameter_packs_r, ppd, ppd->visited); - gcc_assert (TREE_CODE (parm) == TREE_LIST); + /* This switch statement will return immediately if we don't find a + parameter pack. */ + switch (TREE_CODE (t)) + { + case TEMPLATE_PARM_INDEX: + return NULL_TREE; + + case BOUND_TEMPLATE_TEMPLATE_PARM: + /* Check the template itself. */ + cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), + &find_parameter_packs_r, ppd, ppd->visited); + /* Check the template arguments. */ + cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, + ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + return NULL_TREE; + + case PARM_DECL: + return NULL_TREE; + + case RECORD_TYPE: + if (TYPE_PTRMEMFUNC_P (t)) + return NULL_TREE; + /* Fall through. */ + + case UNION_TYPE: + case ENUMERAL_TYPE: + if (TYPE_TEMPLATE_INFO (t)) + cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), + &find_parameter_packs_r, ppd, ppd->visited); + + *walk_subtrees = 0; + return NULL_TREE; + + case TEMPLATE_DECL: + cp_walk_tree (&TREE_TYPE (t), + &find_parameter_packs_r, ppd, ppd->visited); + return NULL_TREE; + + case TYPENAME_TYPE: + cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + + case TYPE_PACK_EXPANSION: + case EXPR_PACK_EXPANSION: + *walk_subtrees = 0; + return NULL_TREE; + + case INTEGER_TYPE: + cp_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + + case IDENTIFIER_NODE: + cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, + ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + + default: + return NULL_TREE; + } + + return NULL_TREE; +} + +/* Determines if the expression or type T uses any parameter packs. */ +bool +uses_parameter_packs (tree t) +{ + tree parameter_packs = NULL_TREE; + struct find_parameter_pack_data ppd; + ppd.parameter_packs = ¶meter_packs; + ppd.visited = pointer_set_create (); + cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited); + pointer_set_destroy (ppd.visited); + return parameter_packs != NULL_TREE; +} + +/* Turn ARG, which may be an expression, type, or a TREE_LIST + representation a base-class initializer into a parameter pack + expansion. If all goes well, the resulting node will be an + EXPR_PACK_EXPANSION, TYPE_PACK_EXPANSION, or TREE_LIST, + respectively. */ +tree +make_pack_expansion (tree arg) +{ + tree result; + tree parameter_packs = NULL_TREE; + bool for_types = false; + struct find_parameter_pack_data ppd; + + if (!arg || arg == error_mark_node) + return arg; + + if (TREE_CODE (arg) == TREE_LIST) + { + /* The only time we will see a TREE_LIST here is for a base + class initializer. In this case, the TREE_PURPOSE will be a + _TYPE node (representing the base class expansion we're + initializing) and the TREE_VALUE will be a TREE_LIST + containing the initialization arguments. + + The resulting expansion looks somewhat different from most + expansions. Rather than returning just one _EXPANSION, we + return a TREE_LIST whose TREE_PURPOSE is a + TYPE_PACK_EXPANSION containing the bases that will be + initialized. The TREE_VALUE will be identical to the + original TREE_VALUE, which is a list of arguments that will + be passed to each base. We do not introduce any new pack + expansion nodes into the TREE_VALUE (although it is possible + that some already exist), because the TREE_PURPOSE and + TREE_VALUE all need to be expanded together with the same + _EXPANSION node. Note that the TYPE_PACK_EXPANSION in the + resulting TREE_PURPOSE will mention the parameter packs in + both the bases and the arguments to the bases. */ + tree purpose; + tree value; + tree parameter_packs = NULL_TREE; + + /* Determine which parameter packs will be used by the base + class expansion. */ + ppd.visited = pointer_set_create (); + ppd.parameter_packs = ¶meter_packs; + cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, + &ppd, ppd.visited); + + if (parameter_packs == NULL_TREE) + { + error ("base initializer expansion %<%T%> contains no parameter packs", arg); + pointer_set_destroy (ppd.visited); + return error_mark_node; + } + + if (TREE_VALUE (arg) != void_type_node) + { + /* Collect the sets of parameter packs used in each of the + initialization arguments. */ + for (value = TREE_VALUE (arg); value; value = TREE_CHAIN (value)) + { + /* Determine which parameter packs will be expanded in this + argument. */ + cp_walk_tree (&TREE_VALUE (value), &find_parameter_packs_r, + &ppd, ppd.visited); + } + } + + pointer_set_destroy (ppd.visited); + + /* Create the pack expansion type for the base type. */ + purpose = make_node (TYPE_PACK_EXPANSION); + SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg)); + PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs; + + /* Just use structural equality for these TYPE_PACK_EXPANSIONS; + they will rarely be compared to anything. */ + SET_TYPE_STRUCTURAL_EQUALITY (purpose); + + return tree_cons (purpose, TREE_VALUE (arg), NULL_TREE); + } + + if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) + for_types = true; + + /* Build the PACK_EXPANSION_* node. */ + result = make_node (for_types ? TYPE_PACK_EXPANSION : EXPR_PACK_EXPANSION); + SET_PACK_EXPANSION_PATTERN (result, arg); + if (TREE_CODE (result) == EXPR_PACK_EXPANSION) + { + /* Propagate type and const-expression information. */ + TREE_TYPE (result) = TREE_TYPE (arg); + TREE_CONSTANT (result) = TREE_CONSTANT (arg); + } + else + /* Just use structural equality for these TYPE_PACK_EXPANSIONS; + they will rarely be compared to anything. */ + SET_TYPE_STRUCTURAL_EQUALITY (result); + + /* Determine which parameter packs will be expanded. */ + ppd.parameter_packs = ¶meter_packs; + ppd.visited = pointer_set_create (); + cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited); + pointer_set_destroy (ppd.visited); + + /* Make sure we found some parameter packs. */ + if (parameter_packs == NULL_TREE) + { + if (TYPE_P (arg)) + error ("expansion pattern %<%T%> contains no argument packs", arg); + else + error ("expansion pattern %<%E%> contains no argument packs", arg); + return error_mark_node; + } + PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs; + + return result; +} + +/* Checks T for any "bare" parameter packs, which have not yet been + expanded, and issues an error if any are found. This operation can + only be done on full expressions or types (e.g., an expression + statement, "if" condition, etc.), because we could have expressions like: + + foo(f(g(h(args)))...) + + where "args" is a parameter pack. check_for_bare_parameter_packs + should not be called for the subexpressions args, h(args), + g(h(args)), or f(g(h(args))), because we would produce erroneous + error messages. + + Returns TRUE and emits an error if there were bare parameter packs, + returns FALSE otherwise. */ +bool +check_for_bare_parameter_packs (tree t) +{ + tree parameter_packs = NULL_TREE; + struct find_parameter_pack_data ppd; + + if (!processing_template_decl || !t || t == error_mark_node) + return false; + + if (TREE_CODE (t) == TYPE_DECL) + t = TREE_TYPE (t); + + ppd.parameter_packs = ¶meter_packs; + ppd.visited = pointer_set_create (); + cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited); + pointer_set_destroy (ppd.visited); + + if (parameter_packs) + { + error ("parameter packs not expanded with %<...%>:"); + while (parameter_packs) + { + tree pack = TREE_VALUE (parameter_packs); + tree name = NULL_TREE; + + if (TREE_CODE (pack) == TEMPLATE_TYPE_PARM + || TREE_CODE (pack) == TEMPLATE_TEMPLATE_PARM) + name = TYPE_NAME (pack); + else if (TREE_CODE (pack) == TEMPLATE_PARM_INDEX) + name = DECL_NAME (TEMPLATE_PARM_DECL (pack)); + else + name = DECL_NAME (pack); + + if (name) + inform (" %qD", name); + else + inform (" "); + + parameter_packs = TREE_CHAIN (parameter_packs); + } + + return true; + } + + return false; +} + +/* Expand any parameter packs that occur in the template arguments in + ARGS. */ +tree +expand_template_argument_pack (tree args) +{ + tree result_args = NULL_TREE; + int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0; + int num_result_args = -1; + + /* First, determine if we need to expand anything, and the number of + slots we'll need. */ + for (in_arg = 0; in_arg < nargs; ++in_arg) + { + tree arg = TREE_VEC_ELT (args, in_arg); + if (ARGUMENT_PACK_P (arg)) + { + int num_packed = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)); + if (num_result_args < 0) + num_result_args = in_arg + num_packed; + else + num_result_args += num_packed; + } + else + { + if (num_result_args >= 0) + num_result_args++; + } + } + + /* If no expansion is necessary, we're done. */ + if (num_result_args < 0) + return args; + + /* Expand arguments. */ + result_args = make_tree_vec (num_result_args); + for (in_arg = 0; in_arg < nargs; ++in_arg) + { + tree arg = TREE_VEC_ELT (args, in_arg); + if (ARGUMENT_PACK_P (arg)) + { + tree packed = ARGUMENT_PACK_ARGS (arg); + int i, num_packed = TREE_VEC_LENGTH (packed); + for (i = 0; i < num_packed; ++i, ++out_arg) + TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i); + } + else + { + TREE_VEC_ELT (result_args, out_arg) = arg; + ++out_arg; + } + } + + return result_args; +} + +/* Complain if DECL shadows a template parameter. + + [temp.local]: A template-parameter shall not be redeclared within its + scope (including nested scopes). */ + +void +check_template_shadow (tree decl) +{ + tree olddecl; + + /* If we're not in a template, we can't possibly shadow a template + parameter. */ + if (!current_template_parms) + return; + + /* Figure out what we're shadowing. */ + if (TREE_CODE (decl) == OVERLOAD) + decl = OVL_CURRENT (decl); + olddecl = innermost_non_namespace_value (DECL_NAME (decl)); + + /* If there's no previous binding for this name, we're not shadowing + anything, let alone a template parameter. */ + if (!olddecl) + return; + + /* If we're not shadowing a template parameter, we're done. Note + that OLDDECL might be an OVERLOAD (or perhaps even an + ERROR_MARK), so we can't just blithely assume it to be a _DECL + node. */ + if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl)) + return; + + /* We check for decl != olddecl to avoid bogus errors for using a + name inside a class. We check TPFI to avoid duplicate errors for + inline member templates. */ + if (decl == olddecl + || TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) + return; + + error ("declaration of %q+#D", decl); + error (" shadows template parm %q+#D", olddecl); +} + +/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, + ORIG_LEVEL, DECL, and TYPE. */ + +static tree +build_template_parm_index (int index, + int level, + int orig_level, + tree decl, + tree type) +{ + tree t = make_node (TEMPLATE_PARM_INDEX); + TEMPLATE_PARM_IDX (t) = index; + TEMPLATE_PARM_LEVEL (t) = level; + TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level; + TEMPLATE_PARM_DECL (t) = decl; + TREE_TYPE (t) = type; + TREE_CONSTANT (t) = TREE_CONSTANT (decl); + TREE_READONLY (t) = TREE_READONLY (decl); + + return t; +} + +/* Find the canonical type parameter for the given template type + parameter. Returns the canonical type parameter, which may be TYPE + if no such parameter existed. */ +static tree +canonical_type_parameter (tree type) +{ + tree list; + int idx = TEMPLATE_TYPE_IDX (type); + if (!canonical_template_parms) + canonical_template_parms = VEC_alloc (tree, gc, idx+1); + + while (VEC_length (tree, canonical_template_parms) <= (unsigned)idx) + VEC_safe_push (tree, gc, canonical_template_parms, NULL_TREE); + + list = VEC_index (tree, canonical_template_parms, idx); + while (list && !comptypes (type, TREE_VALUE (list), COMPARE_STRUCTURAL)) + list = TREE_CHAIN (list); + + if (list) + return TREE_VALUE (list); + else + { + VEC_replace(tree, canonical_template_parms, idx, + tree_cons (NULL_TREE, type, + VEC_index (tree, canonical_template_parms, idx))); + return type; + } +} + +/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose + TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a + TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a + new one is created. */ + +static tree +reduce_template_parm_level (tree index, tree type, int levels, tree args, + tsubst_flags_t complain) +{ + if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE + || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) + != TEMPLATE_PARM_LEVEL (index) - levels)) + { + tree orig_decl = TEMPLATE_PARM_DECL (index); + tree decl, t; + + decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type); + TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl); + TREE_READONLY (decl) = TREE_READONLY (orig_decl); + DECL_ARTIFICIAL (decl) = 1; + SET_DECL_TEMPLATE_PARM_P (decl); + + t = build_template_parm_index (TEMPLATE_PARM_IDX (index), + TEMPLATE_PARM_LEVEL (index) - levels, + TEMPLATE_PARM_ORIG_LEVEL (index), + decl, type); + TEMPLATE_PARM_DESCENDANTS (index) = t; + TEMPLATE_PARM_PARAMETER_PACK (t) + = TEMPLATE_PARM_PARAMETER_PACK (index); + + /* Template template parameters need this. */ + if (TREE_CODE (decl) == TEMPLATE_DECL) + DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms + (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)), + args, complain); + } + + return TEMPLATE_PARM_DESCENDANTS (index); +} + +/* Process information from new template parameter PARM and append it to the + LIST being built. This new parameter is a non-type parameter iff + IS_NON_TYPE is true. This new parameter is a parameter + pack iff IS_PARAMETER_PACK is true. */ + +tree +process_template_parm (tree list, tree parm, bool is_non_type, + bool is_parameter_pack) +{ + tree decl = 0; + tree defval; + tree err_parm_list; + int idx = 0; + + gcc_assert (TREE_CODE (parm) == TREE_LIST); defval = TREE_PURPOSE (parm); if (list) { - tree p = TREE_VALUE (tree_last (list)); + tree p = tree_last (list); + + if (p && TREE_VALUE (p) != error_mark_node) + { + p = TREE_VALUE (p); + if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) + idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); + else + idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); + } - if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) - idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); - else - idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); ++idx; } else @@ -2368,7 +2989,11 @@ process_template_parm (tree list, tree parm, bool is_non_type) SET_DECL_TEMPLATE_PARM_P (parm); if (TREE_TYPE (parm) == error_mark_node) - TREE_TYPE (parm) = void_type_node; + { + err_parm_list = build_tree_list (defval, parm); + TREE_VALUE (err_parm_list) = error_mark_node; + return chainon (list, err_parm_list); + } else { /* [temp.param] @@ -2377,21 +3002,36 @@ process_template_parm (tree list, tree parm, bool is_non_type) ignored when determining its type. */ TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) - TREE_TYPE (parm) = void_type_node; + { + err_parm_list = build_tree_list (defval, parm); + TREE_VALUE (err_parm_list) = error_mark_node; + return chainon (list, err_parm_list); + } + + if (uses_parameter_packs (TREE_TYPE (parm)) && !is_parameter_pack) + { + /* This template parameter is not a parameter pack, but it + should be. Complain about "bare" parameter packs. */ + check_for_bare_parameter_packs (TREE_TYPE (parm)); + + /* Recover by calling this a parameter pack. */ + is_parameter_pack = true; + } } /* A template parameter is not modifiable. */ TREE_CONSTANT (parm) = 1; - TREE_INVARIANT (parm) = 1; TREE_READONLY (parm) = 1; decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); TREE_CONSTANT (decl) = 1; - TREE_INVARIANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (parm) = DECL_INITIAL (decl) = build_template_parm_index (idx, processing_template_decl, processing_template_decl, decl, TREE_TYPE (parm)); + + TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)) + = is_parameter_pack; } else { @@ -2400,7 +3040,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) if (parm && TREE_CODE (parm) == TEMPLATE_DECL) { - t = make_aggr_type (TEMPLATE_TEMPLATE_PARM); + t = cxx_make_type (TEMPLATE_TEMPLATE_PARM); /* This is for distinguishing between real templates and template template parameters */ TREE_TYPE (parm) = t; @@ -2409,7 +3049,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) } else { - t = make_aggr_type (TEMPLATE_TYPE_PARM); + t = cxx_make_type (TEMPLATE_TYPE_PARM); /* parm is either IDENTIFIER_NODE or NULL_TREE. */ decl = build_decl (TYPE_DECL, parm, t); } @@ -2421,6 +3061,8 @@ process_template_parm (tree list, tree parm, bool is_non_type) = build_template_parm_index (idx, processing_template_decl, processing_template_decl, decl, TREE_TYPE (parm)); + TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack; + TYPE_CANONICAL (t) = canonical_type_parameter (t); } DECL_ARTIFICIAL (decl) = 1; SET_DECL_TEMPLATE_PARM_P (decl); @@ -2474,8 +3116,10 @@ end_template_decl (void) current_template_parms = TREE_CHAIN (current_template_parms); } -/* Given a template argument vector containing the template PARMS. - The innermost PARMS are given first. */ +/* Within the declaration of a template, return all levels of template + parameters that apply. The template parameters are represented as + a TREE_VEC, in the form documented in cp-tree.h for template + arguments. */ static tree current_template_args (void) @@ -2508,12 +3152,43 @@ current_template_args (void) { t = TREE_VALUE (t); - if (TREE_CODE (t) == TYPE_DECL - || TREE_CODE (t) == TEMPLATE_DECL) - t = TREE_TYPE (t); - else - t = DECL_INITIAL (t); - TREE_VEC_ELT (a, i) = t; + if (!error_operand_p (t)) + { + if (TREE_CODE (t) == TYPE_DECL + || TREE_CODE (t) == TEMPLATE_DECL) + { + t = TREE_TYPE (t); + + if (TEMPLATE_TYPE_PARAMETER_PACK (t)) + { + /* Turn this argument into a TYPE_ARGUMENT_PACK + with a single element, which expands T. */ + tree vec = make_tree_vec (1); + TREE_VEC_ELT (vec, 0) = make_pack_expansion (t); + + t = make_node (TYPE_ARGUMENT_PACK); + SET_ARGUMENT_PACK_ARGS (t, vec); + } + } + else + { + t = DECL_INITIAL (t); + + if (TEMPLATE_PARM_PARAMETER_PACK (t)) + { + /* Turn this argument into a NONTYPE_ARGUMENT_PACK + with a single element, which expands T. */ + tree vec = make_tree_vec (1); + tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t)); + TREE_VEC_ELT (vec, 0) = make_pack_expansion (t); + + t = make_node (NONTYPE_ARGUMENT_PACK); + SET_ARGUMENT_PACK_ARGS (t, vec); + TREE_TYPE (t) = type; + } + } + TREE_VEC_ELT (a, i) = t; + } } } @@ -2668,7 +3343,8 @@ process_partial_specialization (tree decl) for_each_template_parm (TREE_VEC_ELT (inner_args, i), &mark_template_parm, &tpd, - NULL); + NULL, + /*include_nondeduced_p=*/false); } for (i = 0; i < ntparms; ++i) if (tpd.parms[i] == 0) @@ -2702,74 +3378,118 @@ process_partial_specialization (tree decl) The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the - specialization. */ + specialization. + + Also, we verify that pack expansions only occur at the + end of the argument list. */ gcc_assert (nargs == DECL_NTPARMS (maintmpl)); tpd2.parms = 0; for (i = 0; i < nargs; ++i) { + tree parm = TREE_VALUE (TREE_VEC_ELT (main_inner_parms, i)); tree arg = TREE_VEC_ELT (inner_args, i); - if (/* These first two lines are the `non-type' bit. */ - !TYPE_P (arg) - && TREE_CODE (arg) != TEMPLATE_DECL - /* This next line is the `argument expression is not just a - simple identifier' condition and also the `specialized - non-type argument' bit. */ - && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) - { - if (tpd.arg_uses_template_parms[i]) - error ("template argument %qE involves template parameter(s)", arg); - else - { - /* Look at the corresponding template parameter, - marking which template parameters its type depends - upon. */ - tree type = - TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms, - i))); - - if (!tpd2.parms) - { - /* We haven't yet initialized TPD2. Do so now. */ - tpd2.arg_uses_template_parms - = (int *) alloca (sizeof (int) * nargs); - /* The number of parameters here is the number in the - main template, which, as checked in the assertion - above, is NARGS. */ - tpd2.parms = (int *) alloca (sizeof (int) * nargs); - tpd2.level = - TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); - } - - /* Mark the template parameters. But this time, we're - looking for the template parameters of the main - template, not in the specialization. */ - tpd2.current_arg = i; - tpd2.arg_uses_template_parms[i] = 0; - memset (tpd2.parms, 0, sizeof (int) * nargs); - for_each_template_parm (type, - &mark_template_parm, - &tpd2, - NULL); - - if (tpd2.arg_uses_template_parms [i]) - { - /* The type depended on some template parameters. - If they are fully specialized in the - specialization, that's OK. */ - int j; - for (j = 0; j < nargs; ++j) - if (tpd2.parms[j] != 0 - && tpd.arg_uses_template_parms [j]) - { - error ("type %qT of template argument %qE depends " - "on template parameter(s)", - type, - arg); - break; - } - } - } - } + tree packed_args = NULL_TREE; + int j, len = 1; + + if (ARGUMENT_PACK_P (arg)) + { + /* Extract the arguments from the argument pack. We'll be + iterating over these in the following loop. */ + packed_args = ARGUMENT_PACK_ARGS (arg); + len = TREE_VEC_LENGTH (packed_args); + } + + for (j = 0; j < len; j++) + { + if (packed_args) + /* Get the Jth argument in the parameter pack. */ + arg = TREE_VEC_ELT (packed_args, j); + + if (PACK_EXPANSION_P (arg)) + { + /* Pack expansions must come at the end of the + argument list. */ + if ((packed_args && j < len - 1) + || (!packed_args && i < nargs - 1)) + { + if (TREE_CODE (arg) == EXPR_PACK_EXPANSION) + error ("parameter pack argument %qE must be at the end of the template argument list", arg); + else + error ("parameter pack argument %qT must be at the end of the template argument list", arg); + + if (packed_args) + TREE_VEC_ELT (packed_args, j) = error_mark_node; + } + } + + if (TREE_CODE (arg) == EXPR_PACK_EXPANSION) + /* We only care about the pattern. */ + arg = PACK_EXPANSION_PATTERN (arg); + + if (/* These first two lines are the `non-type' bit. */ + !TYPE_P (arg) + && TREE_CODE (arg) != TEMPLATE_DECL + /* This next line is the `argument expression is not just a + simple identifier' condition and also the `specialized + non-type argument' bit. */ + && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) + { + if ((!packed_args && tpd.arg_uses_template_parms[i]) + || (packed_args && uses_template_parms (arg))) + error ("template argument %qE involves template parameter(s)", + arg); + else + { + /* Look at the corresponding template parameter, + marking which template parameters its type depends + upon. */ + tree type = TREE_TYPE (parm); + + if (!tpd2.parms) + { + /* We haven't yet initialized TPD2. Do so now. */ + tpd2.arg_uses_template_parms + = (int *) alloca (sizeof (int) * nargs); + /* The number of parameters here is the number in the + main template, which, as checked in the assertion + above, is NARGS. */ + tpd2.parms = (int *) alloca (sizeof (int) * nargs); + tpd2.level = + TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); + } + + /* Mark the template parameters. But this time, we're + looking for the template parameters of the main + template, not in the specialization. */ + tpd2.current_arg = i; + tpd2.arg_uses_template_parms[i] = 0; + memset (tpd2.parms, 0, sizeof (int) * nargs); + for_each_template_parm (type, + &mark_template_parm, + &tpd2, + NULL, + /*include_nondeduced_p=*/false); + + if (tpd2.arg_uses_template_parms [i]) + { + /* The type depended on some template parameters. + If they are fully specialized in the + specialization, that's OK. */ + int j; + for (j = 0; j < nargs; ++j) + if (tpd2.parms[j] != 0 + && tpd.arg_uses_template_parms [j]) + { + error ("type %qT of template argument %qE depends " + "on template parameter(s)", + type, + arg); + break; + } + } + } + } + } } if (retrieve_specialization (maintmpl, specargs, @@ -2779,22 +3499,33 @@ process_partial_specialization (tree decl) DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = tree_cons (specargs, inner_parms, - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; return decl; } -/* Check that a template declaration's use of default arguments is not - invalid. Here, PARMS are the template parameters. IS_PRIMARY is - nonzero if DECL is the thing declared by a primary template. - IS_PARTIAL is nonzero if DECL is a partial specialization. */ +/* Check that a template declaration's use of default arguments and + parameter packs is not invalid. Here, PARMS are the template + parameters. IS_PRIMARY is nonzero if DECL is the thing declared by + a primary template. IS_PARTIAL is nonzero if DECL is a partial + specialization. + -static void -check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) + IS_FRIEND_DECL is nonzero if DECL is a friend function template + declaration (but not a definition); 1 indicates a declaration, 2 + indicates a redeclaration. When IS_FRIEND_DECL=2, no errors are + emitted for extraneous default arguments. + + Returns TRUE if there were no errors found, FALSE otherwise. */ + +bool +check_default_tmpl_args (tree decl, tree parms, int is_primary, + int is_partial, int is_friend_decl) { const char *msg; int last_level_to_check; tree parm_level; + bool no_errors = true; /* [temp.param] @@ -2807,7 +3538,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) /* You can't have a function template declaration in a local scope, nor you can you define a member of a class template in a local scope. */ - return; + return true; if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) @@ -2827,36 +3558,72 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) declared, so there's no need to do it again now. This function was defined in class scope, but we're processing it's body now that the class is complete. */ - return; - - /* [temp.param] + return true; - If a template-parameter has a default template-argument, all - subsequent template-parameters shall have a default - template-argument supplied. */ - for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level)) + /* Core issue 226 (C++0x only): the following only applies to class + templates. */ + if ((cxx_dialect == cxx98) || TREE_CODE (decl) != FUNCTION_DECL) { - tree inner_parms = TREE_VALUE (parm_level); - int ntparms = TREE_VEC_LENGTH (inner_parms); - int seen_def_arg_p = 0; - int i; + /* [temp.param] + + If a template-parameter has a default template-argument, all + subsequent template-parameters shall have a default + template-argument supplied. */ + for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level)) + { + tree inner_parms = TREE_VALUE (parm_level); + int ntparms = TREE_VEC_LENGTH (inner_parms); + int seen_def_arg_p = 0; + int i; + + for (i = 0; i < ntparms; ++i) + { + tree parm = TREE_VEC_ELT (inner_parms, i); + + if (parm == error_mark_node) + continue; + + if (TREE_PURPOSE (parm)) + seen_def_arg_p = 1; + else if (seen_def_arg_p) + { + error ("no default argument for %qD", TREE_VALUE (parm)); + /* For better subsequent error-recovery, we indicate that + there should have been a default argument. */ + TREE_PURPOSE (parm) = error_mark_node; + no_errors = false; + } + else if (is_primary + && !is_partial + && !is_friend_decl + && TREE_CODE (decl) == TYPE_DECL + && i < ntparms - 1 + && template_parameter_pack_p (TREE_VALUE (parm))) + { + /* A primary class template can only have one + parameter pack, at the end of the template + parameter list. */ - for (i = 0; i < ntparms; ++i) - { - tree parm = TREE_VEC_ELT (inner_parms, i); - if (TREE_PURPOSE (parm)) - seen_def_arg_p = 1; - else if (seen_def_arg_p) - { - error ("no default argument for %qD", TREE_VALUE (parm)); - /* For better subsequent error-recovery, we indicate that - there should have been a default argument. */ - TREE_PURPOSE (parm) = error_mark_node; - } - } + if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL) + error ("parameter pack %qE must be at the end of the" + " template parameter list", TREE_VALUE (parm)); + else + error ("parameter pack %qT must be at the end of the" + " template parameter list", + TREE_TYPE (TREE_VALUE (parm))); + + TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) + = error_mark_node; + no_errors = false; + } + } + } } - if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) + if (((cxx_dialect == cxx98) && TREE_CODE (decl) != TYPE_DECL) + || is_partial + || !is_primary + || is_friend_decl) /* For an ordinary class template, default template arguments are allowed at the innermost level, e.g.: template @@ -2867,8 +3634,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) The template parameter list of a specialization shall not contain default template argument values. - So, for a partial specialization, or for a function template, - we look at all of them. */ + So, for a partial specialization, or for a function template + (in C++98/C++03), we look at all of them. */ ; else /* But, for a primary class template that is not a partial @@ -2877,7 +3644,11 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) parms = TREE_CHAIN (parms); /* Figure out what error message to issue. */ - if (TREE_CODE (decl) == FUNCTION_DECL) + if (is_friend_decl == 2) + msg = "default template arguments may not be used in function template friend re-declaration"; + else if (is_friend_decl) + msg = "default template arguments may not be used in function template friend declarations"; + else if (TREE_CODE (decl) == FUNCTION_DECL && (cxx_dialect == cxx98)) msg = "default template arguments may not be used in function templates"; else if (is_partial) msg = "default template arguments may not be used in partial specializations"; @@ -2908,24 +3679,35 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) ntparms = TREE_VEC_LENGTH (inner_parms); for (i = 0; i < ntparms; ++i) - if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) - { - if (msg) - { - error (msg, decl); - msg = 0; - } + { + if (TREE_VEC_ELT (inner_parms, i) == error_mark_node) + continue; - /* Clear out the default argument so that we are not - confused later. */ - TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; - } + if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) + { + if (msg) + { + no_errors = false; + if (is_friend_decl == 2) + return no_errors; + + error (msg, decl); + msg = 0; + } + + /* Clear out the default argument so that we are not + confused later. */ + TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; + } + } /* At this point, if we're still interested in issuing messages, they must apply to classes surrounding the object declared. */ if (msg) msg = "default argument for template parameter for class enclosing %qD"; } + + return no_errors; } /* Worker for push_template_decl_real, called via @@ -2999,7 +3781,13 @@ push_template_decl_real (tree decl, bool is_friend) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); /* See if this is a primary template. */ - primary = template_parm_scope_p (); + if (is_friend && ctx) + /* A friend template that specifies a class context, i.e. + template friend void A::f(); + is not primary. */ + primary = 0; + else + primary = template_parm_scope_p (); if (primary) { @@ -3007,7 +3795,10 @@ push_template_decl_real (tree decl, bool is_friend) member_template_p = true; if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) - error ("template class without a name"); + { + error ("template class without a name"); + return error_mark_node; + } else if (TREE_CODE (decl) == FUNCTION_DECL) { if (DECL_DESTRUCTOR_P (decl)) @@ -3047,7 +3838,50 @@ push_template_decl_real (tree decl, bool is_friend) /* Check to see that the rules regarding the use of default arguments are not being violated. */ check_default_tmpl_args (decl, current_template_parms, - primary, is_partial); + primary, is_partial, /*is_friend_decl=*/0); + + /* Ensure that there are no parameter packs in the type of this + declaration that have not been expanded. */ + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* Check each of the arguments individually to see if there are + any bare parameter packs. */ + tree type = TREE_TYPE (decl); + tree arg = DECL_ARGUMENTS (decl); + tree argtype = TYPE_ARG_TYPES (type); + + while (arg && argtype) + { + if (!FUNCTION_PARAMETER_PACK_P (arg) + && check_for_bare_parameter_packs (TREE_TYPE (arg))) + { + /* This is a PARM_DECL that contains unexpanded parameter + packs. We have already complained about this in the + check_for_bare_parameter_packs call, so just replace + these types with ERROR_MARK_NODE. */ + TREE_TYPE (arg) = error_mark_node; + TREE_VALUE (argtype) = error_mark_node; + } + + arg = TREE_CHAIN (arg); + argtype = TREE_CHAIN (argtype); + } + + /* Check for bare parameter packs in the return type and the + exception specifiers. */ + if (check_for_bare_parameter_packs (TREE_TYPE (type))) + /* Errors were already issued, set return type to int + as the frontend doesn't expect error_mark_node as + the return type. */ + TREE_TYPE (type) = integer_type_node; + if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type))) + TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE; + } + else if (check_for_bare_parameter_packs (TREE_TYPE (decl))) + { + TREE_TYPE (decl) = error_mark_node; + return error_mark_node; + } if (is_partial) return process_partial_specialization (decl); @@ -3100,27 +3934,15 @@ push_template_decl_real (tree decl, bool is_friend) { tree a, t, current, parms; int i; + tree tinfo = get_template_info (decl); - if (TREE_CODE (decl) == TYPE_DECL) - { - if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) - || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) - && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) - tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); - else - { - error ("%qD does not declare a template type", decl); - return decl; - } - } - else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl)) + if (!tinfo) { error ("template definition of non-template %q#D", decl); - return decl; + return error_mark_node; } - else - tmpl = DECL_TI_TEMPLATE (decl); + + tmpl = TI_TEMPLATE (tinfo); if (DECL_FUNCTION_TEMPLATE_P (tmpl) && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) @@ -3180,14 +4002,29 @@ push_template_decl_real (tree decl, bool is_friend) return error_mark_node; } - /* Perhaps we should also check that the parms are used in the - appropriate qualifying scopes in the declarator? */ - if (current == decl) current = ctx; else - current = TYPE_CONTEXT (current); + current = (TYPE_P (current) + ? TYPE_CONTEXT (current) + : DECL_CONTEXT (current)); } + + /* Check that the parms are used in the appropriate qualifying scopes + in the declarator. */ + if (!comp_template_args + (TI_ARGS (tinfo), + TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl))))) + { + error ("\ +template arguments to %qD do not match original template %qD", + decl, DECL_TEMPLATE_RESULT (tmpl)); + if (!uses_template_parms (TI_ARGS (tinfo))) + inform ("use template<> for an explicit specialization"); + /* Avoid crash in import_export_decl. */ + DECL_INTERFACE_KNOWN (decl) = 1; + return error_mark_node; + } } DECL_TEMPLATE_RESULT (tmpl) = decl; @@ -3214,10 +4051,13 @@ push_template_decl_real (tree decl, bool is_friend) if (primary) { + tree parms = DECL_TEMPLATE_PARMS (tmpl); + int i; + DECL_PRIMARY_TEMPLATE (tmpl) = tmpl; if (DECL_CONV_FN_P (tmpl)) { - int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); + int depth = TMPL_PARMS_DEPTH (parms); /* It is a conversion operator. See if the type converted to depends on innermost template operands. */ @@ -3226,6 +4066,16 @@ push_template_decl_real (tree decl, bool is_friend) depth)) DECL_TEMPLATE_CONV_FN_P (tmpl) = 1; } + + /* Give template template parms a DECL_CONTEXT of the template + for which they are a parameter. */ + parms = INNERMOST_TEMPLATE_PARMS (parms); + for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i) + { + tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + if (TREE_CODE (parm) == TEMPLATE_DECL) + DECL_CONTEXT (parm) = tmpl; + } } /* The DECL_TI_ARGS of DECL contains full set of arguments referring @@ -3238,14 +4088,7 @@ push_template_decl_real (tree decl, bool is_friend) info = tree_cons (tmpl, args, NULL_TREE); if (DECL_IMPLICIT_TYPEDEF_P (decl)) - { - SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); - if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL) - && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE - /* Don't change the name if we've already set it up. */ - && !IDENTIFIER_TEMPLATE (DECL_NAME (decl))) - DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); - } + SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); else if (DECL_LANG_SPECIFIC (decl)) DECL_TEMPLATE_INFO (decl) = info; @@ -3264,7 +4107,7 @@ push_template_decl (tree decl) template struct S; template struct S {}; */ -void +bool redeclare_class_template (tree type, tree parms) { tree tmpl; @@ -3274,7 +4117,7 @@ redeclare_class_template (tree type, tree parms) if (!TYPE_TEMPLATE_INFO (type)) { error ("%qT is not a template type", type); - return; + return false; } tmpl = TYPE_TI_TEMPLATE (type); @@ -3282,13 +4125,13 @@ redeclare_class_template (tree type, tree parms) /* The type is nested in some template class. Nothing to worry about here; there are no new template parameters for the nested type. */ - return; + return true; if (!parms) { error ("template specifiers not specified in declaration of %qD", tmpl); - return; + return false; } parms = INNERMOST_TEMPLATE_PARMS (parms); @@ -3296,29 +4139,45 @@ redeclare_class_template (tree type, tree parms) if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { - error ("previous declaration %q+D", tmpl); - error ("used %d template parameter(s) instead of %d", - TREE_VEC_LENGTH (tmpl_parms), - TREE_VEC_LENGTH (parms)); - return; + error ("redeclared with %d template parameter(s)", + TREE_VEC_LENGTH (parms)); + inform ("previous declaration %q+D used %d template parameter(s)", + tmpl, TREE_VEC_LENGTH (tmpl_parms)); + return false; } for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i) { - tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)); - tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i)); + tree tmpl_parm; + tree parm; + tree tmpl_default; + tree parm_default; + + if (TREE_VEC_ELT (tmpl_parms, i) == error_mark_node + || TREE_VEC_ELT (parms, i) == error_mark_node) + continue; + + tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); + parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)); + parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i)); /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or TEMPLATE_DECL. */ - if (TREE_CODE (tmpl_parm) != TREE_CODE (parm) - || (TREE_CODE (tmpl_parm) != TYPE_DECL - && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))) + if (tmpl_parm != error_mark_node + && (TREE_CODE (tmpl_parm) != TREE_CODE (parm) + || (TREE_CODE (tmpl_parm) != TYPE_DECL + && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))) + || (TREE_CODE (tmpl_parm) != PARM_DECL + && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm)) + != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))) + || (TREE_CODE (tmpl_parm) == PARM_DECL + && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm)) + != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))))) { error ("template parameter %q+#D", tmpl_parm); error ("redeclared here as %q#D", parm); - return; + return false; } if (tmpl_default != NULL_TREE && parm_default != NULL_TREE) @@ -3328,8 +4187,8 @@ redeclare_class_template (tree type, tree parms) A template-parameter may not be given default arguments by two different declarations in the same scope. */ error ("redefinition of default argument for %q#D", parm); - error ("%J original definition appeared here", tmpl_parm); - return; + inform ("%Joriginal definition appeared here", tmpl_parm); + return false; } if (parm_default != NULL_TREE) @@ -3341,6 +4200,8 @@ redeclare_class_template (tree type, tree parms) parameters for any members. */ TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default; } + + return true; } /* Simplify EXPR if it is a non-dependent expression. Returns the @@ -3349,6 +4210,9 @@ redeclare_class_template (tree type, tree parms) tree fold_non_dependent_expr (tree expr) { + if (expr == NULL_TREE) + return NULL_TREE; + /* If we're in a template, but EXPR isn't value dependent, simplify it. We're supposed to treat: @@ -3368,7 +4232,8 @@ fold_non_dependent_expr (tree expr) /*args=*/NULL_TREE, tf_error, /*in_decl=*/NULL_TREE, - /*function_p=*/false); + /*function_p=*/false, + /*integral_constant_expression_p=*/true); processing_template_decl = saved_processing_template_decl; } return expr; @@ -3376,7 +4241,7 @@ fold_non_dependent_expr (tree expr) /* EXPR is an expression which is used in a constant-expression context. For instance, it could be a VAR_DECL with a constant initializer. - Extract the innest constant expression. + Extract the innermost constant expression. This is basically a more powerful version of integral_constant_value, which can be used also in templates where @@ -3415,7 +4280,9 @@ convert_nontype_argument_function (tree type, tree expr) fn_no_ptr = fn; if (TREE_CODE (fn_no_ptr) == ADDR_EXPR) fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0); - + if (TREE_CODE (fn_no_ptr) == BASELINK) + fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr); + /* [temp.arg.nontype]/1 A template-argument for a non-type, non-template template-parameter @@ -3577,10 +4444,46 @@ convert_nontype_argument (tree type, tree expr) Here, we do not care about functions, as they are invalid anyway for a parameter of type pointer-to-object. */ - bool constant_address_p = - (TREE_CODE (expr) == ADDR_EXPR - || TREE_CODE (expr_type) == ARRAY_TYPE - || (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))); + + if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr)) + /* Non-type template parameters are OK. */ + ; + else if (TREE_CODE (expr) != ADDR_EXPR + && TREE_CODE (expr_type) != ARRAY_TYPE) + { + if (TREE_CODE (expr) == VAR_DECL) + { + error ("%qD is not a valid template argument " + "because %qD is a variable, not the address of " + "a variable", + expr, expr); + return NULL_TREE; + } + /* Other values, like integer constants, might be valid + non-type arguments of some other type. */ + return error_mark_node; + } + else + { + tree decl; + + decl = ((TREE_CODE (expr) == ADDR_EXPR) + ? TREE_OPERAND (expr, 0) : expr); + if (TREE_CODE (decl) != VAR_DECL) + { + error ("%qE is not a valid template argument of type %qT " + "because %qE is not a variable", + expr, type, decl); + return NULL_TREE; + } + else if (!DECL_EXTERNAL_LINKAGE_P (decl)) + { + error ("%qE is not a valid template argument of type %qT " + "because %qD does not have external linkage", + expr, type, decl); + return NULL_TREE; + } + } expr = decay_conversion (expr); if (expr == error_mark_node) @@ -3589,13 +4492,6 @@ convert_nontype_argument (tree type, tree expr) expr = perform_qualification_conversions (type, expr); if (expr == error_mark_node) return error_mark_node; - - if (!constant_address_p) - { - error ("%qE is not a valid template argument for type %qT " - "because it is not a constant pointer", expr, type); - return NULL_TREE; - } } /* [temp.arg.nontype]/5, bullet 3 @@ -3736,6 +4632,77 @@ convert_nontype_argument (tree type, tree expr) return expr; } +/* Subroutine of coerce_template_template_parms, which returns 1 if + PARM_PARM and ARG_PARM match using the rule for the template + parameters of template template parameters. Both PARM and ARG are + template parameters; the rest of the arguments are the same as for + coerce_template_template_parms. + */ +static int +coerce_template_template_parm (tree parm, + tree arg, + tsubst_flags_t complain, + tree in_decl, + tree outer_args) +{ + if (arg == NULL_TREE || arg == error_mark_node + || parm == NULL_TREE || parm == error_mark_node) + return 0; + + if (TREE_CODE (arg) != TREE_CODE (parm)) + return 0; + + switch (TREE_CODE (parm)) + { + case TEMPLATE_DECL: + /* We encounter instantiations of templates like + template