X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=1a1d5c0f2377349cd9a607febb2b9fa5b11e2ced;hb=788f3e3e00e8adfe37d3392f6bd8212b1aa76a95;hp=18e3c0a057dd0d23b5153d6ea6c01fa38b85b2a4;hpb=c6224531a4d142294fa7f14edb1f8b082208e3e1;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 18e3c0a057d..4b8232e9a9b 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 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -18,8 +18,8 @@ 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, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* Known bugs or deficiencies include: @@ -34,7 +34,9 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include "pointer-set.h" #include "flags.h" +#include "c-common.h" #include "cp-tree.h" +#include "cp-objcp-common.h" #include "tree-inline.h" #include "decl.h" #include "output.h" @@ -43,6 +45,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "timevar.h" #include "tree-iterator.h" +#include "vecprim.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -61,8 +64,7 @@ int processing_template_parmlist; static int template_header_count; static GTY(()) tree saved_trees; -static GTY(()) varray_type inline_parm_levels; -static size_t inline_parm_levels_used; +static VEC(int,heap) *inline_parm_levels; static GTY(()) tree current_tinst_level; @@ -86,7 +88,6 @@ static htab_t local_specializations; #define UNIFY_ALLOW_OUTER_LEVEL 16 #define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32 #define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64 -#define UNIFY_ALLOW_MAX_CORRECTION 128 static void push_access_scope (tree); static void pop_access_scope (tree); @@ -96,24 +97,27 @@ 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 tsubst_initializer_list (tree, tree); static tree get_class_bindings (tree, tree, tree); -static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int); +static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, + bool, bool); 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*); static int type_unification_real (tree, tree, tree, tree, - int, unification_kind_t, int, int); + int, unification_kind_t, int); static void note_template_header (int); +static tree convert_nontype_argument_function (tree, tree); static tree convert_nontype_argument (tree, tree); static tree convert_template_argument (tree, tree, tree, tsubst_flags_t, int, tree); -static tree get_bindings_overload (tree, tree, tree); static int for_each_template_parm (tree, tree_fn_t, void*, struct pointer_set_t*); static tree build_template_parm_index (int, int, int, tree, tree); @@ -127,32 +131,25 @@ static int template_parm_this_level_p (tree, void *); static tree tsubst_friend_function (tree, tree); static tree tsubst_friend_class (tree, tree); static int can_complete_type_without_circularity (tree); -static tree get_bindings (tree, tree, tree); -static tree get_bindings_real (tree, tree, tree, int, int, int); +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 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); static void regenerate_decl_from_template (tree, tree); -static tree most_specialized (tree, tree, tree); static tree most_specialized_class (tree, tree); -static int template_class_depth_real (tree, int); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); -static tree tsubst_decl (tree, tree, tree, tsubst_flags_t); 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 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 tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree); static tree get_template_base (tree, tree, tree, tree); -static int verify_class_unification (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 tree determine_specialization (tree, tree, tree *, int, int); static int template_args_equal (tree, tree); static void tsubst_default_arguments (tree); static tree for_each_template_parm_r (tree *, int *, void *); @@ -176,11 +173,13 @@ push_access_scope (tree t) gcc_assert (TREE_CODE (t) == FUNCTION_DECL || TREE_CODE (t) == VAR_DECL); - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_FRIEND_CONTEXT (t)) + push_nested_class (DECL_FRIEND_CONTEXT (t)); + else if (DECL_CLASS_SCOPE_P (t)) push_nested_class (DECL_CONTEXT (t)); else push_to_top_level (); - + if (TREE_CODE (t) == FUNCTION_DECL) { saved_access_scope = tree_cons @@ -201,7 +200,7 @@ pop_access_scope (tree t) saved_access_scope = TREE_CHAIN (saved_access_scope); } - if (DECL_CLASS_SCOPE_P (t)) + if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t)) pop_nested_class (); else pop_from_top_level (); @@ -225,7 +224,7 @@ finish_member_template_decl (tree decl) tree type; type = TREE_TYPE (decl); - if (IS_AGGR_TYPE (type) + if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) { @@ -246,7 +245,7 @@ finish_member_template_decl (tree decl) } else return decl; - } + } else error ("invalid member template declaration %qD", decl); @@ -254,7 +253,7 @@ finish_member_template_decl (tree decl) } /* Returns the template nesting level of the indicated class TYPE. - + For example, in: template struct A @@ -263,41 +262,36 @@ finish_member_template_decl (tree decl) struct B {}; }; - A::B has depth two, while A has depth one. + A::B has depth two, while A has depth one. Both A::B and A::B have depth one, if - COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not - specializations. + they are instantiations, not specializations. This function is guaranteed to return 0 if passed NULL_TREE so that, for example, `template_class_depth (current_class_type)' is always safe. */ -static int -template_class_depth_real (tree type, int count_specializations) +int +template_class_depth (tree type) { int depth; - for (depth = 0; + for (depth = 0; type && TREE_CODE (type) != NAMESPACE_DECL; - type = (TREE_CODE (type) == FUNCTION_DECL) + 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)) - && ((count_specializations - && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) - || uses_template_parms (CLASSTYPE_TI_ARGS (type)))) + && uses_template_parms (CLASSTYPE_TI_ARGS (type))) ++depth; } - else + else { if (DECL_TEMPLATE_INFO (type) && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) - && ((count_specializations - && DECL_TEMPLATE_SPECIALIZATION (type)) - || uses_template_parms (DECL_TI_ARGS (type)))) + && uses_template_parms (DECL_TI_ARGS (type))) ++depth; } } @@ -305,16 +299,6 @@ template_class_depth_real (tree type, int count_specializations) return depth; } -/* Returns the template nesting level of the indicated class TYPE. - Like template_class_depth_real, but instantiations do not count in - the depth. */ - -int -template_class_depth (tree type) -{ - return template_class_depth_real (type, /*count_specializations=*/0); -} - /* Returns 1 if processing DECL as part of do_pending_inlines needs us to push template parms. */ @@ -349,8 +333,8 @@ push_inline_template_parms_recursive (tree parmlist, int levels) TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1; begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec, - NULL); - for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) + NULL); + for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); gcc_assert (DECL_P (parm)); @@ -411,28 +395,22 @@ maybe_begin_member_template_processing (tree decl) /* Remember how many levels of template parameters we pushed so that we can pop them later. */ - if (!inline_parm_levels) - VARRAY_INT_INIT (inline_parm_levels, 4, "inline_parm_levels"); - if (inline_parm_levels_used == inline_parm_levels->num_elements) - VARRAY_GROW (inline_parm_levels, 2 * inline_parm_levels_used); - VARRAY_INT (inline_parm_levels, inline_parm_levels_used) = levels; - ++inline_parm_levels_used; + VEC_safe_push (int, heap, inline_parm_levels, levels); } -/* Undo the effects of begin_member_template_processing. */ +/* Undo the effects of maybe_begin_member_template_processing. */ -void +void maybe_end_member_template_processing (void) { int i; + int last; - if (!inline_parm_levels_used) + if (VEC_length (int, inline_parm_levels) == 0) return; - --inline_parm_levels_used; - for (i = 0; - i < VARRAY_INT (inline_parm_levels, inline_parm_levels_used); - ++i) + last = VEC_pop (int, inline_parm_levels); + for (i = 0; i < last; ++i) { --processing_template_decl; current_template_parms = TREE_CHAIN (current_template_parms); @@ -459,7 +437,7 @@ add_to_template_args (tree args, tree extra_args) for (j = 1; j <= extra_depth; ++j, ++i) SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (extra_args, j)); - + return new_args; } @@ -486,7 +464,7 @@ add_outermost_template_args (tree args, tree extra_args) /* For the moment, we make ARGS look like it contains fewer levels. */ TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH (extra_args); - + new_args = add_to_template_args (args, extra_args); /* Now, we restore ARGS to its full dimensions. */ @@ -509,7 +487,7 @@ get_innermost_template_args (tree args, int n) /* If N is 1, just return the innermost set of template arguments. */ if (n == 1) return TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args)); - + /* If we're not removing anything, just return the arguments we were given. */ extra_levels = TMPL_ARGS_DEPTH (args) - n; @@ -520,7 +498,7 @@ get_innermost_template_args (tree args, int n) /* Make a new set of arguments, not containing the outer arguments. */ new_args = make_tree_vec (n); for (i = 1; i <= n; ++i) - SET_TMPL_ARGS_LEVEL (new_args, i, + SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (args, i + extra_levels)); return new_args; @@ -541,7 +519,7 @@ begin_template_parm_list (void) e.g.: template struct S1 { - template struct S2 {}; + template struct S2 {}; }; pushtag contains special code to call pushdecl_with_scope on the @@ -560,8 +538,8 @@ check_specialization_scope (void) { tree scope = current_scope (); - /* [temp.expl.spec] - + /* [temp.expl.spec] + An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class @@ -572,7 +550,7 @@ check_specialization_scope (void) if (scope && TREE_CODE (scope) != NAMESPACE_DECL) error ("explicit specialization in non-namespace scope %qD", scope); - /* [temp.expl.spec] + /* [temp.expl.spec] In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, @@ -580,7 +558,7 @@ check_specialization_scope (void) remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. */ - if (current_template_parms) + if (current_template_parms) error ("enclosing class templates are not explicitly specialized"); } @@ -597,7 +575,7 @@ begin_specialization (void) /* Called at then end of processing a declaration preceded by template<>. */ -void +void end_specialization (void) { finish_scope (); @@ -617,7 +595,7 @@ reset_specialization (void) /* We've just seen a template header. If SPECIALIZATION is nonzero, it was of the form template <>. */ -static void +static void note_template_header (int specialization) { processing_specialization = specialization; @@ -641,18 +619,18 @@ end_explicit_instantiation (void) processing_explicit_instantiation = false; } -/* A explicit specialization or partial specialization TMPL is being +/* An explicit specialization or partial specialization TMPL is being declared. Check that the namespace in which the specialization is occurring is permissible. Returns false iff it is invalid to specialize TMPL in the current namespace. */ - + static bool check_specialization_namespace (tree tmpl) { tree tpl_ns = decl_namespace_context (tmpl); /* [tmpl.expl.spec] - + An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class @@ -666,19 +644,40 @@ check_specialization_namespace (tree tmpl) else { pedwarn ("specialization of %qD in different namespace", tmpl); - cp_pedwarn_at (" from definition of %q#D", tmpl); + pedwarn (" from definition of %q+#D", tmpl); return false; } } +/* SPEC is an explicit instantiation. Check that it is valid to + perform this explicit instantiation in the current namespace. */ + +static void +check_explicit_instantiation_namespace (tree spec) +{ + tree ns; + + /* DR 275: An explicit instantiation shall appear in an enclosing + 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); +} + /* The TYPE is being declared. If it is a template type, that means it is a partial specialization. Do appropriate error-checking. */ -void +void maybe_process_partial_specialization (tree type) { - /* TYPE maybe an ERROR_MARK_NODE. */ - tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE; + tree context; + + if (type == error_mark_node) + return; + + context = TYPE_CONTEXT (type); if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type)) { @@ -735,8 +734,8 @@ maybe_process_partial_specialization (tree type) != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) { pedwarn ("specializing %q#T in different namespace", type); - cp_pedwarn_at (" from definition of %q#D", - CLASSTYPE_TI_TEMPLATE (type)); + pedwarn (" from definition of %q+#D", + CLASSTYPE_TI_TEMPLATE (type)); } /* Check for invalid specialization after instantiation: @@ -768,7 +767,7 @@ maybe_process_partial_specialization (tree type) for TMPL, a TEMPLATE_DECL. In particular, for such a template, we do not use DECL_TEMPLATE_SPECIALIZATIONS at all. */ -static inline bool +static inline bool optimize_specialization_lookup_p (tree tmpl) { return (DECL_FUNCTION_TEMPLATE_P (tmpl) @@ -786,10 +785,10 @@ optimize_specialization_lookup_p (tree tmpl) && !DECL_CONV_FN_P (tmpl) /* It is possible to have a template that is not a member template and is not a member of a template class: - - template + + template struct S { friend A::f(); }; - + Here, the friend function is a template, but the context does not have template information. The optimized lookup relies on having ARGS be the template arguments for both the class @@ -802,28 +801,28 @@ optimize_specialization_lookup_p (tree tmpl) specialization) of TMPL for the given template ARGS. If there is no such specialization, return NULL_TREE. The ARGS are a vector of arguments, or a vector of vectors of arguments, in the case of - templates with more than one level of parameters. + templates with more than one level of parameters. If TMPL is a type template and CLASS_SPECIALIZATIONS_P is true, then we search for a partial specialization matching ARGS. This parameter is ignored if TMPL is not a class template. */ - + static tree -retrieve_specialization (tree tmpl, tree args, +retrieve_specialization (tree tmpl, tree args, bool class_specializations_p) { gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); /* There should be as many levels of arguments as there are levels of parameters. */ - gcc_assert (TMPL_ARGS_DEPTH (args) + gcc_assert (TMPL_ARGS_DEPTH (args) == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); - + if (optimize_specialization_lookup_p (tmpl)) { tree class_template; tree class_specialization; - VEC(tree) *methods; + VEC(tree,gc) *methods; tree fns; int idx; @@ -831,7 +830,7 @@ retrieve_specialization (tree tmpl, tree args, class. Find the class specialization with those arguments. */ class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl)); - class_specialization + class_specialization = retrieve_specialization (class_template, args, /*class_specializations_p=*/false); if (!class_specialization) @@ -870,11 +869,11 @@ retrieve_specialization (tree tmpl, tree args, while (*sp != NULL_TREE) { tree spec = *sp; - + if (comp_template_args (TREE_PURPOSE (spec), args)) { /* Use the move-to-front heuristic to speed up future - searches. */ + searches. */ if (spec != *head) { *sp = TREE_CHAIN (*sp); @@ -895,8 +894,8 @@ retrieve_specialization (tree tmpl, tree args, static tree retrieve_local_specialization (tree tmpl) { - tree spec = htab_find_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl)); + tree spec = (tree) htab_find_with_hash (local_specializations, tmpl, + htab_hash_pointer (tmpl)); return spec ? TREE_PURPOSE (spec) : NULL_TREE; } @@ -909,13 +908,13 @@ is_specialization_of (tree decl, tree tmpl) if (TREE_CODE (decl) == FUNCTION_DECL) { - for (t = decl; + for (t = decl; t != NULL_TREE; t = DECL_TEMPLATE_INFO (t) ? DECL_TI_TEMPLATE (t) : NULL_TREE) if (t == tmpl) return 1; } - else + else { gcc_assert (TREE_CODE (decl) == TYPE_DECL); @@ -925,7 +924,7 @@ is_specialization_of (tree decl, tree tmpl) ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE) if (same_type_ignoring_top_level_qualifiers_p (t, TREE_TYPE (tmpl))) return 1; - } + } return 0; } @@ -939,7 +938,8 @@ is_specialization_of_friend (tree decl, tree friend) bool need_template = true; int template_depth; - gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == TYPE_DECL); /* For [temp.friend/6] when FRIEND is an ordinary member function of a template class, we want to check if DECL is a specialization @@ -948,23 +948,27 @@ is_specialization_of_friend (tree decl, tree friend) && DECL_TEMPLATE_INFO (friend) && !DECL_USE_TEMPLATE (friend)) { + /* We want a TEMPLATE_DECL for `is_specialization_of'. */ friend = DECL_TI_TEMPLATE (friend); need_template = false; } + else if (TREE_CODE (friend) == TEMPLATE_DECL + && !PRIMARY_TEMPLATE_P (friend)) + need_template = false; /* There is nothing to do if this is not a template friend. */ if (TREE_CODE (friend) != TEMPLATE_DECL) - return 0; + return false; if (is_specialization_of (decl, friend)) - return 1; + return true; /* [temp.friend/6] A member of a class template may be declared to be a friend of a non-template class. In this case, the corresponding member of every specialization of the class template is a friend of the class granting friendship. - + For example, given a template friend declaration template friend void A::f(); @@ -982,21 +986,29 @@ is_specialization_of_friend (tree decl, tree friend) template_depth = template_class_depth (DECL_CONTEXT (friend)); if (template_depth && DECL_CLASS_SCOPE_P (decl) - && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)), + && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)), CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend)))) { /* Next, we check the members themselves. In order to handle - a few tricky cases like + a few tricky cases, such as when FRIEND's are template friend void A::g(T t); template template friend void A::h(); - we need to figure out what ARGS is (corresponding to `T' in above - examples) from DECL for later processing. */ + and DECL's are + + void A::g(int); + template void A::h(); + + we need to figure out ARGS, the template arguments from + the context of DECL. This is required for template substitution + of `T' in the function parameter of `g' and template parameter + of `h' in the above examples. Here ARGS corresponds to `int'. */ tree context = DECL_CONTEXT (decl); tree args = NULL_TREE; int current_depth = 0; + while (current_depth < template_depth) { if (CLASSTYPE_TEMPLATE_INFO (context)) @@ -1023,7 +1035,7 @@ is_specialization_of_friend (tree decl, tree friend) is_template = DECL_TEMPLATE_INFO (decl) && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)); if (need_template ^ is_template) - return 0; + return false; else if (is_template) { /* If both are templates, check template parameter list. */ @@ -1033,7 +1045,7 @@ is_specialization_of_friend (tree decl, tree friend) if (!comp_template_parms (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)), friend_parms)) - return 0; + return false; decl_type = TREE_TYPE (DECL_TI_TEMPLATE (decl)); } @@ -1043,11 +1055,11 @@ is_specialization_of_friend (tree decl, tree friend) friend_type = tsubst_function_type (TREE_TYPE (friend), args, tf_none, NULL_TREE); if (friend_type == error_mark_node) - return 0; + return false; /* Check if return types match. */ if (!same_type_p (TREE_TYPE (decl_type), TREE_TYPE (friend_type))) - return 0; + return false; /* Check if function parameter types match, ignoring the `this' parameter. */ @@ -1057,25 +1069,61 @@ is_specialization_of_friend (tree decl, tree friend) friend_args_type = TREE_CHAIN (friend_args_type); if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) decl_args_type = TREE_CHAIN (decl_args_type); - if (compparms (decl_args_type, friend_args_type)) - return 1; + + return compparms (decl_args_type, friend_args_type); + } + else + { + /* DECL is a TYPE_DECL */ + bool is_template; + tree decl_type = TREE_TYPE (decl); + + /* Make sure that both DECL and FRIEND are templates or + non-templates. */ + is_template + = CLASSTYPE_TEMPLATE_INFO (decl_type) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (decl_type)); + + if (need_template ^ is_template) + return false; + else if (is_template) + { + tree friend_parms; + /* 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)) + return false; + + /* Now check template parameter list. */ + friend_parms + = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend), + args, tf_none); + return comp_template_parms + (DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (decl_type)), + friend_parms); + } + else + return (DECL_NAME (decl) + == DECL_NAME (friend)); } } - return 0; + return false; } /* Register the specialization SPEC as a specialization of TMPL with - the indicated ARGS. Returns SPEC, or an equivalent prior - declaration, if available. */ + the indicated ARGS. IS_FRIEND indicates whether the specialization + is actually just a friend declaration. Returns SPEC, or an + equivalent prior declaration, if available. */ static tree -register_specialization (tree spec, tree tmpl, tree args) +register_specialization (tree spec, tree tmpl, tree args, bool is_friend) { tree fn; gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); - if (TREE_CODE (spec) == FUNCTION_DECL + if (TREE_CODE (spec) == FUNCTION_DECL && uses_template_parms (DECL_TI_ARGS (spec))) /* This is the FUNCTION_DECL for a partial instantiation. Don't register it; we want the corresponding TEMPLATE_DECL instead. @@ -1084,18 +1132,13 @@ register_specialization (tree spec, tree tmpl, tree args) with default function arguments. In particular, given something like this: - template void f(T t1, T t = T()) + template void f(T t1, T t = T()) the default argument expression is not substituted for in an instantiation unless and until it is actually needed. */ return spec; - /* There should be as many levels of arguments as there are - levels of parameters. */ - gcc_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); - - fn = retrieve_specialization (tmpl, args, + fn = retrieve_specialization (tmpl, args, /*class_specializations_p=*/false); /* We can sometimes try to re-register a specialization that we've already got. In particular, regenerate_decl_from_template calls @@ -1108,7 +1151,7 @@ register_specialization (tree spec, tree tmpl, tree args) { if (DECL_TEMPLATE_INSTANTIATION (fn)) { - if (TREE_USED (fn) + if (TREE_USED (fn) || DECL_EXPLICIT_INSTANTIATION (fn)) { error ("specialization of %qD after instantiation", @@ -1117,6 +1160,7 @@ register_specialization (tree spec, tree tmpl, tree args) } else { + tree clone; /* This situation should occur only if the first specialization is an implicit instantiation, the second is an explicit specialization, and the @@ -1124,15 +1168,15 @@ register_specialization (tree spec, tree tmpl, tree args) situation can occur if we have implicitly instantiated a member function and then specialized it later. - + We can also wind up here if a friend declaration that looked like an instantiation turns out to be a specialization: - + template void foo(T); class S { friend void foo<>(int) }; - template <> void foo(int); - + template <> void foo(int); + We transform the existing DECL in place so that any pointers to it become pointers to the updated declaration. @@ -1141,19 +1185,37 @@ register_specialization (tree spec, tree tmpl, tree args) for the specialization, we want this to look as if there were no definition, and vice versa. */ DECL_INITIAL (fn) = NULL_TREE; - duplicate_decls (spec, fn); - + duplicate_decls (spec, fn, is_friend); + /* The call to duplicate_decls will have applied + [temp.expl.spec]: + + An explicit specialization of a function template + is inline only if it is explicitly declared to be, + and independently of whether its function template + is. + + to the primary function; now copy the inline bits to + the various clones. */ + FOR_EACH_CLONE (clone, fn) + { + DECL_DECLARED_INLINE_P (clone) + = DECL_DECLARED_INLINE_P (fn); + DECL_INLINE (clone) + = DECL_INLINE (fn); + } + check_specialization_namespace (fn); + return fn; } } else if (DECL_TEMPLATE_SPECIALIZATION (fn)) { - if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec)) + if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec)) /* Dup decl failed, but this is a new definition. Set the line number so any errors match this new definition. */ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec); - + return fn; } } @@ -1221,7 +1283,7 @@ register_local_specialization (tree spec, tree tmpl) { void **slot; - slot = htab_find_slot_with_hash (local_specializations, tmpl, + slot = htab_find_slot_with_hash (local_specializations, tmpl, htab_hash_pointer (tmpl), INSERT); *slot = build_tree_list (spec, tmpl); } @@ -1240,7 +1302,7 @@ print_candidates (tree fns) tree f; for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f)) - cp_error_at ("%s %+#D", str, OVL_CURRENT (f)); + error ("%s %+#D", str, OVL_CURRENT (f)); str = " "; } } @@ -1258,6 +1320,11 @@ print_candidates (tree fns) template classes that appeared in the name of the function. See check_explicit_specialization for a more accurate description. + TSK indicates what kind of template declaration (if any) is being + declared. TSK_TEMPLATE indicates that the declaration given by + DECL, though a FUNCTION_DECL, has template parameters, and is + therefore a template function. + The template args (those explicitly specified and those deduced) are output in a newly created vector *TARGS_OUT. @@ -1265,16 +1332,22 @@ print_candidates (tree fns) issued. The error_mark_node is returned to indicate failure. */ static tree -determine_specialization (tree template_id, - tree decl, - tree* targs_out, +determine_specialization (tree template_id, + tree decl, + tree* targs_out, int need_member_template, - int template_count) + int template_count, + tmpl_spec_kind tsk) { tree fns; tree targs; tree explicit_targs; tree candidates = NULL_TREE; + /* A TREE_LIST of templates of which DECL may be a specialization. + The TREE_VALUE of each node is a TEMPLATE_DECL. The + corresponding TREE_PURPOSE is the set of template arguments that, + when used to instantiate the template, would produce a function + with the signature of DECL. */ tree templates = NULL_TREE; int header_count; struct cp_binding_level *b; @@ -1304,7 +1377,7 @@ determine_specialization (tree template_id, specialization. */ header_count = 0; for (b = current_binding_level; - b->kind == sk_template_parms || b->kind == sk_template_spec; + b->kind == sk_template_parms; b = b->level_chain) ++header_count; @@ -1321,7 +1394,7 @@ determine_specialization (tree template_id, /* 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) + if (DECL_STATIC_FUNCTION_P (fn) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) decl_arg_types = TREE_CHAIN (decl_arg_types); @@ -1340,7 +1413,7 @@ determine_specialization (tree template_id, 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), + && !same_type_p (TREE_VALUE (fn_arg_types), TREE_VALUE (decl_arg_types))) continue; @@ -1359,23 +1432,44 @@ determine_specialization (tree template_id, is a template member function. So both lines are syntactically correct, and check_explicit_specialization does not reject them. - + Here, we can do better, as we are matching the specialization against the declarations. We count the number of template headers, and we check if they match TEMPLATE_COUNT + 1 (TEMPLATE_COUNT is the number of qualifying template classes, plus there must be another header for the member template itself). - + Notice that if header_count is zero, this is not a specialization but rather a template instantiation, so there is no check we can perform here. */ if (header_count && header_count != template_count + 1) continue; + /* Check that the number of template arguments at the + innermost level for DECL is the same as for FN. */ + if (current_binding_level->kind == sk_template_parms + && !current_binding_level->explicit_spec_p + && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn)) + != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS + (current_template_parms)))) + 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)) + candidates = tree_cons (NULL_TREE, fn, candidates); + continue; + } + /* See whether this function might be a specialization of this template. */ - targs = get_bindings (fn, decl, explicit_targs); + targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true); if (!targs) /* We cannot deduce template arguments that when used to @@ -1407,7 +1501,7 @@ determine_specialization (tree template_id, /* This is an ordinary member function. However, since we're here, we can assume it's enclosing class is a template class. For example, - + template struct S { void f(); }; template <> void S::f() {} @@ -1427,11 +1521,11 @@ determine_specialization (tree template_id, /* 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) + if (DECL_STATIC_FUNCTION_P (fn) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) decl_arg_types = TREE_CHAIN (decl_arg_types); - if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), + if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), decl_arg_types)) /* They match! */ candidates = tree_cons (NULL_TREE, fn, candidates); @@ -1441,7 +1535,7 @@ determine_specialization (tree template_id, if (templates && TREE_CHAIN (templates)) { /* We have: - + [temp.expl.spec] It is possible for a specialization with a given function @@ -1459,10 +1553,10 @@ determine_specialization (tree template_id, Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template - specialization refers: + specialization refers: - -- when an explicit specialization refers to a function - template. + -- when an explicit specialization refers to a function + template. So, we do use the partial ordering rules, at least for now. This extension can only serve to make invalid programs valid, @@ -1471,27 +1565,26 @@ determine_specialization (tree template_id, 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 (templates, decl, explicit_targs); - if (tmpl && tmpl != error_mark_node) - { - targs = get_bindings (tmpl, decl, explicit_targs); - templates = tree_cons (targs, tmpl, NULL_TREE); - } + tree tmpl = most_specialized_instantiation (templates); + if (tmpl != error_mark_node) + { + templates = tmpl; + TREE_CHAIN (templates) = NULL_TREE; + } } if (templates == NULL_TREE && candidates == NULL_TREE) { - cp_error_at ("template-id %qD for %q+D does not match any template " - "declaration", - template_id, decl); + error ("template-id %qD for %q+D does not match any template " + "declaration", template_id, decl); return error_mark_node; } else if ((templates && TREE_CHAIN (templates)) || (candidates && TREE_CHAIN (candidates)) || (templates && candidates)) { - cp_error_at ("ambiguous template specialization %qD for %q+D", - template_id, decl); + error ("ambiguous template specialization %qD for %q+D", + template_id, decl); chainon (candidates, templates); print_candidates (candidates); return error_mark_node; @@ -1500,10 +1593,14 @@ determine_specialization (tree template_id, /* We have one, and exactly one, match. */ if (candidates) { + tree fn = TREE_VALUE (candidates); + /* DECL is a re-declaration of a template function. */ + if (TREE_CODE (fn) == TEMPLATE_DECL) + return fn; /* It was a specialization of an ordinary member function in a template class. */ - *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates))); - return DECL_TI_TEMPLATE (TREE_VALUE (candidates)); + *targs_out = copy_node (DECL_TI_ARGS (fn)); + return DECL_TI_TEMPLATE (fn); } /* It was a specialization of a template. */ @@ -1511,7 +1608,7 @@ determine_specialization (tree template_id, if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs)) { *targs_out = copy_node (targs); - SET_TMPL_ARGS_LEVEL (*targs_out, + SET_TMPL_ARGS_LEVEL (*targs_out, TMPL_ARGS_DEPTH (*targs_out), TREE_PURPOSE (templates)); } @@ -1523,7 +1620,7 @@ determine_specialization (tree template_id, /* Returns a chain of parameter types, exactly like the SPEC_TYPES, but with the default argument values filled in from those in the TMPL_TYPES. */ - + static tree copy_default_args_to_explicit_spec_1 (tree spec_types, tree tmpl_types) @@ -1540,7 +1637,7 @@ copy_default_args_to_explicit_spec_1 (tree spec_types, new_spec_types = copy_default_args_to_explicit_spec_1 (TREE_CHAIN (spec_types), TREE_CHAIN (tmpl_types)); - + /* Add the default argument for this parameter. */ return hash_tree_cons (TREE_PURPOSE (tmpl_types), TREE_VALUE (spec_types), @@ -1552,7 +1649,7 @@ copy_default_args_to_explicit_spec_1 (tree spec_types, template void f(T = 3); template <> void f(double); - void g () { f (); } + void g () { f (); } works, as required.) An alternative approach would be to look up the correct default arguments at the call-site, but this approach @@ -1583,20 +1680,20 @@ copy_default_args_to_explicit_spec (tree decl) old_type = TREE_TYPE (decl); spec_types = TYPE_ARG_TYPES (old_type); - + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) { /* Remove the this pointer, but remember the object's type for - CV quals. */ + CV quals. */ object_type = TREE_TYPE (TREE_VALUE (spec_types)); spec_types = TREE_CHAIN (spec_types); tmpl_types = TREE_CHAIN (tmpl_types); - + if (DECL_HAS_IN_CHARGE_PARM_P (decl)) - { - /* DECL may contain more parameters than TMPL due to the extra - in-charge parameter in constructors and destructors. */ - in_charge = spec_types; + { + /* DECL may contain more parameters than TMPL due to the extra + in-charge parameter in constructors and destructors. */ + in_charge = spec_types; spec_types = TREE_CHAIN (spec_types); } if (DECL_HAS_VTT_PARM_P (decl)) @@ -1607,22 +1704,22 @@ copy_default_args_to_explicit_spec (tree decl) } /* Compute the merged default arguments. */ - new_spec_types = + new_spec_types = copy_default_args_to_explicit_spec_1 (spec_types, tmpl_types); /* Compute the new FUNCTION_TYPE. */ if (object_type) { if (vtt) - new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt), - TREE_VALUE (vtt), - new_spec_types); + new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt), + TREE_VALUE (vtt), + new_spec_types); if (in_charge) - /* Put the in-charge parameter back. */ - new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge), - TREE_VALUE (in_charge), - new_spec_types); + /* Put the in-charge parameter back. */ + new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge), + TREE_VALUE (in_charge), + new_spec_types); new_type = build_method_type_directly (object_type, TREE_TYPE (old_type), @@ -1647,8 +1744,8 @@ copy_default_args_to_explicit_spec (tree decl) instead if all goes well. Issues an error message if something is amiss. Returns error_mark_node if the error is not easily recoverable. - - FLAGS is a bitmask consisting of the following flags: + + FLAGS is a bitmask consisting of the following flags: 2: The function has a definition. 4: The function is a friend. @@ -1659,7 +1756,7 @@ copy_default_args_to_explicit_spec (tree decl) template struct S { void f(); }; void S::f(); - + the TEMPLATE_COUNT would be 1. However, explicitly specialized classes are not counted in the TEMPLATE_COUNT, so that in @@ -1672,14 +1769,14 @@ copy_default_args_to_explicit_spec (tree decl) If the function is a specialization, it is marked as such via DECL_TEMPLATE_SPECIALIZATION. Furthermore, its DECL_TEMPLATE_INFO - is set up correctly, and it is added to the list of specializations + is set up correctly, and it is added to the list of specializations for that template. */ tree -check_explicit_specialization (tree declarator, - tree decl, - int template_count, - int flags) +check_explicit_specialization (tree declarator, + tree decl, + int template_count, + int flags) { int have_def = flags & 2; int is_friend = flags & 4; @@ -1690,12 +1787,20 @@ check_explicit_specialization (tree declarator, tree dname = DECL_NAME (decl); tmpl_spec_kind tsk; - tsk = current_tmpl_spec_kind (template_count); + if (is_friend) + { + if (!processing_specialization) + tsk = tsk_none; + else + tsk = tsk_excessive_parms; + } + else + tsk = current_tmpl_spec_kind (template_count); switch (tsk) { case tsk_none: - if (processing_specialization) + if (processing_specialization) { specialization = 1; SET_DECL_TEMPLATE_SPECIALIZATION (decl); @@ -1714,7 +1819,7 @@ check_explicit_specialization (tree declarator, template void f(); */ error ("template-id %qD in declaration of primary template", - declarator); + declarator); return decl; } } @@ -1733,20 +1838,20 @@ check_explicit_specialization (tree declarator, case tsk_expl_inst: if (have_def) error ("definition provided for explicit instantiation"); - + explicit_instantiation = 1; break; case tsk_excessive_parms: case tsk_insufficient_parms: if (tsk == tsk_excessive_parms) - error ("too many template parameter lists in declaration of %qD", + error ("too many template parameter lists in declaration of %qD", decl); else if (template_header_count) error("too few template parameter lists in declaration of %qD", decl); else error("explicit specialization of %qD must be introduced by " - "`template <>'", decl); + "%