diff options
Diffstat (limited to 'contrib/gcc/cp/pt.c')
-rw-r--r-- | contrib/gcc/cp/pt.c | 7574 |
1 files changed, 4297 insertions, 3277 deletions
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 0ae2d23e70f8f..cca1f38a27300 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -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: @@ -32,16 +32,20 @@ Boston, MA 02111-1307, USA. */ #include "tm.h" #include "obstack.h" #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 "lex.h" #include "output.h" #include "except.h" #include "toplev.h" #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. */ @@ -60,13 +64,17 @@ 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; static GTY(()) tree saved_access_scope; +/* Live only within one (recursive) call to tsubst_expr. We use + this to pass the statement expression node from the STMT_EXPR + to the EXPR_STMT that is its result. */ +static tree cur_stmt_expr; + /* A map from local variable declarations in the body of the template presently being instantiated to the corresponding instantiated local variables. */ @@ -80,13 +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 - -#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is - virtual, or a base class of a virtual - base. */ -#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current - type with the desired type. */ static void push_access_scope (tree); static void pop_access_scope (tree); @@ -96,66 +97,59 @@ 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*, htab_t); +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); static int inline_needs_template_parms (tree); static void push_inline_template_parms_recursive (tree, int); -static tree retrieve_specialization (tree, tree); static tree retrieve_local_specialization (tree); -static tree register_specialization (tree, tree, tree); static void register_local_specialization (tree, tree); static tree reduce_template_parm_level (tree, tree, int); -static tree build_template_decl (tree, tree); static int mark_template_parm (tree, void *); 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 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 tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree); -static tree get_template_base_recursive (tree, tree, tree, tree, tree, int); 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); static int template_args_equal (tree, tree); static void tsubst_default_arguments (tree); static tree for_each_template_parm_r (tree *, int *, void *); @@ -165,7 +159,7 @@ static int invalid_nontype_parm_type_p (tree, tsubst_flags_t); static int eq_local_specializations (const void *, const void *); 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); /* Make the current scope suitable for access checking when we are @@ -176,9 +170,8 @@ static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static void push_access_scope (tree t) { - my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL - || TREE_CODE (t) == VAR_DECL, - 0); + gcc_assert (TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == VAR_DECL); if (DECL_FRIEND_CONTEXT (t)) push_nested_class (DECL_FRIEND_CONTEXT (t)); @@ -186,7 +179,7 @@ push_access_scope (tree t) push_nested_class (DECL_CONTEXT (t)); else push_to_top_level (); - + if (TREE_CODE (t) == FUNCTION_DECL) { saved_access_scope = tree_cons @@ -224,14 +217,14 @@ finish_member_template_decl (tree decl) if (decl == error_mark_node) return error_mark_node; - my_friendly_assert (DECL_P (decl), 20020812); + gcc_assert (DECL_P (decl)); if (TREE_CODE (decl) == TYPE_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)) { @@ -242,7 +235,7 @@ finish_member_template_decl (tree decl) return NULL_TREE; } else if (TREE_CODE (decl) == FIELD_DECL) - error ("data member `%D' cannot be a member template", decl); + error ("data member %qD cannot be a member template", decl); else if (DECL_TEMPLATE_INFO (decl)) { if (!DECL_TEMPLATE_SPECIALIZATION (decl)) @@ -252,15 +245,15 @@ finish_member_template_decl (tree decl) } else return decl; - } + } else - error ("invalid member template declaration `%D'", decl); + error ("invalid member template declaration %qD", decl); return error_mark_node; } /* Returns the template nesting level of the indicated class TYPE. - + For example, in: template <class T> struct A @@ -269,41 +262,36 @@ finish_member_template_decl (tree decl) struct B {}; }; - A<T>::B<U> has depth two, while A<T> has depth one. + A<T>::B<U> has depth two, while A<T> has depth one. Both A<T>::B<int> and A<int>::B<U> 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; } } @@ -311,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. */ @@ -355,11 +333,15 @@ 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)); - my_friendly_assert (DECL_P (parm), 0); + + if (parm == error_mark_node) + continue; + + gcc_assert (DECL_P (parm)); switch (TREE_CODE (parm)) { @@ -377,7 +359,9 @@ push_inline_template_parms_recursive (tree parmlist, int levels) tree decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); DECL_ARTIFICIAL (decl) = 1; - TREE_CONSTANT (decl) = TREE_READONLY (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); pushdecl (decl); @@ -385,7 +369,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels) break; default: - abort (); + gcc_unreachable (); } } } @@ -415,28 +399,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); @@ -444,67 +422,6 @@ maybe_end_member_template_processing (void) } } -/* Returns nonzero iff T is a member template function. We must be - careful as in - - template <class T> class C { void f(); } - - Here, f is a template function, and a member, but not a member - template. This function does not concern itself with the origin of - T, only its present state. So if we have - - template <class T> class C { template <class U> void f(U); } - - then neither C<int>::f<char> nor C<T>::f<double> is considered - to be a member template. But, `template <class U> void - C<int>::f(U)' is considered a member template. */ - -int -is_member_template (tree t) -{ - if (!DECL_FUNCTION_TEMPLATE_P (t)) - /* Anything that isn't a function or a template function is - certainly not a member template. */ - return 0; - - /* A local class can't have member templates. */ - if (decl_function_context (t)) - return 0; - - return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)) - /* If there are more levels of template parameters than - there are template classes surrounding the declaration, - then we have a member template. */ - && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > - template_class_depth (DECL_CONTEXT (t)))); -} - -#if 0 /* UNUSED */ -/* Returns nonzero iff T is a member template class. See - is_member_template for a description of what precisely constitutes - a member template. */ - -int -is_member_template_class (tree t) -{ - if (!DECL_CLASS_TEMPLATE_P (t)) - /* Anything that isn't a class template, is certainly not a member - template. */ - return 0; - - if (!DECL_CLASS_SCOPE_P (t)) - /* Anything whose context isn't a class type is surely not a - member template. */ - return 0; - - /* If there are more levels of template parameters than there are - template classes surrounding the declaration, then we have a - member template. */ - return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > - template_class_depth (DECL_CONTEXT (t))); -} -#endif - /* Return a new template argument vector which contains all of ARGS, but has as its innermost set of arguments the EXTRA_ARGS. */ @@ -524,7 +441,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; } @@ -542,8 +459,7 @@ add_outermost_template_args (tree args, tree extra_args) /* If there are more levels of EXTRA_ARGS than there are ARGS, something very fishy is going on. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args), - 0); + gcc_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args)); /* If *all* the new arguments will be the EXTRA_ARGS, just return them. */ @@ -552,7 +468,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. */ @@ -570,23 +486,23 @@ get_innermost_template_args (tree args, int n) int extra_levels; int i; - my_friendly_assert (n >= 0, 20000603); + gcc_assert (n >= 0); /* 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; - my_friendly_assert (extra_levels >= 0, 20000603); + gcc_assert (extra_levels >= 0); if (extra_levels == 0) return args; /* 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; @@ -607,7 +523,7 @@ begin_template_parm_list (void) e.g.: template <class T> struct S1 { - template <class T> struct S2 {}; + template <class T> struct S2 {}; }; pushtag contains special code to call pushdecl_with_scope on the @@ -619,15 +535,16 @@ 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 (); - /* [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 @@ -636,10 +553,12 @@ 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 `%D'", - scope); + { + error ("explicit specialization in non-namespace scope %qD", scope); + return false; + } - /* [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, @@ -647,24 +566,29 @@ 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) - error ("enclosing class templates are not explicitly specialized"); + if (current_template_parms) + { + 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 template<>. */ -void +void end_specialization (void) { finish_scope (); @@ -684,7 +608,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; @@ -696,7 +620,7 @@ note_template_header (int specialization) void begin_explicit_instantiation (void) { - my_friendly_assert (!processing_explicit_instantiation, 20020913); + gcc_assert (!processing_explicit_instantiation); processing_explicit_instantiation = true; } @@ -704,22 +628,22 @@ begin_explicit_instantiation (void) void end_explicit_instantiation (void) { - my_friendly_assert(processing_explicit_instantiation, 20020913); + gcc_assert (processing_explicit_instantiation); 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 @@ -732,22 +656,46 @@ check_specialization_namespace (tree tmpl) return true; else { - pedwarn ("specialization of `%D' in different namespace", tmpl); - cp_pedwarn_at (" from definition of `%#D'", tmpl); + pedwarn ("specialization of %qD in different namespace", 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 +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); @@ -773,7 +721,7 @@ maybe_process_partial_specialization (tree type) push_template_decl (TYPE_MAIN_DECL (type)); } else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - error ("specialization of `%T' after instantiation", type); + error ("specialization of %qT after instantiation", type); } else if (CLASS_TYPE_P (type) && !CLASSTYPE_USE_TEMPLATE (type) @@ -805,9 +753,9 @@ maybe_process_partial_specialization (tree type) if (current_namespace != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) { - pedwarn ("specializing `%#T' in different namespace", type); - cp_pedwarn_at (" from definition of `%#D'", - CLASSTYPE_TI_TEMPLATE (type)); + pedwarn ("specializing %q#T in different namespace", type); + pedwarn (" from definition of %q+#D", + CLASSTYPE_TI_TEMPLATE (type)); } /* Check for invalid specialization after instantiation: @@ -820,7 +768,7 @@ maybe_process_partial_specialization (tree type) t; t = TREE_CHAIN (t)) if (TREE_VALUE (t) != type && TYPE_CONTEXT (TREE_VALUE (t)) == context) - error ("specialization `%T' after instantiation `%T'", + error ("specialization %qT after instantiation %qT", type, TREE_VALUE (t)); /* Mark TYPE as a specialization. And as a result, we only @@ -832,7 +780,45 @@ maybe_process_partial_specialization (tree type) } } else if (processing_specialization) - error ("explicit specialization of non-template `%T'", 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 + for TMPL, a TEMPLATE_DECL. In particular, for such a template, we + do not use DECL_TEMPLATE_SPECIALIZATIONS at all. */ + +static inline bool +optimize_specialization_lookup_p (tree tmpl) +{ + return (DECL_FUNCTION_TEMPLATE_P (tmpl) + && DECL_CLASS_SCOPE_P (tmpl) + /* DECL_CLASS_SCOPE_P holds of T::f even if T is a template + parameter. */ + && CLASS_TYPE_P (DECL_CONTEXT (tmpl)) + /* The optimized lookup depends on the fact that the + template arguments for the member function template apply + purely to the containing class, which is not true if the + containing class is an explicit or partial + specialization. */ + && !CLASSTYPE_TEMPLATE_SPECIALIZATION (DECL_CONTEXT (tmpl)) + && !DECL_MEMBER_TEMPLATE_P (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 <typename T> + 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 + and the function template. */ + && !DECL_FRIEND_P (DECL_TEMPLATE_RESULT (tmpl))); } /* Retrieve the specialization (in the sense of [temp.spec] - a @@ -840,26 +826,93 @@ maybe_process_partial_specialization (tree type) 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) { - tree s; + if (args == error_mark_node) + return NULL_TREE; - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); /* There should be as many levels of arguments as there are levels of parameters. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), - 0); - - for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - s != NULL_TREE; - s = TREE_CHAIN (s)) - if (comp_template_args (TREE_PURPOSE (s), args)) - return TREE_VALUE (s); + 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,gc) *methods; + tree fns; + int idx; + + /* The template arguments actually apply to the containing + class. Find the class specialization with those + arguments. */ + class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl)); + class_specialization + = retrieve_specialization (class_template, args, + /*class_specializations_p=*/false); + if (!class_specialization) + return NULL_TREE; + /* Now, find the appropriate entry in the CLASSTYPE_METHOD_VEC + for the specialization. */ + idx = class_method_index_for_fn (class_specialization, tmpl); + if (idx == -1) + return NULL_TREE; + /* Iterate through the methods with the indicated name, looking + for the one that has an instance of TMPL. */ + methods = CLASSTYPE_METHOD_VEC (class_specialization); + for (fns = VEC_index (tree, methods, idx); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl) + return fn; + } + return NULL_TREE; + } + else + { + tree *sp; + tree *head; + + /* Class templates store their instantiations on the + DECL_TEMPLATE_INSTANTIATIONS list; other templates use the + DECL_TEMPLATE_SPECIALIZATIONS list. */ + if (!class_specializations_p + && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL) + sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl); + else + sp = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); + head = sp; + /* Iterate through the list until we find a matching template. */ + 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. */ + if (spec != *head) + { + *sp = TREE_CHAIN (*sp); + TREE_CHAIN (spec) = *head; + *head = spec; + } + return TREE_VALUE (spec); + } + sp = &TREE_CHAIN (spec); + } + } return NULL_TREE; } @@ -869,8 +922,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; } @@ -883,15 +936,15 @@ 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 { - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 0); + gcc_assert (TREE_CODE (decl) == TYPE_DECL); for (t = TREE_TYPE (decl); t != NULL_TREE; @@ -899,7 +952,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; } @@ -913,7 +966,8 @@ is_specialization_of_friend (tree decl, tree friend) bool need_template = true; int template_depth; - my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0); + 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 @@ -922,23 +976,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 <class T> friend void A<T>::f(); @@ -956,21 +1014,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 <class T> friend void A<T>::g(T t); template <class T> template <T t> friend void A<T>::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<int>::g(int); + template <int> void A<int>::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)) @@ -997,7 +1063,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. */ @@ -1007,7 +1073,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)); } @@ -1017,11 +1083,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. */ @@ -1031,25 +1097,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 s; + tree fn; - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); + 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. @@ -1058,98 +1160,103 @@ register_specialization (tree spec, tree tmpl, tree args) with default function arguments. In particular, given something like this: - template <class T> void f(T t1, T t = T()) + template <class T> 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. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), - 0); - - for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - s != NULL_TREE; - s = TREE_CHAIN (s)) - { - tree fn = TREE_VALUE (s); - - /* We can sometimes try to re-register a specialization that we've - already got. In particular, regenerate_decl_from_template - calls duplicate_decls which will update the specialization - list. But, we'll still get called again here anyhow. It's - more convenient to simply allow this than to try to prevent it. */ - if (fn == spec) - return spec; - else if (comp_template_args (TREE_PURPOSE (s), 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 + duplicate_decls which will update the specialization list. But, + we'll still get called again here anyhow. It's more convenient + to simply allow this than to try to prevent it. */ + if (fn == spec) + return spec; + else if (fn && DECL_TEMPLATE_SPECIALIZATION (spec)) + { + if (DECL_TEMPLATE_INSTANTIATION (fn)) { - if (DECL_TEMPLATE_SPECIALIZATION (spec)) + if (TREE_USED (fn) + || DECL_EXPLICIT_INSTANTIATION (fn)) { - if (DECL_TEMPLATE_INSTANTIATION (fn)) - { - if (TREE_USED (fn) - || DECL_EXPLICIT_INSTANTIATION (fn)) - { - error ("specialization of %D after instantiation", - fn); - return spec; - } - else - { - /* This situation should occur only if the first - specialization is an implicit instantiation, - the second is an explicit specialization, and - the implicit instantiation has not yet been - used. That 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 <class T> void foo(T); - class S { friend 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. - - If there was a definition for the template, but - not for the specialization, we want this to - look as if there is no definition, and vice - versa. */ - DECL_INITIAL (fn) = NULL_TREE; - duplicate_decls (spec, fn); - - return fn; - } - } - else if (DECL_TEMPLATE_SPECIALIZATION (fn)) + error ("specialization of %qD after instantiation", + fn); + return error_mark_node; + } + else + { + tree clone; + /* This situation should occur only if the first + specialization is an implicit instantiation, the + second is an explicit specialization, and the + implicit instantiation has not yet been used. That + 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 <class T> void foo(T); + class S { friend 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. + + If there was a definition for the template, but not + 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, 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) { - if (!duplicate_decls (spec, fn) && 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; + 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, 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; + } + } /* A specialization must be declared in the same namespace as the 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)); - DECL_TEMPLATE_SPECIALIZATIONS (tmpl) - = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); + if (!optimize_specialization_lookup_p (tmpl)) + DECL_TEMPLATE_SPECIALIZATIONS (tmpl) + = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); return spec; } @@ -1204,11 +1311,22 @@ 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); } +/* 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 @@ -1223,7 +1341,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 = " "; } } @@ -1237,6 +1355,15 @@ print_candidates (tree fns) If NEED_MEMBER_TEMPLATE is nonzero the function is known to be a specialization of a member template. + The TEMPLATE_COUNT is the number of references to qualifying + 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. @@ -1244,20 +1371,29 @@ 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, - int need_member_template) +determine_specialization (tree template_id, + tree decl, + tree* targs_out, + int need_member_template, + 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; *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); @@ -1272,10 +1408,18 @@ determine_specialization (tree template_id, if (!is_overloaded_fn (fns)) { - error ("`%D' is not a function template", fns); + error ("%qD is not a function template", fns); return error_mark_node; } + /* Count the number of template headers specified for this + specialization. */ + header_count = 0; + for (b = current_binding_level; + b->kind == sk_template_parms; + b = b->level_chain) + ++header_count; + for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); @@ -1285,13 +1429,65 @@ determine_specialization (tree template_id, tree decl_arg_types; tree fn_arg_types; - /* DECL might be a specialization of FN. */ + /* 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, + but the check done there cannot be exhaustive when specializing + member functions. Consider the following code: + + template <> void A<int>::f(int); + template <> template <> void A<int>::f(int); + + Assuming that A<int> is not itself an explicit specialization + already, the first line specializes "f" which is a non-template + member function, whilst the second line specializes "f" which + 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; - /* Adjust the type of DECL in case FN is a static member. */ + /* 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; + + /* DECL might be a specialization of FN. */ 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); + 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, @@ -1299,22 +1495,23 @@ determine_specialization (tree template_id, template <> void f<int>(); The specialization f<int> 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; + /* 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 (fn_arg_types, 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 @@ -1346,7 +1543,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 <typename T> struct S { void f(); }; template <> void S<int>::f() {} @@ -1366,11 +1563,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); @@ -1380,7 +1577,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 @@ -1398,10 +1595,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, @@ -1410,26 +1607,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 `%D' for `%+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 `%D' for `%+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; @@ -1438,10 +1635,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. */ @@ -1449,7 +1650,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)); } @@ -1461,7 +1662,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) @@ -1478,7 +1679,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), @@ -1490,7 +1691,7 @@ copy_default_args_to_explicit_spec_1 (tree spec_types, template <class T> 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 @@ -1521,20 +1722,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)) @@ -1545,22 +1746,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), @@ -1585,8 +1786,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. @@ -1597,7 +1798,7 @@ copy_default_args_to_explicit_spec (tree decl) template <class T> struct S { void f(); }; void S<int>::f(); - + the TEMPLATE_COUNT would be 1. However, explicitly specialized classes are not counted in the TEMPLATE_COUNT, so that in @@ -1610,14 +1811,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; @@ -1628,12 +1829,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); @@ -1651,8 +1860,8 @@ check_explicit_specialization (tree declarator, /* This case handles bogus declarations like template <> template <class T> void f<int>(); */ - error ("template-id `%D' in declaration of primary template", - declarator); + error ("template-id %qD in declaration of primary template", + declarator); return decl; } } @@ -1671,14 +1880,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: - error ("too many template parameter lists in declaration of `%D'", - decl); - return error_mark_node; + case tsk_insufficient_parms: + if (tsk == tsk_excessive_parms) + 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); /* Fall through. */ case tsk_expl_spec: @@ -1688,32 +1903,6 @@ check_explicit_specialization (tree declarator, else specialization = 1; break; - - case tsk_insufficient_parms: - if (template_header_count) - { - error("too few template parameter lists in declaration of `%D'", - decl); - return decl; - } - else if (ctype != NULL_TREE - && !TYPE_BEING_DEFINED (ctype) - && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype) - && !is_friend) - { - /* For backwards compatibility, we accept: - - template <class T> struct S { void f(); }; - void S<int>::f() {} // Missing template <> - - That used to be valid C++. */ - if (pedantic) - pedwarn - ("explicit specialization not preceded by `template <>'"); - specialization = 1; - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - } - break; case tsk_template: if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) @@ -1722,11 +1911,11 @@ check_explicit_specialization (tree declarator, template <class T> void f<int>(); */ if (uses_template_parms (declarator)) - error ("partial specialization `%D' of function template", - declarator); + error ("function template partial specialization %qD " + "is not allowed", declarator); else - error ("template-id `%D' in declaration of primary template", - declarator); + error ("template-id %qD in declaration of primary template", + declarator); return decl; } @@ -1735,16 +1924,16 @@ check_explicit_specialization (tree declarator, specialization the containing class. Something like: template <class T> struct S { - template <class U> void f (U); - }; + template <class U> void f (U); + }; template <> template <class U> void S<int>::f(U) {} - + That's a specialization -- but of the entire template. */ specialization = 1; break; default: - abort (); + gcc_unreachable (); } if (specialization || member_specialization) @@ -1757,8 +1946,6 @@ check_explicit_specialization (tree declarator, ("default argument specified in explicit specialization"); break; } - if (current_lang_name == lang_name_c) - error ("template specialization with C linkage"); } if (specialization || member_specialization || explicit_instantiation) @@ -1771,23 +1958,32 @@ check_explicit_specialization (tree declarator, { tree fns; - my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 0); + gcc_assert (TREE_CODE (declarator) == IDENTIFIER_NODE); if (ctype) fns = dname; else { /* If there is no class context, the explicit instantiation - must be at namespace scope. */ - my_friendly_assert (DECL_NAMESPACE_SCOPE_P (decl), 20030625); + must be at namespace scope. */ + gcc_assert (DECL_NAMESPACE_SCOPE_P (decl)); /* Find the namespace binding, using the declaration - context. */ - fns = namespace_binding (dname, CP_DECL_CONTEXT (decl)); + context. */ + fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, + false, true); if (!fns || !is_overloaded_fn (fns)) { - error ("`%D' is not a template function", dname); + error ("%qD is not a template function", dname); fns = error_mark_node; } + else + { + tree fn = OVL_CURRENT (fns); + if (!is_associated_namespace (CP_DECL_CONTEXT (decl), + CP_DECL_CONTEXT (fn))) + error ("%qD is not declared in %qD", + decl, current_namespace); + } } declarator = lookup_template_function (fns, NULL_TREE); @@ -1808,11 +2004,11 @@ check_explicit_specialization (tree declarator, /* It's not valid to write an explicit instantiation in class scope, e.g.: - class C { template void f(); } + class C { template void f(); } This case is caught by the parser. However, on something like: - + template class C { void f(); }; (which is invalid) we can get here. The error will be @@ -1822,7 +2018,7 @@ check_explicit_specialization (tree declarator, return decl; } - else if (ctype != NULL_TREE + else if (ctype != NULL_TREE && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE)) { @@ -1835,16 +2031,16 @@ check_explicit_specialization (tree declarator, if (constructor_name_p (name, ctype)) { int is_constructor = DECL_CONSTRUCTOR_P (decl); - + if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype) - : !TYPE_HAS_DESTRUCTOR (ctype)) + : !CLASSTYPE_DESTRUCTORS (ctype)) { /* From [temp.expl.spec]: - + If such an explicit specialization for the member of a class template names an implicitly-declared special member function (clause _special_), the - program is ill-formed. + program is ill-formed. Similar language is found in [temp.explicit]. */ error ("specialization of implicitly-declared special member function"); @@ -1858,11 +2054,12 @@ check_explicit_specialization (tree declarator, { idx = lookup_fnfields_1 (ctype, name); if (idx >= 0) - fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx); + fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (ctype), idx); } else { - tree methods; + VEC(tree,gc) *methods; + tree ovl; /* For a type-conversion operator, we cannot do a name-based lookup. We might be looking for `operator @@ -1874,11 +2071,10 @@ check_explicit_specialization (tree declarator, methods = CLASSTYPE_METHOD_VEC (ctype); if (methods) for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT; - idx < TREE_VEC_LENGTH (methods); ++idx) + VEC_iterate (tree, methods, idx, ovl); + ++idx) { - tree ovl = TREE_VEC_ELT (methods, idx); - - if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl))) + if (!DECL_CONV_FN_P (OVL_CURRENT (ovl))) /* There are no more conversion functions. */ break; @@ -1888,17 +2084,16 @@ check_explicit_specialization (tree declarator, fns = ovl_cons (OVL_CURRENT (ovl), fns); } } - - if (fns == NULL_TREE) + + if (fns == NULL_TREE) { - error ("no member function `%D' declared in `%T'", - name, ctype); + error ("no member function %qD declared in %qT", name, ctype); return error_mark_node; } else TREE_OPERAND (declarator, 0) = fns; } - + /* Figure out what exactly is being specialized at this point. Note that for an explicit instantiation, even one for a member function, we cannot tell apriori whether the @@ -1908,9 +2103,11 @@ check_explicit_specialization (tree declarator, elided if they can be deduced from the rest of the declaration. */ tmpl = determine_specialization (declarator, decl, - &targs, - member_specialization); - + &targs, + member_specialization, + template_count, + tsk); + if (!tmpl || tmpl == error_mark_node) /* We couldn't figure out what this declaration was specializing. */ @@ -1922,7 +2119,7 @@ check_explicit_specialization (tree declarator, if (explicit_instantiation) { /* We don't set DECL_EXPLICIT_INSTANTIATION here; that - is done by do_decl_instantiation later. */ + is done by do_decl_instantiation later. */ int arg_depth = TMPL_ARGS_DEPTH (targs); int parm_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); @@ -1943,7 +2140,7 @@ check_explicit_specialization (tree declarator, = TREE_VEC_ELT (targs, i); targs = new_targs; } - + return instantiate_template (tmpl, targs, tf_error); } @@ -1955,8 +2152,8 @@ check_explicit_specialization (tree declarator, revert_static_member_fn (decl); /* If this is a specialization of a member template of a - template class. In we want to return the TEMPLATE_DECL, - not the specialization of it. */ + template class, we want to return the TEMPLATE_DECL, not + the specialization of it. */ if (tsk == tsk_template) { SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); @@ -1986,6 +2183,20 @@ check_explicit_specialization (tree declarator, TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl); TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl); + /* If DECL is a friend declaration, declared using an + unqualified name, the namespace associated with DECL may + have been set incorrectly. For example, in: + + template <typename T> void f(T); + namespace N { + struct S { friend void f<int>(int); } + } + + we will have set the DECL_CONTEXT for the friend + declaration to N, rather than to the global namespace. */ + if (DECL_NAMESPACE_SCOPE_P (decl)) + DECL_CONTEXT (decl) = DECL_CONTEXT (tmpl); + if (is_friend && !have_def) /* This is not really a declaration of a specialization. It's just the name of an instantiation. But, it's not @@ -1999,10 +2210,10 @@ check_explicit_specialization (tree declarator, /* Register this specialization so that we can find it again. */ - decl = register_specialization (decl, gen_tmpl, targs); + decl = register_specialization (decl, gen_tmpl, targs, is_friend); } } - + return decl; } @@ -2010,7 +2221,8 @@ check_explicit_specialization (tree declarator, parameters. These are represented in the same format used for DECL_TEMPLATE_PARMS. */ -int comp_template_parms (tree parms1, tree parms2) +int +comp_template_parms (tree parms1, tree parms2) { tree p1; tree p2; @@ -2018,7 +2230,7 @@ int comp_template_parms (tree parms1, tree parms2) if (parms1 == parms2) return 1; - for (p1 = parms1, p2 = parms2; + for (p1 = parms1, p2 = parms2; p1 != NULL_TREE && p2 != NULL_TREE; p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2)) { @@ -2026,16 +2238,21 @@ int comp_template_parms (tree parms1, tree parms2) tree t2 = TREE_VALUE (p2); int i; - my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0); - my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0); + gcc_assert (TREE_CODE (t1) == TREE_VEC); + gcc_assert (TREE_CODE (t2) == TREE_VEC); if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2)) return 0; - for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) + 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; @@ -2073,7 +2290,7 @@ check_template_shadow (tree decl) /* Figure out what we're shadowing. */ if (TREE_CODE (decl) == OVERLOAD) decl = OVL_CURRENT (decl); - olddecl = IDENTIFIER_VALUE (DECL_NAME (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. */ @@ -2090,23 +2307,23 @@ check_template_shadow (tree decl) /* 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 + if (decl == olddecl || TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) return; - cp_error_at ("declaration of `%#D'", decl); - cp_error_at (" shadows template parm `%#D'", olddecl); + 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) +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; @@ -2115,6 +2332,7 @@ build_template_parm_index (int index, 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; @@ -2125,7 +2343,7 @@ build_template_parm_index (int index, TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a new one is created. */ -static tree +static tree reduce_template_parm_level (tree index, tree type, int levels) { if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE @@ -2134,78 +2352,98 @@ reduce_template_parm_level (tree index, tree type, int 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_INVARIANT (decl) = TREE_INVARIANT (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 template parameters need this. */ - DECL_TEMPLATE_PARMS (decl) - = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); + /* Template template parameters need this. */ + if (TREE_CODE (decl) != CONST_DECL) + DECL_TEMPLATE_PARMS (decl) + = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); } return TEMPLATE_PARM_DESCENDANTS (index); } -/* Process information from new template parameter NEXT and append it to the - LIST being built. */ +/* 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. */ tree -process_template_parm (tree list, tree next) +process_template_parm (tree list, tree parm, bool is_non_type) { - tree parm; tree decl = 0; tree defval; - int is_type, idx; + tree err_parm_list; + int idx = 0; - parm = next; - my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259); + gcc_assert (TREE_CODE (parm) == TREE_LIST); defval = TREE_PURPOSE (parm); - parm = TREE_VALUE (parm); - is_type = TREE_PURPOSE (parm) == class_type_node; 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 idx = 0; - if (!is_type) + if (is_non_type) { - my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260); - /* is a const-param */ - parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), - PARM, 0, NULL); - SET_DECL_TEMPLATE_PARM_P (parm); + parm = TREE_VALUE (parm); - /* [temp.param] + SET_DECL_TEMPLATE_PARM_P (parm); - The top-level cv-qualifiers on the template-parameter are - ignored when determining its type. */ - TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); + if (TREE_TYPE (parm) == error_mark_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] + + The top-level cv-qualifiers on the template-parameter are + ignored when determining its type. */ + TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); + if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) + { + err_parm_list = build_tree_list (defval, parm); + TREE_VALUE (err_parm_list) = error_mark_node; + return chainon (list, err_parm_list); + } + } /* A template parameter is not modifiable. */ - TREE_READONLY (parm) = TREE_CONSTANT (parm) = 1; - if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) - TREE_TYPE (parm) = void_type_node; + 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) = TREE_READONLY (decl) = 1; - DECL_INITIAL (parm) = DECL_INITIAL (decl) + 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)); @@ -2213,12 +2451,12 @@ process_template_parm (tree list, tree next) else { tree t; - parm = TREE_VALUE (parm); - + parm = TREE_VALUE (TREE_VALUE (parm)); + if (parm && TREE_CODE (parm) == TEMPLATE_DECL) { t = make_aggr_type (TEMPLATE_TEMPLATE_PARM); - /* This is for distinguishing between real templates and template + /* This is for distinguishing between real templates and template template parameters */ TREE_TYPE (parm) = t; TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t; @@ -2230,12 +2468,12 @@ process_template_parm (tree list, tree next) /* parm is either IDENTIFIER_NODE or NULL_TREE. */ decl = build_decl (TYPE_DECL, parm, t); } - + TYPE_NAME (t) = decl; TYPE_STUB_DECL (t) = decl; parm = decl; TEMPLATE_TYPE_PARM_INDEX (t) - = build_template_parm_index (idx, processing_template_decl, + = build_template_parm_index (idx, processing_template_decl, processing_template_decl, decl, TREE_TYPE (parm)); } @@ -2294,7 +2532,7 @@ end_template_decl (void) /* Given a template argument vector containing the template PARMS. The innermost PARMS are given first. */ -tree +static tree current_template_args (void) { tree header; @@ -2321,15 +2559,19 @@ current_template_args (void) /* T will be a list if we are called from within a begin/end_template_parm_list pair, but a vector directly if within a begin/end_member_template_processing pair. */ - if (TREE_CODE (t) == TREE_LIST) + if (TREE_CODE (t) == TREE_LIST) { t = TREE_VALUE (t); - - if (TREE_CODE (t) == TYPE_DECL - || TREE_CODE (t) == TEMPLATE_DECL) - t = TREE_TYPE (t); - else - t = DECL_INITIAL (t); + + if (t != error_mark_node) + { + 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; } } @@ -2344,14 +2586,16 @@ current_template_args (void) } /* Return a TEMPLATE_DECL corresponding to DECL, using the indicated - template PARMS. Used by push_template_decl below. */ + template PARMS. If MEMBER_TEMPLATE_P is true, the new template is + a member template. Used by push_template_decl below. */ static tree -build_template_decl (tree decl, tree parms) +build_template_decl (tree decl, tree parms, bool member_template_p) { tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE); DECL_TEMPLATE_PARMS (tmpl) = parms; DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); + DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p; if (DECL_LANG_SPECIFIC (decl)) { DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl); @@ -2360,7 +2604,7 @@ build_template_decl (tree decl, tree parms) DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl); DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl); if (DECL_OVERLOADED_OPERATOR_P (decl)) - SET_OVERLOADED_OPERATOR_CODE (tmpl, + SET_OVERLOADED_OPERATOR_CODE (tmpl, DECL_OVERLOADED_OPERATOR_P (decl)); } @@ -2465,17 +2709,17 @@ process_partial_specialization (tree decl) }; The S2<T> declaration is actually invalid; it is a - full-specialization. Of course, + full-specialization. Of course, template <class U> struct S2<T (*)(U)>; or some such would have been OK. */ tpd.level = TMPL_PARMS_DEPTH (current_template_parms); - tpd.parms = alloca (sizeof (int) * ntparms); + tpd.parms = (int *) alloca (sizeof (int) * ntparms); memset (tpd.parms, 0, sizeof (int) * ntparms); - tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs); + tpd.arg_uses_template_parms = (int *) alloca (sizeof (int) * nargs); memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs); for (i = 0; i < nargs; ++i) { @@ -2496,19 +2740,18 @@ process_partial_specialization (tree decl) did_error_intro = 1; } - error (" `%D'", - TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); + error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); } /* [temp.class.spec] The argument list of the specialization shall not be identical to the implicit argument list of the primary template. */ - if (comp_template_args - (inner_args, + if (comp_template_args + (inner_args, INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (maintmpl))))) - error ("partial specialization `%T' does not specialize any template arguments", type); + error ("partial specialization %qT does not specialize any template arguments", type); /* [temp.class.spec] @@ -2519,7 +2762,7 @@ 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. */ - my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0); + gcc_assert (nargs == DECL_NTPARMS (maintmpl)); tpd2.parms = 0; for (i = 0; i < nargs; ++i) { @@ -2533,26 +2776,26 @@ process_partial_specialization (tree decl) && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) { if (tpd.arg_uses_template_parms[i]) - error ("template argument `%E' involves template parameter(s)", arg); - else + 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, + 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 - = alloca (sizeof (int) * nargs); + 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 = alloca (sizeof (int) * nargs); - tpd2.level = + tpd2.parms = (int *) alloca (sizeof (int) * nargs); + tpd2.level = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); } @@ -2566,7 +2809,7 @@ process_partial_specialization (tree decl) &mark_template_parm, &tpd2, NULL); - + if (tpd2.arg_uses_template_parms [i]) { /* The type depended on some template parameters. @@ -2577,9 +2820,10 @@ process_partial_specialization (tree decl) if (tpd2.parms[j] != 0 && tpd.arg_uses_template_parms [j]) { - error ("type `%T' of template argument `%E' depends on template parameter(s)", - type, - arg); + error ("type %qT of template argument %qE depends " + "on template parameter(s)", + type, + arg); break; } } @@ -2587,12 +2831,13 @@ process_partial_specialization (tree decl) } } - if (retrieve_specialization (maintmpl, specargs)) + if (retrieve_specialization (maintmpl, specargs, + /*class_specializations_p=*/true)) /* We've already got this specialization. */ return decl; DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) - = tree_cons (inner_args, inner_parms, + = tree_cons (specargs, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; return decl; @@ -2610,7 +2855,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) int last_level_to_check; tree parm_level; - /* [temp.param] + /* [temp.param] A default template-argument shall not be specified in a function template declaration or a function template definition, nor @@ -2644,7 +2889,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) return; /* [temp.param] - + If a template-parameter has a default template-argument, all subsequent template-parameters shall have a default template-argument supplied. */ @@ -2652,17 +2897,21 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) { tree inner_parms = TREE_VALUE (parm_level); int ntparms = TREE_VEC_LENGTH (inner_parms); - int seen_def_arg_p = 0; + int seen_def_arg_p = 0; int i; - for (i = 0; i < ntparms; ++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 `%D'", TREE_VALUE (parm)); + 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; @@ -2673,13 +2922,13 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) /* For an ordinary class template, default template arguments are allowed at the innermost level, e.g.: - template <class T = int> + template <class T = int> struct S {}; but, in a partial specialization, they're not allowed even there, as we have in [temp.class.spec]: - + The template parameter list of a specialization shall not - contain default template argument values. + contain default template argument values. So, for a partial specialization, or for a function template, we look at all of them. */ @@ -2696,15 +2945,15 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) else if (is_partial) msg = "default template arguments may not be used in partial specializations"; else - msg = "default argument for template parameter for class enclosing `%D'"; + msg = "default argument for template parameter for class enclosing %qD"; if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) /* If we're inside a class definition, there's no need to examine the parameters to the class itself. On the one hand, they will be checked when the class is defined, and, on the other, default arguments are valid in things like: - template <class T = double> - struct S { template <class U> void f(U); }; + template <class T = double> + struct S { template <class U> void f(U); }; Here the default argument for `S' has no bearing on the declaration of `f'. */ last_level_to_check = template_class_depth (current_class_type) + 1; @@ -2712,8 +2961,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) /* Check everything. */ last_level_to_check = 0; - for (parm_level = parms; - parm_level && TMPL_PARMS_DEPTH (parm_level) >= last_level_to_check; + for (parm_level = parms; + parm_level && TMPL_PARMS_DEPTH (parm_level) >= last_level_to_check; parm_level = TREE_CHAIN (parm_level)) { tree inner_parms = TREE_VALUE (parm_level); @@ -2721,24 +2970,29 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) int ntparms; 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; - } + for (i = 0; i < ntparms; ++i) + { + 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) + { + 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 `%D'"; + msg = "default argument for template parameter for class enclosing %qD"; } } @@ -2763,12 +3017,12 @@ template_parm_this_level_p (tree t, void* data) /* Creates a TEMPLATE_DECL for the indicated DECL using the template parameters given by current_template_args, or reuses a previously existing one, if appropriate. Returns the DECL, or an - equivalent one, if it is replaced via a call to duplicate_decls. + equivalent one, if it is replaced via a call to duplicate_decls. - If IS_FRIEND is nonzero, DECL is a friend declaration. */ + If IS_FRIEND is true, DECL is a friend declaration. */ tree -push_template_decl_real (tree decl, int is_friend) +push_template_decl_real (tree decl, bool is_friend) { tree tmpl; tree args; @@ -2777,13 +3031,20 @@ push_template_decl_real (tree decl, int is_friend) int primary; int is_partial; int new_template_p = 0; + /* True if the template is a member template, in the sense of + [temp.mem]. */ + bool member_template_p = false; + + if (decl == error_mark_node) + return decl; /* See if this is a partial specialization. */ is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl) && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))); - is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)) + is_friend = true; if (is_friend) /* For a friend, we want the context of the friend function, not @@ -2806,23 +3067,29 @@ push_template_decl_real (tree decl, int 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 <typename T> friend void A<T>::f(); + is not primary. */ + primary = 0; + else + primary = template_parm_scope_p (); if (primary) { - if (current_lang_name == lang_name_c) - error ("template with C linkage"); - else if (TREE_CODE (decl) == TYPE_DECL - && ANON_AGGRNAME_P (DECL_NAME (decl))) + if (DECL_CLASS_SCOPE_P (decl)) + member_template_p = true; + if (TREE_CODE (decl) == TYPE_DECL + && ANON_AGGRNAME_P (DECL_NAME (decl))) error ("template class without a name"); else if (TREE_CODE (decl) == FUNCTION_DECL) { if (DECL_DESTRUCTOR_P (decl)) { /* [temp.mem] - - A destructor shall not be a member template. */ - error ("destructor `%D' declared as member template", decl); + + A destructor shall not be a member template. */ + error ("destructor %qD declared as member template", decl); return error_mark_node; } if (NEW_DELETE_OPNAME_P (DECL_NAME (decl)) @@ -2832,13 +3099,13 @@ push_template_decl_real (tree decl, int is_friend) || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl)))) == void_list_node))) { - /* [basic.stc.dynamic.allocation] + /* [basic.stc.dynamic.allocation] - An allocation function can be a function + An allocation function can be a function template. ... Template allocation functions shall have two or more parameters. */ - error ("invalid template declaration of `%D'", decl); - return decl; + error ("invalid template declaration of %qD", decl); + return error_mark_node; } } else if (DECL_IMPLICIT_TYPEDEF_P (decl) @@ -2846,14 +3113,14 @@ push_template_decl_real (tree decl, int is_friend) /* OK */; else { - error ("template declaration of `%#D'", decl); + error ("template declaration of %q#D", decl); return error_mark_node; } } /* Check to see that the rules regarding the use of default arguments are not being violated. */ - check_default_tmpl_args (decl, current_template_parms, + check_default_tmpl_args (decl, current_template_parms, primary, is_partial); if (is_partial) @@ -2861,7 +3128,7 @@ push_template_decl_real (tree decl, int is_friend) args = current_template_args (); - if (!ctx + if (!ctx || TREE_CODE (ctx) == FUNCTION_DECL || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx)) || (is_friend && !DECL_TEMPLATE_INFO (decl))) @@ -2873,7 +3140,7 @@ push_template_decl_real (tree decl, int is_friend) /* If DECL is a TYPE_DECL for a class-template, then there won't be DECL_LANG_SPECIFIC. The information equivalent to DECL_TEMPLATE_INFO is found in TYPE_TEMPLATE_INFO instead. */ - else if (DECL_IMPLICIT_TYPEDEF_P (decl) + else if (DECL_IMPLICIT_TYPEDEF_P (decl) && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) { @@ -2888,7 +3155,8 @@ push_template_decl_real (tree decl, int is_friend) } else { - tmpl = build_template_decl (decl, current_template_parms); + tmpl = build_template_decl (decl, current_template_parms, + member_template_p); new_template_p = 1; if (DECL_LANG_SPECIFIC (decl) @@ -2916,22 +3184,22 @@ push_template_decl_real (tree decl, int is_friend) tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); else { - error ("`%D' does not declare a template type", decl); + error ("%qD does not declare a template type", decl); return decl; } } else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl)) { - error ("template definition of non-template `%#D'", decl); + error ("template definition of non-template %q#D", decl); return decl; } else tmpl = DECL_TI_TEMPLATE (decl); - + if (DECL_FUNCTION_TEMPLATE_P (tmpl) - && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) + && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) && DECL_TEMPLATE_SPECIALIZATION (decl) - && is_member_template (tmpl)) + && DECL_MEMBER_TEMPLATE_P (tmpl)) { tree new_tmpl; @@ -2942,18 +3210,20 @@ push_template_decl_real (tree decl, int is_friend) earlier call to check_explicit_specialization. */ args = DECL_TI_ARGS (decl); - new_tmpl - = build_template_decl (decl, current_template_parms); + new_tmpl + = build_template_decl (decl, current_template_parms, + member_template_p); DECL_TEMPLATE_RESULT (new_tmpl) = decl; TREE_TYPE (new_tmpl) = TREE_TYPE (decl); DECL_TI_TEMPLATE (decl) = new_tmpl; SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl); - DECL_TEMPLATE_INFO (new_tmpl) + DECL_TEMPLATE_INFO (new_tmpl) = tree_cons (tmpl, args, NULL_TREE); - register_specialization (new_tmpl, - most_general_template (tmpl), - args); + register_specialization (new_tmpl, + most_general_template (tmpl), + args, + is_friend); return decl; } @@ -2963,8 +3233,8 @@ push_template_decl_real (tree decl, int is_friend) i = TMPL_PARMS_DEPTH (parms); if (TMPL_ARGS_DEPTH (args) != i) { - error ("expected %d levels of template parms for `%#D', got %d", - i, decl, TMPL_ARGS_DEPTH (args)); + error ("expected %d levels of template parms for %q#D, got %d", + i, decl, TMPL_ARGS_DEPTH (args)); } else for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms)) @@ -2975,17 +3245,17 @@ push_template_decl_real (tree decl, int is_friend) if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) { if (current == decl) - error ("got %d template parameters for `%#D'", - TREE_VEC_LENGTH (a), decl); + error ("got %d template parameters for %q#D", + TREE_VEC_LENGTH (a), decl); else - error ("got %d template parameters for `%#T'", - TREE_VEC_LENGTH (a), current); + error ("got %d template parameters for %q#T", + TREE_VEC_LENGTH (a), current); error (" but %d required", TREE_VEC_LENGTH (t)); return error_mark_node; } /* Perhaps we should also check that the parms are used in the - appropriate qualifying scopes in the declarator? */ + appropriate qualifying scopes in the declarator? */ if (current == decl) current = ctx; @@ -3001,9 +3271,20 @@ push_template_decl_real (tree decl, int is_friend) that we do not try to push a global template friend declared in a template class; such a thing may well depend on the template parameters of the class. */ - if (new_template_p && !ctx + if (new_template_p && !ctx && !(is_friend && template_class_depth (current_class_type) > 0)) - tmpl = pushdecl_namespace_level (tmpl); + { + tmpl = pushdecl_namespace_level (tmpl, is_friend); + if (tmpl == error_mark_node) + return error_mark_node; + + /* Hide template friend classes that haven't been declared yet. */ + if (is_friend && TREE_CODE (decl) == TYPE_DECL) + { + DECL_ANTICIPATED (tmpl) = 1; + DECL_FRIEND_P (tmpl) = 1; + } + } if (primary) { @@ -3014,14 +3295,14 @@ push_template_decl_real (tree decl, int is_friend) /* It is a conversion operator. See if the type converted to depends on innermost template operands. */ - + if (uses_template_parms_level (TREE_TYPE (TREE_TYPE (tmpl)), depth)) DECL_TEMPLATE_CONV_FN_P (tmpl) = 1; } } - /* The DECL_TI_ARGS of DECL contains full set of arguments refering + /* The DECL_TI_ARGS of DECL contains full set of arguments referring back to its most general template. If TMPL is a specialization, ARGS may only have the innermost set of arguments. Add the missing argument levels if necessary. */ @@ -3048,7 +3329,7 @@ push_template_decl_real (tree decl, int is_friend) tree push_template_decl (tree decl) { - return push_template_decl_real (decl, 0); + return push_template_decl_real (decl, false); } /* Called when a class template TYPE is redeclared with the indicated @@ -3057,7 +3338,7 @@ push_template_decl (tree decl) template <class T> struct S; template <class T> struct S {}; */ -void +bool redeclare_class_template (tree type, tree parms) { tree tmpl; @@ -3066,8 +3347,8 @@ redeclare_class_template (tree type, tree parms) if (!TYPE_TEMPLATE_INFO (type)) { - error ("`%T' is not a template type", type); - return; + error ("%qT is not a template type", type); + return false; } tmpl = TYPE_TI_TEMPLATE (type); @@ -3075,32 +3356,53 @@ 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 false; + } parms = INNERMOST_TEMPLATE_PARMS (parms); tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { - cp_error_at ("previous declaration `%D'", tmpl); + error ("previous declaration %q+D", tmpl); error ("used %d template parameter(s) instead of %d", - TREE_VEC_LENGTH (tmpl_parms), + TREE_VEC_LENGTH (tmpl_parms), TREE_VEC_LENGTH (parms)); - return; + 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)); - - if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)) + 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 (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))))) { - cp_error_at ("template parameter `%#D'", tmpl_parm); - error ("redeclared here as `%#D'", parm); - return; + error ("template parameter %q+#D", tmpl_parm); + error ("redeclared here as %q#D", parm); + return false; } if (tmpl_default != NULL_TREE && parm_default != NULL_TREE) @@ -3109,9 +3411,9 @@ 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 `%#D'", parm); + error ("redefinition of default argument for %q#D", parm); error ("%J original definition appeared here", tmpl_parm); - return; + return false; } if (parm_default != NULL_TREE) @@ -3123,6 +3425,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 @@ -3131,12 +3435,15 @@ 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: - + template <typename T> void f(T[1 + 1]); template <typename T> void f(T[2]); - + as two declarations of the same function, for example. */ if (processing_template_decl && !type_dependent_expression_p (expr) @@ -3150,12 +3457,74 @@ 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; } +/* 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. + + This is basically a more powerful version of + integral_constant_value, which can be used also in templates where + initializers can maintain a syntactic rather than semantic form + (even if they are non-dependent, for access-checking purposes). */ + +static tree +fold_decl_constant_value (tree expr) +{ + tree const_expr = expr; + do + { + expr = fold_non_dependent_expr (const_expr); + const_expr = integral_constant_value (expr); + } + while (expr != const_expr); + + return expr; +} + +/* Subroutine of convert_nontype_argument. Converts EXPR to TYPE, which + must be a function or a pointer-to-function type, as specified + in [temp.arg.nontype]: disambiguate EXPR if it is an overload set, + and check that the resulting function has external linkage. */ + +static tree +convert_nontype_argument_function (tree type, tree expr) +{ + tree fns = expr; + tree fn, fn_no_ptr; + + fn = instantiate_type (type, fns, tf_none); + if (fn == error_mark_node) + return error_mark_node; + + 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 + shall be one of: + [...] + -- the address of an object or function with external linkage. */ + if (!DECL_EXTERNAL_LINKAGE_P (fn_no_ptr)) + { + error ("%qE is not a valid template argument for type %qT " + "because function %qD has not external linkage", + expr, type, fn_no_ptr); + return NULL_TREE; + } + + return fn; +} + /* Attempt to convert the non-type template parameter EXPR to the indicated TYPE. If the conversion is successful, return the converted value. If the conversion is unsuccessful, return @@ -3163,13 +3532,37 @@ fold_non_dependent_expr (tree expr) did not. We issue error messages for out-and-out bad template parameters, but not simply because the conversion failed, since we might be just trying to do argument deduction. Both TYPE and EXPR - must be non-dependent. */ + must be non-dependent. + + The conversion follows the special rules described in + [temp.arg.nontype], and it is much more strict than an implicit + conversion. + + This function is called twice for each template argument (see + lookup_template_class for a more accurate description of this + problem). This means that we need to handle expressions which + are not valid in a C++ source, but can be created from the + first call (for instance, casts to perform conversions). These + hacks can go away after we fix the double coercion problem. */ static tree convert_nontype_argument (tree type, tree expr) { tree expr_type; + /* Detect immediately string literals as invalid non-type argument. + This special-case is not needed for correctness (we would easily + catch this later), but only to provide better diagnostic for this + common user mistake. As suggested by DR 100, we do not mention + linkage issues in the diagnostic as this is not the point. */ + if (TREE_CODE (expr) == STRING_CST) + { + error ("%qE is not a valid template argument for type %qT " + "because string literals can never be used in this context", + expr, type); + return NULL_TREE; + } + /* If we are in a template, EXPR may be non-dependent, but still have a syntactic, rather than semantic, form. For example, EXPR might be a SCOPE_REF, rather than the VAR_DECL to which the @@ -3178,417 +3571,339 @@ convert_nontype_argument (tree type, tree expr) instantiated -- but here we need the resolved form so that we can convert the argument. */ expr = fold_non_dependent_expr (expr); + if (error_operand_p (expr)) + return error_mark_node; expr_type = TREE_TYPE (expr); - /* A template-argument for a non-type, non-template - template-parameter shall be one of: - - --an integral constant-expression of integral or enumeration - type; or - - --the name of a non-type template-parameter; or - - --the name of an object or function with external linkage, - including function templates and function template-ids but - excluding non-static class members, expressed as id-expression; - or - - --the address of an object or function with external linkage, - including function templates and function template-ids but - excluding non-static class members, expressed as & id-expression - where the & is optional if the name refers to a function or - array; or - - --a pointer to member expressed as described in _expr.unary.op_. */ - - /* An integral constant-expression can include const variables or -. enumerators. Simplify things by folding them to their values, - unless we're about to bind the declaration to a reference - parameter. */ - if (INTEGRAL_TYPE_P (expr_type) && TREE_CODE (type) != REFERENCE_TYPE) - while (true) - { - tree const_expr = decl_constant_value (expr); - /* In a template, the initializer for a VAR_DECL may not be - marked as TREE_CONSTANT, in which case decl_constant_value - will not return the initializer. Handle that special case - here. */ - if (expr == const_expr - && DECL_INTEGRAL_CONSTANT_VAR_P (expr) - /* DECL_INITIAL can be NULL if we are processing a - variable initialized to an expression involving itself. - We know it is initialized to a constant -- but not what - constant, yet. */ - && DECL_INITIAL (expr)) - const_expr = DECL_INITIAL (expr); - if (expr == const_expr) - break; - expr = fold_non_dependent_expr (const_expr); - } - - if (is_overloaded_fn (expr)) - /* OK for now. We'll check that it has external linkage later. - Check this first since if expr_type is the unknown_type_node - we would otherwise complain below. */ - ; - else if (TYPE_PTR_TO_MEMBER_P (expr_type)) - { - if (TREE_CODE (expr) != PTRMEM_CST) - goto bad_argument; - } - else if (TYPE_PTR_P (expr_type) - || TREE_CODE (expr_type) == ARRAY_TYPE - || TREE_CODE (type) == REFERENCE_TYPE - /* If expr is the address of an overloaded function, we - will get the unknown_type_node at this point. */ - || expr_type == unknown_type_node) - { - tree referent; - tree e = expr; - STRIP_NOPS (e); - - if (TREE_CODE (expr_type) == ARRAY_TYPE - || (TREE_CODE (type) == REFERENCE_TYPE - && TREE_CODE (e) != ADDR_EXPR)) - referent = e; - else + /* HACK: Due to double coercion, we can get a + NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here, + which is the tree that we built on the first call (see + below when coercing to reference to object or to reference to + function). We just strip everything and get to the arg. + See g++.old-deja/g++.oliva/template4.C and g++.dg/template/nontype9.C + for examples. */ + if (TREE_CODE (expr) == NOP_EXPR) + { + if (TYPE_REF_OBJ_P (type) || TYPE_REFFN_P (type)) { - if (TREE_CODE (e) != ADDR_EXPR) - { - bad_argument: - error ("`%E' is not a valid template argument", expr); - if (TYPE_PTR_P (expr_type)) - { - if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE) - error ("it must be the address of a function with external linkage"); - else - error ("it must be the address of an object with external linkage"); - } - else if (TYPE_PTR_TO_MEMBER_P (expr_type)) - error ("it must be a pointer-to-member of the form `&X::Y'"); - - return NULL_TREE; - } - - referent = TREE_OPERAND (e, 0); - STRIP_NOPS (referent); + /* ??? Maybe we could use convert_from_reference here, but we + would need to relax its constraints because the NOP_EXPR + could actually change the type to something more cv-qualified, + and this is not folded by convert_from_reference. */ + tree addr = TREE_OPERAND (expr, 0); + gcc_assert (TREE_CODE (expr_type) == REFERENCE_TYPE); + gcc_assert (TREE_CODE (addr) == ADDR_EXPR); + gcc_assert (TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE); + gcc_assert (same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (expr_type), + TREE_TYPE (TREE_TYPE (addr)))); + + expr = TREE_OPERAND (addr, 0); + expr_type = TREE_TYPE (expr); } - if (TREE_CODE (referent) == STRING_CST) + /* We could also generate a NOP_EXPR(ADDR_EXPR()) when the + parameter is a pointer to object, through decay and + qualification conversion. Let's strip everything. */ + else if (TYPE_PTROBV_P (type)) { - error ("string literal %E is not a valid template argument because it is the address of an object with static linkage", - referent); - return NULL_TREE; + STRIP_NOPS (expr); + gcc_assert (TREE_CODE (expr) == ADDR_EXPR); + gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE); + /* Skip the ADDR_EXPR only if it is part of the decay for + an array. Otherwise, it is part of the original argument + in the source code. */ + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE) + expr = TREE_OPERAND (expr, 0); + expr_type = TREE_TYPE (expr); } + } - if (TREE_CODE (referent) == SCOPE_REF) - referent = TREE_OPERAND (referent, 1); + /* [temp.arg.nontype]/5, bullet 1 - if (is_overloaded_fn (referent)) - /* We'll check that it has external linkage later. */ - ; - else if (TREE_CODE (referent) != VAR_DECL) - goto bad_argument; - else if (!DECL_EXTERNAL_LINKAGE_P (referent)) - { - error ("address of non-extern `%E' cannot be used as template argument", referent); - return error_mark_node; - } - } - else if (INTEGRAL_TYPE_P (expr_type) || TYPE_PTR_TO_MEMBER_P (expr_type)) + For a non-type template-parameter of integral or enumeration type, + integral promotions (_conv.prom_) and integral conversions + (_conv.integral_) are applied. */ + if (INTEGRAL_TYPE_P (type)) { - if (! TREE_CONSTANT (expr)) + if (!INTEGRAL_TYPE_P (expr_type)) + return error_mark_node; + + expr = fold_decl_constant_value (expr); + /* Notice that there are constant expressions like '4 % 0' which + do not fold into integer constants. */ + if (TREE_CODE (expr) != INTEGER_CST) { - non_constant: - error ("non-constant `%E' cannot be used as template argument", - expr); + error ("%qE is not a valid template argument for type %qT " + "because it is a non-constant expression", expr, type); return NULL_TREE; } - } - else - { - if (TYPE_P (expr)) - error ("type '%T' cannot be used as a value for a non-type " - "template-parameter", expr); - else if (DECL_P (expr)) - error ("invalid use of '%D' as a non-type template-argument", expr); - else - error ("invalid use of '%E' as a non-type template-argument", expr); - - return NULL_TREE; - } - switch (TREE_CODE (type)) - { - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case ENUMERAL_TYPE: - /* For a non-type template-parameter of integral or enumeration - type, integral promotions (_conv.prom_) and integral - conversions (_conv.integral_) are applied. */ - if (!INTEGRAL_TYPE_P (expr_type)) + /* At this point, an implicit conversion does what we want, + because we already know that the expression is of integral + type. */ + expr = ocp_convert (type, expr, CONV_IMPLICIT, LOOKUP_PROTECT); + if (expr == error_mark_node) return error_mark_node; - - /* It's safe to call digest_init in this case; we know we're - just converting one integral constant expression to another. */ - expr = digest_init (type, expr, (tree*) 0); - if (TREE_CODE (expr) != INTEGER_CST) - /* Curiously, some TREE_CONSTANT integral expressions do not - simplify to integer constants. For example, `3 % 0', - remains a TRUNC_MOD_EXPR. */ - goto non_constant; - - return expr; + /* Conversion was allowed: fold it to a bare integer constant. */ + expr = fold (expr); + } + /* [temp.arg.nontype]/5, bullet 2 - case OFFSET_TYPE: - { - tree e; - - /* For a non-type template-parameter of type pointer to data - member, qualification conversions (_conv.qual_) are - applied. */ - e = perform_qualification_conversions (type, expr); - if (TREE_CODE (e) == NOP_EXPR) - /* The call to perform_qualification_conversions will - insert a NOP_EXPR over EXPR to do express conversion, - if necessary. But, that will confuse us if we use - this (converted) template parameter to instantiate - another template; then the thing will not look like a - valid template argument. So, just make a new - constant, of the appropriate type. */ - e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr)); - return e; - } + For a non-type template-parameter of type pointer to object, + qualification conversions (_conv.qual_) and the array-to-pointer + conversion (_conv.array_) are applied. */ + else if (TYPE_PTROBV_P (type)) + { + /* [temp.arg.nontype]/1 (TC1 version, DR 49): - case POINTER_TYPE: - { - tree type_pointed_to = TREE_TYPE (type); - - if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE) - { - /* For a non-type template-parameter of type pointer to - function, only the function-to-pointer conversion - (_conv.func_) is applied. If the template-argument - represents a set of overloaded functions (or a pointer to - such), the matching function is selected from the set - (_over.over_). */ - tree fns; - tree fn; - - if (TREE_CODE (expr) == ADDR_EXPR) - fns = TREE_OPERAND (expr, 0); - else - fns = expr; + A template-argument for a non-type, non-template template-parameter + shall be one of: [...] - fn = instantiate_type (type_pointed_to, fns, tf_none); + -- the name of a non-type template-parameter; + -- the address of an object or function with external linkage, [...] + expressed as "& id-expression" where the & is optional if the name + refers to a function or array, or if the corresponding + template-parameter is a reference. - if (fn == error_mark_node) - return error_mark_node; + Here, we do not care about functions, as they are invalid anyway + for a parameter of type pointer-to-object. */ - if (!DECL_EXTERNAL_LINKAGE_P (fn)) - { - if (really_overloaded_fn (fns)) - return error_mark_node; - else - goto bad_argument; - } + 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; - expr = build_unary_op (ADDR_EXPR, fn, 0); + 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; + } + } - my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), - 0); - return expr; - } - else - { - /* For a non-type template-parameter of type pointer to - object, qualification conversions (_conv.qual_) and the - array-to-pointer conversion (_conv.array_) are applied. - [Note: In particular, neither the null pointer conversion - (_conv.ptr_) nor the derived-to-base conversion - (_conv.ptr_) are applied. Although 0 is a valid - template-argument for a non-type template-parameter of - integral type, it is not a valid template-argument for a - non-type template-parameter of pointer type.] - - The call to decay_conversion performs the - array-to-pointer conversion, if appropriate. */ - expr = decay_conversion (expr); - - if (expr == error_mark_node) - return error_mark_node; - else - return perform_qualification_conversions (type, expr); - } - } - break; + expr = decay_conversion (expr); + if (expr == error_mark_node) + return error_mark_node; - case REFERENCE_TYPE: - { - tree type_referred_to = TREE_TYPE (type); + expr = perform_qualification_conversions (type, expr); + if (expr == error_mark_node) + return error_mark_node; + } + /* [temp.arg.nontype]/5, bullet 3 - /* If this expression already has reference type, get the - underlying object. */ - if (TREE_CODE (expr_type) == REFERENCE_TYPE) - { - if (TREE_CODE (expr) == NOP_EXPR - && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR) - STRIP_NOPS (expr); - my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604); - expr = TREE_OPERAND (expr, 0); - expr_type = TREE_TYPE (expr); - } + For a non-type template-parameter of type reference to object, no + conversions apply. The type referred to by the reference may be more + cv-qualified than the (otherwise identical) type of the + template-argument. The template-parameter is bound directly to the + template-argument, which must be an lvalue. */ + else if (TYPE_REF_OBJ_P (type)) + { + if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type), + expr_type)) + return error_mark_node; - if (TREE_CODE (type_referred_to) == FUNCTION_TYPE) - { - /* For a non-type template-parameter of type reference to - function, no conversions apply. If the - template-argument represents a set of overloaded - functions, the matching function is selected from the - set (_over.over_). */ - tree fn; + if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type)) + { + error ("%qE is not a valid template argument for type %qT " + "because of conflicts in cv-qualification", expr, type); + return NULL_TREE; + } - fn = instantiate_type (type_referred_to, expr, tf_none); + if (!real_lvalue_p (expr)) + { + error ("%qE is not a valid template argument for type %qT " + "because it is not an lvalue", expr, type); + return NULL_TREE; + } - if (fn == error_mark_node) - return error_mark_node; + /* [temp.arg.nontype]/1 - if (!DECL_EXTERNAL_LINKAGE_P (fn)) - { - if (really_overloaded_fn (expr)) - /* Don't issue an error here; we might get a different - function if the overloading had worked out - differently. */ - return error_mark_node; - else - goto bad_argument; - } + A template-argument for a non-type, non-template template-parameter + shall be one of: [...] - my_friendly_assert (same_type_p (type_referred_to, - TREE_TYPE (fn)), - 0); + -- the address of an object or function with external linkage. */ + if (!DECL_EXTERNAL_LINKAGE_P (expr)) + { + error ("%qE is not a valid template argument for type %qT " + "because object %qD has not external linkage", + expr, type, expr); + return NULL_TREE; + } - expr = fn; - } - else - { - /* For a non-type template-parameter of type reference to - object, no conversions apply. The type referred to by the - reference may be more cv-qualified than the (otherwise - identical) type of the template-argument. The - template-parameter is bound directly to the - template-argument, which must be an lvalue. */ - if (!same_type_p (TYPE_MAIN_VARIANT (expr_type), - TYPE_MAIN_VARIANT (type_referred_to)) - || !at_least_as_qualified_p (type_referred_to, - expr_type) - || !real_lvalue_p (expr)) - return error_mark_node; - } + expr = build_nop (type, build_address (expr)); + } + /* [temp.arg.nontype]/5, bullet 4 - cxx_mark_addressable (expr); - return build_nop (type, build_address (expr)); - } - break; + For a non-type template-parameter of type pointer to function, only + the function-to-pointer conversion (_conv.func_) is applied. If the + template-argument represents a set of overloaded functions (or a + pointer to such), the matching function is selected from the set + (_over.over_). */ + else if (TYPE_PTRFN_P (type)) + { + /* If the argument is a template-id, we might not have enough + context information to decay the pointer. */ + if (!type_unknown_p (expr_type)) + { + expr = decay_conversion (expr); + if (expr == error_mark_node) + return error_mark_node; + } - case RECORD_TYPE: - { - my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112); + expr = convert_nontype_argument_function (type, expr); + if (!expr || expr == error_mark_node) + return expr; + } + /* [temp.arg.nontype]/5, bullet 5 - /* For a non-type template-parameter of type pointer to member - function, no conversions apply. If the template-argument - represents a set of overloaded member functions, the - matching member function is selected from the set - (_over.over_). */ + For a non-type template-parameter of type reference to function, no + conversions apply. If the template-argument represents a set of + overloaded functions, the matching function is selected from the set + (_over.over_). */ + else if (TYPE_REFFN_P (type)) + { + if (TREE_CODE (expr) == ADDR_EXPR) + { + error ("%qE is not a valid template argument for type %qT " + "because it is a pointer", expr, type); + inform ("try using %qE instead", TREE_OPERAND (expr, 0)); + return NULL_TREE; + } - if (!TYPE_PTRMEMFUNC_P (expr_type) && - expr_type != unknown_type_node) - return error_mark_node; + expr = convert_nontype_argument_function (TREE_TYPE (type), expr); + if (!expr || expr == error_mark_node) + return expr; - if (TREE_CODE (expr) == PTRMEM_CST) - { - /* A ptr-to-member constant. */ - if (!same_type_p (type, expr_type)) - return error_mark_node; - else - return expr; - } + expr = build_nop (type, build_address (expr)); + } + /* [temp.arg.nontype]/5, bullet 6 - if (TREE_CODE (expr) != ADDR_EXPR) - return error_mark_node; + For a non-type template-parameter of type pointer to member function, + no conversions apply. If the template-argument represents a set of + overloaded member functions, the matching member function is selected + from the set (_over.over_). */ + else if (TYPE_PTRMEMFUNC_P (type)) + { + expr = instantiate_type (type, expr, tf_none); + if (expr == error_mark_node) + return error_mark_node; - expr = instantiate_type (type, expr, tf_none); - - if (expr == error_mark_node) - return error_mark_node; + /* There is no way to disable standard conversions in + resolve_address_of_overloaded_function (called by + instantiate_type). It is possible that the call succeeded by + converting &B::I to &D::I (where B is a base of D), so we need + to reject this conversion here. - if (!same_type_p (type, TREE_TYPE (expr))) - return error_mark_node; + Actually, even if there was a way to disable standard conversions, + it would still be better to reject them here so that we can + provide a superior diagnostic. */ + if (!same_type_p (TREE_TYPE (expr), type)) + { + /* Make sure we are just one standard conversion off. */ + gcc_assert (can_convert (type, TREE_TYPE (expr))); + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, + TREE_TYPE (expr)); + inform ("standard conversions are not allowed in this context"); + return NULL_TREE; + } + } + /* [temp.arg.nontype]/5, bullet 7 + For a non-type template-parameter of type pointer to data member, + qualification conversions (_conv.qual_) are applied. */ + else if (TYPE_PTRMEM_P (type)) + { + expr = perform_qualification_conversions (type, expr); + if (expr == error_mark_node) return expr; - } - break; - - default: - /* All non-type parameters must have one of these types. */ - abort (); - break; } + /* A template non-type parameter must be one of the above. */ + else + gcc_unreachable (); - return error_mark_node; + /* Sanity check: did we actually convert the argument to the + right type? */ + gcc_assert (same_type_p (type, TREE_TYPE (expr))); + return expr; } -/* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for - template template parameters. Both PARM_PARMS and ARG_PARMS are - vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL + +/* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for + template template parameters. Both PARM_PARMS and ARG_PARMS are + vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL or PARM_DECL. - - ARG_PARMS may contain more parameters than PARM_PARMS. If this is - the case, then extra parameters must have default arguments. Consider the example: - template <class T, class Allocator = allocator> class vector; - template<template <class U> class TT> class C; + template <class T> class A; + template<template <class U> class TT> class B; - C<vector> is a valid instantiation. PARM_PARMS for the above code - contains a TYPE_DECL (for U), ARG_PARMS contains two TYPE_DECLs (for - T and Allocator) and OUTER_ARGS contains the argument that is used to - substitute the TT parameter. */ + For B<A>, PARM_PARMS are the parameters to TT, while ARG_PARMS are + the parameters to A, and OUTER_ARGS contains A. */ static int -coerce_template_template_parms (tree parm_parms, - tree arg_parms, - tsubst_flags_t complain, +coerce_template_template_parms (tree parm_parms, + tree arg_parms, + tsubst_flags_t complain, tree in_decl, - tree outer_args) + tree outer_args) { int nparms, nargs, i; tree parm, arg; - my_friendly_assert (TREE_CODE (parm_parms) == TREE_VEC, 0); - my_friendly_assert (TREE_CODE (arg_parms) == TREE_VEC, 0); + gcc_assert (TREE_CODE (parm_parms) == TREE_VEC); + gcc_assert (TREE_CODE (arg_parms) == TREE_VEC); nparms = TREE_VEC_LENGTH (parm_parms); nargs = TREE_VEC_LENGTH (arg_parms); - /* The rule here is opposite of coerce_template_parms. */ - if (nargs < nparms - || (nargs > nparms - && TREE_PURPOSE (TREE_VEC_ELT (arg_parms, nparms)) == NULL_TREE)) + if (nargs != nparms) return 0; for (i = 0; i < nparms; ++i) { + if (TREE_VEC_ELT (parm_parms, i) == error_mark_node + || TREE_VEC_ELT (arg_parms, i) == error_mark_node) + continue; + parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i)); arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i)); if (arg == NULL_TREE || arg == error_mark_node - || parm == NULL_TREE || parm == error_mark_node) + || parm == NULL_TREE || parm == error_mark_node) return 0; if (TREE_CODE (arg) != TREE_CODE (parm)) - return 0; + return 0; switch (TREE_CODE (parm)) { @@ -3611,16 +3926,21 @@ coerce_template_template_parms (tree parm_parms, case PARM_DECL: /* The tsubst call is used to handle cases such as - template <class T, template <T> class TT> class D; + + template <int> class C {}; + template <class T, template <T> class TT> class D {}; + D<int, C> d; + i.e. the parameter list of TT depends on earlier parameters. */ - if (!same_type_p - (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), - TREE_TYPE (arg))) + if (!dependent_type_p (TREE_TYPE (arg)) + && !same_type_p + (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), + TREE_TYPE (arg))) return 0; break; - + default: - abort (); + gcc_unreachable (); } } return 1; @@ -3634,22 +3954,19 @@ coerce_template_template_parms (tree parm_parms, the full set of template arguments deduced so far. */ static tree -convert_template_argument (tree parm, - tree arg, - tree args, - tsubst_flags_t complain, - int i, - tree in_decl) +convert_template_argument (tree parm, + tree arg, + tree args, + tsubst_flags_t complain, + int i, + tree in_decl) { tree val; - tree inner_args; int is_type, requires_type, is_tmpl_type, requires_tmpl_type; - - inner_args = INNERMOST_TEMPLATE_ARGS (args); - if (TREE_CODE (arg) == TREE_LIST + if (TREE_CODE (arg) == TREE_LIST && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF) - { + { /* The template argument was the name of some member function. That's usually invalid, but static members are OK. In any @@ -3667,7 +3984,7 @@ convert_template_argument (tree parm, && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); - + if (is_tmpl_type && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)) @@ -3678,10 +3995,12 @@ convert_template_argument (tree parm, if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM) { - pedwarn ("to refer to a type member of a template parameter, use `typename %E'", arg); - + pedwarn ("to refer to a type member of a template parameter, " + "use %<typename %E%>", arg); + arg = make_typename_type (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), + typename_type, complain & tf_error); is_type = 1; } @@ -3691,16 +4010,17 @@ convert_template_argument (tree parm, { if (complain & tf_error) { - error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); + error ("type/value mismatch at argument %d in template " + "parameter list for %qD", + i + 1, in_decl); if (is_type) - error (" expected a constant of type `%T', got `%T'", - TREE_TYPE (parm), - (is_tmpl_type ? DECL_NAME (arg) : arg)); + error (" expected a constant of type %qT, got %qT", + TREE_TYPE (parm), + (is_tmpl_type ? DECL_NAME (arg) : arg)); else if (requires_tmpl_type) - error (" expected a class template, got `%E'", arg); + error (" expected a class template, got %qE", arg); else - error (" expected a type, got `%E'", arg); + error (" expected a type, got %qE", arg); } } return error_mark_node; @@ -3709,16 +4029,17 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { - error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); + error ("type/value mismatch at argument %d in template " + "parameter list for %qD", + i + 1, in_decl); if (is_tmpl_type) - error (" expected a type, got `%T'", DECL_NAME (arg)); + error (" expected a type, got %qT", DECL_NAME (arg)); else - error (" expected a class template, got `%T'", arg); + error (" expected a class template, got %qT", arg); } return error_mark_node; } - + if (is_type) { if (requires_tmpl_type) @@ -3734,13 +4055,13 @@ convert_template_argument (tree parm, if (coerce_template_template_parms (parmparm, argparm, complain, in_decl, - inner_args)) + args)) { val = arg; - - /* TEMPLATE_TEMPLATE_PARM node is preferred over + + /* TEMPLATE_TEMPLATE_PARM node is preferred over TEMPLATE_DECL. */ - if (val != error_mark_node + if (val != error_mark_node && DECL_TEMPLATE_TEMPLATE_PARM_P (val)) val = TREE_TYPE (val); } @@ -3748,25 +4069,34 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { - error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); - error (" expected a template of type `%D', got `%D'", parm, arg); + error ("type/value mismatch at argument %d in " + "template parameter list for %qD", + i + 1, in_decl); + error (" expected a template of type %qD, got %qD", + parm, arg); } - + val = error_mark_node; } } } else - val = groktypename (arg); + val = arg; + /* We only form one instance of each template specialization. + Therefore, if we use a non-canonical variant (i.e., a + typedef), any future messages referring to the type will use + the typedef, which is confusing if those future uses do not + themselves also use the typedef. */ + if (TYPE_P (val)) + val = canonical_type_variant (val); } else { tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl); if (invalid_nontype_parm_type_p (t, complain)) - return error_mark_node; - + return error_mark_node; + if (!uses_template_parms (arg) && !uses_template_parms (t)) /* We used to call digest_init here. However, digest_init will report errors, which we don't want when complain @@ -3785,8 +4115,7 @@ convert_template_argument (tree parm, if (val == NULL_TREE) val = error_mark_node; else if (val == error_mark_node && (complain & tf_error)) - error ("could not convert template argument `%E' to `%T'", - arg, t); + error ("could not convert template argument %qE to %qT", arg, t); } return val; @@ -3797,22 +4126,26 @@ convert_template_argument (tree parm, arguments. If any error occurs, return error_mark_node. Error and warning messages are issued under control of COMPLAIN. - If REQUIRE_ALL_ARGUMENTS is nonzero, all arguments must be - provided in ARGLIST, or else trailing parameters must have default - values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument - deduction for any unspecified trailing arguments. */ - + If REQUIRE_ALL_ARGS is false, argument deduction will be performed + for arguments not specified in ARGS. Otherwise, if + USE_DEFAULT_ARGS is true, default arguments will be used to fill in + unspecified arguments. If REQUIRE_ALL_ARGS is true, but + USE_DEFAULT_ARGS is false, then all arguments must be specified in + ARGS. */ + static tree -coerce_template_parms (tree parms, - tree args, - tree in_decl, +coerce_template_parms (tree parms, + tree args, + tree in_decl, tsubst_flags_t complain, - int require_all_arguments) + bool require_all_args, + bool use_default_args) { int nparms, nargs, i, lost = 0; tree inner_args; tree new_args; tree new_inner_args; + bool saved_skip_evaluation; inner_args = INNERMOST_TEMPLATE_ARGS (args); nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; @@ -3820,21 +4153,27 @@ coerce_template_parms (tree parms, if (nargs > nparms || (nargs < nparms - && require_all_arguments - && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE)) + && require_all_args + && (!use_default_args + || (TREE_VEC_ELT (parms, nargs) != error_mark_node + && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))) { - if (complain & tf_error) + if (complain & tf_error) { error ("wrong number of template arguments (%d, should be %d)", - nargs, nparms); - + nargs, nparms); + if (in_decl) - cp_error_at ("provided for `%D'", in_decl); + error ("provided for %q+D", in_decl); } return error_mark_node; } + /* We need to evaluate the template arguments, even though this + template-id may be nested within a "sizeof". */ + saved_skip_evaluation = skip_evaluation; + skip_evaluation = false; new_inner_args = make_tree_vec (nparms); new_args = add_outermost_template_args (args, new_inner_args); for (i = 0; i < nparms; i++) @@ -3844,29 +4183,39 @@ coerce_template_parms (tree parms, /* Get the Ith template parameter. */ parm = TREE_VEC_ELT (parms, i); + + if (parm == error_mark_node) + { + TREE_VEC_ELT (new_inner_args, i) = error_mark_node; + continue; + } /* Calculate the Ith argument. */ if (i < nargs) arg = TREE_VEC_ELT (inner_args, i); - else if (require_all_arguments) + else if (require_all_args) /* There must be a default arg in this case. */ arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args, complain, in_decl); else break; - - my_friendly_assert (arg, 20030727); + + gcc_assert (arg); if (arg == error_mark_node) - error ("template argument %d is invalid", i + 1); - else - arg = convert_template_argument (TREE_VALUE (parm), + { + if (complain & tf_error) + error ("template argument %d is invalid", i + 1); + } + else + arg = convert_template_argument (TREE_VALUE (parm), arg, new_args, complain, i, - in_decl); - + in_decl); + if (arg == error_mark_node) lost++; TREE_VEC_ELT (new_inner_args, i) = arg; } + skip_evaluation = saved_skip_evaluation; if (lost) return error_mark_node; @@ -3929,7 +4278,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) gcc_obstack_init (&scratch_obstack); else obstack_free (&scratch_obstack, scratch_firstobj); - scratch_firstobj = obstack_alloc (&scratch_obstack, 1); + scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1); #define ccat(C) obstack_1grow (&scratch_obstack, (C)); #define cat(S) obstack_grow (&scratch_obstack, (S), strlen (S)) @@ -3938,11 +4287,17 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) ccat ('<'); nparms = TREE_VEC_LENGTH (parms); arglist = INNERMOST_TEMPLATE_ARGS (arglist); - my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268); + gcc_assert (nparms == TREE_VEC_LENGTH (arglist)); for (i = 0; i < nparms; i++) { - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - tree arg = TREE_VEC_ELT (arglist, i); + tree parm; + tree arg; + + parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + arg = TREE_VEC_ELT (arglist, i); + + if (parm == error_mark_node) + continue; if (i) ccat (','); @@ -3956,18 +4311,18 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) { if (TREE_CODE (arg) == TEMPLATE_DECL) { - /* Already substituted with real template. Just output + /* Already substituted with real template. Just output the template name here */ - tree context = DECL_CONTEXT (arg); - if (context) - { - /* The template may be defined in a namespace, or - may be a member template. */ - my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL - || CLASS_TYPE_P (context), - 980422); - cat(decl_as_string (DECL_CONTEXT (arg), TFF_PLAIN_IDENTIFIER)); - cat("::"); + tree context = DECL_CONTEXT (arg); + if (context) + { + /* The template may be defined in a namespace, or + may be a member template. */ + gcc_assert (TREE_CODE (context) == NAMESPACE_DECL + || CLASS_TYPE_P (context)); + cat (decl_as_string (DECL_CONTEXT (arg), + TFF_PLAIN_IDENTIFIER)); + cat ("::"); } cat (IDENTIFIER_POINTER (DECL_NAME (arg))); } @@ -3977,7 +4332,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) continue; } else - my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); + gcc_assert (TREE_CODE (parm) == PARM_DECL); /* No need to check arglist against parmlist here; we did that in coerce_template_parms, called from lookup_template_class. */ @@ -4015,7 +4370,7 @@ classtype_mangled_name (tree t) { tree name = DECL_NAME (tmpl); char *mangled_name = mangle_class_name_for_template - (IDENTIFIER_POINTER (name), + (IDENTIFIER_POINTER (name), DECL_INNERMOST_TEMPLATE_PARMS (tmpl), CLASSTYPE_TI_ARGS (t)); tree id = get_identifier (mangled_name); @@ -4074,25 +4429,24 @@ lookup_template_function (tree fns, tree arglist) if (fns == error_mark_node || arglist == error_mark_node) return error_mark_node; - my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726); - my_friendly_assert (fns && (is_overloaded_fn (fns) - || TREE_CODE (fns) == IDENTIFIER_NODE), - 20050608); + gcc_assert (!arglist || TREE_CODE (arglist) == TREE_VEC); + gcc_assert (fns && (is_overloaded_fn (fns) + || TREE_CODE (fns) == IDENTIFIER_NODE)); if (BASELINK_P (fns)) { - BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR, - unknown_type_node, - BASELINK_FUNCTIONS (fns), - arglist); + BASELINK_FUNCTIONS (fns) = build2 (TEMPLATE_ID_EXPR, + unknown_type_node, + BASELINK_FUNCTIONS (fns), + arglist); return fns; } type = TREE_TYPE (fns); if (TREE_CODE (fns) == OVERLOAD || !type) type = unknown_type_node; - - return build (TEMPLATE_ID_EXPR, type, fns, arglist); + + return build2 (TEMPLATE_ID_EXPR, type, fns, arglist); } /* Within the scope of a template class S<T>, the name S gets bound @@ -4106,10 +4460,10 @@ tree maybe_get_template_decl_from_type_decl (tree decl) { return (decl != NULL_TREE - && TREE_CODE (decl) == TYPE_DECL + && TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) && CLASS_TYPE_P (TREE_TYPE (decl)) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))) + && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))) ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl; } @@ -4119,40 +4473,47 @@ maybe_get_template_decl_from_type_decl (tree decl) D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. IN_DECL, if non-NULL, is the template declaration we are trying to - instantiate. + instantiate. If ENTERING_SCOPE is nonzero, we are about to enter the scope of the class we are looking up. - + Issue error and warning messages under control of COMPLAIN. If the template class is really a local class in a template function, then the FUNCTION_CONTEXT is the function in which it is - being instantiated. */ + being instantiated. + + ??? Note that this function is currently called *twice* for each + template-id: the first time from the parser, while creating the + incomplete type (finish_template_type), and the second type during the + real instantiation (instantiate_template_class). This is surely something + that we want to avoid. It also causes some problems with argument + coercion (see convert_nontype_argument for more information on this). */ tree -lookup_template_class (tree d1, - tree arglist, - tree in_decl, - tree context, - int entering_scope, - tsubst_flags_t complain) +lookup_template_class (tree d1, + tree arglist, + tree in_decl, + tree context, + int entering_scope, + tsubst_flags_t complain) { tree template = NULL_TREE, parmlist; tree t; - + timevar_push (TV_NAME_LOOKUP); - + if (TREE_CODE (d1) == IDENTIFIER_NODE) { - if (IDENTIFIER_VALUE (d1) - && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1))) - template = IDENTIFIER_VALUE (d1); + tree value = innermost_non_namespace_value (d1); + if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value)) + template = value; else { if (context) push_decl_namespace (context); - template = lookup_name (d1, /*prefer_type=*/0); + template = lookup_name (d1); template = maybe_get_template_decl_from_type_decl (template); if (context) pop_decl_namespace (); @@ -4168,14 +4529,14 @@ lookup_template_class (tree d1, an implicit typename for the second A. Deal with it. */ if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) type = TREE_TYPE (type); - + if (CLASSTYPE_TEMPLATE_INFO (type)) { template = CLASSTYPE_TI_TEMPLATE (type); d1 = DECL_NAME (template); } } - else if (TREE_CODE (d1) == ENUMERAL_TYPE + else if (TREE_CODE (d1) == ENUMERAL_TYPE || (TYPE_P (d1) && IS_AGGR_TYPE (d1))) { template = TYPE_TI_TEMPLATE (d1); @@ -4189,39 +4550,35 @@ lookup_template_class (tree d1, context = DECL_CONTEXT (template); } - /* With something like `template <class T> class X class X { ... };' - we could end up with D1 having nothing but an IDENTIFIER_VALUE. - We don't want to do that, but we have to deal with the situation, - so let's give them some syntax errors to chew on instead of a - crash. Alternatively D1 might not be a template type at all. */ + /* Issue an error message if we didn't find a template. */ if (! template) { if (complain & tf_error) - error ("`%T' is not a template", d1); + error ("%qT is not a template", d1); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } if (TREE_CODE (template) != TEMPLATE_DECL - /* Make sure it's a user visible template, if it was named by + /* Make sure it's a user visible template, if it was named by the user. */ || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template) && !PRIMARY_TEMPLATE_P (template))) { if (complain & tf_error) - { - error ("non-template type `%T' used as a template", d1); - if (in_decl) - cp_error_at ("for template declaration `%D'", in_decl); + { + error ("non-template type %qT used as a template", d1); + if (in_decl) + error ("for template declaration %q+D", in_decl); } POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } complain &= ~tf_user; - + if (DECL_TEMPLATE_TEMPLATE_PARM_P (template)) { /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store - template arguments */ + template arguments */ tree parm; tree arglist2; @@ -4232,8 +4589,8 @@ lookup_template_class (tree d1, template <class T, class U = std::allocator<T> > class TT - The template parameter level of T and U are one level larger than - of TT. To proper process the default argument of U, say when an + The template parameter level of T and U are one level larger than + of TT. To proper process the default argument of U, say when an instantiation `TT<int>' is seen, we need to build the full arguments containing {int} as the innermost level. Outer levels, available when not appearing as default template argument, can be @@ -4248,22 +4605,23 @@ lookup_template_class (tree d1, arglist = add_to_template_args (current_template_args (), arglist); arglist2 = coerce_template_parms (parmlist, arglist, template, - complain, /*require_all_args=*/1); + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); if (arglist2 == error_mark_node || (!uses_template_parms (arglist2) && check_instantiated_args (template, arglist2, complain))) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); parm = bind_template_template_parm (TREE_TYPE (template), arglist2); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm); } - else + else { tree template_type = TREE_TYPE (template); tree gen_tmpl; tree type_decl; tree found = NULL_TREE; - tree *tp; int arg_depth; int parm_depth; int is_partial_instantiation; @@ -4279,23 +4637,23 @@ lookup_template_class (tree d1, For example, given: template <class T> struct S1 { - template <class U> struct S2 {}; + template <class U> struct S2 {}; template <class U> struct S2<U*> {}; - }; - + }; + we will be called with an ARGLIST of `U*', but the TEMPLATE will be `template <class T> template <class U> struct S1<T>::S2'. We must fill in the missing arguments. */ - arglist + arglist = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (template)), arglist); arg_depth = TMPL_ARGS_DEPTH (arglist); } /* Now we should have enough arguments. */ - my_friendly_assert (parm_depth == arg_depth, 0); - + gcc_assert (parm_depth == arg_depth); + /* From here on, we're only interested in the most general template. */ template = gen_tmpl; @@ -4310,15 +4668,17 @@ lookup_template_class (tree d1, int saved_depth = TMPL_ARGS_DEPTH (arglist); tree bound_args = make_tree_vec (parm_depth); - + for (i = saved_depth, - t = DECL_TEMPLATE_PARMS (template); + t = DECL_TEMPLATE_PARMS (template); i > 0 && t != NULL_TREE; --i, t = TREE_CHAIN (t)) { tree a = coerce_template_parms (TREE_VALUE (t), arglist, template, - complain, /*require_all_args=*/1); + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); /* Don't process further if one of the levels fails. */ if (a == error_mark_node) @@ -4327,7 +4687,7 @@ lookup_template_class (tree d1, TREE_VEC_LENGTH (arglist) = saved_depth; POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } - + SET_TMPL_ARGS_LEVEL (bound_args, i, a); /* We temporarily reduce the length of the ARGLIST so @@ -4347,7 +4707,9 @@ lookup_template_class (tree d1, = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), INNERMOST_TEMPLATE_ARGS (arglist), template, - complain, /*require_all_args=*/1); + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); if (arglist == error_mark_node) /* We were unable to bind the arguments. */ @@ -4356,7 +4718,7 @@ lookup_template_class (tree d1, /* In the scope of a template class, explicit references to the template class refer to the type of the template, not any instantiation of it. For example, in: - + template <class T> class C { void f(C<T>); } the `C<T>' is just the same as `C'. Outside of the @@ -4365,19 +4727,19 @@ lookup_template_class (tree d1, arglist)) { found = template_type; - + if (!entering_scope && PRIMARY_TEMPLATE_P (template)) { tree ctx; - - for (ctx = current_class_type; + + for (ctx = current_class_type; ctx && TREE_CODE (ctx) != NAMESPACE_DECL; ctx = (TYPE_P (ctx) ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx))) if (TYPE_P (ctx) && same_type_p (ctx, template_type)) goto found_ctx; - + /* We're not in the scope of the class, so the TEMPLATE_TYPE is not the type we want after all. */ found = NULL_TREE; @@ -4385,24 +4747,13 @@ lookup_template_class (tree d1, } } if (found) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); - for (tp = &DECL_TEMPLATE_INSTANTIATIONS (template); - *tp; - tp = &TREE_CHAIN (*tp)) - if (comp_template_args (TREE_PURPOSE (*tp), arglist)) - { - found = *tp; - - /* Use the move-to-front heuristic to speed up future - searches. */ - *tp = TREE_CHAIN (*tp); - TREE_CHAIN (found) - = DECL_TEMPLATE_INSTANTIATIONS (template); - DECL_TEMPLATE_INSTANTIATIONS (template) = found; - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (found)); - } + /* If we already have this specialization, return it. */ + found = retrieve_specialization (template, arglist, + /*class_specializations_p=*/false); + if (found) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); /* This type is a "partial instantiation" if any of the template arguments still involve template parameters. Note that we set @@ -4417,17 +4768,17 @@ lookup_template_class (tree d1, INNERMOST_TEMPLATE_ARGS (arglist), complain)) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - - if (!is_partial_instantiation + + if (!is_partial_instantiation && !PRIMARY_TEMPLATE_P (template) && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL) { found = xref_tag_from_type (TREE_TYPE (template), DECL_NAME (template), - /*globalize=*/1); + /*tag_scope=*/ts_global); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); } - + context = tsubst (DECL_CONTEXT (template), arglist, complain, in_decl); if (!context) @@ -4451,14 +4802,14 @@ lookup_template_class (tree d1, else { t = make_aggr_type (TREE_CODE (template_type)); - CLASSTYPE_DECLARED_CLASS (t) + CLASSTYPE_DECLARED_CLASS (t) = CLASSTYPE_DECLARED_CLASS (template_type); SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t); TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type); /* A local class. Make sure the decl gets registered properly. */ if (context == current_function_decl) - pushtag (DECL_NAME (template), t, 0); + pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current); } /* If we called start_enum or pushtag above, this information @@ -4466,11 +4817,11 @@ lookup_template_class (tree d1, if (!TYPE_NAME (t)) { TYPE_CONTEXT (t) = FROB_CONTEXT (context); - + type_decl = create_implicit_typedef (DECL_NAME (template), t); DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t); TYPE_STUB_DECL (t) = type_decl; - DECL_SOURCE_LOCATION (type_decl) + DECL_SOURCE_LOCATION (type_decl) = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type)); } else @@ -4480,6 +4831,13 @@ lookup_template_class (tree d1, = TREE_PRIVATE (TYPE_STUB_DECL (template_type)); TREE_PROTECTED (type_decl) = TREE_PROTECTED (TYPE_STUB_DECL (template_type)); + DECL_IN_SYSTEM_HEADER (type_decl) + = DECL_IN_SYSTEM_HEADER (template); + if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type)) + { + DECL_VISIBILITY_SPECIFIED (type_decl) = 1; + DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type); + } /* Set up the template information. We have to figure out which template is the immediate parent if this is a full @@ -4529,26 +4887,26 @@ lookup_template_class (tree d1, if (!found) { /* There was no partial instantiation. This happens - where C<T> is a member template of A<T> and it's used - in something like - - template <typename T> struct B { A<T>::C<int> m; }; - B<float>; - - Create the partial instantiation. - */ - TREE_VEC_LENGTH (arglist)--; - found = tsubst (template, arglist, complain, NULL_TREE); - TREE_VEC_LENGTH (arglist)++; - } - } - - SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); - DECL_TEMPLATE_INSTANTIATIONS (template) - = tree_cons (arglist, t, + where C<T> is a member template of A<T> and it's used + in something like + + template <typename T> struct B { A<T>::C<int> m; }; + B<float>; + + Create the partial instantiation. + */ + TREE_VEC_LENGTH (arglist)--; + found = tsubst (template, arglist, complain, NULL_TREE); + TREE_VEC_LENGTH (arglist)++; + } + } + + SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); + DECL_TEMPLATE_INSTANTIATIONS (template) + = tree_cons (arglist, t, DECL_TEMPLATE_INSTANTIATIONS (template)); - if (TREE_CODE (t) == ENUMERAL_TYPE + if (TREE_CODE (t) == ENUMERAL_TYPE && !is_partial_instantiation) /* Now that the type has been registered on the instantiations list, we set up the enumerators. Because the enumeration @@ -4568,22 +4926,26 @@ lookup_template_class (tree d1, code that generates debugging information will crash. */ DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1; + /* Possibly limit visibility based on template args. */ + TREE_PUBLIC (type_decl) = 1; + determine_visibility (type_decl); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } timevar_pop (TV_NAME_LOOKUP); } -struct pair_fn_data +struct pair_fn_data { tree_fn_t fn; void *data; - htab_t visited; + struct pointer_set_t *visited; }; /* Called from for_each_template_parm via walk_tree. */ static tree -for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) +for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) { tree t = *tp; struct pair_fn_data *pfd = (struct pair_fn_data *) d; @@ -4644,7 +5006,7 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) break; case TYPEOF_TYPE: - if (for_each_template_parm (TYPE_FIELDS (t), fn, data, + if (for_each_template_parm (TYPE_FIELDS (t), fn, data, pfd->visited)) return error_mark_node; break; @@ -4663,7 +5025,7 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) && for_each_template_parm (DECL_INITIAL (t), fn, data, pfd->visited)) return error_mark_node; - if (DECL_CONTEXT (t) + if (DECL_CONTEXT (t) && for_each_template_parm (DECL_CONTEXT (t), fn, data, pfd->visited)) return error_mark_node; @@ -4695,7 +5057,7 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) break; case TYPENAME_TYPE: - if (!fn + if (!fn || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn, data, pfd->visited)) return error_mark_node; @@ -4708,7 +5070,7 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) pfd->visited)) return error_mark_node; break; - + case INDIRECT_REF: case COMPONENT_REF: /* If there's no type, then this thing must be some expression @@ -4749,8 +5111,8 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) return NULL_TREE; } -/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, - BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T, +/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, + BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA. If FN returns nonzero, the iteration is terminated, and for_each_template_parm returns 1. Otherwise, the iteration @@ -4759,7 +5121,8 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) considered to be the function which always returns 1. */ static int -for_each_template_parm (tree t, tree_fn_t fn, void* data, htab_t visited) +for_each_template_parm (tree t, tree_fn_t fn, void* data, + struct pointer_set_t *visited) { struct pair_fn_data pfd; int result; @@ -4776,16 +5139,18 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data, htab_t visited) if (visited) pfd.visited = visited; else - pfd.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer, - NULL); - result = walk_tree (&t, - for_each_template_parm_r, + pfd.visited = pointer_set_create (); + result = walk_tree (&t, + for_each_template_parm_r, &pfd, pfd.visited) != NULL_TREE; /* Clean up. */ if (!visited) - htab_delete (pfd.visited); + { + pointer_set_destroy (pfd.visited); + pfd.visited = 0; + } return result; } @@ -4810,19 +5175,21 @@ uses_template_parms (tree t) || uses_template_parms (TREE_CHAIN (t))); else if (TREE_CODE (t) == TYPE_DECL) dependent_p = dependent_type_p (TREE_TYPE (t)); - else if (DECL_P (t) - || EXPR_P (t) + else if (DECL_P (t) + || EXPR_P (t) || TREE_CODE (t) == TEMPLATE_PARM_INDEX || TREE_CODE (t) == OVERLOAD || TREE_CODE (t) == BASELINK || TREE_CODE (t) == IDENTIFIER_NODE - || TREE_CODE_CLASS (TREE_CODE (t)) == 'c') + || CONSTANT_CLASS_P (t)) dependent_p = (type_dependent_expression_p (t) || value_dependent_expression_p (t)); - else if (t == error_mark_node) - dependent_p = false; - else - abort (); + else + { + gcc_assert (t == error_mark_node); + dependent_p = false; + } + processing_template_decl = saved_processing_template_decl; return dependent_p; @@ -4847,7 +5214,7 @@ static int last_template_error_tick; /* We're starting to instantiate D; record the template instantiation context for diagnostics and to restore it later. */ -int +static int push_tinst_level (tree d) { tree new; @@ -4856,12 +5223,13 @@ push_tinst_level (tree d) { /* If the instantiation in question still has unbound template parms, we don't really care if we can't instantiate it, so just return. - This happens with base instantiation for implicit `typename'. */ + This happens with base instantiation for implicit `typename'. */ if (uses_template_parms (d)) return 0; last_template_error_tick = tinst_level_tick; - error ("template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'", + error ("template instantiation depth exceeds maximum of %d (use " + "-ftemplate-depth-NN to increase the maximum) instantiating %qD", max_tinst_depth, d); print_instantiation_context (); @@ -4869,7 +5237,10 @@ push_tinst_level (tree d) return 0; } - new = build_expr_wfl (d, input_filename, input_line, 0); + new = make_node (TINST_LEVEL); + TINST_DECL (new) = d; + TINST_LOCATION (new) = input_location; + TINST_IN_SYSTEM_HEADER_P (new) = in_system_header; TREE_CHAIN (new) = current_tinst_level; current_tinst_level = new; @@ -4886,17 +5257,15 @@ push_tinst_level (tree d) /* We're done instantiating this template; return to the instantiation context. */ -void +static void pop_tinst_level (void) { tree old = current_tinst_level; /* Restore the filename and line number stashed away when we started this instantiation. */ - input_line = TINST_LINE (old); - input_filename = TINST_FILE (old); - extract_interface_info (); - + input_location = TINST_LOCATION (old); + in_system_header = TINST_IN_SYSTEM_HEADER_P (old); current_tinst_level = TREE_CHAIN (old); --tinst_depth; ++tinst_level_tick; @@ -4919,20 +5288,6 @@ reopen_tinst_level (tree level) pop_tinst_level (); } -/* Return the outermost template instantiation context, for use with - -falt-external-templates. */ - -tree -tinst_for_decl (void) -{ - tree p = current_tinst_level; - - if (p) - for (; TREE_CHAIN (p) ; p = TREE_CHAIN (p)) - ; - return p; -} - /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. @@ -4942,18 +5297,15 @@ static tree tsubst_friend_function (tree decl, tree args) { tree new_friend; - location_t saved_loc = input_location; - - input_location = DECL_SOURCE_LOCATION (decl); - if (TREE_CODE (decl) == FUNCTION_DECL + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (decl) && TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL) /* This was a friend declared with an explicit template argument list, e.g.: - + friend void f<>(T); - + to indicate that f was a template instantiation, not a new function declaration. Now, we have to figure out what instantiation of what template. */ @@ -4962,41 +5314,43 @@ tsubst_friend_function (tree decl, tree args) tree new_args; tree tmpl; tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type)); - + /* Friend functions are looked up in the containing namespace scope. - We must enter that scope, to avoid finding member functions of the - current cless with same name. */ + We must enter that scope, to avoid finding member functions of the + current cless with same name. */ push_nested_namespace (ns); fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args, - tf_error | tf_warning, NULL_TREE); + tf_warning_or_error, NULL_TREE, + /*integral_constant_expression_p=*/false); pop_nested_namespace (ns); arglist = tsubst (DECL_TI_ARGS (decl), args, - tf_error | tf_warning, NULL_TREE); + tf_warning_or_error, NULL_TREE); template_id = lookup_template_function (fns, arglist); - - new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE); + + new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE); tmpl = determine_specialization (template_id, new_friend, - &new_args, - /*need_member_template=*/0); - new_friend = instantiate_template (tmpl, new_args, tf_error); - goto done; + &new_args, + /*need_member_template=*/0, + TREE_VEC_LENGTH (args), + tsk_none); + return instantiate_template (tmpl, new_args, tf_error); } - new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE); - + new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE); + /* The NEW_FRIEND will look like an instantiation, to the compiler, but is not an instantiation from the point of view of the language. For example, we might have had: - + template <class T> struct S { template <class U> friend void f(T, U); }; - + Then, in S<int>, template <class U> void f(int, U) is not an instantiation of anything. */ if (new_friend == error_mark_node) return error_mark_node; - + DECL_USE_TEMPLATE (new_friend) = 0; if (TREE_CODE (decl) == TEMPLATE_DECL) { @@ -5014,7 +5368,7 @@ tsubst_friend_function (tree decl, tree args) SET_DECL_RTL (new_friend, NULL_RTX); SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE); } - + if (DECL_NAMESPACE_SCOPE_P (new_friend)) { tree old_decl; @@ -5028,36 +5382,43 @@ tsubst_friend_function (tree decl, tree args) possible. */ new_friend_template_info = DECL_TEMPLATE_INFO (new_friend); new_friend_is_defn = - (DECL_INITIAL (DECL_TEMPLATE_RESULT + (DECL_INITIAL (DECL_TEMPLATE_RESULT (template_for_substitution (new_friend))) != NULL_TREE); if (TREE_CODE (new_friend) == TEMPLATE_DECL) { /* This declaration is a `primary' template. */ DECL_PRIMARY_TEMPLATE (new_friend) = new_friend; - + new_friend_result_template_info = DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (new_friend)); } else new_friend_result_template_info = NULL_TREE; + /* Make the init_value nonzero so pushdecl knows this is a defn. */ + if (new_friend_is_defn) + DECL_INITIAL (new_friend) = error_mark_node; + /* Inside pushdecl_namespace_level, we will push into the current namespace. However, the friend function should go into the namespace of the template. */ ns = decl_namespace_context (new_friend); push_nested_namespace (ns); - old_decl = pushdecl_namespace_level (new_friend); + old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true); pop_nested_namespace (ns); + if (old_decl == error_mark_node) + return error_mark_node; + if (old_decl != new_friend) { /* This new friend declaration matched an existing declaration. For example, given: template <class T> void f(T); - template <class U> class C { - template <class T> friend void f(T) {} + template <class U> class C { + template <class T> friend void f(T) {} }; the friend declaration actually provides the definition @@ -5074,14 +5435,14 @@ tsubst_friend_function (tree decl, tree args) run through all specialization of `f', adding to their DECL_TI_ARGS appropriately. In particular, they need a new set of outer arguments, corresponding to the - arguments for this class instantiation. + arguments for this class instantiation. The same situation can arise with something like this: friend void f(int); - template <class T> class C { - friend void f(T) {} - }; + template <class T> class C { + friend void f(T) {} + }; when `C<int>' is instantiated. Now, `f(int)' is defined in the class. */ @@ -5103,22 +5464,22 @@ tsubst_friend_function (tree decl, tree args) reregister_specialization (new_friend, most_general_template (old_decl), old_decl); - else + else { tree t; tree new_friend_args; - DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (old_decl)) + DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (old_decl)) = new_friend_result_template_info; - + new_friend_args = TI_ARGS (new_friend_template_info); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl); + for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl); t != NULL_TREE; t = TREE_CHAIN (t)) { tree spec = TREE_VALUE (t); - - DECL_TI_ARGS (spec) + + DECL_TI_ARGS (spec) = add_outermost_template_args (new_friend_args, DECL_TI_ARGS (spec)); } @@ -5142,19 +5503,40 @@ tsubst_friend_function (tree decl, tree args) new_friend = old_decl; } } - else if (COMPLETE_TYPE_P (DECL_CONTEXT (new_friend))) + else { - /* Check to see that the declaration is really present, and, - possibly obtain an improved declaration. */ - tree fn = check_classfn (DECL_CONTEXT (new_friend), - new_friend, false); - - if (fn) - new_friend = fn; + tree context = DECL_CONTEXT (new_friend); + bool dependent_p; + + /* In the code + template <class T> class C { + template <class U> friend void C1<U>::f (); // case 1 + friend void C2<T>::f (); // case 2 + }; + we only need to make sure CONTEXT is a complete type for + case 2. To distinguish between the two cases, we note that + CONTEXT of case 1 remains dependent type after tsubst while + this isn't true for case 2. */ + ++processing_template_decl; + dependent_p = dependent_type_p (context); + --processing_template_decl; + + if (!dependent_p + && !complete_type_or_else (context, NULL_TREE)) + return error_mark_node; + + if (COMPLETE_TYPE_P (context)) + { + /* Check to see that the declaration is really present, and, + possibly obtain an improved declaration. */ + tree fn = check_classfn (context, + new_friend, NULL_TREE); + + if (fn) + new_friend = fn; + } } - done: - input_location = saved_loc; return new_friend; } @@ -5178,11 +5560,24 @@ tsubst_friend_class (tree friend_tmpl, tree args) if (TREE_CODE (context) == NAMESPACE_DECL) push_nested_namespace (context); else - push_nested_class (tsubst (context, args, tf_none, NULL_TREE)); + push_nested_class (tsubst (context, args, tf_none, NULL_TREE)); } - /* First, we look for a class template. */ - tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); + /* Look for a class template declaration. We look for hidden names + because two friend declarations of the same template are the + same. For example, in: + + struct A { + template <typename> friend class F; + }; + template <typename> struct B { + template <typename> friend class F; + }; + + both F templates are the same. */ + tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0, + /*block_p=*/true, 0, + LOOKUP_COMPLAIN | LOOKUP_HIDDEN); /* But, if we don't find one, it might be because we're in a situation like this: @@ -5197,7 +5592,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) for `S<int>', not the TEMPLATE_DECL. */ if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { - tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1); + tmpl = lookup_name_prefer_type (DECL_NAME (friend_tmpl), 1); tmpl = maybe_get_template_decl_from_type_decl (tmpl); } @@ -5214,7 +5609,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) { tree parms; parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), - args, tf_error | tf_warning); + args, tf_warning_or_error); redeclare_class_template (TREE_TYPE (tmpl), parms); } @@ -5225,10 +5620,12 @@ tsubst_friend_class (tree friend_tmpl, tree args) /* The friend template has not already been declared. In this case, the instantiation of the template class will cause the injection of this template into the global scope. */ - tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE); + tmpl = tsubst (friend_tmpl, args, tf_warning_or_error, NULL_TREE); + if (tmpl == error_mark_node) + return error_mark_node; /* The new TMPL is not an instantiation of anything, so we - forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for + forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for the new type because that is supposed to be the corresponding template decl, i.e., TMPL. */ DECL_USE_TEMPLATE (tmpl) = 0; @@ -5238,10 +5635,10 @@ tsubst_friend_class (tree friend_tmpl, tree args) = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))); /* Inject this template into the global scope. */ - friend_type = TREE_TYPE (pushdecl_top_level (tmpl)); + friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true)); } - if (context) + if (context) { if (TREE_CODE (context) == NAMESPACE_DECL) pop_nested_namespace (context); @@ -5277,47 +5674,48 @@ instantiate_class_template (tree type) tree template, args, pattern, t, member; tree typedecl; tree pbinfo; - + tree base_list; + if (type == error_mark_node) return error_mark_node; - if (TYPE_BEING_DEFINED (type) + if (TYPE_BEING_DEFINED (type) || COMPLETE_TYPE_P (type) || dependent_type_p (type)) return type; /* Figure out which template is being instantiated. */ template = most_general_template (CLASSTYPE_TI_TEMPLATE (type)); - my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279); - - /* Figure out which arguments are being used to do the - instantiation. */ - args = CLASSTYPE_TI_ARGS (type); + gcc_assert (TREE_CODE (template) == TEMPLATE_DECL); /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (template, args); + t = most_specialized_class (type, template); if (t == error_mark_node) { - const char *str = "candidates are:"; - error ("ambiguous class template instantiation for `%#T'", type); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; - t = TREE_CHAIN (t)) - { - if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args)) - { - cp_error_at ("%s %+#T", str, TREE_TYPE (t)); - str = " "; - } - } TYPE_BEING_DEFINED (type) = 1; return error_mark_node; } + else if (t) + { + /* This TYPE is actually an instantiation of a partial + specialization. We replace the innermost set of ARGS with + the arguments appropriate for substitution. For example, + given: - if (t) - pattern = TREE_TYPE (t); + template <class T> struct S {}; + template <class T> struct S<T*> {}; + + and supposing that we are instantiating S<int*>, ARGS will + presently be {int*} -- but we need {int}. */ + pattern = TREE_TYPE (t); + args = TREE_PURPOSE (t); + } else - pattern = TREE_TYPE (template); + { + pattern = TREE_TYPE (template); + args = CLASSTYPE_TI_ARGS (type); + } /* If the template we're instantiating is incomplete, then clearly there's nothing we can do. */ @@ -5338,122 +5736,86 @@ instantiate_class_template (tree type) push_to_top_level (); - if (t) - { - /* This TYPE is actually an instantiation of a partial - specialization. We replace the innermost set of ARGS with - the arguments appropriate for substitution. For example, - given: - - template <class T> struct S {}; - template <class T> struct S<T*> {}; - - and supposing that we are instantiating S<int*>, ARGS will - present be {int*} but we need {int}. */ - tree inner_args - = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), - args); - - /* If there were multiple levels in ARGS, replacing the - innermost level would alter CLASSTYPE_TI_ARGS, which we don't - want, so we make a copy first. */ - if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) - { - args = copy_node (args); - SET_TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args), inner_args); - } - else - args = inner_args; - } - SET_CLASSTYPE_INTERFACE_UNKNOWN (type); /* Set the input location to the template definition. This is needed if tsubsting causes an error. */ - input_location = DECL_SOURCE_LOCATION (TYPE_NAME (pattern)); + typedecl = TYPE_MAIN_DECL (type); + input_location = DECL_SOURCE_LOCATION (typedecl); + in_system_header = DECL_IN_SYSTEM_HEADER (typedecl); TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern); - TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern); TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern); TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern); TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern); TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern); - TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern); TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern); TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern); TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern); TYPE_HAS_CONVERSION (type) = TYPE_HAS_CONVERSION (pattern); - TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type) - = TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (pattern); - TYPE_USES_MULTIPLE_INHERITANCE (type) - = TYPE_USES_MULTIPLE_INHERITANCE (pattern); - TYPE_USES_VIRTUAL_BASECLASSES (type) - = TYPE_USES_VIRTUAL_BASECLASSES (pattern); TYPE_PACKED (type) = TYPE_PACKED (pattern); TYPE_ALIGN (type) = TYPE_ALIGN (pattern); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern); TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */ if (ANON_AGGR_TYPE_P (pattern)) SET_ANON_AGGR_TYPE_P (type); + if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern)) + { + CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1; + CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern); + } pbinfo = TYPE_BINFO (pattern); -#ifdef ENABLE_CHECKING - if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern)) - && ! COMPLETE_TYPE_P (TYPE_CONTEXT (type)) - && ! TYPE_BEING_DEFINED (TYPE_CONTEXT (type))) - /* We should never instantiate a nested class before its enclosing - class; we need to look up the nested class by name before we can - instantiate it, and that lookup should instantiate the enclosing - class. */ - abort (); -#endif + /* We should never instantiate a nested class before its enclosing + class; we need to look up the nested class by name before we can + instantiate it, and that lookup should instantiate the enclosing + class. */ + gcc_assert (!DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern)) + || COMPLETE_TYPE_P (TYPE_CONTEXT (type)) + || TYPE_BEING_DEFINED (TYPE_CONTEXT (type))); - if (BINFO_BASETYPES (pbinfo)) + base_list = NULL_TREE; + if (BINFO_N_BASE_BINFOS (pbinfo)) { - tree base_list = NULL_TREE; - tree pbases = BINFO_BASETYPES (pbinfo); - tree paccesses = BINFO_BASEACCESSES (pbinfo); + tree pbase_binfo; tree context = TYPE_CONTEXT (type); - bool pop_p; + tree pushed_scope; int i; /* We must enter the scope containing the type, as that is where the accessibility of types named in dependent bases are looked up from. */ - pop_p = push_scope (context ? context : global_namespace); - + pushed_scope = push_scope (context ? context : global_namespace); + /* Substitute into each of the bases to determine the actual basetypes. */ - for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i) + for (i = 0; BINFO_BASE_ITERATE (pbinfo, i, pbase_binfo); i++) { tree base; - tree access; - tree pbase; - - pbase = TREE_VEC_ELT (pbases, i); - access = TREE_VEC_ELT (paccesses, i); + tree access = BINFO_BASE_ACCESS (pbinfo, i); /* Substitute to figure out the base class. */ - base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE); + base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error, NULL_TREE); if (base == error_mark_node) continue; - + base_list = tree_cons (access, base, base_list); - TREE_VIA_VIRTUAL (base_list) = TREE_VIA_VIRTUAL (pbase); + if (BINFO_VIRTUAL_P (pbase_binfo)) + TREE_TYPE (base_list) = integer_type_node; } /* The list is now in reverse order; correct that. */ base_list = nreverse (base_list); - /* Now call xref_basetypes to set up all the base-class - information. */ - xref_basetypes (type, base_list); - - if (pop_p) - pop_scope (context ? context : global_namespace); + if (pushed_scope) + pop_scope (pushed_scope); } + /* Now call xref_basetypes to set up all the base-class + information. */ + xref_basetypes (type, base_list); + /* Now that our base classes are set up, enter the scope of the class, so that name lookups into base classes, etc. will work @@ -5474,23 +5836,21 @@ instantiate_class_template (tree type) { /* Build new CLASSTYPE_NESTED_UTDS. */ - tree tag = t; - tree name = TYPE_IDENTIFIER (tag); tree newtag; bool class_template_p; - class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE - && TYPE_LANG_SPECIFIC (tag) - && CLASSTYPE_IS_TEMPLATE (tag)); + class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE + && TYPE_LANG_SPECIFIC (t) + && CLASSTYPE_IS_TEMPLATE (t)); /* If the member is a class template, then -- even after - substituition -- there may be dependent types in the + substitution -- there may be dependent types in the template argument list for the class. We increment PROCESSING_TEMPLATE_DECL so that dependent_type_p, as that function will assume that no types are dependent when outside of a template. */ if (class_template_p) ++processing_template_decl; - newtag = tsubst (tag, args, tf_error, NULL_TREE); + newtag = tsubst (t, args, tf_error, NULL_TREE); if (class_template_p) --processing_template_decl; if (newtag == error_mark_node) @@ -5498,6 +5858,8 @@ instantiate_class_template (tree type) if (TREE_CODE (newtag) != ENUMERAL_TYPE) { + tree name = TYPE_IDENTIFIER (t); + if (class_template_p) /* Unfortunately, lookup_template_class sets CLASSTYPE_IMPLICIT_INSTANTIATION for a partial @@ -5518,22 +5880,21 @@ instantiate_class_template (tree type) tsubst_enum. */ if (name) SET_IDENTIFIER_TYPE_VALUE (name, newtag); - pushtag (name, newtag, /*globalize=*/0); + pushtag (name, newtag, /*tag_scope=*/ts_current); } } - else if (TREE_CODE (t) == FUNCTION_DECL + else if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) { /* Build new TYPE_METHODS. */ tree r; - + if (TREE_CODE (t) == TEMPLATE_DECL) ++processing_template_decl; r = tsubst (t, args, tf_error, NULL_TREE); if (TREE_CODE (t) == TEMPLATE_DECL) --processing_template_decl; set_current_access_from_decl (r); - grok_special_member_properties (r); finish_member_declaration (r); } else @@ -5552,22 +5913,28 @@ instantiate_class_template (tree type) if (TREE_CODE (t) == TEMPLATE_DECL) ++processing_template_decl; - r = tsubst (t, args, tf_error | tf_warning, NULL_TREE); + r = tsubst (t, args, tf_warning_or_error, NULL_TREE); if (TREE_CODE (t) == TEMPLATE_DECL) --processing_template_decl; if (TREE_CODE (r) == VAR_DECL) { - tree init; + /* In [temp.inst]: - if (DECL_INITIALIZED_IN_CLASS_P (r)) - init = tsubst_expr (DECL_INITIAL (t), args, - tf_error | tf_warning, NULL_TREE); - else - init = NULL_TREE; + [t]he initialization (and any associated + side-effects) of a static data member does + not occur unless the static data member is + itself used in a way that requires the + definition of the static data member to + exist. + Therefore, we do not substitute into the + initialized for the static data member here. */ finish_static_data_member_decl - (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0); - + (r, + /*init=*/NULL_TREE, + /*init_const_expr_p=*/false, + /*asmspec_tree=*/NULL_TREE, + /*flags=*/0); if (DECL_INITIALIZED_IN_CLASS_P (r)) check_static_variable_definition (r, TREE_TYPE (r)); } @@ -5584,7 +5951,7 @@ instantiate_class_template (tree type) if (!COMPLETE_TYPE_P (rtype)) { cxx_incomplete_type_error (r, rtype); - r = error_mark_node; + r = error_mark_node; } } @@ -5599,7 +5966,7 @@ instantiate_class_template (tree type) set_current_access_from_decl (r); finish_member_declaration (r); } - } + } } } else @@ -5609,28 +5976,76 @@ instantiate_class_template (tree type) /* Build new CLASSTYPE_FRIEND_CLASSES. */ tree friend_type = t; - tree new_friend_type; + bool adjust_processing_template_decl = false; if (TREE_CODE (friend_type) == TEMPLATE_DECL) - new_friend_type = tsubst_friend_class (friend_type, args); - else if (uses_template_parms (friend_type)) - new_friend_type = tsubst (friend_type, args, - tf_error | tf_warning, NULL_TREE); - else if (CLASSTYPE_USE_TEMPLATE (friend_type)) - new_friend_type = friend_type; - else { + /* template <class T> friend class C; */ + friend_type = tsubst_friend_class (friend_type, args); + adjust_processing_template_decl = true; + } + else if (TREE_CODE (friend_type) == UNBOUND_CLASS_TEMPLATE) + { + /* template <class T> friend class C::D; */ + friend_type = tsubst (friend_type, args, + tf_warning_or_error, NULL_TREE); + if (TREE_CODE (friend_type) == TEMPLATE_DECL) + friend_type = TREE_TYPE (friend_type); + adjust_processing_template_decl = true; + } + else if (TREE_CODE (friend_type) == TYPENAME_TYPE) + { + /* This could be either + + friend class T::C; + + when dependent_type_p is false or + + template <class U> friend class T::C; + + otherwise. */ + friend_type = tsubst (friend_type, args, + tf_warning_or_error, NULL_TREE); + /* Bump processing_template_decl for correct + dependent_type_p calculation. */ + ++processing_template_decl; + if (dependent_type_p (friend_type)) + adjust_processing_template_decl = true; + --processing_template_decl; + } + else if (!CLASSTYPE_USE_TEMPLATE (friend_type) + && hidden_name_p (TYPE_NAME (friend_type))) + { + /* friend class C; + + where C hasn't been declared yet. Let's lookup name + from namespace scope directly, bypassing any name that + come from dependent base class. */ tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type)); /* The call to xref_tag_from_type does injection for friend classes. */ push_nested_namespace (ns); - new_friend_type = - xref_tag_from_type (friend_type, NULL_TREE, 1); + friend_type = + xref_tag_from_type (friend_type, NULL_TREE, + /*tag_scope=*/ts_current); pop_nested_namespace (ns); } + else if (uses_template_parms (friend_type)) + /* friend class C<T>; */ + friend_type = tsubst (friend_type, args, + tf_warning_or_error, NULL_TREE); + /* Otherwise it's - if (TREE_CODE (friend_type) == TEMPLATE_DECL) + friend class C; + + where C is already declared or + + friend class C<int>; + + We don't have to do anything in these cases. */ + + if (adjust_processing_template_decl) /* Trick make_friend_class into realizing that the friend we're adding is a template, not an ordinary class. It's important that we use make_friend_class since it will @@ -5638,11 +6053,10 @@ instantiate_class_template (tree type) information. */ ++processing_template_decl; - if (new_friend_type != error_mark_node) - make_friend_class (type, new_friend_type, - /*complain=*/false); + if (friend_type != error_mark_node) + make_friend_class (type, friend_type, /*complain=*/false); - if (TREE_CODE (friend_type) == TEMPLATE_DECL) + if (adjust_processing_template_decl) --processing_template_decl; } else @@ -5650,12 +6064,25 @@ instantiate_class_template (tree type) /* Build new DECL_FRIENDLIST. */ tree r; + /* The the file and line for this declaration, to + assist in error message reporting. Since we + called push_tinst_level above, we don't need to + restore these. */ + input_location = DECL_SOURCE_LOCATION (t); + if (TREE_CODE (t) == TEMPLATE_DECL) - ++processing_template_decl; + { + ++processing_template_decl; + push_deferring_access_checks (dk_no_check); + } + r = tsubst_friend_function (t, args); - if (TREE_CODE (t) == TEMPLATE_DECL) - --processing_template_decl; add_friend (type, r, /*complain=*/false); + if (TREE_CODE (t) == TEMPLATE_DECL) + { + pop_deferring_access_checks (); + --processing_template_decl; + } } } } @@ -5664,22 +6091,18 @@ instantiate_class_template (tree type) the class itself. This puts error messages involving generated implicit functions at a predictable point, and the same point that would be used for non-template classes. */ - typedecl = TYPE_MAIN_DECL (type); input_location = DECL_SOURCE_LOCATION (typedecl); - + unreverse_member_declarations (type); finish_struct_1 (type); - - /* Clear this now so repo_template_used is happy. */ TYPE_BEING_DEFINED (type) = 0; - repo_template_used (type); /* Now that the class is complete, instantiate default arguments for any member functions. We don't do this earlier because the default arguments may reference members of the class. */ if (!PRIMARY_TEMPLATE_P (template)) for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t)) - if (TREE_CODE (t) == FUNCTION_DECL + if (TREE_CODE (t) == FUNCTION_DECL /* Implicitly generated member functions will not have template information; they are not instantiations, but instead are created "fresh" for each instantiation. */ @@ -5691,7 +6114,11 @@ instantiate_class_template (tree type) pop_deferring_access_checks (); pop_tinst_level (); - if (TYPE_CONTAINS_VPTR_P (type)) + /* The vtable for a template class can be emitted in any translation + unit in which the class is instantiated. When there is no key + method, however, finish_struct_1 will already have added TYPE to + the keyed_classes list. */ + if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type)) keyed_classes = tree_cons (NULL_TREE, type, keyed_classes); return type; @@ -5701,40 +6128,16 @@ static tree tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree r; - + if (!t) r = t; else if (TYPE_P (t)) r = tsubst (t, args, complain, in_decl); else { - r = tsubst_expr (t, args, complain, in_decl); - - if (!uses_template_parms (r)) - { - /* Sometimes, one of the args was an expression involving a - template constant parameter, like N - 1. Now that we've - tsubst'd, we might have something like 2 - 1. This will - confuse lookup_template_class, so we do constant folding - here. We have to unset processing_template_decl, to fool - tsubst_copy_and_build() into building an actual tree. */ - - /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already - as simple as it's going to get, and trying to reprocess - the trees will break. Once tsubst_expr et al DTRT for - non-dependent exprs, this code can go away, as the type - will always be set. */ - if (!TREE_TYPE (r)) - { - int saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; - r = tsubst_copy_and_build (r, /*args=*/NULL_TREE, - tf_error, /*in_decl=*/NULL_TREE, - /*function_p=*/false); - processing_template_decl = saved_processing_template_decl; - } - r = fold (r); - } + r = tsubst_expr (t, args, complain, in_decl, + /*integral_constant_expression_p=*/true); + r = fold_non_dependent_expr (r); } return r; } @@ -5746,8 +6149,8 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) { int len = TREE_VEC_LENGTH (t); int need_new = 0, i; - tree *elts = alloca (len * sizeof (tree)); - + tree *elts = (tree *) alloca (len * sizeof (tree)); + for (i = 0; i < len; i++) { tree orig_arg = TREE_VEC_ELT (t, i); @@ -5757,7 +6160,7 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) new_arg = tsubst_template_args (orig_arg, args, complain, in_decl); else new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl); - + if (new_arg == error_mark_node) return error_mark_node; @@ -5765,14 +6168,14 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (new_arg != orig_arg) need_new = 1; } - + if (!need_new) return t; t = make_tree_vec (len); for (i = 0; i < len; i++) TREE_VEC_ELT (t, i) = elts[i]; - + return t; } @@ -5800,26 +6203,40 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) new_parms = &(TREE_CHAIN (*new_parms)), parms = TREE_CHAIN (parms)) { - tree new_vec = + tree new_vec = make_tree_vec (TREE_VEC_LENGTH (TREE_VALUE (parms))); int i; - + for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i) { - tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i); - tree default_value = TREE_PURPOSE (tuple); - tree parm_decl = TREE_VALUE (tuple); + tree tuple; + tree default_value; + tree parm_decl; + + if (parms == error_mark_node) + continue; + + tuple = TREE_VEC_ELT (TREE_VALUE (parms), i); + + if (tuple == error_mark_node) + continue; + + default_value = TREE_PURPOSE (tuple); + parm_decl = TREE_VALUE (tuple); parm_decl = tsubst (parm_decl, args, complain, NULL_TREE); + if (TREE_CODE (parm_decl) == PARM_DECL + && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain)) + parm_decl = error_mark_node; default_value = tsubst_template_arg (default_value, args, complain, NULL_TREE); - + tuple = build_tree_list (default_value, parm_decl); TREE_VEC_ELT (new_vec, i) = tuple; } - - *new_parms = - tree_cons (size_int (TMPL_PARMS_DEPTH (parms) + + *new_parms = + tree_cons (size_int (TMPL_PARMS_DEPTH (parms) - TMPL_ARGS_DEPTH (args)), new_vec, NULL_TREE); } @@ -5836,11 +6253,11 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) we are presently tsubst'ing. Return the substituted value. */ static tree -tsubst_aggr_type (tree t, - tree args, - tsubst_flags_t complain, - tree in_decl, - int entering_scope) +tsubst_aggr_type (tree t, + tree args, + tsubst_flags_t complain, + tree in_decl, + int entering_scope) { if (t == NULL_TREE) return NULL_TREE; @@ -5859,6 +6276,11 @@ tsubst_aggr_type (tree t, tree argvec; tree context; tree r; + bool saved_skip_evaluation; + + /* In "sizeof(X<I>)" we need to evaluate "I". */ + saved_skip_evaluation = skip_evaluation; + skip_evaluation = false; /* First, determine the context for the type we are looking up. */ @@ -5879,14 +6301,19 @@ tsubst_aggr_type (tree t, argvec = tsubst_template_args (TYPE_TI_ARGS (t), args, complain, in_decl); if (argvec == error_mark_node) - return error_mark_node; + r = error_mark_node; + else + { + r = lookup_template_class (t, argvec, in_decl, context, + entering_scope, complain); + r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); + } - r = lookup_template_class (t, argvec, in_decl, context, - entering_scope, complain); + skip_evaluation = saved_skip_evaluation; - return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); + return r; } - else + else /* This is not a template type, so there's nothing to do. */ return t; @@ -5906,21 +6333,17 @@ tsubst_default_argument (tree fn, tree type, tree arg) /* This default argument came from a template. Instantiate the default argument here, not in tsubst. In the case of - something like: - + something like: + template <class T> struct S { static T t(); void f(T = t()); }; - + we must be careful to do name lookup in the scope of S<T>, rather than in the current class. */ push_access_scope (fn); - /* The default argument expression should not be considered to be - within the scope of FN. Since push_access_scope sets - current_function_decl, we must explicitly clear it here. */ - current_function_decl = NULL_TREE; /* The "this" pointer is not valid in a default argument. */ if (cfun) { @@ -5931,8 +6354,16 @@ tsubst_default_argument (tree fn, tree type, tree arg) } push_deferring_access_checks(dk_no_deferred); + /* The default argument expression may cause implicitly defined + member functions to be synthesized, which will result in garbage + collection. We must treat this situation as if we were within + the body of function so as to avoid collecting live data on the + stack. */ + ++function_depth; arg = tsubst_expr (arg, DECL_TI_ARGS (fn), - tf_error | tf_warning, NULL_TREE); + tf_warning_or_error, NULL_TREE, + /*integral_constant_expression_p=*/false); + --function_depth; pop_deferring_access_checks(); /* Restore the "this" pointer. */ @@ -5965,22 +6396,21 @@ tsubst_default_arguments (tree fn) if (uses_template_parms (tmpl_args)) return; - for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); - arg; + for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); + arg; arg = TREE_CHAIN (arg)) if (TREE_PURPOSE (arg)) - TREE_PURPOSE (arg) = tsubst_default_argument (fn, + TREE_PURPOSE (arg) = tsubst_default_argument (fn, TREE_VALUE (arg), TREE_PURPOSE (arg)); } -/* Substitute the ARGS into the T, which is a _DECL. TYPE is the - (already computed) substitution of ARGS into TREE_TYPE (T), if - appropriate. Return the result of the substitution. Issue error - and warning messages under control of COMPLAIN. */ +/* Substitute the ARGS into the T, which is a _DECL. Return the + result of the substitution. Issue error and warning messages under + control of COMPLAIN. */ static tree -tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) +tsubst_decl (tree t, tree args, tsubst_flags_t complain) { location_t saved_loc; tree r = NULL_TREE; @@ -5994,62 +6424,73 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) { case TEMPLATE_DECL: { - /* We can get here when processing a member template function - of a template class. */ + /* We can get here when processing a member function template, + member class template, and template template parameter of + a template class. */ tree decl = DECL_TEMPLATE_RESULT (t); tree spec; - int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t); + tree tmpl_args; + tree full_args; - if (!is_template_template_parm) + if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) { - /* We might already have an instance of this template. - The ARGS are for the surrounding class type, so the - full args contain the tsubst'd args for the context, - plus the innermost args from the template decl. */ - tree tmpl_args = DECL_CLASS_TEMPLATE_P (t) - ? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) - : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); - tree full_args; - - /* Because this is a template, the arguments will still be - dependent, even after substitution. If - PROCESSING_TEMPLATE_DECL is not set, the dependency - predicates will short-circuit. */ - ++processing_template_decl; - full_args = tsubst_template_args (tmpl_args, args, - complain, in_decl); - --processing_template_decl; + /* Template template parameter is treated here. */ + tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (new_type == error_mark_node) + return error_mark_node; - /* tsubst_template_args doesn't copy the vector if - nothing changed. But, *something* should have - changed. */ - my_friendly_assert (full_args != tmpl_args, 0); + r = copy_decl (t); + TREE_CHAIN (r) = NULL_TREE; + TREE_TYPE (r) = new_type; + DECL_TEMPLATE_RESULT (r) + = build_decl (TYPE_DECL, DECL_NAME (decl), new_type); + DECL_TEMPLATE_PARMS (r) + = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, + complain); + TYPE_NAME (new_type) = r; + break; + } - spec = retrieve_specialization (t, full_args); - if (spec != NULL_TREE) - { - r = spec; - break; - } + /* We might already have an instance of this template. + The ARGS are for the surrounding class type, so the + full args contain the tsubst'd args for the context, + plus the innermost args from the template decl. */ + tmpl_args = DECL_CLASS_TEMPLATE_P (t) + ? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) + : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)); + /* Because this is a template, the arguments will still be + dependent, even after substitution. If + PROCESSING_TEMPLATE_DECL is not set, the dependency + predicates will short-circuit. */ + ++processing_template_decl; + full_args = tsubst_template_args (tmpl_args, args, + complain, in_decl); + --processing_template_decl; + if (full_args == error_mark_node) + return error_mark_node; + + /* tsubst_template_args doesn't copy the vector if + nothing changed. But, *something* should have + changed. */ + gcc_assert (full_args != tmpl_args); + + spec = retrieve_specialization (t, full_args, + /*class_specializations_p=*/true); + if (spec != NULL_TREE) + { + r = spec; + break; } /* Make a new template decl. It will be similar to the - original, but will record the current template arguments. + original, but will record the current template arguments. We also create a new function declaration, which is just like the old one, but points to this new template, rather than the old one. */ r = copy_decl (t); - my_friendly_assert (DECL_LANG_SPECIFIC (r) != 0, 0); + gcc_assert (DECL_LANG_SPECIFIC (r) != 0); TREE_CHAIN (r) = NULL_TREE; - if (is_template_template_parm) - { - tree new_decl = tsubst (decl, args, complain, in_decl); - DECL_TEMPLATE_RESULT (r) = new_decl; - TREE_TYPE (r) = TREE_TYPE (new_decl); - break; - } - DECL_TEMPLATE_INFO (r) = build_tree_list (t, args); if (TREE_CODE (decl) == TYPE_DECL) @@ -6057,7 +6498,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree new_type; ++processing_template_decl; new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); - --processing_template_decl; + --processing_template_decl; if (new_type == error_mark_node) return error_mark_node; @@ -6080,7 +6521,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) DECL_TI_TEMPLATE (new_decl) = r; TREE_TYPE (r) = TREE_TYPE (new_decl); DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl); - DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); + DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); } SET_DECL_IMPLICIT_INSTANTIATION (r); @@ -6090,7 +6531,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) /* The template parameters for this new template are all the template parameters for the old template, except the outermost level of parameters. */ - DECL_TEMPLATE_PARMS (r) + DECL_TEMPLATE_PARMS (r) = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, complain); @@ -6099,8 +6540,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) if (TREE_CODE (decl) != TYPE_DECL) /* Record this non-type partial instantiation. */ - register_specialization (r, t, - DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r))); + register_specialization (r, t, + DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)), + false); } break; @@ -6110,12 +6552,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree argvec = NULL_TREE; tree *friends; tree gen_tmpl; + tree type; int member; int args_depth; int parms_depth; /* Nobody should be tsubst'ing into non-template functions. */ - my_friendly_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE, 0); + gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE); if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL) { @@ -6136,12 +6579,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) specialization, and the complete set of arguments used to specialize R. */ gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t)); - argvec = tsubst_template_args (DECL_TI_ARGS + argvec = tsubst_template_args (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (gen_tmpl)), - args, complain, in_decl); + args, complain, in_decl); /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, argvec); + spec = retrieve_specialization (gen_tmpl, argvec, + /*class_specializations_p=*/false); if (spec) { @@ -6153,17 +6597,17 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) there was a specialization of a member template, like this: - template <class T> struct S { template <class U> void f(); } - template <> template <class U> void S<int>::f(U); + template <class T> struct S { template <class U> void f(); } + template <> template <class U> void S<int>::f(U); Here, we'll be substituting into the specialization, because that's where we can find the code we actually want to generate, but we'll have enough arguments for - the most general template. + the most general template. We also deal with the peculiar case: - template <class T> struct S { + template <class T> struct S { template <class U> friend void f(); }; template <class U> void f() {} @@ -6182,8 +6626,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) which we can spot because the pattern will be a specialization in this case. */ args_depth = TMPL_ARGS_DEPTH (args); - parms_depth = - TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t))); + parms_depth = + TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t))); if (args_depth > parms_depth && !DECL_TEMPLATE_SPECIALIZATION (t)) args = get_innermost_template_args (args, parms_depth); @@ -6192,8 +6636,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) { /* This special case arises when we have something like this: - template <class T> struct S { - friend void f<int>(int, double); + template <class T> struct S { + friend void f<int>(int, double); }; Here, the DECL_TI_TEMPLATE for the friend declaration @@ -6210,7 +6654,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) member = 2; else member = 1; - ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, + ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, t, /*entering_scope=*/1); } else @@ -6218,14 +6662,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) member = 0; ctx = DECL_CONTEXT (t); } - type = tsubst (type, args, complain, in_decl); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (type == error_mark_node) return error_mark_node; /* We do NOT check for matching decls pushed separately at this - point, as they may not represent instantiations of this - template, and in any case are considered separate under the - discrete model. */ + point, as they may not represent instantiations of this + template, and in any case are considered separate under the + discrete model. */ r = copy_decl (t); DECL_USE_TEMPLATE (r) = 0; TREE_TYPE (r) = type; @@ -6235,7 +6679,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) DECL_INITIAL (r) = NULL_TREE; DECL_CONTEXT (r) = ctx; - if (member && DECL_CONV_FN_P (r)) + if (member && DECL_CONV_FN_P (r)) /* Type-conversion operator. Reconstruct the name, in case it's the name of one of the template's parameters. */ DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type)); @@ -6247,7 +6691,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) TREE_STATIC (r) = 0; TREE_PUBLIC (r) = TREE_PUBLIC (t); DECL_EXTERNAL (r) = 1; - DECL_INTERFACE_KNOWN (r) = 0; + /* If this is an instantiation of a function with internal + linkage, we already know what object file linkage will be + assigned to the instantiation. */ + DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r); DECL_DEFER_OUTPUT (r) = 0; TREE_CHAIN (r) = NULL_TREE; DECL_PENDING_INLINE_INFO (r) = 0; @@ -6267,18 +6714,18 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) GEN_TMPL is NULL. */ if (gen_tmpl) { - DECL_TEMPLATE_INFO (r) + DECL_TEMPLATE_INFO (r) = tree_cons (gen_tmpl, argvec, NULL_TREE); SET_DECL_IMPLICIT_INSTANTIATION (r); - register_specialization (r, gen_tmpl, argvec); + register_specialization (r, gen_tmpl, argvec, false); /* We're not supposed to instantiate default arguments until they are called, for a template. But, for a declaration like: - template <class T> void f () - { extern void g(int i = T()); } - + template <class T> void f () + { extern void g(int i = T()); } + we should do the substitution when the template is instantiated. We handle the member function case in instantiate_class_template since the default arguments @@ -6288,11 +6735,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) && !uses_template_parms (argvec)) tsubst_default_arguments (r); } + else + DECL_TEMPLATE_INFO (r) = NULL_TREE; /* Copy the list of befriending classes. */ for (friends = &DECL_BEFRIENDING_CLASSES (r); *friends; - friends = &TREE_CHAIN (*friends)) + friends = &TREE_CHAIN (*friends)) { *friends = copy_node (*friends); TREE_VALUE (*friends) = tsubst (TREE_VALUE (*friends), @@ -6311,24 +6760,39 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) if (PRIMARY_TEMPLATE_P (gen_tmpl)) clone_function_decl (r, /*update_method_vec_p=*/0); } - else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, (complain & tf_error) != 0); + else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)) + && !grok_op_properties (r, (complain & tf_error) != 0)) + return error_mark_node; if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t)) SET_DECL_FRIEND_CONTEXT (r, tsubst (DECL_FRIEND_CONTEXT (t), args, complain, in_decl)); + + /* Possibly limit visibility based on template args. */ + DECL_VISIBILITY (r) = VISIBILITY_DEFAULT; + if (DECL_VISIBILITY_SPECIFIED (t)) + { + DECL_VISIBILITY_SPECIFIED (r) = 0; + DECL_ATTRIBUTES (r) + = remove_attribute ("visibility", DECL_ATTRIBUTES (r)); + } + determine_visibility (r); } break; case PARM_DECL: { + tree type; + r = copy_node (t); if (DECL_TEMPLATE_PARM_P (t)) SET_DECL_TEMPLATE_PARM_P (r); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + type = type_decays_to (type); TREE_TYPE (r) = type; - c_apply_type_quals_to_decl (cp_type_quals (type), r); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); if (DECL_INITIAL (r)) { @@ -6351,47 +6815,46 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) case FIELD_DECL: { + tree type; + r = copy_decl (t); + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; TREE_TYPE (r) = type; - c_apply_type_quals_to_decl (cp_type_quals (type), r); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); + /* DECL_INITIAL gives the number of bits in a bit-field. */ + DECL_INITIAL (r) + = tsubst_expr (DECL_INITIAL (t), args, + complain, in_decl, + /*integral_constant_expression_p=*/true); /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ - DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args, - complain, in_decl); TREE_CHAIN (r) = NULL_TREE; - if (VOID_TYPE_P (type)) - cp_error_at ("instantiation of `%D' as type `%T'", r, type); + if (VOID_TYPE_P (type)) + error ("instantiation of %q+D as type %qT", r, type); } break; case USING_DECL: - { - r = copy_node (t); - /* It is not a dependent using decl any more. */ - TREE_TYPE (r) = void_type_node; - DECL_INITIAL (r) - = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); - DECL_NAME (r) - = tsubst_copy (DECL_NAME (t), args, complain, in_decl); - TREE_CHAIN (r) = NULL_TREE; - } + /* We reach here only for member using decls. */ + if (DECL_DEPENDENT_P (t)) + { + r = do_class_using_decl + (tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl), + tsubst_copy (DECL_NAME (t), args, complain, in_decl)); + if (!r) + r = error_mark_node; + } + else + { + r = copy_node (t); + TREE_CHAIN (r) = NULL_TREE; + } break; case TYPE_DECL: - if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM - || t == TYPE_MAIN_DECL (TREE_TYPE (t))) - { - /* If this is the canonical decl, we don't have to mess with - instantiations, and often we can't (for typename, template - type parms and such). Note that TYPE_NAME is not correct for - the above test if we've copied the type for a typedef. */ - r = TYPE_NAME (type); - break; - } - - /* Fall through. */ - case VAR_DECL: { tree argvec = NULL_TREE; @@ -6399,70 +6862,154 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) tree spec; tree tmpl = NULL_TREE; tree ctx; - int local_p; - - /* Assume this is a non-local variable. */ - local_p = 0; + tree type = NULL_TREE; + bool local_p; - if (TYPE_P (CP_DECL_CONTEXT (t))) - ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, - complain, - in_decl, /*entering_scope=*/1); - else if (DECL_NAMESPACE_SCOPE_P (t)) - ctx = DECL_CONTEXT (t); - else + if (TREE_CODE (t) == TYPE_DECL) { - /* Subsequent calls to pushdecl will fill this in. */ - ctx = NULL_TREE; - local_p = 1; + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM + || t == TYPE_MAIN_DECL (TREE_TYPE (t))) + { + /* If this is the canonical decl, we don't have to + mess with instantiations, and often we can't (for + typename, template type parms and such). Note that + TYPE_NAME is not correct for the above test if + we've copied the type for a typedef. */ + r = TYPE_NAME (type); + break; + } } - /* Check to see if we already have this specialization. */ - if (!local_p) + /* Check to see if we already have the specialization we + need. */ + spec = NULL_TREE; + if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t)) { - tmpl = DECL_TI_TEMPLATE (t); - gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); - spec = retrieve_specialization (gen_tmpl, argvec); + /* T is a static data member or namespace-scope entity. + We have to substitute into namespace-scope variables + (even though such entities are never templates) because + of cases like: + + template <class T> void f() { extern T t; } + + where the entity referenced is not known until + instantiation time. */ + local_p = false; + ctx = DECL_CONTEXT (t); + if (DECL_CLASS_SCOPE_P (t)) + { + ctx = tsubst_aggr_type (ctx, args, + complain, + in_decl, /*entering_scope=*/1); + /* If CTX is unchanged, then T is in fact the + specialization we want. That situation occurs when + referencing a static data member within in its own + class. We can use pointer equality, rather than + same_type_p, because DECL_CONTEXT is always + canonical. */ + if (ctx == DECL_CONTEXT (t)) + spec = t; + } + + if (!spec) + { + tmpl = DECL_TI_TEMPLATE (t); + gen_tmpl = most_general_template (tmpl); + argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); + spec = (retrieve_specialization + (gen_tmpl, argvec, + /*class_specializations_p=*/false)); + } } else - spec = retrieve_local_specialization (t); - + { + /* A local variable. */ + local_p = true; + /* Subsequent calls to pushdecl will fill this in. */ + ctx = NULL_TREE; + spec = retrieve_local_specialization (t); + } + /* If we already have the specialization we need, there is + nothing more to do. */ if (spec) { r = spec; break; } + /* Create a new node for the specialization we need. */ r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) { + /* Even if the original location is out of scope, the + newly substituted one is not. */ + DECL_DEAD_FOR_LOCAL (r) = 0; + DECL_INITIALIZED_P (r) = 0; + DECL_TEMPLATE_INSTANTIATED (r) = 0; + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + return error_mark_node; + if (TREE_CODE (type) == FUNCTION_TYPE) + { + /* It may seem that this case cannot occur, since: + + typedef void f(); + void g() { f x; } + + declares a function, not a variable. However: + + typedef void f(); + template <typename T> void g() { T t; } + template void g<f>(); + + is an attempt to declare a variable with function + type. */ + error ("variable %qD has function type", + /* R is not yet sufficiently initialized, so we + just use its name. */ + DECL_NAME (r)); + return error_mark_node; + } type = complete_type (type); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t); type = check_var_type (DECL_NAME (r), type); + + if (DECL_HAS_VALUE_EXPR_P (t)) + { + tree ve = DECL_VALUE_EXPR (t); + ve = tsubst_expr (ve, args, complain, in_decl, + /*constant_expression_p=*/false); + SET_DECL_VALUE_EXPR (r, ve); + } } else if (DECL_SELF_REFERENCE_P (t)) SET_DECL_SELF_REFERENCE_P (r); TREE_TYPE (r) = type; - c_apply_type_quals_to_decl (cp_type_quals (type), r); + cp_apply_type_quals_to_decl (cp_type_quals (type), r); DECL_CONTEXT (r) = ctx; /* Clear out the mangled name and RTL for the instantiation. */ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE); - SET_DECL_RTL (r, NULL_RTX); - - /* Don't try to expand the initializer until someone tries to use - this variable; otherwise we run into circular dependencies. */ + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) + SET_DECL_RTL (r, NULL_RTX); + /* The initializer must not be expanded until it is required; + see [temp.inst]. */ DECL_INITIAL (r) = NULL_TREE; - SET_DECL_RTL (r, NULL_RTX); + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) + SET_DECL_RTL (r, NULL_RTX); DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0; - - /* Even if the original location is out of scope, the newly - substituted one is not. */ if (TREE_CODE (r) == VAR_DECL) { - DECL_DEAD_FOR_LOCAL (r) = 0; - DECL_INITIALIZED_P (r) = 0; + /* Possibly limit visibility based on template args. */ + DECL_VISIBILITY (r) = VISIBILITY_DEFAULT; + if (DECL_VISIBILITY_SPECIFIED (t)) + { + DECL_VISIBILITY_SPECIFIED (r) = 0; + DECL_ATTRIBUTES (r) + = remove_attribute ("visibility", DECL_ATTRIBUTES (r)); + } + determine_visibility (r); } if (!local_p) @@ -6473,7 +7020,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) processing here. */ DECL_EXTERNAL (r) = 1; - register_specialization (r, gen_tmpl, argvec); + register_specialization (r, gen_tmpl, argvec, false); DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE); SET_DECL_IMPLICIT_INSTANTIATION (r); } @@ -6486,8 +7033,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) break; default: - abort (); - } + gcc_unreachable (); + } /* Restore the file and line information. */ input_location = saved_loc; @@ -6498,10 +7045,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) /* Substitute into the ARG_TYPES of a function type. */ static tree -tsubst_arg_types (tree arg_types, - tree args, - tsubst_flags_t complain, - tree in_decl) +tsubst_arg_types (tree arg_types, + tree args, + tsubst_flags_t complain, + tree in_decl) { tree remaining_arg_types; tree type; @@ -6510,7 +7057,7 @@ tsubst_arg_types (tree arg_types, if (!arg_types || arg_types == void_list_node) return arg_types; - + remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types), args, complain, in_decl); if (remaining_arg_types == error_mark_node) @@ -6522,11 +7069,11 @@ tsubst_arg_types (tree arg_types, if (VOID_TYPE_P (type)) { if (complain & tf_error) - { - error ("invalid parameter type `%T'", type); - if (in_decl) - cp_error_at ("in declaration `%D'", in_decl); - } + { + error ("invalid parameter type %qT", type); + if (in_decl) + error ("in declaration %q+D", in_decl); + } return error_mark_node; } @@ -6538,20 +7085,19 @@ tsubst_arg_types (tree arg_types, mandates that they be instantiated only when needed, which is done in build_over_call. */ default_arg = TREE_PURPOSE (arg_types); - + if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG) { /* We've instantiated a template before its default arguments - have been parsed. This can happen for a nested template - class, and is not an error unless we require the default - argument in a call of this function. */ + have been parsed. This can happen for a nested template + class, and is not an error unless we require the default + argument in a call of this function. */ result = tree_cons (default_arg, type, remaining_arg_types); - TREE_CHAIN (default_arg) = tree_cons (result, NULL_TREE, - TREE_CHAIN (default_arg)); + VEC_safe_push (tree, gc, DEFARG_INSTANTIATIONS (default_arg), result); } else result = hash_tree_cons (default_arg, type, remaining_arg_types); - + return result; } @@ -6573,29 +7119,45 @@ tsubst_arg_types (tree arg_types, results in an invalid type.] */ static tree -tsubst_function_type (tree t, - tree args, - tsubst_flags_t complain, - tree in_decl) +tsubst_function_type (tree t, + tree args, + tsubst_flags_t complain, + tree in_decl) { tree return_type; tree arg_types; tree fntype; /* The TYPE_CONTEXT is not used for function/method types. */ - my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0); + gcc_assert (TYPE_CONTEXT (t) == NULL_TREE); /* Substitute the return type. */ return_type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (return_type == error_mark_node) return error_mark_node; + /* The standard does not presently indicate that creation of a + function type with an invalid return type is a deduction failure. + However, that is clearly analogous to creating an array of "void" + or a reference to a reference. This is core issue #486. */ + if (TREE_CODE (return_type) == ARRAY_TYPE + || TREE_CODE (return_type) == FUNCTION_TYPE) + { + if (complain & tf_error) + { + if (TREE_CODE (return_type) == ARRAY_TYPE) + error ("function returning an array"); + else + error ("function returning a function"); + } + return error_mark_node; + } /* Substitute the argument types. */ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, - complain, in_decl); + complain, in_decl); if (arg_types == error_mark_node) return error_mark_node; - + /* Construct a new type node and return it. */ if (TREE_CODE (t) == FUNCTION_TYPE) fntype = build_function_type (return_type, arg_types); @@ -6605,61 +7167,58 @@ tsubst_function_type (tree t, if (! IS_AGGR_TYPE (r)) { /* [temp.deduct] - + Type deduction may fail for any of the following reasons: - + -- Attempting to create "pointer to member of T" when T is not a class type. */ if (complain & tf_error) - error ("creating pointer to member function of non-class type `%T'", + error ("creating pointer to member function of non-class type %qT", r); return error_mark_node; } - - fntype = build_method_type_directly (r, return_type, + + fntype = build_method_type_directly (r, return_type, TREE_CHAIN (arg_types)); } fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain); fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t)); - - return fntype; + + return fntype; } -/* Substitute into the PARMS of a call-declarator. */ +/* FNTYPE is a FUNCTION_TYPE or METHOD_TYPE. Substitute the template + ARGS into that specification, and return the substituted + specification. If there is no specification, return NULL_TREE. */ static tree -tsubst_call_declarator_parms (tree parms, - tree args, - tsubst_flags_t complain, - tree in_decl) +tsubst_exception_specification (tree fntype, + tree args, + tsubst_flags_t complain, + tree in_decl) { - tree new_parms; - tree type; - tree defarg; - - if (!parms || parms == void_list_node) - return parms; - - new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms), - args, complain, in_decl); - - /* Figure out the type of this parameter. */ - type = tsubst (TREE_VALUE (parms), args, complain, in_decl); - - /* Figure out the default argument as well. Note that we use - tsubst_expr since the default argument is really an expression. */ - defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl); + tree specs; + tree new_specs; - /* Chain this parameter on to the front of those we have already - processed. We don't use hash_tree_cons because that function - doesn't check TREE_PARMLIST. */ - new_parms = tree_cons (defarg, type, new_parms); - - /* And note that these are parameters. */ - TREE_PARMLIST (new_parms) = 1; - - return new_parms; + specs = TYPE_RAISES_EXCEPTIONS (fntype); + new_specs = NULL_TREE; + if (specs) + { + if (! TREE_VALUE (specs)) + new_specs = specs; + else + while (specs) + { + tree spec; + spec = tsubst (TREE_VALUE (specs), args, complain, in_decl); + if (spec == error_mark_node) + return spec; + new_specs = add_exception_specifier (new_specs, spec, complain); + specs = TREE_CHAIN (specs); + } + } + return new_specs; } /* Take the tree structure T and replace template parameters used @@ -6691,16 +7250,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) || TREE_CODE (t) == NAMESPACE_DECL) return t; + if (DECL_P (t)) + return tsubst_decl (t, args, complain); + if (TREE_CODE (t) == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else type = TREE_TYPE (t); - my_friendly_assert (type != unknown_type_node, 20030716); + gcc_assert (type != unknown_type_node); - if (type && TREE_CODE (t) != FUNCTION_DECL + if (type && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_DECL && TREE_CODE (t) != IDENTIFIER_NODE && TREE_CODE (t) != FUNCTION_TYPE && TREE_CODE (t) != METHOD_TYPE) @@ -6708,9 +7269,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (type == error_mark_node) return error_mark_node; - if (DECL_P (t)) - return tsubst_decl (t, args, type, complain); - switch (TREE_CODE (t)) { case RECORD_TYPE: @@ -6742,30 +7300,36 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0); - /* The array dimension behaves like a non-type template arg, - in that we want to fold it as much as possible. */ - max = tsubst_template_arg (omax, args, complain, in_decl); - max = fold_non_dependent_expr (max); + max = tsubst_expr (omax, args, complain, in_decl, + /*integral_constant_expression_p=*/false); + max = fold_decl_constant_value (max); - if (integer_zerop (omax)) + if (TREE_CODE (max) != INTEGER_CST + && TREE_CODE (max) != TEMPLATE_PARM_INDEX + && !at_function_scope_p ()) { - /* Still allow an explicit array of size zero. */ - if (pedantic) - pedwarn ("creating array with size zero"); + if (complain & tf_error) + error ("array bound is not an integer constant"); + return error_mark_node; } - else if (integer_zerop (max) - || (TREE_CODE (max) == INTEGER_CST - && INT_CST_LT (max, integer_zero_node))) - { - /* [temp.deduct] - Type deduction may fail for any of the following - reasons: + /* [temp.deduct] - Attempting to create an array with a size that is - zero or negative. */ + Type deduction may fail for any of the following + reasons: + + Attempting to create an array with a size that is + zero or negative. */ + if (integer_zerop (max) && !(complain & tf_error)) + /* We must fail if performing argument deduction (as + indicated by the state of complain), so that + another substitution can be found. */ + return error_mark_node; + else if (TREE_CODE (max) == INTEGER_CST + && INT_CST_LT (max, integer_zero_node)) + { if (complain & tf_error) - error ("creating array with size zero (`%E')", max); + error ("creating array with negative size (%qE)", max); return error_mark_node; } @@ -6781,9 +7345,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) int idx; int level; int levels; + tree arg = NULL_TREE; r = NULL_TREE; + gcc_assert (TREE_VEC_LENGTH (args) > 0); if (TREE_CODE (t) == TEMPLATE_TYPE_PARM || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) @@ -6797,57 +7363,60 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) level = TEMPLATE_PARM_LEVEL (t); } - if (TREE_VEC_LENGTH (args) > 0) - { - tree arg = NULL_TREE; + levels = TMPL_ARGS_DEPTH (args); + if (level <= levels) + arg = TMPL_ARG (args, level, idx); - levels = TMPL_ARGS_DEPTH (args); - if (level <= levels) - arg = TMPL_ARG (args, level, idx); - - if (arg == error_mark_node) - return error_mark_node; - else if (arg != NULL_TREE) + if (arg == error_mark_node) + return error_mark_node; + else if (arg != NULL_TREE) + { + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) { - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) - { - my_friendly_assert (TYPE_P (arg), 0); - return cp_build_qualified_type_real - (arg, cp_type_quals (arg) | cp_type_quals (t), - complain | tf_ignore_bad_quals); - } - else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) - { - /* We are processing a type constructed from - a template template parameter. */ - tree argvec = tsubst (TYPE_TI_ARGS (t), - args, complain, in_decl); - if (argvec == error_mark_node) - return error_mark_node; - - /* We can get a TEMPLATE_TEMPLATE_PARM here when - we are resolving nested-types in the signature of - a member function templates. - Otherwise ARG is a TEMPLATE_DECL and is the real - template to be instantiated. */ - if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - arg = TYPE_NAME (arg); - - r = lookup_template_class (arg, - argvec, in_decl, - DECL_CONTEXT (arg), - /*entering_scope=*/0, - complain); - return cp_build_qualified_type_real - (r, TYPE_QUALS (t), complain); - } + int quals; + gcc_assert (TYPE_P (arg)); + + /* cv-quals from the template are discarded when + substituting in a function or reference type. */ + if (TREE_CODE (arg) == FUNCTION_TYPE + || TREE_CODE (arg) == METHOD_TYPE + || TREE_CODE (arg) == REFERENCE_TYPE) + quals = cp_type_quals (arg); else - /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ - return arg; + quals = cp_type_quals (arg) | cp_type_quals (t); + + return cp_build_qualified_type_real + (arg, quals, complain | tf_ignore_bad_quals); + } + else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) + { + /* We are processing a type constructed from a + template template parameter. */ + tree argvec = tsubst (TYPE_TI_ARGS (t), + args, complain, in_decl); + if (argvec == error_mark_node) + return error_mark_node; + + /* We can get a TEMPLATE_TEMPLATE_PARM here when we + are resolving nested-types in the signature of a + member function templates. Otherwise ARG is a + TEMPLATE_DECL and is the real template to be + instantiated. */ + if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) + arg = TYPE_NAME (arg); + + r = lookup_template_class (arg, + argvec, in_decl, + DECL_CONTEXT (arg), + /*entering_scope=*/0, + complain); + return cp_build_qualified_type_real + (r, TYPE_QUALS (t), complain); } + else + /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ + return arg; } - else - abort (); if (level == 1) /* This can happen during the attempted tsubst'ing in @@ -6866,8 +7435,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (cp_type_quals (t)) { r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); - r = cp_build_qualified_type_real - (r, cp_type_quals (t), + r = cp_build_qualified_type_real + (r, cp_type_quals (t), complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM ? tf_ignore_bad_quals : 0)); } @@ -6885,7 +7454,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) { tree argvec = tsubst (TYPE_TI_ARGS (t), args, - complain, in_decl); + complain, in_decl); if (argvec == error_mark_node) return error_mark_node; @@ -6898,9 +7467,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TEMPLATE_PARM_INDEX: r = reduce_template_parm_level (t, type, levels); break; - + default: - abort (); + gcc_unreachable (); } return r; @@ -6908,7 +7477,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TREE_LIST: { - tree purpose, value, chain, result; + tree purpose, value, chain; if (t == void_list_node) return t; @@ -6938,38 +7507,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) && value == TREE_VALUE (t) && chain == TREE_CHAIN (t)) return t; - if (TREE_PARMLIST (t)) - { - result = tree_cons (purpose, value, chain); - TREE_PARMLIST (result) = 1; - } - else - result = hash_tree_cons (purpose, value, chain); - return result; + return hash_tree_cons (purpose, value, chain); } - case TREE_VEC: - if (type != NULL_TREE) - { - /* A binfo node. We always need to make a copy, of the node - itself and of its BINFO_BASETYPES. */ - t = copy_node (t); + case TREE_BINFO: + /* We should never be tsubsting a binfo. */ + gcc_unreachable (); - /* Make sure type isn't a typedef copy. */ - type = BINFO_TYPE (TYPE_BINFO (type)); - - TREE_TYPE (t) = complete_type (type); - if (IS_AGGR_TYPE (type)) - { - BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type); - BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type); - if (TYPE_BINFO_BASETYPES (type) != NULL_TREE) - BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type)); - } - return t; - } - - /* Otherwise, a vector of template arguments. */ + case TREE_VEC: + /* A vector of template arguments. */ + gcc_assert (!type); return tsubst_template_args (t, args, complain, in_decl); case POINTER_TYPE: @@ -6984,9 +7531,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* [temp.deduct] - + Type deduction may fail for any of the following - reasons: + reasons: -- Attempting to create a pointer to reference type. -- Attempting to create a reference to a reference type or @@ -7000,15 +7547,20 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) message to avoid spewing a ton of messages during a single bad template instantiation. */ if (complain & tf_error +#ifdef USE_MAPPED_LOCATION + && last_loc != input_location +#else && (last_loc.line != input_line - || last_loc.file != input_filename)) + || last_loc.file != input_filename) +#endif + ) { if (TREE_CODE (type) == VOID_TYPE) error ("forming reference to void"); else - error ("forming %s to reference type `%T'", - (code == POINTER_TYPE) ? "pointer" : "reference", - type); + error ("forming %s to reference type %qT", + (code == POINTER_TYPE) ? "pointer" : "reference", + type); last_loc = input_location; } @@ -7027,7 +7579,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (r != error_mark_node) /* Will this ever be needed for TYPE_..._TO values? */ layout_type (r); - + return r; } case OFFSET_TYPE: @@ -7039,39 +7591,40 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) Type deduction may fail for any of the following reasons: - + -- Attempting to create "pointer to member of T" when T - is not a class type. */ + is not a class type. */ if (complain & tf_error) - error ("creating pointer to member of non-class type `%T'", r); + error ("creating pointer to member of non-class type %qT", r); return error_mark_node; } if (TREE_CODE (type) == REFERENCE_TYPE) { if (complain & tf_error) - error ("creating pointer to member reference type `%T'", type); - + error ("creating pointer to member reference type %qT", type); return error_mark_node; } - my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231); + if (TREE_CODE (type) == VOID_TYPE) + { + if (complain & tf_error) + error ("creating pointer to member of type void"); + return error_mark_node; + } + gcc_assert (TREE_CODE (type) != METHOD_TYPE); if (TREE_CODE (type) == FUNCTION_TYPE) { - /* This is really a method type. The cv qualifiers of the - this pointer should _not_ be determined by the cv - qualifiers of the class type. They should be held - somewhere in the FUNCTION_TYPE, but we don't do that at - the moment. Consider - typedef void (Func) () const; - - template <typename T1> void Foo (Func T1::*); - - */ + /* The type of the implicit object parameter gets its + cv-qualifiers from the FUNCTION_TYPE. */ tree method_type; - - method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r), + tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r), + cp_type_quals (type)); + tree memptr; + method_type = build_method_type_directly (this_type, TREE_TYPE (type), TYPE_ARG_TYPES (type)); - return build_ptrmemfunc_type (build_pointer_type (method_type)); + memptr = build_ptrmemfunc_type (build_pointer_type (method_type)); + return cp_build_qualified_type_real (memptr, cp_type_quals (t), + complain); } else return cp_build_qualified_type_real (build_ptrmem_type (r, type), @@ -7082,32 +7635,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case METHOD_TYPE: { tree fntype; - tree raises; - + tree specs; fntype = tsubst_function_type (t, args, complain, in_decl); if (fntype == error_mark_node) return error_mark_node; /* Substitute the exception specification. */ - raises = TYPE_RAISES_EXCEPTIONS (t); - if (raises) - { - tree list = NULL_TREE; - - if (! TREE_VALUE (raises)) - list = raises; - else - for (; raises != NULL_TREE; raises = TREE_CHAIN (raises)) - { - tree spec = TREE_VALUE (raises); - - spec = tsubst (spec, args, complain, in_decl); - if (spec == error_mark_node) - return spec; - list = add_exception_specifier (list, spec, complain); - } - fntype = build_exception_variant (fntype, list); - } + specs = tsubst_exception_specification (t, args, complain, + in_decl); + if (specs == error_mark_node) + return error_mark_node; + if (specs) + fntype = build_exception_variant (fntype, specs); return fntype; } case ARRAY_TYPE: @@ -7121,29 +7660,29 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t)) return t; - /* These checks should match the ones in grokdeclarator. + /* These checks should match the ones in grokdeclarator. + + [temp.deduct] - [temp.deduct] - - The deduction may fail for any of the following reasons: + The deduction may fail for any of the following reasons: -- Attempting to create an array with an element type that - is void, a function type, or a reference type, or [DR337] + is void, a function type, or a reference type, or [DR337] an abstract class type. */ - if (TREE_CODE (type) == VOID_TYPE + if (TREE_CODE (type) == VOID_TYPE || TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == REFERENCE_TYPE) { if (complain & tf_error) - error ("creating array of `%T'", type); + error ("creating array of %qT", type); return error_mark_node; } if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type)) { if (complain & tf_error) - error ("creating array of `%T', which is an abstract class type", + error ("creating array of %qT, which is an abstract class type", type); - return error_mark_node; + return error_mark_node; } r = build_cplus_array_type (type, domain); @@ -7159,7 +7698,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; - return fold (build (TREE_CODE (t), TREE_TYPE (t), e1, e2)); + return fold_build2 (TREE_CODE (t), TREE_TYPE (t), e1, e2); } case NEGATE_EXPR: @@ -7169,7 +7708,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e == error_mark_node) return error_mark_node; - return fold (build (TREE_CODE (t), TREE_TYPE (t), e)); + return fold_build1 (TREE_CODE (t), TREE_TYPE (t), e); } case TYPENAME_TYPE: @@ -7177,7 +7716,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/1); tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, - complain, in_decl); + complain, in_decl); if (ctx == error_mark_node || f == error_mark_node) return error_mark_node; @@ -7185,16 +7724,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (!IS_AGGR_TYPE (ctx)) { if (complain & tf_error) - error ("`%T' is not a class, struct, or union type", - ctx); + error ("%qT is not a class, struct, or union type", ctx); return error_mark_node; } else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx)) { /* Normally, make_typename_type does not require that the CTX have complete type in order to allow things like: - - template <class T> struct S { typename S<T>::X Y; }; + + template <class T> struct S { typename S<T>::X Y; }; But, such constructs have already been resolved by this point, so here CTX really should have complete type, unless @@ -7208,71 +7746,59 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } - f = make_typename_type (ctx, f, + f = make_typename_type (ctx, f, typename_type, (complain & tf_error) | tf_keep_type_decl); if (f == error_mark_node) return f; - if (TREE_CODE (f) == TYPE_DECL) - { + if (TREE_CODE (f) == TYPE_DECL) + { complain |= tf_ignore_bad_quals; - f = TREE_TYPE (f); - } - - return cp_build_qualified_type_real - (f, cp_type_quals (f) | cp_type_quals (t), complain); + f = TREE_TYPE (f); + } + + if (TREE_CODE (f) != TYPENAME_TYPE) + { + if (TYPENAME_IS_ENUM_P (t) && TREE_CODE (f) != ENUMERAL_TYPE) + error ("%qT resolves to %qT, which is not an enumeration type", + t, f); + else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f)) + error ("%qT resolves to %qT, which is is not a class type", + t, f); + } + + return cp_build_qualified_type_real + (f, cp_type_quals (f) | cp_type_quals (t), complain); } - + case UNBOUND_CLASS_TEMPLATE: { tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/1); tree name = TYPE_IDENTIFIER (t); + tree parm_list = DECL_TEMPLATE_PARMS (TYPE_NAME (t)); if (ctx == error_mark_node || name == error_mark_node) return error_mark_node; - return make_unbound_class_template (ctx, name, complain); + if (parm_list) + parm_list = tsubst_template_parms (parm_list, args, complain); + return make_unbound_class_template (ctx, name, parm_list, complain); } case INDIRECT_REF: - { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - if (e == error_mark_node) - return error_mark_node; - return make_pointer_declarator (type, e); - } - case ADDR_EXPR: - { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - if (e == error_mark_node) - return error_mark_node; - return make_reference_declarator (type, e); - } + case CALL_EXPR: + gcc_unreachable (); case ARRAY_REF: { tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl); + tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl, + /*integral_constant_expression_p=*/false); if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; - return build_nt (ARRAY_REF, e1, e2); - } - - case CALL_EXPR: - { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); - tree e2 = (tsubst_call_declarator_parms - (CALL_DECLARATOR_PARMS (t), args, complain, in_decl)); - tree e3 = tsubst (CALL_DECLARATOR_EXCEPTION_SPEC (t), args, - complain, in_decl); - - if (e1 == error_mark_node || e2 == error_mark_node - || e3 == error_mark_node) - return error_mark_node; - - return make_call_declarator (e1, e2, CALL_DECLARATOR_QUALS (t), e3); + return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE); } case SCOPE_REF: @@ -7282,15 +7808,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; - return build_nt (TREE_CODE (t), e1, e2); + return build_qualified_name (/*type=*/NULL_TREE, + e1, e2, QUALIFIED_NAME_IS_TEMPLATE (t)); } case TYPEOF_TYPE: { tree type; - type = finish_typeof (tsubst_expr (TYPE_FIELDS (t), args, complain, - in_decl)); + type = finish_typeof (tsubst_expr + (TYPEOF_TYPE_EXPR (t), args, + complain, in_decl, + /*integral_constant_expression_p=*/false)); return cp_build_qualified_type_real (type, cp_type_quals (t) | cp_type_quals (type), @@ -7298,7 +7827,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } default: - sorry ("use of `%s' in template", + sorry ("use of %qs in template", tree_code_name [(int) TREE_CODE (t)]); return error_mark_node; } @@ -7315,19 +7844,21 @@ tsubst_baselink (tree baselink, tree object_type, tree name; tree qualifying_scope; tree fns; + tree optype; tree template_args = 0; bool template_id_p = false; - /* A baselink indicates a function from a base class. The - BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have - non-dependent types; otherwise, the lookup could not have - succeeded. However, they may indicate bases of the template - class, rather than the instantiated class. - - In addition, lookups that were not ambiguous before may be - ambiguous now. Therefore, we perform the lookup again. */ + /* A baselink indicates a function from a base class. Both the + BASELINK_ACCESS_BINFO and the base class referenced may + indicate bases of the template class, rather than the + instantiated class. In addition, lookups that were not + ambiguous before may be ambiguous now. Therefore, we perform + the lookup again. */ qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)); + qualifying_scope = tsubst (qualifying_scope, args, + complain, in_decl); fns = BASELINK_FUNCTIONS (baselink); + optype = BASELINK_OPTYPE (baselink); if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) { template_id_p = true; @@ -7339,14 +7870,29 @@ tsubst_baselink (tree baselink, tree object_type, } name = DECL_NAME (get_first_fn (fns)); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); + + /* If lookup found a single function, mark it as used at this + point. (If it lookup found multiple functions the one selected + later by overload resolution will be marked as used at that + point.) */ + if (BASELINK_P (baselink)) + fns = BASELINK_FUNCTIONS (baselink); + if (!template_id_p && !really_overloaded_fn (fns)) + mark_used (OVL_CURRENT (fns)); + + /* Add back the template arguments, if present. */ if (BASELINK_P (baselink) && template_id_p) - BASELINK_FUNCTIONS (baselink) + BASELINK_FUNCTIONS (baselink) = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (baselink), template_args); + /* Update the conversion operator type. */ + BASELINK_OPTYPE (baselink) + = tsubst (optype, args, complain, in_decl); + if (!object_type) object_type = current_class_type; - return adjust_result_of_qualified_name_lookup (baselink, + return adjust_result_of_qualified_name_lookup (baselink, qualifying_scope, object_type); } @@ -7358,7 +7904,7 @@ tsubst_baselink (tree baselink, tree object_type, of "&". */ static tree -tsubst_qualified_id (tree qualified_id, tree args, +tsubst_qualified_id (tree qualified_id, tree args, tsubst_flags_t complain, tree in_decl, bool done, bool address_p) { @@ -7368,7 +7914,7 @@ tsubst_qualified_id (tree qualified_id, tree args, bool is_template; tree template_args; - my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706); + gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF); /* Figure out what name to look up. */ name = TREE_OPERAND (qualified_id, 1); @@ -7401,44 +7947,71 @@ tsubst_qualified_id (tree qualified_id, tree args, expr = name; if (dependent_type_p (scope)) - return build_nt (SCOPE_REF, scope, expr); - + return build_qualified_name (/*type=*/NULL_TREE, + scope, expr, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + if (!BASELINK_P (name) && !DECL_P (expr)) { - expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); + if (TREE_CODE (expr) == BIT_NOT_EXPR) + /* If this were actually a destructor call, it would have been + parsed as such by the parser. */ + expr = error_mark_node; + else + expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL) { if (complain & tf_error) { - error ("dependent-name `%E' is parsed as a non-type, but " + error ("dependent-name %qE is parsed as a non-type, but " "instantiation yields a type", qualified_id); - inform ("say `typename %E' if a type is meant", qualified_id); + inform ("say %<typename %E%> if a type is meant", qualified_id); } return error_mark_node; } } - - if (DECL_P (expr)) - check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, - scope); - - /* Remember that there was a reference to this entity. */ + if (DECL_P (expr)) - mark_used (expr); + { + check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, + scope); + /* Remember that there was a reference to this entity. */ + mark_used (expr); + } + + if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST) + { + if (complain & tf_error) + qualified_name_lookup_error (scope, + TREE_OPERAND (qualified_id, 1), + expr); + return error_mark_node; + } if (is_template) expr = lookup_template_function (expr, template_args); if (expr == error_mark_node && complain & tf_error) - qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1)); + qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1), + expr); else if (TYPE_P (scope)) { - expr = (adjust_result_of_qualified_name_lookup + expr = (adjust_result_of_qualified_name_lookup (expr, scope, current_class_type)); - expr = finish_qualified_id_expr (scope, expr, done, address_p); + expr = (finish_qualified_id_expr + (scope, expr, done, address_p, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id), + /*template_arg_p=*/false)); } + /* Expressions do not generally have reference type. */ + if (TREE_CODE (expr) != SCOPE_REF + /* However, if we're about to form a pointer-to-member, we just + want the referenced member referenced. */ + && TREE_CODE (expr) != OFFSET_REF) + expr = convert_from_reference (expr); + return expr; } @@ -7461,7 +8034,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) { case PARM_DECL: r = retrieve_local_specialization (t); - my_friendly_assert (r != NULL, 20020903); + gcc_assert (r != NULL); mark_used (r); return r; @@ -7478,24 +8051,24 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; /* If ARGS is NULL, then T is known to be non-dependent. */ if (args == NULL_TREE) - return decl_constant_value (t); + return integral_constant_value (t); /* Unfortunately, we cannot just call lookup_name here. Consider: - + template <int I> int f() { enum E { a = I }; struct S { void g() { E e = a; } }; }; - + When we instantiate f<7>::S::g(), say, lookup_name is not clever enough to find f<7>::a. */ - enum_type - = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl, + enum_type + = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl, /*entering_scope=*/0); - for (v = TYPE_VALUES (enum_type); - v != NULL_TREE; + for (v = TYPE_VALUES (enum_type); + v != NULL_TREE; v = TREE_CHAIN (v)) if (TREE_PURPOSE (v) == DECL_NAME (t)) return TREE_VALUE (v); @@ -7503,7 +8076,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* We didn't find the name. That should never happen; if name-lookup found it during preliminary parsing, we should find it again here during instantiation. */ - abort (); + gcc_unreachable (); } return t; @@ -7520,12 +8093,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (!r) { if (complain & tf_error) - error ("using invalid field `%D'", t); + error ("using invalid field %qD", t); return error_mark_node; } return r; } } + return t; case VAR_DECL: @@ -7541,9 +8115,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TEMPLATE_DECL: if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) - return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)), + return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)), args, complain, in_decl); - else if (is_member_template (t)) + else if (DECL_FUNCTION_TEMPLATE_P (t) && DECL_MEMBER_TEMPLATE_P (t)) return tsubst (t, args, complain, in_decl); else if (DECL_CLASS_SCOPE_P (t) && uses_template_parms (DECL_CONTEXT (t))) @@ -7554,7 +8128,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) template <template <class> class TT> struct C {}; template <class T> struct D { template <class U> struct E {}; - C<E> c; // #1 + C<E> c; // #1 }; D<int> d; // #2 @@ -7585,7 +8159,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TRUTH_NOT_EXPR: case BIT_NOT_EXPR: case ADDR_EXPR: - case CONVERT_EXPR: /* Unary + */ + case UNARY_PLUS_EXPR: /* Unary + */ case SIZEOF_EXPR: case ALIGNOF_EXPR: case ARROW_EXPR: @@ -7604,7 +8178,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) object = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl); name = TREE_OPERAND (t, 1); - if (TREE_CODE (name) == BIT_NOT_EXPR) + if (TREE_CODE (name) == BIT_NOT_EXPR) { name = tsubst_copy (TREE_OPERAND (name, 0), args, complain, in_decl); @@ -7619,16 +8193,18 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) name = tsubst_copy (TREE_OPERAND (name, 0), args, complain, in_decl); name = build1 (BIT_NOT_EXPR, NULL_TREE, name); - name = build_nt (SCOPE_REF, base, name); + name = build_qualified_name (/*type=*/NULL_TREE, + base, name, + /*template_p=*/false); } else if (TREE_CODE (name) == BASELINK) - name = tsubst_baselink (name, - non_reference (TREE_TYPE (object)), - args, complain, + name = tsubst_baselink (name, + non_reference (TREE_TYPE (object)), + args, complain, in_decl); else name = tsubst_copy (name, args, complain, in_decl); - return build_nt (COMPONENT_REF, object, name); + return build_nt (COMPONENT_REF, object, name, NULL_TREE); } case PLUS_EXPR: @@ -7660,9 +8236,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case GE_EXPR: case LT_EXPR: case GT_EXPR: - case ARRAY_REF: case COMPOUND_EXPR: - case SCOPE_REF: case DOTSTAR_EXPR: case MEMBER_REF: case PREDECREMENT_EXPR: @@ -7673,30 +8247,29 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + case SCOPE_REF: + return build_qualified_name (/*type=*/NULL_TREE, + tsubst_copy (TREE_OPERAND (t, 0), + args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), + args, complain, in_decl), + QUALIFIED_NAME_IS_TEMPLATE (t)); + + case ARRAY_REF: + return build_nt + (ARRAY_REF, + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl), + NULL_TREE, NULL_TREE); + case CALL_EXPR: - return build_nt (code, + return build_nt (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl), NULL_TREE); - case STMT_EXPR: - /* This processing should really occur in tsubst_expr. However, - tsubst_expr does not recurse into expressions, since it - assumes that there aren't any statements inside them. So, we - need to expand the STMT_EXPR here. */ - if (!processing_template_decl) - { - tree stmt_expr = begin_stmt_expr (); - - tsubst_expr (STMT_EXPR_STMT (t), args, - complain | tf_stmt_expr_cmpd, in_decl); - return finish_stmt_expr (stmt_expr, false); - } - - return t; - case COND_EXPR: case MODOP_EXPR: case PSEUDO_DTOR_EXPR: @@ -7705,6 +8278,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl), tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl)); + TREE_NO_WARNING (r) = TREE_NO_WARNING (t); return r; } @@ -7730,14 +8304,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TEMPLATE_ID_EXPR: { - /* Substituted template arguments */ + /* Substituted template arguments */ tree fn = TREE_OPERAND (t, 0); tree targs = TREE_OPERAND (t, 1); fn = tsubst_copy (fn, args, complain, in_decl); if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); - + return lookup_template_function (fn, targs); } @@ -7794,19 +8368,20 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; case CONSTRUCTOR: - { - r = build_constructor - (tsubst (TREE_TYPE (t), args, complain, in_decl), - tsubst_copy (CONSTRUCTOR_ELTS (t), args, complain, in_decl)); - TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); - return r; - } + /* This is handled by tsubst_copy_and_build. */ + gcc_unreachable (); case VA_ARG_EXPR: return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), tsubst (TREE_TYPE (t), args, complain, in_decl)); + case CLEANUP_POINT_EXPR: + /* We shouldn't have built any of these during initial template + generation. Instead, they should be built during instantiation + in response to the saved STMT_IS_FULL_EXPR_P setting. */ + gcc_unreachable (); + case OFFSET_REF: mark_used (TREE_OPERAND (t, 1)); return t; @@ -7816,79 +8391,154 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } +/* Like tsubst_copy, but specifically for OpenMP clauses. */ + +static tree +tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain, + tree in_decl) +{ + tree new_clauses = NULL, nc, oc; + + for (oc = clauses; oc ; oc = OMP_CLAUSE_CHAIN (oc)) + { + nc = copy_node (oc); + OMP_CLAUSE_CHAIN (nc) = new_clauses; + new_clauses = nc; + + switch (OMP_CLAUSE_CODE (nc)) + { + case OMP_CLAUSE_PRIVATE: + case OMP_CLAUSE_SHARED: + case OMP_CLAUSE_FIRSTPRIVATE: + case OMP_CLAUSE_LASTPRIVATE: + case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_COPYIN: + case OMP_CLAUSE_COPYPRIVATE: + case OMP_CLAUSE_IF: + case OMP_CLAUSE_NUM_THREADS: + case OMP_CLAUSE_SCHEDULE: + OMP_CLAUSE_OPERAND (nc, 0) + = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, + in_decl, /*integral_constant_expression_p=*/false); + break; + case OMP_CLAUSE_NOWAIT: + case OMP_CLAUSE_ORDERED: + case OMP_CLAUSE_DEFAULT: + break; + default: + gcc_unreachable (); + } + } + + return finish_omp_clauses (nreverse (new_clauses)); +} + +/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes. */ + +static tree +tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain, + tree in_decl) +{ +#define RECUR(t) tsubst_copy_asm_operands (t, args, complain, in_decl) + + tree purpose, value, chain; + + if (t == NULL) + return t; + + if (TREE_CODE (t) != TREE_LIST) + return tsubst_copy_and_build (t, args, complain, in_decl, + /*function_p=*/false, + /*integral_constant_expression_p=*/false); + + if (t == void_list_node) + return t; + + purpose = TREE_PURPOSE (t); + if (purpose) + purpose = RECUR (purpose); + value = TREE_VALUE (t); + if (value) + value = RECUR (value); + chain = TREE_CHAIN (t); + if (chain && chain != void_type_node) + chain = RECUR (chain); + return tree_cons (purpose, value, chain); +#undef RECUR +} + /* Like tsubst_copy for expressions, etc. but also does semantic processing. */ static tree -tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) +tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, + bool integral_constant_expression_p) { +#define RECUR(NODE) \ + tsubst_expr ((NODE), args, complain, in_decl, \ + integral_constant_expression_p) + tree stmt, tmp; - tsubst_flags_t stmt_expr - = complain & (tf_stmt_expr_cmpd | tf_stmt_expr_body); - complain ^= stmt_expr; if (t == NULL_TREE || t == error_mark_node) return t; - if (!STATEMENT_CODE_P (TREE_CODE (t))) - return tsubst_copy_and_build (t, args, complain, in_decl, - /*function_p=*/false); - + if (EXPR_HAS_LOCATION (t)) + input_location = EXPR_LOCATION (t); + if (STATEMENT_CODE_P (TREE_CODE (t))) + current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t); + switch (TREE_CODE (t)) { + case STATEMENT_LIST: + { + tree_stmt_iterator i; + for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) + RECUR (tsi_stmt (i)); + break; + } + case CTOR_INITIALIZER: - prep_stmt (t); - finish_mem_initializers (tsubst_initializer_list + finish_mem_initializers (tsubst_initializer_list (TREE_OPERAND (t, 0), args)); break; - case RETURN_STMT: - prep_stmt (t); - finish_return_stmt (tsubst_expr (RETURN_STMT_EXPR (t), - args, complain, in_decl)); + case RETURN_EXPR: + finish_return_stmt (RECUR (TREE_OPERAND (t, 0))); break; case EXPR_STMT: - { - tree r; - - prep_stmt (t); - - r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl); - if (stmt_expr & tf_stmt_expr_body && !TREE_CHAIN (t)) - finish_stmt_expr_expr (r); - else - finish_expr_stmt (r); - break; - } + tmp = RECUR (EXPR_STMT_EXPR (t)); + if (EXPR_STMT_STMT_EXPR_RESULT (t)) + finish_stmt_expr_expr (tmp, cur_stmt_expr); + else + finish_expr_stmt (tmp); + break; case USING_STMT: - prep_stmt (t); - do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t), - args, complain, in_decl)); + do_using_directive (RECUR (USING_STMT_NAMESPACE (t))); break; - - case DECL_STMT: + + case DECL_EXPR: { tree decl; tree init; - prep_stmt (t); - decl = DECL_STMT_DECL (t); + decl = DECL_EXPR_DECL (t); if (TREE_CODE (decl) == LABEL_DECL) finish_label_decl (DECL_NAME (decl)); else if (TREE_CODE (decl) == USING_DECL) { - tree scope = DECL_INITIAL (decl); + tree scope = USING_DECL_SCOPE (decl); tree name = DECL_NAME (decl); tree decl; - - scope = tsubst_expr (scope, args, complain, in_decl); + + scope = RECUR (scope); decl = lookup_qualified_name (scope, name, /*is_type_p=*/false, /*complain=*/false); - if (decl == error_mark_node) - qualified_name_lookup_error (scope, name); + if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) + qualified_name_lookup_error (scope, name, decl); else do_local_using_decl (decl, scope, name); } @@ -7898,20 +8548,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) decl = tsubst (decl, args, complain, in_decl); if (decl != error_mark_node) { - if (init) - DECL_INITIAL (decl) = error_mark_node; - /* By marking the declaration as instantiated, we avoid - trying to instantiate it. Since instantiate_decl can't - handle local variables, and since we've already done - all that needs to be done, that's the right thing to - do. */ - if (TREE_CODE (decl) == VAR_DECL) - DECL_TEMPLATE_INSTANTIATED (decl) = 1; + /* By marking the declaration as instantiated, we avoid + trying to instantiate it. Since instantiate_decl can't + handle local variables, and since we've already done + all that needs to be done, that's the right thing to + do. */ + if (TREE_CODE (decl) == VAR_DECL) + DECL_TEMPLATE_INSTANTIATED (decl) = 1; if (TREE_CODE (decl) == VAR_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) /* Anonymous aggregates are a special case. */ finish_anon_union (decl); - else + else { maybe_push_decl (decl); if (TREE_CODE (decl) == VAR_DECL @@ -7924,242 +8572,278 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) init = cp_fname_init (name, &TREE_TYPE (decl)); } else - init = tsubst_expr (init, args, complain, in_decl); - cp_finish_decl (decl, init, NULL_TREE, 0); + init = RECUR (init); + finish_decl (decl, init, NULL_TREE); } } } - /* A DECL_STMT can also be used as an expression, in the condition - clause of an if/for/while construct. If we aren't followed by - another statement, return our decl. */ - if (TREE_CHAIN (t) == NULL_TREE) - return decl; + /* A DECL_EXPR can also be used as an expression, in the condition + clause of an if/for/while construct. */ + return decl; } - break; case FOR_STMT: - { - prep_stmt (t); - - stmt = begin_for_stmt (); - tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl); - finish_for_init_stmt (stmt); - finish_for_cond (tsubst_expr (FOR_COND (t), - args, complain, in_decl), - stmt); - tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl); - finish_for_expr (tmp, stmt); - tsubst_expr (FOR_BODY (t), args, complain, in_decl); - finish_for_stmt (stmt); - } + stmt = begin_for_stmt (); + RECUR (FOR_INIT_STMT (t)); + finish_for_init_stmt (stmt); + tmp = RECUR (FOR_COND (t)); + finish_for_cond (tmp, stmt); + tmp = RECUR (FOR_EXPR (t)); + finish_for_expr (tmp, stmt); + RECUR (FOR_BODY (t)); + finish_for_stmt (stmt); break; case WHILE_STMT: - { - prep_stmt (t); - stmt = begin_while_stmt (); - finish_while_stmt_cond (tsubst_expr (WHILE_COND (t), - args, complain, in_decl), - stmt); - tsubst_expr (WHILE_BODY (t), args, complain, in_decl); - finish_while_stmt (stmt); - } + stmt = begin_while_stmt (); + tmp = RECUR (WHILE_COND (t)); + finish_while_stmt_cond (tmp, stmt); + RECUR (WHILE_BODY (t)); + finish_while_stmt (stmt); break; case DO_STMT: - { - prep_stmt (t); - stmt = begin_do_stmt (); - tsubst_expr (DO_BODY (t), args, complain, in_decl); - finish_do_body (stmt); - finish_do_stmt (tsubst_expr (DO_COND (t), - args, complain, in_decl), - stmt); - } + stmt = begin_do_stmt (); + RECUR (DO_BODY (t)); + finish_do_body (stmt); + tmp = RECUR (DO_COND (t)); + finish_do_stmt (tmp, stmt); break; case IF_STMT: - { - prep_stmt (t); - stmt = begin_if_stmt (); - finish_if_stmt_cond (tsubst_expr (IF_COND (t), - args, complain, in_decl), - stmt); - - if (tmp = THEN_CLAUSE (t), tmp) - { - tsubst_expr (tmp, args, complain, in_decl); - finish_then_clause (stmt); - } + stmt = begin_if_stmt (); + tmp = RECUR (IF_COND (t)); + finish_if_stmt_cond (tmp, stmt); + RECUR (THEN_CLAUSE (t)); + finish_then_clause (stmt); - if (tmp = ELSE_CLAUSE (t), tmp) - { - begin_else_clause (); - tsubst_expr (tmp, args, complain, in_decl); - finish_else_clause (stmt); - } + if (ELSE_CLAUSE (t)) + { + begin_else_clause (stmt); + RECUR (ELSE_CLAUSE (t)); + finish_else_clause (stmt); + } - finish_if_stmt (); - } + finish_if_stmt (stmt); break; - case COMPOUND_STMT: - { - prep_stmt (t); - if (COMPOUND_STMT_BODY_BLOCK (t)) - stmt = begin_function_body (); - else - stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t)); + case BIND_EXPR: + if (BIND_EXPR_BODY_BLOCK (t)) + stmt = begin_function_body (); + else + stmt = begin_compound_stmt (BIND_EXPR_TRY_BLOCK (t) + ? BCS_TRY_BLOCK : 0); - tsubst_expr (COMPOUND_BODY (t), args, - complain | ((stmt_expr & tf_stmt_expr_cmpd) << 1), - in_decl); + RECUR (BIND_EXPR_BODY (t)); - if (COMPOUND_STMT_BODY_BLOCK (t)) - finish_function_body (stmt); - else - finish_compound_stmt (stmt); - } + if (BIND_EXPR_BODY_BLOCK (t)) + finish_function_body (stmt); + else + finish_compound_stmt (stmt); break; case BREAK_STMT: - prep_stmt (t); finish_break_stmt (); break; case CONTINUE_STMT: - prep_stmt (t); finish_continue_stmt (); break; case SWITCH_STMT: - { - tree val; - - prep_stmt (t); - stmt = begin_switch_stmt (); - val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl); - finish_switch_cond (val, stmt); - tsubst_expr (SWITCH_BODY (t), args, complain, in_decl); - finish_switch_stmt (stmt); - } + stmt = begin_switch_stmt (); + tmp = RECUR (SWITCH_STMT_COND (t)); + finish_switch_cond (tmp, stmt); + RECUR (SWITCH_STMT_BODY (t)); + finish_switch_stmt (stmt); break; - case CASE_LABEL: - prep_stmt (t); - finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl), - tsubst_expr (CASE_HIGH (t), args, complain, - in_decl)); + case CASE_LABEL_EXPR: + finish_case_label (RECUR (CASE_LOW (t)), + RECUR (CASE_HIGH (t))); break; - case LABEL_STMT: - input_line = STMT_LINENO (t); - finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t))); + case LABEL_EXPR: + finish_label_stmt (DECL_NAME (LABEL_EXPR_LABEL (t))); break; - case FILE_STMT: - input_filename = FILE_STMT_FILENAME (t); - add_stmt (build_nt (FILE_STMT, FILE_STMT_FILENAME_NODE (t))); - break; - - case GOTO_STMT: - prep_stmt (t); + case GOTO_EXPR: tmp = GOTO_DESTINATION (t); if (TREE_CODE (tmp) != LABEL_DECL) /* Computed goto's must be tsubst'd into. On the other hand, non-computed gotos must not be; the identifier in question will have no binding. */ - tmp = tsubst_expr (tmp, args, complain, in_decl); + tmp = RECUR (tmp); else tmp = DECL_NAME (tmp); finish_goto_stmt (tmp); break; - case ASM_STMT: - prep_stmt (t); + case ASM_EXPR: tmp = finish_asm_stmt - (ASM_CV_QUAL (t), - tsubst_expr (ASM_STRING (t), args, complain, in_decl), - tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl), - tsubst_expr (ASM_INPUTS (t), args, complain, in_decl), - tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl)); - ASM_INPUT_P (tmp) = ASM_INPUT_P (t); + (ASM_VOLATILE_P (t), + RECUR (ASM_STRING (t)), + tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl), + tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl), + tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl)); + { + tree asm_expr = tmp; + if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR) + asm_expr = TREE_OPERAND (asm_expr, 0); + ASM_INPUT_P (asm_expr) = ASM_INPUT_P (t); + } break; case TRY_BLOCK: - prep_stmt (t); if (CLEANUP_P (t)) { stmt = begin_try_block (); - tsubst_expr (TRY_STMTS (t), args, complain, in_decl); + RECUR (TRY_STMTS (t)); finish_cleanup_try_block (stmt); - finish_cleanup (tsubst_expr (TRY_HANDLERS (t), args, - complain, in_decl), - stmt); + finish_cleanup (RECUR (TRY_HANDLERS (t)), stmt); } else { + tree compound_stmt = NULL_TREE; + if (FN_TRY_BLOCK_P (t)) - stmt = begin_function_try_block (); + stmt = begin_function_try_block (&compound_stmt); else stmt = begin_try_block (); - tsubst_expr (TRY_STMTS (t), args, complain, in_decl); + RECUR (TRY_STMTS (t)); if (FN_TRY_BLOCK_P (t)) finish_function_try_block (stmt); else finish_try_block (stmt); - tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl); + RECUR (TRY_HANDLERS (t)); if (FN_TRY_BLOCK_P (t)) - finish_function_handler_sequence (stmt); + finish_function_handler_sequence (stmt, compound_stmt); else finish_handler_sequence (stmt); } break; - + case HANDLER: { - tree decl; + tree decl = HANDLER_PARMS (t); - prep_stmt (t); - stmt = begin_handler (); - if (HANDLER_PARMS (t)) + if (decl) { - decl = DECL_STMT_DECL (HANDLER_PARMS (t)); decl = tsubst (decl, args, complain, in_decl); /* Prevent instantiate_decl from trying to instantiate this variable. We've already done all that needs to be done. */ - DECL_TEMPLATE_INSTANTIATED (decl) = 1; + if (decl != error_mark_node) + DECL_TEMPLATE_INSTANTIATED (decl) = 1; } - else - decl = NULL_TREE; + stmt = begin_handler (); finish_handler_parms (decl, stmt); - tsubst_expr (HANDLER_BODY (t), args, complain, in_decl); + RECUR (HANDLER_BODY (t)); finish_handler (stmt); } break; case TAG_DEFN: - prep_stmt (t); tsubst (TREE_TYPE (t), args, complain, NULL_TREE); break; + case OMP_PARALLEL: + tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), + args, complain, in_decl); + stmt = begin_omp_parallel (); + RECUR (OMP_PARALLEL_BODY (t)); + OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt)) + = OMP_PARALLEL_COMBINED (t); + break; + + case OMP_FOR: + { + tree clauses, decl, init, cond, incr, body, pre_body; + + clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), + args, complain, in_decl); + init = OMP_FOR_INIT (t); + gcc_assert (TREE_CODE (init) == MODIFY_EXPR); + decl = RECUR (TREE_OPERAND (init, 0)); + init = RECUR (TREE_OPERAND (init, 1)); + cond = RECUR (OMP_FOR_COND (t)); + incr = RECUR (OMP_FOR_INCR (t)); + + stmt = begin_omp_structured_block (); + + pre_body = push_stmt_list (); + RECUR (OMP_FOR_PRE_BODY (t)); + pre_body = pop_stmt_list (pre_body); + + body = push_stmt_list (); + RECUR (OMP_FOR_BODY (t)); + body = pop_stmt_list (body); + + t = finish_omp_for (EXPR_LOCATION (t), decl, init, cond, incr, body, + pre_body); + if (t) + OMP_FOR_CLAUSES (t) = clauses; + + add_stmt (finish_omp_structured_block (stmt)); + } + break; + + case OMP_SECTIONS: + case OMP_SINGLE: + tmp = tsubst_omp_clauses (OMP_CLAUSES (t), args, complain, in_decl); + stmt = push_stmt_list (); + RECUR (OMP_BODY (t)); + stmt = pop_stmt_list (stmt); + + t = copy_node (t); + OMP_BODY (t) = stmt; + OMP_CLAUSES (t) = tmp; + add_stmt (t); + break; + + case OMP_SECTION: + case OMP_CRITICAL: + case OMP_MASTER: + case OMP_ORDERED: + stmt = push_stmt_list (); + RECUR (OMP_BODY (t)); + stmt = pop_stmt_list (stmt); + + t = copy_node (t); + OMP_BODY (t) = stmt; + add_stmt (t); + break; + + case OMP_ATOMIC: + { + tree op0, op1; + op0 = RECUR (TREE_OPERAND (t, 0)); + op1 = RECUR (TREE_OPERAND (t, 1)); + finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1); + } + break; + default: - abort (); + gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t))); + + return tsubst_copy_and_build (t, args, complain, in_decl, + /*function_p=*/false, + integral_constant_expression_p); } - return tsubst_expr (TREE_CHAIN (t), args, complain | stmt_expr, in_decl); + return NULL_TREE; +#undef RECUR } /* T is a postfix-expression that is not being used in a function call. Return the substituted version of T. */ static tree -tsubst_non_call_postfix_expression (tree t, tree args, +tsubst_non_call_postfix_expression (tree t, tree args, tsubst_flags_t complain, tree in_decl) { @@ -8168,7 +8852,8 @@ tsubst_non_call_postfix_expression (tree t, tree args, /*done=*/false, /*address_p=*/false); else t = tsubst_copy_and_build (t, args, complain, in_decl, - /*function_p=*/false); + /*function_p=*/false, + /*integral_constant_expression_p=*/false); return t; } @@ -8177,14 +8862,17 @@ tsubst_non_call_postfix_expression (tree t, tree args, analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */ tree -tsubst_copy_and_build (tree t, - tree args, - tsubst_flags_t complain, - tree in_decl, - bool function_p) +tsubst_copy_and_build (tree t, + tree args, + tsubst_flags_t complain, + tree in_decl, + bool function_p, + bool integral_constant_expression_p) { -#define RECUR(NODE) \ - tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false) +#define RECUR(NODE) \ + tsubst_copy_and_build (NODE, args, complain, in_decl, \ + /*function_p=*/false, \ + integral_constant_expression_p) tree op1; @@ -8195,12 +8883,11 @@ tsubst_copy_and_build (tree t, { case USING_DECL: t = DECL_NAME (t); - /* Fallthrough. */ + /* Fall through. */ case IDENTIFIER_NODE: { tree decl; cp_id_kind idk; - tree qualifying_class; bool non_integral_constant_expression_p; const char *error_msg; @@ -8211,7 +8898,7 @@ tsubst_copy_and_build (tree t, } /* Look up the name. */ - decl = lookup_name (t, 0); + decl = lookup_name (t); /* By convention, expressions use ERROR_MARK_NODE to indicate failure, not NULL_TREE. */ @@ -8220,10 +8907,13 @@ tsubst_copy_and_build (tree t, decl = finish_id_expression (t, decl, NULL_TREE, &idk, - &qualifying_class, - /*integral_constant_expression_p=*/false, + integral_constant_expression_p, /*allow_non_integral_constant_expression_p=*/false, &non_integral_constant_expression_p, + /*template_p=*/false, + /*done=*/true, + /*address_p=*/false, + /*template_arg_p=*/false, &error_msg); if (error_msg) error (error_msg); @@ -8240,7 +8930,7 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); - + if (TREE_CODE (template) == COMPONENT_REF) { object = TREE_OPERAND (template, 0); @@ -8249,16 +8939,30 @@ tsubst_copy_and_build (tree t, else object = NULL_TREE; template = lookup_template_function (template, targs); - + if (object) - return build (COMPONENT_REF, TREE_TYPE (template), - object, template); + return build3 (COMPONENT_REF, TREE_TYPE (template), + object, template, NULL_TREE); else - return template; + return baselink_for_fns (template); } case INDIRECT_REF: - return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *"); + { + tree r = RECUR (TREE_OPERAND (t, 0)); + + if (REFERENCE_REF_P (t)) + { + /* A type conversion to reference type will be enclosed in + such an indirect ref, but the substitution of the cast + will have also added such an indirect ref. */ + if (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE) + r = convert_from_reference (r); + } + else + r = build_x_indirect_ref (r, "unary *"); + return r; + } case NOP_EXPR: return build_nop @@ -8266,29 +8970,41 @@ tsubst_copy_and_build (tree t, RECUR (TREE_OPERAND (t, 0))); case CAST_EXPR: - return build_functional_cast - (tsubst (TREE_TYPE (t), args, complain, in_decl), - RECUR (TREE_OPERAND (t, 0))); - case REINTERPRET_CAST_EXPR: - return build_reinterpret_cast - (tsubst (TREE_TYPE (t), args, complain, in_decl), - RECUR (TREE_OPERAND (t, 0))); - case CONST_CAST_EXPR: - return build_const_cast - (tsubst (TREE_TYPE (t), args, complain, in_decl), - RECUR (TREE_OPERAND (t, 0))); - case DYNAMIC_CAST_EXPR: - return build_dynamic_cast - (tsubst (TREE_TYPE (t), args, complain, in_decl), - RECUR (TREE_OPERAND (t, 0))); - case STATIC_CAST_EXPR: - return build_static_cast - (tsubst (TREE_TYPE (t), args, complain, in_decl), - RECUR (TREE_OPERAND (t, 0))); + { + tree type; + tree op; + + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (integral_constant_expression_p + && !cast_valid_in_integral_constant_expression_p (type)) + { + error ("a cast to a type other than an integral or " + "enumeration type cannot appear in a constant-expression"); + return error_mark_node; + } + + op = RECUR (TREE_OPERAND (t, 0)); + + switch (TREE_CODE (t)) + { + case CAST_EXPR: + return build_functional_cast (type, op); + case REINTERPRET_CAST_EXPR: + return build_reinterpret_cast (type, op); + case CONST_CAST_EXPR: + return build_const_cast (type, op); + case DYNAMIC_CAST_EXPR: + return build_dynamic_cast (type, op); + case STATIC_CAST_EXPR: + return build_static_cast (type, op); + default: + gcc_unreachable (); + } + } case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: @@ -8302,7 +9018,7 @@ tsubst_copy_and_build (tree t, case BIT_NOT_EXPR: case ABS_EXPR: case TRUTH_NOT_EXPR: - case CONVERT_EXPR: /* Unary + */ + case UNARY_PLUS_EXPR: /* Unary + */ case REALPART_EXPR: case IMAGPART_EXPR: return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0))); @@ -8310,10 +9026,10 @@ tsubst_copy_and_build (tree t, case ADDR_EXPR: op1 = TREE_OPERAND (t, 0); if (TREE_CODE (op1) == SCOPE_REF) - op1 = tsubst_qualified_id (op1, args, complain, in_decl, + op1 = tsubst_qualified_id (op1, args, complain, in_decl, /*done=*/true, /*address_p=*/true); else - op1 = tsubst_non_call_postfix_expression (op1, args, complain, + op1 = tsubst_non_call_postfix_expression (op1, args, complain, in_decl); if (TREE_CODE (op1) == LABEL_DECL) return finish_label_address_expr (DECL_NAME (op1)); @@ -8351,7 +9067,7 @@ tsubst_copy_and_build (tree t, case MEMBER_REF: case DOTSTAR_EXPR: return build_x_binary_op - (TREE_CODE (t), + (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 1)), /*overloaded_p=*/NULL); @@ -8359,19 +9075,11 @@ tsubst_copy_and_build (tree t, case SCOPE_REF: return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true, /*address_p=*/false); - case ARRAY_REF: - if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl) - == NULL_TREE) - /* new-type-id */ - return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1))); - op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); - /* Remember that there was a reference to this entity. */ - if (DECL_P (op1)) - mark_used (op1); - return grok_array_decl (op1, RECUR (TREE_OPERAND (t, 1))); + return build_x_binary_op (ARRAY_REF, op1, RECUR (TREE_OPERAND (t, 1)), + /*overloaded_p=*/NULL); case SIZEOF_EXPR: case ALIGNOF_EXPR: @@ -8387,7 +9095,9 @@ tsubst_copy_and_build (tree t, else { ++skip_evaluation; - op1 = RECUR (op1); + op1 = tsubst_copy_and_build (op1, args, complain, in_decl, + /*function_p=*/false, + /*integral_constant_expression_p=*/false); --skip_evaluation; } if (TYPE_P (op1)) @@ -8396,10 +9106,21 @@ tsubst_copy_and_build (tree t, return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t)); case MODOP_EXPR: - return build_x_modify_expr - (RECUR (TREE_OPERAND (t, 0)), - TREE_CODE (TREE_OPERAND (t, 1)), - RECUR (TREE_OPERAND (t, 2))); + { + tree r = build_x_modify_expr + (RECUR (TREE_OPERAND (t, 0)), + TREE_CODE (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2))); + /* TREE_NO_WARNING must be set if either the expression was + parenthesized or it uses an operator such as >>= rather + than plain assignment. In the former case, it was already + set and must be copied. In the latter case, + build_x_modify_expr sets it and it must not be reset + here. */ + if (TREE_NO_WARNING (t)) + TREE_NO_WARNING (r) = TREE_NO_WARNING (t); + return r; + } case ARROW_EXPR: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), @@ -8414,6 +9135,7 @@ tsubst_copy_and_build (tree t, (RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 2)), + RECUR (TREE_OPERAND (t, 3)), NEW_EXPR_USE_GLOBAL (t)); case DELETE_EXPR: @@ -8442,17 +9164,27 @@ tsubst_copy_and_build (tree t, { qualified_p = true; function = tsubst_qualified_id (function, args, complain, in_decl, - /*done=*/false, + /*done=*/false, /*address_p=*/false); } else { - qualified_p = (TREE_CODE (function) == COMPONENT_REF - && (TREE_CODE (TREE_OPERAND (function, 1)) - == SCOPE_REF)); - function = tsubst_copy_and_build (function, args, complain, + if (TREE_CODE (function) == COMPONENT_REF) + { + tree op = TREE_OPERAND (function, 1); + + qualified_p = (TREE_CODE (op) == SCOPE_REF + || (BASELINK_P (op) + && BASELINK_QUALIFIED_P (op))); + } + else + qualified_p = false; + + function = tsubst_copy_and_build (function, args, complain, in_decl, - !qualified_p); + !qualified_p, + integral_constant_expression_p); + if (BASELINK_P (function)) qualified_p = true; } @@ -8481,8 +9213,6 @@ tsubst_copy_and_build (tree t, if (DECL_P (function)) mark_used (function); - function = convert_from_reference (function); - if (TREE_CODE (function) == OFFSET_REF) return build_offset_ref_call_from_tree (function, call_args); if (TREE_CODE (function) == COMPONENT_REF) @@ -8492,13 +9222,14 @@ tsubst_copy_and_build (tree t, /*disallow_virtual=*/false, /*koenig_p=*/false); else - return (build_new_method_call + return (build_new_method_call (TREE_OPERAND (function, 0), TREE_OPERAND (function, 1), - call_args, NULL_TREE, - qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL)); + call_args, NULL_TREE, + qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, + /*fn_p=*/NULL)); } - return finish_call_expr (function, call_args, + return finish_call_expr (function, call_args, /*disallow_virtual=*/qualified_p, koenig_p); } @@ -8510,7 +9241,7 @@ tsubst_copy_and_build (tree t, RECUR (TREE_OPERAND (t, 2))); case PSEUDO_DTOR_EXPR: - return finish_pseudo_destructor_expr + return finish_pseudo_destructor_expr (RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 2))); @@ -8541,6 +9272,7 @@ tsubst_copy_and_build (tree t, case COMPONENT_REF: { tree object; + tree object_type; tree member; object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), @@ -8548,54 +9280,55 @@ tsubst_copy_and_build (tree t, /* Remember that there was a reference to this entity. */ if (DECL_P (object)) mark_used (object); + object_type = TREE_TYPE (object); member = TREE_OPERAND (t, 1); if (BASELINK_P (member)) - member = tsubst_baselink (member, + member = tsubst_baselink (member, non_reference (TREE_TYPE (object)), args, complain, in_decl); else member = tsubst_copy (member, args, complain, in_decl); - if (member == error_mark_node) return error_mark_node; - else if (!CLASS_TYPE_P (TREE_TYPE (object))) + + if (object_type && !CLASS_TYPE_P (object_type)) { if (TREE_CODE (member) == BIT_NOT_EXPR) - return finish_pseudo_destructor_expr (object, + return finish_pseudo_destructor_expr (object, NULL_TREE, - TREE_TYPE (object)); + object_type); else if (TREE_CODE (member) == SCOPE_REF && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR)) - return finish_pseudo_destructor_expr (object, + return finish_pseudo_destructor_expr (object, object, - TREE_TYPE (object)); + object_type); } else if (TREE_CODE (member) == SCOPE_REF && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR) { tree tmpl; tree args; - + /* Lookup the template functions now that we know what the scope is. */ tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0); args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); - member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, + member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, /*is_type_p=*/false, /*complain=*/false); if (BASELINK_P (member)) { - BASELINK_FUNCTIONS (member) + BASELINK_FUNCTIONS (member) = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), args); - member = (adjust_result_of_qualified_name_lookup - (member, BINFO_TYPE (BASELINK_BINFO (member)), - TREE_TYPE (object))); + member = (adjust_result_of_qualified_name_lookup + (member, BINFO_TYPE (BASELINK_BINFO (member)), + object_type)); } else { - qualified_name_lookup_error (TREE_TYPE (object), tmpl); + qualified_name_lookup_error (object_type, tmpl, member); return error_mark_node; } } @@ -8606,10 +9339,10 @@ tsubst_copy_and_build (tree t, if (complain & tf_error) { if (TYPE_P (TREE_OPERAND (member, 0))) - error ("`%T' is not a class or namespace", + error ("%qT is not a class or namespace", TREE_OPERAND (member, 0)); else - error ("`%D' is not a class or namespace", + error ("%qD is not a class or namespace", TREE_OPERAND (member, 0)); } return error_mark_node; @@ -8617,7 +9350,8 @@ tsubst_copy_and_build (tree t, else if (TREE_CODE (member) == FIELD_DECL) return finish_non_static_data_member (member, object, NULL_TREE); - return finish_class_member_access_expr (object, member); + return finish_class_member_access_expr (object, member, + /*template_p=*/false); } case THROW_EXPR: @@ -8626,39 +9360,36 @@ tsubst_copy_and_build (tree t, case CONSTRUCTOR: { - tree r; - tree elts; + VEC(constructor_elt,gc) *n; + constructor_elt *ce; + unsigned HOST_WIDE_INT idx; tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); - bool purpose_p; + bool process_index_p; + + if (type == error_mark_node) + return error_mark_node; /* digest_init will do the wrong thing if we let it. */ if (type && TYPE_PTRMEMFUNC_P (type)) return t; - r = NULL_TREE; - /* We do not want to process the purpose of aggregate + /* We do not want to process the index of aggregate initializers as they are identifier nodes which will be looked up by digest_init. */ - purpose_p = !(type && IS_AGGR_TYPE (type)); - for (elts = CONSTRUCTOR_ELTS (t); - elts; - elts = TREE_CHAIN (elts)) + process_index_p = !(type && IS_AGGR_TYPE (type)); + + n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t)); + for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++) { - tree purpose = TREE_PURPOSE (elts); - tree value = TREE_VALUE (elts); - - if (purpose && purpose_p) - purpose = RECUR (purpose); - value = RECUR (value); - r = tree_cons (purpose, value, r); + if (ce->index && process_index_p) + ce->index = RECUR (ce->index); + ce->value = RECUR (ce->value); } - - r = build_constructor (NULL_TREE, nreverse (r)); - TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); - if (type) - return digest_init (type, r, 0); - return r; + if (TREE_HAS_CONSTRUCTOR (t)) + return finish_compound_literal (type, n); + + return build_constructor (NULL_TREE, n); } case TYPEID_EXPR: @@ -8669,28 +9400,64 @@ tsubst_copy_and_build (tree t, return build_typeid (operand_0); } + case VAR_DECL: + if (!args) + return t; + /* Fall through */ + case PARM_DECL: - return convert_from_reference (tsubst_copy (t, args, complain, in_decl)); + { + tree r = tsubst_copy (t, args, complain, in_decl); - case VAR_DECL: - if (args) - t = tsubst_copy (t, args, complain, in_decl); - return convert_from_reference (t); + if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) + /* If the original type was a reference, we'll be wrapped in + the appropriate INDIRECT_REF. */ + r = convert_from_reference (r); + return r; + } case VA_ARG_EXPR: return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)), - tsubst_copy (TREE_TYPE (t), args, complain, + tsubst_copy (TREE_TYPE (t), args, complain, in_decl)); + case OFFSETOF_EXPR: + return finish_offsetof (RECUR (TREE_OPERAND (t, 0))); + + case STMT_EXPR: + { + tree old_stmt_expr = cur_stmt_expr; + tree stmt_expr = begin_stmt_expr (); + + cur_stmt_expr = stmt_expr; + tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl, + integral_constant_expression_p); + stmt_expr = finish_stmt_expr (stmt_expr, false); + cur_stmt_expr = old_stmt_expr; + + return stmt_expr; + } + case CONST_DECL: t = tsubst_copy (t, args, complain, in_decl); /* As in finish_id_expression, we resolve enumeration constants to their underlying values. */ if (TREE_CODE (t) == CONST_DECL) - return DECL_INITIAL (t); + { + used_types_insert (TREE_TYPE (t)); + return DECL_INITIAL (t); + } return t; default: + /* Handle Objective-C++ constructs, if appropriate. */ + { + tree subst + = objcp_tsubst_copy_and_build (t, args, complain, + in_decl, /*function_p=*/false); + if (subst) + return subst; + } return tsubst_copy (t, args, complain, in_decl); } @@ -8711,7 +9478,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) for (ix = 0; ix != len; ix++) { tree t = TREE_VEC_ELT (args, ix); - + if (TYPE_P (t)) { /* [basic.link]: A name with no linkage (notably, the name @@ -8719,24 +9486,28 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) shall not be used to declare an entity with linkage. This implies that names with no linkage cannot be used as template arguments. */ - tree nt = no_linkage_check (t); + tree nt = no_linkage_check (t, /*relaxed_p=*/false); if (nt) { - if (!(complain & tf_error)) - /*OK*/; - else if (TYPE_ANONYMOUS_P (nt)) - error ("`%T' uses anonymous type", t); - else - error ("`%T' uses local type `%T'", t, nt); + /* DR 488 makes use of a type with no linkage cause + type deduction to fail. */ + if (complain & tf_error) + { + if (TYPE_ANONYMOUS_P (nt)) + error ("%qT is/uses anonymous type", t); + else + error ("template argument for %qD uses local type %qT", + tmpl, t); + } result = true; } /* In order to avoid all sorts of complications, we do not allow variably-modified types as template arguments. */ - else if (variably_modified_type_p (t)) + else if (variably_modified_type_p (t, NULL_TREE)) { if (complain & tf_error) - error ("`%T' is a variably modified type", t); + error ("%qT is a variably modified type", t); result = true; } } @@ -8747,12 +9518,12 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) && !TREE_CONSTANT (t)) { if (complain & tf_error) - error ("integral expression `%E' is not constant", t); + error ("integral expression %qE is not constant", t); result = true; } } - if (result && complain & tf_error) - error (" trying to instantiate `%D'", tmpl); + if (result && (complain & tf_error)) + error (" trying to instantiate %qD", tmpl); return result; } @@ -8765,36 +9536,36 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) tree fndecl; tree gen_tmpl; tree spec; + HOST_WIDE_INT saved_processing_template_decl; if (tmpl == error_mark_node) return error_mark_node; - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283); + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); /* If this function is a clone, handle it specially. */ if (DECL_CLONED_FUNCTION_P (tmpl)) { tree spec; tree clone; - + spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr, complain); if (spec == error_mark_node) return error_mark_node; /* Look for the clone. */ - for (clone = TREE_CHAIN (spec); - clone && DECL_CLONED_FUNCTION_P (clone); - clone = TREE_CHAIN (clone)) + FOR_EACH_CLONE (clone, spec) if (DECL_NAME (clone) == DECL_NAME (tmpl)) return clone; /* We should always have found the clone by now. */ - abort (); + gcc_unreachable (); return NULL_TREE; } - + /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (tmpl, targ_ptr); + spec = retrieve_specialization (tmpl, targ_ptr, + /*class_specializations_p=*/false); if (spec != NULL_TREE) return spec; @@ -8808,7 +9579,8 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) targ_ptr); /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, targ_ptr); + spec = retrieve_specialization (gen_tmpl, targ_ptr, + /*class_specializations_p=*/false); if (spec != NULL_TREE) return spec; } @@ -8816,7 +9588,7 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) if (check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (targ_ptr), complain)) return error_mark_node; - + /* We are building a FUNCTION_DECL, during which the access of its parameters and return types have to be checked. However this FUNCTION_DECL which is the desired context for access checking @@ -8824,9 +9596,20 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) deferring all checks until we have the FUNCTION_DECL. */ push_deferring_access_checks (dk_deferred); - /* Substitute template parameters. */ + /* Although PROCESSING_TEMPLATE_DECL may be true at this point + (because, for example, we have encountered a non-dependent + function call in the body of a template function and must now + determine which of several overloaded functions will be called), + within the instantiation itself we are not processing a + template. */ + saved_processing_template_decl = processing_template_decl; + processing_template_decl = 0; + /* Substitute template parameters to obtain the specialization. */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, complain, gen_tmpl); + processing_template_decl = saved_processing_template_decl; + if (fndecl == error_mark_node) + return error_mark_node; /* Now we know the specialization, compute access previously deferred. */ @@ -8851,7 +9634,7 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) /* The FN is a TEMPLATE_DECL for a function. The ARGS are the arguments that are being used when calling it. TARGS is a vector - into which the deduced template arguments are placed. + into which the deduced template arguments are placed. Return zero for success, 2 for an incomplete match that doesn't resolve all the types, and 1 for complete failure. An error message will be @@ -8865,51 +9648,40 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) The parameter STRICT is one of: - DEDUCE_CALL: + DEDUCE_CALL: We are deducing arguments for a function call, as in [temp.deduct.call]. DEDUCE_CONV: - We are deducing arguments for a conversion function, as in + We are deducing arguments for a conversion function, as in [temp.deduct.conv]. DEDUCE_EXACT: We are deducing arguments when doing an explicit instantiation as in [temp.explicit], when determining an explicit specialization as in [temp.expl.spec], or when taking the address of a function - template, as in [temp.deduct.funcaddr]. - - DEDUCE_ORDER: - We are deducing arguments when calculating the partial - ordering between specializations of function or class - templates, as in [temp.func.order] and [temp.class.order]. - - LEN is the number of parms to consider before returning success, or -1 - for all. This is used in partial ordering to avoid comparing parms for - which no actual argument was passed, since they are not considered in - overload resolution (and are explicitly excluded from consideration in - partial ordering in [temp.func.order]/6). */ + template, as in [temp.deduct.funcaddr]. */ int -fn_type_unification (tree fn, - tree explicit_targs, - tree targs, - tree args, - tree return_type, - unification_kind_t strict, - int len) +fn_type_unification (tree fn, + tree explicit_targs, + tree targs, + tree args, + tree return_type, + unification_kind_t strict, + int flags) { tree parms; tree fntype; int result; - my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0); + gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL); fntype = TREE_TYPE (fn); if (explicit_targs) { /* [temp.deduct] - + The specified template arguments must match the template parameters in kind (i.e., type, nontype, template), and there must not be more arguments than there are parameters; @@ -8933,23 +9705,24 @@ fn_type_unification (tree fn, return 1; converted_args - = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), - explicit_targs, NULL_TREE, tf_none, - /*require_all_arguments=*/0)); + = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), + explicit_targs, NULL_TREE, tf_none, + /*require_all_args=*/false, + /*use_default_args=*/false)); if (converted_args == error_mark_node) return 1; /* Substitute the explicit args into the function type. This is - necessary so that, for instance, explicitly declared function - arguments can match null pointed constants. If we were given - an incomplete set of explicit args, we must not do semantic - processing during substitution as we could create partial - instantiations. */ + necessary so that, for instance, explicitly declared function + arguments can match null pointed constants. If we were given + an incomplete set of explicit args, we must not do semantic + processing during substitution as we could create partial + instantiations. */ incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs); processing_template_decl += incomplete; fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE); processing_template_decl -= incomplete; - + if (fntype == error_mark_node) return 1; @@ -8957,34 +9730,29 @@ fn_type_unification (tree fn, for (i = NUM_TMPL_ARGS (converted_args); i--;) TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i); } - - parms = TYPE_ARG_TYPES (fntype); + /* Never do unification on the 'this' parameter. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) - parms = TREE_CHAIN (parms); - + parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype)); + if (return_type) { - /* We've been given a return type to match, prepend it. */ parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms); args = tree_cons (NULL_TREE, return_type, args); - if (len >= 0) - ++len; } /* We allow incomplete unification without an error message here because the standard doesn't seem to explicitly prohibit it. Our callers must be ready to deal with unification failures in any event. */ - result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), + result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs, parms, args, /*subr=*/0, - strict, /*allow_incomplete*/1, len); + strict, flags); - if (result == 0) + if (result == 0) /* All is well so far. Now, check: - - [temp.deduct] - + + [temp.deduct] + When all template arguments have been deduced, all uses of template parameters in nondeduced contexts are replaced with the corresponding deduced argument values. If the @@ -9005,12 +9773,12 @@ fn_type_unification (tree fn, initialized with the result of the conversion function. */ static int -maybe_adjust_types_for_deduction (unification_kind_t strict, - tree* parm, - tree* arg) +maybe_adjust_types_for_deduction (unification_kind_t strict, + tree* parm, + tree* arg) { int result = 0; - + switch (strict) { case DEDUCE_CALL: @@ -9031,47 +9799,25 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, /* There is nothing to do in this case. */ return 0; - case DEDUCE_ORDER: - /* DR 214. [temp.func.order] is underspecified, and leads to no - ordering between things like `T *' and `T const &' for `U *'. - The former has T=U and the latter T=U*. The former looks more - specialized and John Spicer considers it well-formed (the EDG - compiler accepts it). - - John also confirms that deduction should proceed as in a function - call. Which implies the usual ARG and PARM conversions as DEDUCE_CALL. - However, in ordering, ARG can have REFERENCE_TYPE, but no argument - to an actual call can have such a type. - - If both ARG and PARM are REFERENCE_TYPE, we change neither. - If only ARG is a REFERENCE_TYPE, we look through that and then - proceed as with DEDUCE_CALL (which could further convert it). */ - if (TREE_CODE (*arg) == REFERENCE_TYPE) - { - if (TREE_CODE (*parm) == REFERENCE_TYPE) - return 0; - *arg = TREE_TYPE (*arg); - } - break; default: - abort (); + gcc_unreachable (); } if (TREE_CODE (*parm) != REFERENCE_TYPE) { /* [temp.deduct.call] - + If P is not a reference type: - + --If A is an array type, the pointer type produced by the array-to-pointer standard conversion (_conv.array_) is used in place of A for type deduction; otherwise, - + --If A is a function type, the pointer type produced by the function-to-pointer standard conversion (_conv.func_) is used in place of A for type deduction; otherwise, - + --If A is a cv-qualified type, the top level cv-qualifiers of A's type are ignored for type deduction. */ @@ -9082,9 +9828,9 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, else *arg = TYPE_MAIN_VARIANT (*arg); } - + /* [temp.deduct.call] - + If P is a cv-qualified type, the top level cv-qualifiers of P's type are ignored for type deduction. If P is a reference type, the type referred to by P is used for @@ -9100,7 +9846,7 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, too (which has been swapped into ARG). */ if (strict == DEDUCE_CONV && TREE_CODE (*arg) == REFERENCE_TYPE) *arg = TREE_TYPE (*arg); - + return result; } @@ -9108,17 +9854,16 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, If SUBR is 1, we're being called recursively (to unify the arguments of a function or method parameter of a function - template). */ + template). */ static int -type_unification_real (tree tparms, - tree targs, - tree xparms, - tree xargs, - int subr, - unification_kind_t strict, - int allow_incomplete, - int xlen) +type_unification_real (tree tparms, + tree targs, + tree xparms, + tree xargs, + int subr, + unification_kind_t strict, + int flags) { tree parm, arg; int i; @@ -9126,21 +9871,19 @@ type_unification_real (tree tparms, int sub_strict; int saw_undeduced = 0; tree parms, args; - int len; - my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289); - my_friendly_assert (xparms == NULL_TREE - || TREE_CODE (xparms) == TREE_LIST, 290); - my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291); - my_friendly_assert (ntparms > 0, 292); + gcc_assert (TREE_CODE (tparms) == TREE_VEC); + gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST); + gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST); + gcc_assert (ntparms > 0); switch (strict) { case DEDUCE_CALL: sub_strict = (UNIFY_ALLOW_OUTER_LEVEL | UNIFY_ALLOW_MORE_CV_QUAL - | UNIFY_ALLOW_DERIVED); + | UNIFY_ALLOW_DERIVED); break; - + case DEDUCE_CONV: sub_strict = UNIFY_ALLOW_LESS_CV_QUAL; break; @@ -9148,27 +9891,17 @@ type_unification_real (tree tparms, case DEDUCE_EXACT: sub_strict = UNIFY_ALLOW_NONE; break; - - case DEDUCE_ORDER: - sub_strict = UNIFY_ALLOW_NONE; - break; - + default: - abort (); + gcc_unreachable (); } - if (xlen == 0) - return 0; - again: parms = xparms; args = xargs; - len = xlen; - while (parms - && parms != void_list_node - && args - && args != void_list_node) + while (parms && parms != void_list_node + && args && args != void_list_node) { parm = TREE_VALUE (parms); parms = TREE_CHAIN (parms); @@ -9198,15 +9931,16 @@ type_unification_real (tree tparms, if (same_type_p (parm, type)) continue; if (strict != DEDUCE_EXACT - && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, + flags)) continue; - + return 1; } - + if (!TYPE_P (arg)) { - my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293); + gcc_assert (TREE_TYPE (arg) != NULL_TREE); if (type_unknown_p (arg)) { /* [temp.deduct.type] A template-argument can be deduced from @@ -9221,41 +9955,41 @@ type_unification_real (tree tparms, return 1; continue; } - arg = TREE_TYPE (arg); + arg = unlowered_expr_type (arg); if (arg == error_mark_node) return 1; } - + { - int arg_strict = sub_strict; - - if (!subr) + int arg_strict = sub_strict; + + if (!subr) arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg); - if (unify (tparms, targs, parm, arg, arg_strict)) - return 1; + if (unify (tparms, targs, parm, arg, arg_strict)) + return 1; } - - /* Are we done with the interesting parms? */ - if (--len == 0) - goto done; } + /* Fail if we've reached the end of the parm list, and more args are present, and the parm list isn't variadic. */ if (args && args != void_list_node && parms == void_list_node) return 1; /* Fail if parms are left and they don't have default values. */ - if (parms - && parms != void_list_node + if (parms && parms != void_list_node && TREE_PURPOSE (parms) == NULL_TREE) return 1; - done: if (!subr) for (i = 0; i < ntparms; i++) - if (TREE_VEC_ELT (targs, i) == NULL_TREE) + if (!TREE_VEC_ELT (targs, i)) { - tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); + tree tparm; + + if (TREE_VEC_ELT (tparms, i) == error_mark_node) + continue; + + tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); /* If this is an undeduced nontype parameter that depends on a type parameter, try another pass; its type may have been @@ -9266,10 +10000,9 @@ type_unification_real (tree tparms, && !saw_undeduced++) goto again; - if (!allow_incomplete) - error ("incomplete type unification"); return 2; } + return 0; } @@ -9279,11 +10012,11 @@ type_unification_real (tree tparms, succeeds, we go with that. Modifies TARGS and returns 0 on success. */ static int -resolve_overloaded_unification (tree tparms, - tree targs, - tree parm, - tree arg, - unification_kind_t strict, +resolve_overloaded_unification (tree tparms, + tree targs, + tree parm, + tree arg, + unification_kind_t strict, int sub_strict) { tree tempargs = copy_node (targs); @@ -9327,26 +10060,26 @@ resolve_overloaded_unification (tree tparms, if (TREE_CODE (fn) != TEMPLATE_DECL) continue; - subargs = get_bindings_overload (fn, DECL_TEMPLATE_RESULT (fn), - expl_subargs); + subargs = get_bindings (fn, DECL_TEMPLATE_RESULT (fn), + expl_subargs, /*check_ret=*/false); if (subargs) { elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE); - good += try_one_overload (tparms, targs, tempargs, parm, + good += try_one_overload (tparms, targs, tempargs, parm, elem, strict, sub_strict, addr_p); } } } - else if (TREE_CODE (arg) == OVERLOAD - || TREE_CODE (arg) == FUNCTION_DECL) + else { + gcc_assert (TREE_CODE (arg) == OVERLOAD + || TREE_CODE (arg) == FUNCTION_DECL); + for (; arg; arg = OVL_NEXT (arg)) good += try_one_overload (tparms, targs, tempargs, parm, TREE_TYPE (OVL_CURRENT (arg)), strict, sub_strict, addr_p); } - else - abort (); /* [temp.deduct.type] A template-argument can be deduced from a pointer to function or pointer to member function argument if the set of @@ -9379,11 +10112,11 @@ resolve_overloaded_unification (tree tparms, static int try_one_overload (tree tparms, - tree orig_targs, - tree targs, - tree parm, - tree arg, - unification_kind_t strict, + tree orig_targs, + tree targs, + tree parm, + tree arg, + unification_kind_t strict, int sub_strict, bool addr_p) { @@ -9425,17 +10158,14 @@ try_one_overload (tree tparms, tree elt = TREE_VEC_ELT (tempargs, i); tree oldelt = TREE_VEC_ELT (orig_targs, i); - if (elt == NULL_TREE) - continue; + if (!elt) + /*NOP*/; else if (uses_template_parms (elt)) - { - /* Since we're unifying against ourselves, we will fill in template - args used in the function parm list with our own template parms. - Discard them. */ - TREE_VEC_ELT (tempargs, i) = NULL_TREE; - continue; - } - else if (oldelt && ! template_args_equal (oldelt, elt)) + /* Since we're unifying against ourselves, we will fill in + template args used in the function parm list with our own + template parms. Discard them. */ + TREE_VEC_ELT (tempargs, i) = NULL_TREE; + else if (oldelt && !template_args_equal (oldelt, elt)) return 0; } @@ -9450,34 +10180,6 @@ try_one_overload (tree tparms, return 1; } -/* Verify that nondeduce template argument agrees with the type - obtained from argument deduction. Return nonzero if the - verification fails. - - For example: - - struct A { typedef int X; }; - template <class T, class U> struct C {}; - template <class T> struct C<T, typename T::X> {}; - - Then with the instantiation `C<A, int>', we can deduce that - `T' is `A' but unify () does not check whether `typename T::X' - is `int'. This function ensure that they agree. - - TARGS, PARMS are the same as the arguments of unify. - ARGS contains template arguments from all levels. */ - -static int -verify_class_unification (tree targs, tree parms, tree args) -{ - parms = tsubst (parms, add_outermost_template_args (args, targs), - tf_none, NULL_TREE); - if (parms == error_mark_node) - return 1; - - return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args)); -} - /* PARM is a template class (perhaps with unbound template parameters). ARG is a fully instantiated type. If ARG can be bound to PARM, return ARG, otherwise return NULL_TREE. TPARMS and @@ -9489,7 +10191,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) tree copy_of_targs; if (!CLASSTYPE_TEMPLATE_INFO (arg) - || (most_general_template (CLASSTYPE_TI_TEMPLATE (arg)) + || (most_general_template (CLASSTYPE_TI_TEMPLATE (arg)) != most_general_template (CLASSTYPE_TI_TEMPLATE (parm)))) return NULL_TREE; @@ -9503,18 +10205,18 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) template <int I, int J, int K> struct S {}; - + template <int I, int J> struct S<I, J, 2> : public S<I, I, I>, S<J, J, J> {}; - + template <int I, int J, int K> void f(S<I, J, K>, S<I, I, I>); - + void g() { - S<0, 0, 0> s0; - S<0, 1, 2> s2; - - f(s0, s2); + S<0, 0, 0> s0; + S<0, 1, 2> s2; + + f(s0, s2); } Now, by the time we consider the unification involving `s2', we @@ -9524,7 +10226,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) with S<I, I, I>. If we kept the already deduced knowledge, we would reject the possibility I=1. */ copy_of_targs = make_tree_vec (TREE_VEC_LENGTH (targs)); - + /* If unification failed, we're done. */ if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm), CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE)) @@ -9533,101 +10235,48 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) return arg; } -/* Subroutine of get_template_base. RVAL, if non-NULL, is a base we - have already discovered to be satisfactory. ARG_BINFO is the binfo - for the base class of ARG that we are currently examining. */ +/* Given a template type PARM and a class type ARG, find the unique + base type in ARG that is an instance of PARM. We do not examine + ARG itself; only its base-classes. If there is not exactly one + appropriate base class, return NULL_TREE. PARM may be the type of + a partial specialization, as well as a plain template type. Used + by unify. */ static tree -get_template_base_recursive (tree tparms, - tree targs, - tree parm, - tree arg_binfo, - tree rval, - int flags) +get_template_base (tree tparms, tree targs, tree parm, tree arg) { - tree binfos; - int i, n_baselinks; - tree arg = BINFO_TYPE (arg_binfo); + tree rval = NULL_TREE; + tree binfo; - if (!(flags & GTB_IGNORE_TYPE)) - { - tree r = try_class_unification (tparms, targs, - parm, arg); - - /* If there is more than one satisfactory baseclass, then: - - [temp.deduct.call] - - If they yield more than one possible deduced A, the type - deduction fails. - - applies. */ - if (r && rval && !same_type_p (r, rval)) - return error_mark_node; - else if (r) - rval = r; - } + gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg))); - binfos = BINFO_BASETYPES (arg_binfo); - n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; + binfo = TYPE_BINFO (complete_type (arg)); + if (!binfo) + /* The type could not be completed. */ + return NULL_TREE; - /* Process base types. */ - for (i = 0; i < n_baselinks; i++) + /* Walk in inheritance graph order. The search order is not + important, and this avoids multiple walks of virtual bases. */ + for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo)) { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int this_virtual; - - /* Skip this base, if we've already seen it. */ - if (BINFO_MARKED (base_binfo)) - continue; - - this_virtual = - (flags & GTB_VIA_VIRTUAL) || TREE_VIA_VIRTUAL (base_binfo); - - /* When searching for a non-virtual, we cannot mark virtually - found binfos. */ - if (! this_virtual) - BINFO_MARKED (base_binfo) = 1; - - rval = get_template_base_recursive (tparms, targs, - parm, - base_binfo, - rval, - GTB_VIA_VIRTUAL * this_virtual); - - /* If we discovered more than one matching base class, we can - stop now. */ - if (rval == error_mark_node) - return error_mark_node; - } + tree r = try_class_unification (tparms, targs, parm, BINFO_TYPE (binfo)); - return rval; -} + if (r) + { + /* If there is more than one satisfactory baseclass, then: -/* Given a template type PARM and a class type ARG, find the unique - base type in ARG that is an instance of PARM. We do not examine - ARG itself; only its base-classes. If there is no appropriate base - class, return NULL_TREE. If there is more than one, return - error_mark_node. PARM may be the type of a partial specialization, - as well as a plain template type. Used by unify. */ + [temp.deduct.call] -static tree -get_template_base (tree tparms, tree targs, tree parm, tree arg) -{ - tree rval; - tree arg_binfo; + If they yield more than one possible deduced A, the type + deduction fails. - my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92); - - arg_binfo = TYPE_BINFO (complete_type (arg)); - rval = get_template_base_recursive (tparms, targs, - parm, arg_binfo, - NULL_TREE, - GTB_IGNORE_TYPE); + applies. */ + if (rval && !same_type_p (r, rval)) + return NULL_TREE; - /* Since get_template_base_recursive marks the bases classes, we - must unmark them here. */ - dfs_walk (arg_binfo, dfs_unmark, markedp, 0); + rval = r; + } + } return rval; } @@ -9647,14 +10296,14 @@ template_decl_level (tree decl) return TEMPLATE_PARM_LEVEL (DECL_INITIAL (decl)); default: - abort (); - return 0; + gcc_unreachable (); } + return 0; } /* Decide whether ARG can be unified with PARM, considering only the cv-qualifiers of each type, given STRICT as documented for unify. - Returns nonzero iff the unification is OK on that basis. */ + Returns nonzero iff the unification is OK on that basis. */ static int check_cv_quals_for_unify (int strict, tree arg, tree parm) @@ -9666,11 +10315,11 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) { /* Although a CVR qualifier is ignored when being applied to a - substituted template parameter ([8.3.2]/1 for example), that - does not apply during deduction [14.8.2.4]/1, (even though - that is not explicitly mentioned, [14.8.2.4]/9 indicates - this). Except when we're allowing additional CV qualifiers - at the outer level [14.8.2.1]/3,1st bullet. */ + substituted template parameter ([8.3.2]/1 for example), that + does not apply during deduction [14.8.2.4]/1, (even though + that is not explicitly mentioned, [14.8.2.4]/9 indicates + this). Except when we're allowing additional CV qualifiers + at the outer level [14.8.2.1]/3,1st bullet. */ if ((TREE_CODE (arg) == REFERENCE_TYPE || TREE_CODE (arg) == FUNCTION_TYPE || TREE_CODE (arg) == METHOD_TYPE) @@ -9693,9 +10342,18 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) return 1; } -/* Takes parameters as for type_unification. Returns 0 if the - type deduction succeeds, 1 otherwise. The parameter STRICT is a - bitwise or of the following flags: +/* Deduce the value of template parameters. TPARMS is the (innermost) + set of template parameters to a template. TARGS is the bindings + for those template parameters, as determined thus far; TARGS may + include template arguments for outer levels of template parameters + as well. PARM is a parameter to a template function, or a + subcomponent of that parameter; ARG is the corresponding argument. + This function attempts to match PARM with ARG in a manner + consistent with the existing assignments in TARGS. If more values + are deduced, then TARGS is updated. + + Returns 0 if the type deduction succeeds, 1 otherwise. The + parameter STRICT is a bitwise or of the following flags: UNIFY_ALLOW_NONE: Require an exact match between PARM and ARG. @@ -9710,7 +10368,7 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) ARG. UNIFY_ALLOW_INTEGER: Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX - case for more information. + case for more information. UNIFY_ALLOW_OUTER_LEVEL: This is the outermost level of a deduction. Used to determine validity of qualification conversions. A valid qualification conversion must @@ -9723,14 +10381,7 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) qualified at this point. UNIFY_ALLOW_OUTER_LESS_CV_QUAL: This is the outermost level of a deduction, and PARM can be less CV - qualified at this point. - UNIFY_ALLOW_MAX_CORRECTION: - This is an INTEGER_TYPE's maximum value. Used if the range may - have been derived from a size specification, such as an array size. - If the size was given by a nontype template parameter N, the maximum - value will have the form N-1. The flag says that we can (and indeed - must) unify N with (ARG + 1), an exception to the normal rules on - folding PARM. */ + qualified at this point. */ static int unify (tree tparms, tree targs, tree parm, tree arg, int strict) @@ -9766,8 +10417,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) if (TREE_CODE (arg) == TREE_CODE (parm) && TYPE_P (arg) /* It is the elements of the array which hold the cv quals of an array - type, and the elements might be template type parms. We'll check - when we recurse. */ + type, and the elements might be template type parms. We'll check + when we recurse. */ && TREE_CODE (arg) != ARRAY_TYPE /* We check the cv-qualifiers when unifying with template type parameters below. We want to allow ARG `const T' to unify with @@ -9784,8 +10435,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) strict &= ~UNIFY_ALLOW_DERIVED; strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL; strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL; - strict &= ~UNIFY_ALLOW_MAX_CORRECTION; - + switch (TREE_CODE (parm)) { case TYPENAME_TYPE: @@ -9808,13 +10458,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) return (TREE_CODE (arg) == TREE_CODE (parm) && same_type_p (parm, arg)) ? 0 : 1; idx = TEMPLATE_TYPE_IDX (parm); - targ = TREE_VEC_ELT (targs, idx); + targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); /* Check for mixed types and values. */ if ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM && TREE_CODE (tparm) != TYPE_DECL) - || (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM + || (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM && TREE_CODE (tparm) != TEMPLATE_DECL)) return 1; @@ -9823,39 +10473,61 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) /* ARG must be constructed from a template class or a template template parameter. */ if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM - && (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))) + && !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg)) return 1; { - tree parmtmpl = TYPE_TI_TEMPLATE (parm); tree parmvec = TYPE_TI_ARGS (parm); - tree argvec = TYPE_TI_ARGS (arg); + tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg)); tree argtmplvec = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg)); int i; - /* The parameter and argument roles have to be switched here - in order to handle default arguments properly. For example, - template<template <class> class TT> void f(TT<int>) - should be able to accept vector<int> which comes from - template <class T, class Allocator = allocator> - class vector. */ + /* The resolution to DR150 makes clear that default + arguments for an N-argument may not be used to bind T + to a template template parameter with fewer than N + parameters. It is not safe to permit the binding of + default arguments as an extension, as that may change + the meaning of a conforming program. Consider: + + struct Dense { static const unsigned int dim = 1; }; + + template <template <typename> class View, + typename Block> + void operator+(float, View<Block> const&); + + template <typename Block, + unsigned int Dim = Block::dim> + struct Lvalue_proxy { operator float() const; }; + + void + test_1d (void) { + Lvalue_proxy<Dense> p; + float b; + b + p; + } - if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1) - == error_mark_node) + Here, if Lvalue_proxy is permitted to bind to View, then + the global operator+ will be used; if they are not, the + Lvalue_proxy will be converted to float. */ + if (coerce_template_parms (argtmplvec, parmvec, + TYPE_TI_TEMPLATE (parm), + tf_none, + /*require_all_args=*/true, + /*use_default_args=*/false) + == error_mark_node) return 1; - - /* Deduce arguments T, i from TT<T> or TT<i>. + + /* Deduce arguments T, i from TT<T> or TT<i>. We check each element of PARMVEC and ARGVEC individually rather than the whole TREE_VEC since they can have different number of elements. */ for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i) { - tree t = TREE_VEC_ELT (parmvec, i); - - if (unify (tparms, targs, t, - TREE_VEC_ELT (argvec, i), + if (unify (tparms, targs, + TREE_VEC_ELT (parmvec, i), + TREE_VEC_ELT (argvec, i), UNIFY_ALLOW_NONE)) return 1; } @@ -9882,7 +10554,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) a match unless we are allowing additional qualification. If ARG is `const int' and PARM is just `T' that's OK; that binds `const int' to `T'. */ - if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, + if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, arg, parm)) return 1; @@ -9906,17 +10578,19 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) the bound of the array will not be computable in an instantiation. Besides, such types are not allowed in ISO C++, so we can do as we please here. */ - if (variably_modified_type_p (arg)) + if (variably_modified_type_p (arg, NULL_TREE)) return 1; } - TREE_VEC_ELT (targs, idx) = arg; + TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; return 0; case TEMPLATE_PARM_INDEX: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); + if (tparm == error_mark_node) + return 1; - if (TEMPLATE_PARM_LEVEL (parm) + if (TEMPLATE_PARM_LEVEL (parm) != template_decl_level (tparm)) /* The PARM is not one we're trying to unify. Just check to see if it matches ARG. */ @@ -9924,7 +10598,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) && cp_tree_equal (parm, arg)); idx = TEMPLATE_PARM_IDX (parm); - targ = TREE_VEC_ELT (targs, idx); + targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); if (targ) return !cp_tree_equal (targ, arg); @@ -9935,7 +10609,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) parameter-list and, if the corresponding template-argument is deduced, the template-argument type shall match the type of the template-parameter exactly, except that a template-argument - deduced from an array bound may be of any integral type. + deduced from an array bound may be of any integral type. The non-type parameter might use already deduced type parameters. */ tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE); if (!TREE_TYPE (arg)) @@ -9958,35 +10632,35 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) else return 1; - TREE_VEC_ELT (targs, idx) = arg; + TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; return 0; case PTRMEM_CST: { - /* A pointer-to-member constant can be unified only with - another constant. */ + /* A pointer-to-member constant can be unified only with + another constant. */ if (TREE_CODE (arg) != PTRMEM_CST) - return 1; + return 1; /* Just unify the class member. It would be useless (and possibly - wrong, depending on the strict flags) to unify also - PTRMEM_CST_CLASS, because we want to be sure that both parm and - arg refer to the same variable, even if through different - classes. For instance: + wrong, depending on the strict flags) to unify also + PTRMEM_CST_CLASS, because we want to be sure that both parm and + arg refer to the same variable, even if through different + classes. For instance: - struct A { int x; }; - struct B : A { }; + struct A { int x; }; + struct B : A { }; - Unification of &A::x and &B::x must succeed. */ + Unification of &A::x and &B::x must succeed. */ return unify (tparms, targs, PTRMEM_CST_MEMBER (parm), - PTRMEM_CST_MEMBER (arg), strict); + PTRMEM_CST_MEMBER (arg), strict); } case POINTER_TYPE: { if (TREE_CODE (arg) != POINTER_TYPE) return 1; - + /* [temp.deduct.call] A can be another pointer or pointer to member type that can @@ -9996,13 +10670,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) We pass down STRICT here rather than UNIFY_ALLOW_NONE. This will allow for additional cv-qualification of the pointed-to types if appropriate. */ - + if (TREE_CODE (TREE_TYPE (arg)) == RECORD_TYPE) /* The derived-to-base conversion only persists through one level of pointers. */ strict |= (strict_in & UNIFY_ALLOW_DERIVED); - return unify (tparms, targs, TREE_TYPE (parm), + return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), strict); } @@ -10018,10 +10692,64 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) if ((TYPE_DOMAIN (parm) == NULL_TREE) != (TYPE_DOMAIN (arg) == NULL_TREE)) return 1; - if (TYPE_DOMAIN (parm) != NULL_TREE - && unify (tparms, targs, TYPE_DOMAIN (parm), - TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE) != 0) - return 1; + if (TYPE_DOMAIN (parm) != NULL_TREE) + { + tree parm_max; + tree arg_max; + bool parm_cst; + bool arg_cst; + + /* Our representation of array types uses "N - 1" as the + TYPE_MAX_VALUE for an array with "N" elements, if "N" is + not an integer constant. We cannot unify arbitrarily + complex expressions, so we eliminate the MINUS_EXPRs + here. */ + parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm)); + parm_cst = TREE_CODE (parm_max) == INTEGER_CST; + if (!parm_cst) + { + gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR); + parm_max = TREE_OPERAND (parm_max, 0); + } + arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg)); + arg_cst = TREE_CODE (arg_max) == INTEGER_CST; + if (!arg_cst) + { + /* The ARG_MAX may not be a simple MINUS_EXPR, if we are + trying to unify the type of a variable with the type + of a template parameter. For example: + + template <unsigned int N> + void f (char (&) [N]); + int g(); + void h(int i) { + char a[g(i)]; + f(a); + } + + Here, the type of the ARG will be "int [g(i)]", and + may be a SAVE_EXPR, etc. */ + if (TREE_CODE (arg_max) != MINUS_EXPR) + return 1; + arg_max = TREE_OPERAND (arg_max, 0); + } + + /* If only one of the bounds used a MINUS_EXPR, compensate + by adding one to the other bound. */ + if (parm_cst && !arg_cst) + parm_max = fold_build2 (PLUS_EXPR, + integer_type_node, + parm_max, + integer_one_node); + else if (arg_cst && !parm_cst) + arg_max = fold_build2 (PLUS_EXPR, + integer_type_node, + arg_max, + integer_one_node); + + if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER)) + return 1; + } return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), strict & UNIFY_ALLOW_MORE_CV_QUAL); @@ -10035,22 +10763,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) if (TREE_CODE (arg) != TREE_CODE (parm)) return 1; - if (TREE_CODE (parm) == INTEGER_TYPE - && TREE_CODE (TYPE_MAX_VALUE (parm)) != INTEGER_CST) - { - if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) - && unify (tparms, targs, TYPE_MIN_VALUE (parm), - TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER)) - return 1; - if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg) - && unify (tparms, targs, TYPE_MAX_VALUE (parm), - TYPE_MAX_VALUE (arg), - UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION)) - return 1; - } /* We have already checked cv-qualification at the top of the function. */ - else if (!same_type_ignoring_top_level_qualifiers_p (arg, parm)) + if (!same_type_ignoring_top_level_qualifiers_p (arg, parm)) return 1; /* As far as unification is concerned, this wins. Later checks @@ -10086,13 +10801,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) case UNION_TYPE: if (TREE_CODE (arg) != TREE_CODE (parm)) return 1; - + if (TYPE_PTRMEMFUNC_P (parm)) { if (!TYPE_PTRMEMFUNC_P (arg)) return 1; - return unify (tparms, targs, + return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm), TYPE_PTRMEMFUNC_FN_TYPE (arg), strict); @@ -10112,22 +10827,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) { /* Fallback to the special case allowed in [temp.deduct.call]: - + If P is a class, and P has the form template-id, then A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form template-id, A can be a pointer to a derived class pointed to by the deduced A. */ - t = get_template_base (tparms, targs, - parm, arg); + t = get_template_base (tparms, targs, parm, arg); - if (! t || t == error_mark_node) + if (!t) return 1; } } - else if (CLASSTYPE_TEMPLATE_INFO (arg) - && (CLASSTYPE_TI_TEMPLATE (parm) + else if (CLASSTYPE_TEMPLATE_INFO (arg) + && (CLASSTYPE_TI_TEMPLATE (parm) == CLASSTYPE_TI_TEMPLATE (arg))) /* Perhaps PARM is something like S<U> and ARG is S<int>. Then, we should unify `int' and `U'. */ @@ -10148,14 +10862,56 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) if (TREE_CODE (arg) != TREE_CODE (parm)) return 1; + /* CV qualifications for methods can never be deduced, they must + match exactly. We need to check them explicitly here, + because type_unification_real treats them as any other + cvqualified parameter. */ + if (TREE_CODE (parm) == METHOD_TYPE + && (!check_cv_quals_for_unify + (UNIFY_ALLOW_NONE, + TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))), + TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm)))))) + return 1; + if (unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), UNIFY_ALLOW_NONE)) return 1; return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), - TYPE_ARG_TYPES (arg), 1, - DEDUCE_EXACT, 0, -1); + TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT, + LOOKUP_NORMAL); case OFFSET_TYPE: + /* Unify a pointer to member with a pointer to member function, which + deduces the type of the member as a function type. */ + if (TYPE_PTRMEMFUNC_P (arg)) + { + tree method_type; + tree fntype; + cp_cv_quals cv_quals; + + /* Check top-level cv qualifiers */ + if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm)) + return 1; + + if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), + TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE)) + return 1; + + /* Determine the type of the function we are unifying against. */ + method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg)); + fntype = + build_function_type (TREE_TYPE (method_type), + TREE_CHAIN (TYPE_ARG_TYPES (method_type))); + + /* Extract the cv-qualifiers of the member function from the + implicit object parameter and place them on the function + type to be restored later. */ + cv_quals = + cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type)))); + fntype = build_qualified_type (fntype, cv_quals); + return unify (tparms, targs, TREE_TYPE (parm), fntype, strict); + } + if (TREE_CODE (arg) != OFFSET_TYPE) return 1; if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), @@ -10167,7 +10923,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) case CONST_DECL: if (DECL_TEMPLATE_PARM_P (parm)) return unify (tparms, targs, DECL_INITIAL (parm), arg, strict); - if (arg != decl_constant_value (parm)) + if (arg != integral_constant_value (parm)) return 1; return 0; @@ -10176,76 +10932,55 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) /* Matched cases are handled by the ARG == PARM test above. */ return 1; - case MINUS_EXPR: - if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node) - && (strict_in & UNIFY_ALLOW_MAX_CORRECTION)) - { - /* We handle this case specially, since it comes up with - arrays. In particular, something like: - - template <int N> void f(int (&x)[N]); + default: + gcc_assert (EXPR_P (parm)); - Here, we are trying to unify the range type, which - looks like [0 ... (N - 1)]. */ - tree t, t1, t2; - t1 = TREE_OPERAND (parm, 0); - t2 = TREE_OPERAND (parm, 1); + /* We must be looking at an expression. This can happen with + something like: - t = fold (build (PLUS_EXPR, integer_type_node, arg, t2)); + template <int I> + void foo(S<I>, S<I + 2>); - return unify (tparms, targs, t1, t, strict); - } - /* Else fall through. */ + This is a "nondeduced context": - default: - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm)))) - { + [deduct.type] - /* We're looking at an expression. This can happen with - something like: - - template <int I> - void foo(S<I>, S<I + 2>); + The nondeduced contexts are: - This is a "nondeduced context": + --A type that is a template-id in which one or more of + the template-arguments is an expression that references + a template-parameter. - [deduct.type] - - The nondeduced contexts are: + In these cases, we assume deduction succeeded, but don't + actually infer any unifications. */ - --A type that is a template-id in which one or more of - the template-arguments is an expression that references - a template-parameter. - - In these cases, we assume deduction succeeded, but don't - actually infer any unifications. */ - - if (!uses_template_parms (parm) - && !template_args_equal (parm, arg)) - return 1; - else - return 0; - } - sorry ("use of `%s' in template type unification", - tree_code_name [(int) TREE_CODE (parm)]); - return 1; + if (!uses_template_parms (parm) + && !template_args_equal (parm, arg)) + return 1; + else + return 0; } } +/* Note that DECL can be defined in this translation unit, if + required. */ + +static void +mark_definable (tree decl) +{ + tree clone; + DECL_NOT_REALLY_EXTERN (decl) = 1; + FOR_EACH_CLONE (clone, decl) + DECL_NOT_REALLY_EXTERN (clone) = 1; +} + /* Called if RESULT is explicitly instantiated, or is a member of an - explicitly instantiated class, or if using -frepo and the - instantiation of RESULT has been assigned to this file. */ + explicitly instantiated class. */ void mark_decl_instantiated (tree result, int extern_p) { - /* We used to set this unconditionally; we moved that to - do_decl_instantiation so it wouldn't get set on members of - explicit class template instantiations. But we still need to set - it here for the 'extern template' case in order to suppress - implicit instantiations. */ - if (extern_p) - SET_DECL_EXPLICIT_INSTANTIATION (result); + SET_DECL_EXPLICIT_INSTANTIATION (result); /* If this entity has already been written out, it's too late to make any modifications. */ @@ -10260,11 +10995,11 @@ mark_decl_instantiated (tree result, int extern_p) /* This might have been set by an earlier implicit instantiation. */ DECL_COMDAT (result) = 0; - if (! extern_p) + if (extern_p) + DECL_NOT_REALLY_EXTERN (result) = 0; + else { - DECL_INTERFACE_KNOWN (result) = 1; - DECL_NOT_REALLY_EXTERN (result) = 1; - + mark_definable (result); /* Always make artificials weak. */ if (DECL_ARTIFICIAL (result) && flag_weak) comdat_linkage (result); @@ -10274,71 +11009,227 @@ mark_decl_instantiated (tree result, int extern_p) maybe_make_one_only (result); } - if (TREE_CODE (result) == FUNCTION_DECL) - defer_fn (result); + /* If EXTERN_P, then this function will not be emitted -- unless + followed by an explicit instantiation, at which point its linkage + will be adjusted. If !EXTERN_P, then this function will be + emitted here. In neither circumstance do we want + import_export_decl to adjust the linkage. */ + DECL_INTERFACE_KNOWN (result) = 1; } /* Given two function templates PAT1 and PAT2, return: - DEDUCE should be DEDUCE_EXACT or DEDUCE_ORDER. - 1 if PAT1 is more specialized than PAT2 as described in [temp.func.order]. -1 if PAT2 is more specialized than PAT1. 0 if neither is more specialized. - LEN is passed through to fn_type_unification. */ - + LEN indicates the number of parameters we should consider + (defaulted parameters should not be considered). + + The 1998 std underspecified function template partial ordering, and + DR214 addresses the issue. We take pairs of arguments, one from + each of the templates, and deduce them against each other. One of + the templates will be more specialized if all the *other* + template's arguments deduce against its arguments and at least one + of its arguments *does* *not* deduce against the other template's + corresponding argument. Deduction is done as for class templates. + The arguments used in deduction have reference and top level cv + qualifiers removed. Iff both arguments were originally reference + types *and* deduction succeeds in both directions, the template + with the more cv-qualified argument wins for that pairing (if + neither is more cv-qualified, they both are equal). Unlike regular + deduction, after all the arguments have been deduced in this way, + we do *not* verify the deduced template argument values can be + substituted into non-deduced contexts, nor do we have to verify + that all template arguments have been deduced. */ + int -more_specialized (tree pat1, tree pat2, int deduce, int len) -{ - tree targs; - int winner = 0; +more_specialized_fn (tree pat1, tree pat2, int len) +{ + tree decl1 = DECL_TEMPLATE_RESULT (pat1); + tree decl2 = DECL_TEMPLATE_RESULT (pat2); + tree targs1 = make_tree_vec (DECL_NTPARMS (pat1)); + tree targs2 = make_tree_vec (DECL_NTPARMS (pat2)); + tree tparms1 = DECL_INNERMOST_TEMPLATE_PARMS (pat1); + tree tparms2 = DECL_INNERMOST_TEMPLATE_PARMS (pat2); + tree args1 = TYPE_ARG_TYPES (TREE_TYPE (decl1)); + tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2)); + int better1 = 0; + int better2 = 0; + + /* Remove the this parameter from non-static member functions. If + one is a non-static member function and the other is not a static + member function, remove the first parameter from that function + also. This situation occurs for operator functions where we + locate both a member function (with this pointer) and non-member + operator (with explicit first operand). */ + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1)) + { + len--; /* LEN is the number of significant arguments for DECL1 */ + args1 = TREE_CHAIN (args1); + if (!DECL_STATIC_FUNCTION_P (decl2)) + args2 = TREE_CHAIN (args2); + } + else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) + { + args2 = TREE_CHAIN (args2); + if (!DECL_STATIC_FUNCTION_P (decl1)) + { + len--; + args1 = TREE_CHAIN (args1); + } + } - /* If template argument deduction succeeds, we substitute the - resulting arguments into non-deduced contexts. While doing that, - we must be aware that we may encounter dependent types. */ - ++processing_template_decl; - targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2), - NULL_TREE, 0, deduce, len); - if (targs) - --winner; + /* If only one is a conversion operator, they are unordered. */ + if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2)) + return 0; - targs = get_bindings_real (pat2, DECL_TEMPLATE_RESULT (pat1), - NULL_TREE, 0, deduce, len); - if (targs) - ++winner; - --processing_template_decl; + /* Consider the return type for a conversion function */ + if (DECL_CONV_FN_P (decl1)) + { + args1 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl1)), args1); + args2 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl2)), args2); + len++; + } - return winner; + processing_template_decl++; + + while (len--) + { + tree arg1 = TREE_VALUE (args1); + tree arg2 = TREE_VALUE (args2); + int deduce1, deduce2; + int quals1 = -1; + int quals2 = -1; + + if (TREE_CODE (arg1) == REFERENCE_TYPE) + { + arg1 = TREE_TYPE (arg1); + quals1 = cp_type_quals (arg1); + } + + if (TREE_CODE (arg2) == REFERENCE_TYPE) + { + arg2 = TREE_TYPE (arg2); + quals2 = cp_type_quals (arg2); + } + + if ((quals1 < 0) != (quals2 < 0)) + { + /* Only of the args is a reference, see if we should apply + array/function pointer decay to it. This is not part of + DR214, but is, IMHO, consistent with the deduction rules + for the function call itself, and with our earlier + implementation of the underspecified partial ordering + rules. (nathan). */ + if (quals1 >= 0) + { + switch (TREE_CODE (arg1)) + { + case ARRAY_TYPE: + arg1 = TREE_TYPE (arg1); + /* FALLTHROUGH. */ + case FUNCTION_TYPE: + arg1 = build_pointer_type (arg1); + break; + + default: + break; + } + } + else + { + switch (TREE_CODE (arg2)) + { + case ARRAY_TYPE: + arg2 = TREE_TYPE (arg2); + /* FALLTHROUGH. */ + case FUNCTION_TYPE: + arg2 = build_pointer_type (arg2); + break; + + default: + break; + } + } + } + + arg1 = TYPE_MAIN_VARIANT (arg1); + arg2 = TYPE_MAIN_VARIANT (arg2); + + deduce1 = !unify (tparms1, targs1, arg1, arg2, UNIFY_ALLOW_NONE); + deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE); + + if (!deduce1) + better2 = -1; + if (!deduce2) + better1 = -1; + if (better1 < 0 && better2 < 0) + /* We've failed to deduce something in either direction. + These must be unordered. */ + break; + + if (deduce1 && deduce2 && quals1 >= 0 && quals2 >= 0) + { + /* Deduces in both directions, see if quals can + disambiguate. Pretend the worse one failed to deduce. */ + if ((quals1 & quals2) == quals2) + deduce1 = 0; + if ((quals1 & quals2) == quals1) + deduce2 = 0; + } + if (deduce1 && !deduce2 && !better2) + better2 = 1; + if (deduce2 && !deduce1 && !better1) + better1 = 1; + + args1 = TREE_CHAIN (args1); + args2 = TREE_CHAIN (args2); + } + + processing_template_decl--; + + return (better1 > 0) - (better2 > 0); } -/* Given two class template specialization list nodes PAT1 and PAT2, return: +/* Determine which of two partial specializations is more specialized. - 1 if PAT1 is more specialized than PAT2 as described in [temp.class.order]. - -1 if PAT2 is more specialized than PAT1. - 0 if neither is more specialized. + PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding + to the first partial specialization. The TREE_VALUE is the + innermost set of template parameters for the partial + specialization. PAT2 is similar, but for the second template. - FULL_ARGS is the full set of template arguments that triggers this - partial ordering. */ - -int -more_specialized_class (tree pat1, tree pat2, tree full_args) + Return 1 if the first partial specialization is more specialized; + -1 if the second is more specialized; 0 if neither is more + specialized. + + See [temp.class.order] for information about determining which of + two templates is more specialized. */ + +static int +more_specialized_class (tree pat1, tree pat2) { tree targs; + tree tmpl1, tmpl2; int winner = 0; - /* Just like what happens for functions, if we are ordering between + tmpl1 = TREE_TYPE (pat1); + tmpl2 = TREE_TYPE (pat2); + + /* Just like what happens for functions, if we are ordering between different class template specializations, we may encounter dependent types in the arguments, and we need our dependency check functions to behave correctly. */ ++processing_template_decl; - targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1), - add_outermost_template_args (full_args, TREE_PURPOSE (pat2))); + targs = get_class_bindings (TREE_VALUE (pat1), + CLASSTYPE_TI_ARGS (tmpl1), + CLASSTYPE_TI_ARGS (tmpl2)); if (targs) --winner; - targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2), - add_outermost_template_args (full_args, TREE_PURPOSE (pat1))); + targs = get_class_bindings (TREE_VALUE (pat2), + CLASSTYPE_TI_ARGS (tmpl2), + CLASSTYPE_TI_ARGS (tmpl1)); if (targs) ++winner; --processing_template_decl; @@ -10348,23 +11239,17 @@ more_specialized_class (tree pat1, tree pat2, tree full_args) /* Return the template arguments that will produce the function signature DECL from the function template FN, with the explicit template - arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must + arguments EXPLICIT_ARGS. If CHECK_RETTYPE is true, the return type must also match. Return NULL_TREE if no satisfactory arguments could be - found. DEDUCE and LEN are passed through to fn_type_unification. */ - + found. */ + static tree -get_bindings_real (tree fn, - tree decl, - tree explicit_args, - int check_rettype, - int deduce, - int len) +get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) { int ntparms = DECL_NTPARMS (fn); tree targs = make_tree_vec (ntparms); tree decl_type; tree decl_arg_types; - int i; /* Substitute the explicit template arguments into the type of DECL. The call to fn_type_unification will handle substitution into the @@ -10382,55 +11267,37 @@ get_bindings_real (tree fn, return NULL_TREE; converted_args - = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - explicit_args, NULL_TREE, - tf_none, /*require_all_arguments=*/0)); + = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), + explicit_args, NULL_TREE, + tf_none, + /*require_all_args=*/false, + /*use_default_args=*/false); if (converted_args == error_mark_node) return NULL_TREE; - - decl_type = tsubst (decl_type, converted_args, tf_none, NULL_TREE); + + decl_type = tsubst (decl_type, converted_args, tf_none, NULL_TREE); if (decl_type == error_mark_node) return NULL_TREE; } - decl_arg_types = TYPE_ARG_TYPES (decl_type); /* Never do unification on the 'this' parameter. */ - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) - decl_arg_types = TREE_CHAIN (decl_arg_types); + decl_arg_types = skip_artificial_parms_for (decl, + TYPE_ARG_TYPES (decl_type)); - i = fn_type_unification (fn, explicit_args, targs, + if (fn_type_unification (fn, explicit_args, targs, decl_arg_types, (check_rettype || DECL_CONV_FN_P (fn) - ? TREE_TYPE (decl_type) : NULL_TREE), - deduce, len); - - if (i != 0) + ? TREE_TYPE (decl_type) : NULL_TREE), + DEDUCE_EXACT, LOOKUP_NORMAL)) return NULL_TREE; return targs; } -/* For most uses, we want to check the return type. */ - -static tree -get_bindings (tree fn, tree decl, tree explicit_args) -{ - return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1); -} - -/* But for resolve_overloaded_unification, we only care about the parameter - types. */ - -static tree -get_bindings_overload (tree fn, tree decl, tree explicit_args) -{ - return get_bindings_real (fn, decl, explicit_args, 0, DEDUCE_EXACT, -1); -} - /* Return the innermost template arguments that, when applied to a template specialization whose innermost template parameters are TPARMS, and whose specialization arguments are PARMS, yield the - ARGS. + ARGS. For example, suppose we have: @@ -10438,96 +11305,128 @@ get_bindings_overload (tree fn, tree decl, tree explicit_args) template <class T> struct S<T*, int> {}; Then, suppose we want to get `S<double*, int>'. The TPARMS will be - {T}, the PARMS will be {T*, int} and the ARGS will be {double*, + {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*, int}. The resulting vector will be {double}, indicating that `T' is bound to `double'. */ static tree -get_class_bindings (tree tparms, tree parms, tree args) +get_class_bindings (tree tparms, tree spec_args, tree args) { int i, ntparms = TREE_VEC_LENGTH (tparms); - tree vec = make_tree_vec (ntparms); + tree deduced_args; + tree innermost_deduced_args; - if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args), - UNIFY_ALLOW_NONE)) + innermost_deduced_args = make_tree_vec (ntparms); + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) + { + deduced_args = copy_node (args); + SET_TMPL_ARGS_LEVEL (deduced_args, + TMPL_ARGS_DEPTH (deduced_args), + innermost_deduced_args); + } + else + deduced_args = innermost_deduced_args; + + if (unify (tparms, deduced_args, + INNERMOST_TEMPLATE_ARGS (spec_args), + INNERMOST_TEMPLATE_ARGS (args), + UNIFY_ALLOW_NONE)) return NULL_TREE; for (i = 0; i < ntparms; ++i) - if (! TREE_VEC_ELT (vec, i)) + if (! TREE_VEC_ELT (innermost_deduced_args, i)) return NULL_TREE; - if (verify_class_unification (vec, parms, args)) + /* Verify that nondeduced template arguments agree with the type + obtained from argument deduction. + + For example: + + struct A { typedef int X; }; + template <class T, class U> struct C {}; + template <class T> struct C<T, typename T::X> {}; + + Then with the instantiation `C<A, int>', we can deduce that + `T' is `A' but unify () does not check whether `typename T::X' + is `int'. */ + spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE); + if (spec_args == error_mark_node + /* We only need to check the innermost arguments; the other + arguments will always agree. */ + || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args), + INNERMOST_TEMPLATE_ARGS (args))) return NULL_TREE; - return vec; + return deduced_args; } -/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs. - Pick the most specialized template, and return the corresponding - instantiation, or if there is no corresponding instantiation, the - template itself. If there is no most specialized template, - error_mark_node is returned. If there are no templates at all, - NULL_TREE is returned. */ +/* TEMPLATES is a TREE_LIST. Each TREE_VALUE is a TEMPLATE_DECL. + Return the TREE_LIST node with the most specialized template, if + any. If there is no most specialized template, the error_mark_node + is returned. + + Note that this function does not look at, or modify, the + TREE_PURPOSE or TREE_TYPE of any of the nodes. Since the node + returned is one of the elements of INSTANTIATIONS, callers may + store information in the TREE_PURPOSE or TREE_TYPE of the nodes, + and retrieve it from the value returned. */ tree -most_specialized_instantiation (tree instantiations) +most_specialized_instantiation (tree templates) { tree fn, champ; - int fate; - if (!instantiations) - return NULL_TREE; + ++processing_template_decl; - champ = instantiations; - for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn)) + champ = templates; + for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn)) { - fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), - DEDUCE_EXACT, -1); - if (fate == 1) - ; - else + int fate = 0; + + if (get_bindings (TREE_VALUE (champ), + DECL_TEMPLATE_RESULT (TREE_VALUE (fn)), + NULL_TREE, /*check_ret=*/false)) + fate--; + + if (get_bindings (TREE_VALUE (fn), + DECL_TEMPLATE_RESULT (TREE_VALUE (champ)), + NULL_TREE, /*check_ret=*/false)) + fate++; + + if (fate == -1) + champ = fn; + else if (!fate) { - if (fate == 0) - { - fn = TREE_CHAIN (fn); - if (! fn) - return error_mark_node; - } + /* Equally specialized, move to next function. If there + is no next function, nothing's most specialized. */ + fn = TREE_CHAIN (fn); champ = fn; + if (!fn) + break; } } - for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn)) - { - fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), - DEDUCE_EXACT, -1); - if (fate != 1) - return error_mark_node; - } - - return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ); -} - -/* Return the most specialized of the list of templates in FNS that can - produce an instantiation matching DECL, given the explicit template - arguments EXPLICIT_ARGS. */ - -static tree -most_specialized (tree fns, tree decl, tree explicit_args) -{ - tree candidates = NULL_TREE; - tree fn, args; + if (champ) + /* Now verify that champ is better than everything earlier in the + instantiation list. */ + for (fn = templates; fn != champ; fn = TREE_CHAIN (fn)) + if (get_bindings (TREE_VALUE (champ), + DECL_TEMPLATE_RESULT (TREE_VALUE (fn)), + NULL_TREE, /*check_ret=*/false) + || !get_bindings (TREE_VALUE (fn), + DECL_TEMPLATE_RESULT (TREE_VALUE (champ)), + NULL_TREE, /*check_ret=*/false)) + { + champ = NULL_TREE; + break; + } - for (fn = fns; fn; fn = TREE_CHAIN (fn)) - { - tree candidate = TREE_VALUE (fn); + processing_template_decl--; - args = get_bindings (candidate, decl, explicit_args); - if (args) - candidates = tree_cons (NULL_TREE, candidate, candidates); - } + if (!champ) + return error_mark_node; - return most_specialized_instantiation (candidates); + return champ; } /* If DECL is a specialization of some template, return the most @@ -10588,26 +11487,42 @@ most_general_template (tree decl) return decl; } -/* Return the most specialized of the class template specializations - of TMPL which can produce an instantiation matching ARGS, or - error_mark_node if the choice is ambiguous. */ +/* Return the most specialized of the class template partial + specializations of TMPL which can produce TYPE, a specialization of + TMPL. The value returned is actually a TREE_LIST; the TREE_TYPE is + a _TYPE node corresponding to the partial specialization, while the + TREE_PURPOSE is the set of template arguments that must be + substituted into the TREE_TYPE in order to generate TYPE. + + If the choice of partial specialization is ambiguous, a diagnostic + is issued, and the error_mark_node is returned. If there are no + partial specializations of TMPL matching TYPE, then NULL_TREE is + returned. */ static tree -most_specialized_class (tree tmpl, tree args) +most_specialized_class (tree type, tree tmpl) { tree list = NULL_TREE; tree t; tree champ; int fate; + bool ambiguous_p; + tree args; tmpl = most_general_template (tmpl); + args = CLASSTYPE_TI_ARGS (type); for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t)) { - tree spec_args - = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args); + tree partial_spec_args; + tree spec_args; + + partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t)); + spec_args = get_class_bindings (TREE_VALUE (t), + partial_spec_args, + args); if (spec_args) { - list = tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list); + list = tree_cons (spec_args, TREE_VALUE (t), list); TREE_TYPE (list) = TREE_TYPE (t); } } @@ -10615,12 +11530,13 @@ most_specialized_class (tree tmpl, tree args) if (! list) return NULL_TREE; + ambiguous_p = false; t = list; champ = t; t = TREE_CHAIN (t); for (; t; t = TREE_CHAIN (t)) { - fate = more_specialized_class (champ, t, args); + fate = more_specialized_class (champ, t); if (fate == 1) ; else @@ -10629,17 +11545,36 @@ most_specialized_class (tree tmpl, tree args) { t = TREE_CHAIN (t); if (! t) - return error_mark_node; + { + ambiguous_p = true; + break; + } } champ = t; } } - for (t = list; t && t != champ; t = TREE_CHAIN (t)) + if (!ambiguous_p) + for (t = list; t && t != champ; t = TREE_CHAIN (t)) + { + fate = more_specialized_class (champ, t); + if (fate != 1) + { + ambiguous_p = true; + break; + } + } + + if (ambiguous_p) { - fate = more_specialized_class (champ, t, args); - if (fate != 1) - return error_mark_node; + const char *str = "candidates are:"; + error ("ambiguous class template instantiation for %q#T", type); + for (t = list; t; t = TREE_CHAIN (t)) + { + error ("%s %+#T", str, TREE_TYPE (t)); + str = " "; + } + return error_mark_node; } return champ; @@ -10653,13 +11588,13 @@ do_decl_instantiation (tree decl, tree storage) tree result = NULL_TREE; int extern_p = 0; - if (!decl) + if (!decl || decl == error_mark_node) /* An error occurred, for which grokdeclarator has already issued an appropriate message. */ return; else if (! DECL_LANG_SPECIFIC (decl)) { - error ("explicit instantiation of non-template `%#D'", decl); + error ("explicit instantiation of non-template %q#D", decl); return; } else if (TREE_CODE (decl) == VAR_DECL) @@ -10675,13 +11610,13 @@ do_decl_instantiation (tree decl, tree storage) result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false); if (!result || TREE_CODE (result) != VAR_DECL) { - error ("no matching template for `%D' found", decl); + error ("no matching template for %qD found", decl); return; } } else if (TREE_CODE (decl) != FUNCTION_DECL) { - error ("explicit instantiation of `%#D'", decl); + error ("explicit instantiation of %q#D", decl); return; } else @@ -10711,27 +11646,26 @@ do_decl_instantiation (tree decl, tree storage) /* [temp.spec] No program shall explicitly instantiate any template more - than once. - - We check DECL_INTERFACE_KNOWN so as not to complain when the first - instantiation was `extern' and the second is not, and EXTERN_P for - the opposite case. If -frepo, chances are we already got marked - as an explicit instantiation because of the repo file. */ - if (DECL_INTERFACE_KNOWN (result) && !extern_p && !flag_use_repository) - pedwarn ("duplicate explicit instantiation of `%#D'", result); - - /* If we've already instantiated the template, just return now. */ - if (DECL_INTERFACE_KNOWN (result)) + than once. + + We check DECL_NOT_REALLY_EXTERN so as not to complain when + the first instantiation was `extern' and the second is not, + and EXTERN_P for the opposite case. */ + if (DECL_NOT_REALLY_EXTERN (result) && !extern_p) + pedwarn ("duplicate explicit instantiation of %q#D", result); + /* If an "extern" explicit instantiation follows an ordinary + explicit instantiation, the template is instantiated. */ + if (extern_p) return; } else if (!DECL_IMPLICIT_INSTANTIATION (result)) { - error ("no matching template for `%D' found", result); + error ("no matching template for %qD found", result); return; } else if (!DECL_TEMPLATE_INFO (result)) { - pedwarn ("explicit instantiation of non-template `%#D'", result); + pedwarn ("explicit instantiation of non-template %q#D", result); return; } @@ -10740,21 +11674,21 @@ do_decl_instantiation (tree decl, tree storage) else if (storage == ridpointers[(int) RID_EXTERN]) { if (pedantic && !in_system_header) - pedwarn ("ISO C++ forbids the use of `extern' on explicit instantiations"); + pedwarn ("ISO C++ forbids the use of %<extern%> on explicit " + "instantiations"); extern_p = 1; } else - error ("storage class `%D' applied to template instantiation", - storage); + error ("storage class %qD applied to template instantiation", storage); - SET_DECL_EXPLICIT_INSTANTIATION (result); + check_explicit_instantiation_namespace (result); mark_decl_instantiated (result, extern_p); - repo_template_instantiated (result, extern_p); if (! extern_p) - instantiate_decl (result, /*defer_ok=*/1); + instantiate_decl (result, /*defer_ok=*/1, + /*expl_inst_class_mem_p=*/false); } -void +static void mark_class_instantiated (tree t, int extern_p) { SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t); @@ -10766,7 +11700,7 @@ mark_class_instantiated (tree t, int extern_p) CLASSTYPE_DEBUG_REQUESTED (t) = 1; rest_of_type_compilation (t, 1); } -} +} /* Called from do_type_instantiation through binding_table_foreach to do recursive instantiation for the type bound in ENTRY. */ @@ -10780,24 +11714,37 @@ bt_instantiate_type_proc (binding_entry entry, void *data) do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0); } +/* Called from do_type_instantiation to instantiate a member + (a member function or a static member variable) of an + explicitly instantiated class template. */ +static void +instantiate_class_member (tree decl, int extern_p) +{ + mark_decl_instantiated (decl, extern_p); + if (! extern_p) + instantiate_decl (decl, /*defer_ok=*/1, + /*expl_inst_class_mem_p=*/true); +} + /* Perform an explicit instantiation of template class T. STORAGE, if non-null, is the RID for extern, inline or static. COMPLAIN is nonzero if this is called from the parser, zero if called recursively, since the standard is unclear (as detailed below). */ - + void do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) { int extern_p = 0; int nomem_p = 0; int static_p = 0; + int previous_instantiation_extern_p = 0; if (TREE_CODE (t) == TYPE_DECL) t = TREE_TYPE (t); if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t)) { - error ("explicit instantiation of non-template type `%T'", t); + error ("explicit instantiation of non-template type %qT", t); return; } @@ -10806,16 +11753,16 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) if (!COMPLETE_TYPE_P (t)) { if (complain & tf_error) - error ("explicit instantiation of `%#T' before definition of template", - t); + error ("explicit instantiation of %q#T before definition of template", + t); return; } if (storage != NULL_TREE) { if (pedantic && !in_system_header) - pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations", - IDENTIFIER_POINTER (storage)); + pedwarn("ISO C++ forbids the use of %qE on explicit instantiations", + storage); if (storage == ridpointers[(int) RID_INLINE]) nomem_p = 1; @@ -10825,8 +11772,8 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) static_p = 1; else { - error ("storage class `%D' applied to template instantiation", - storage); + error ("storage class %qD applied to template instantiation", + storage); extern_p = 0; } } @@ -10850,23 +11797,24 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) /* [temp.spec] No program shall explicitly instantiate any template more - than once. + than once. + + If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit + instantiation was `extern'. If EXTERN_P then the second is. + These cases are OK. */ + previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t); - If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation - was `extern'. If EXTERN_P then the second is. If -frepo, chances - are we already got marked as an explicit instantiation because of the - repo file. All these cases are OK. */ - if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository + if (!previous_instantiation_extern_p && !extern_p && (complain & tf_error)) - pedwarn ("duplicate explicit instantiation of `%#T'", t); - + pedwarn ("duplicate explicit instantiation of %q#T", t); + /* If we've already instantiated the template, just return now. */ if (!CLASSTYPE_INTERFACE_ONLY (t)) return; } + check_explicit_instantiation_namespace (TYPE_NAME (t)); mark_class_instantiated (t, extern_p); - repo_template_instantiated (t, extern_p); if (nomem_p) return; @@ -10878,44 +11826,32 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) declarations, and not the definitions, of members are instantiated, we have here: - [temp.explicit] + [temp.explicit] The explicit instantiation of a class template specialization implies the instantiation of all of its members not previously explicitly specialized in the translation unit - containing the explicit instantiation. + containing the explicit instantiation. Of course, we can't instantiate member template classes, since we don't have any arguments for them. Note that the standard is unclear on whether the instantiation of the members are - *explicit* instantiations or not. We choose to be generous, - and not set DECL_EXPLICIT_INSTANTIATION. Therefore, we allow - the explicit instantiation of a class where some of the members - have no definition in the current translation unit. */ + *explicit* instantiations or not. However, the most natural + interpretation is that it should be an explicit instantiation. */ if (! static_p) for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) - { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp, /*defer_ok=*/1); - } + instantiate_class_member (tmp, extern_p); for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) - { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp, /*defer_ok=*/1); - } + instantiate_class_member (tmp, extern_p); if (CLASSTYPE_NESTED_UTDS (t)) binding_table_foreach (CLASSTYPE_NESTED_UTDS (t), - bt_instantiate_type_proc, &storage); + bt_instantiate_type_proc, &storage); } } @@ -10942,75 +11878,81 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain) static void regenerate_decl_from_template (tree decl, tree tmpl) { - /* The most general version of TMPL. */ - tree gen_tmpl; /* The arguments used to instantiate DECL, from the most general template. */ tree args; tree code_pattern; - tree new_decl; - bool unregistered; args = DECL_TI_ARGS (decl); code_pattern = DECL_TEMPLATE_RESULT (tmpl); - /* Unregister the specialization so that when we tsubst we will not - just return DECL. We don't have to unregister DECL from TMPL - because if would only be registered there if it were a partial - instantiation of a specialization, which it isn't: it's a full - instantiation. */ - gen_tmpl = most_general_template (tmpl); - unregistered = reregister_specialization (decl, gen_tmpl, - /*new_spec=*/NULL_TREE); - - /* If the DECL was not unregistered then something peculiar is - happening: we created a specialization but did not call - register_specialization for it. */ - my_friendly_assert (unregistered, 0); - /* Make sure that we can see identifiers, and compute access correctly. */ push_access_scope (decl); - /* Do the substitution to get the new declaration. */ - new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE); - - if (TREE_CODE (decl) == VAR_DECL) - { - /* Set up DECL_INITIAL, since tsubst doesn't. */ - if (!DECL_INITIALIZED_IN_CLASS_P (decl)) - DECL_INITIAL (new_decl) = - tsubst_expr (DECL_INITIAL (code_pattern), args, - tf_error, DECL_TI_TEMPLATE (decl)); - } - else if (TREE_CODE (decl) == FUNCTION_DECL) + if (TREE_CODE (decl) == FUNCTION_DECL) { - /* Convince duplicate_decls to use the DECL_ARGUMENTS from the - new decl. */ - DECL_INITIAL (new_decl) = error_mark_node; - /* And don't complain about a duplicate definition. */ - DECL_INITIAL (decl) = NULL_TREE; + tree decl_parm; + tree pattern_parm; + tree specs; + int args_depth; + int parms_depth; + + args_depth = TMPL_ARGS_DEPTH (args); + parms_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); + if (args_depth > parms_depth) + args = get_innermost_template_args (args, parms_depth); + + specs = tsubst_exception_specification (TREE_TYPE (code_pattern), + args, tf_error, NULL_TREE); + if (specs) + TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), + specs); + + /* Merge parameter declarations. */ + decl_parm = skip_artificial_parms_for (decl, + DECL_ARGUMENTS (decl)); + pattern_parm + = skip_artificial_parms_for (code_pattern, + DECL_ARGUMENTS (code_pattern)); + while (decl_parm) + { + tree parm_type; + tree attributes; + + if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm)) + DECL_NAME (decl_parm) = DECL_NAME (pattern_parm); + parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error, + NULL_TREE); + parm_type = type_decays_to (parm_type); + if (!same_type_p (TREE_TYPE (decl_parm), parm_type)) + TREE_TYPE (decl_parm) = parm_type; + attributes = DECL_ATTRIBUTES (pattern_parm); + if (DECL_ATTRIBUTES (decl_parm) != attributes) + { + DECL_ATTRIBUTES (decl_parm) = attributes; + cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0); + } + decl_parm = TREE_CHAIN (decl_parm); + pattern_parm = TREE_CHAIN (pattern_parm); + } + + /* Merge additional specifiers from the CODE_PATTERN. */ + if (DECL_DECLARED_INLINE_P (code_pattern) + && !DECL_DECLARED_INLINE_P (decl)) + DECL_DECLARED_INLINE_P (decl) = 1; + if (DECL_INLINE (code_pattern) && !DECL_INLINE (decl)) + DECL_INLINE (decl) = 1; } + else if (TREE_CODE (decl) == VAR_DECL) + DECL_INITIAL (decl) = + tsubst_expr (DECL_INITIAL (code_pattern), args, + tf_error, DECL_TI_TEMPLATE (decl), + /*integral_constant_expression_p=*/false); + else + gcc_unreachable (); pop_access_scope (decl); - - /* The immediate parent of the new template is still whatever it was - before, even though tsubst sets DECL_TI_TEMPLATE up as the most - general template. We also reset the DECL_ASSEMBLER_NAME since - tsubst always calculates the name as if the function in question - were really a template instance, and sometimes, with friend - functions, this is not so. See tsubst_friend_function for - details. */ - DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl); - COPY_DECL_ASSEMBLER_NAME (decl, new_decl); - COPY_DECL_RTL (decl, new_decl); - DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl); - - /* Call duplicate decls to merge the old and new declarations. */ - duplicate_decls (new_decl, decl); - - /* Now, re-register the specialization. */ - register_specialization (decl, gen_tmpl, args); } /* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be @@ -11025,9 +11967,9 @@ template_for_substitution (tree decl) for the instantiation. This is not always the most general template. Consider, for example: - template <class T> + template <class T> struct S { template <class U> void f(); - template <> void f<int>(); }; + template <> void f<int>(); }; and an instantiation of S<double>::f<int>. We want TD to be the specialization S<T>::f<int>, not the more general S<T>::f<U>. */ @@ -11036,7 +11978,7 @@ template_for_substitution (tree decl) DECL_TEMPLATE_INSTANTIATION (tmpl) /* We must also deal with friend templates. Given: - template <class T> struct S { + template <class T> struct S { template <class U> friend void f() {}; }; @@ -11045,7 +11987,7 @@ template_for_substitution (tree decl) where we get the pattern for the instantiation from. On other hand, if the definition comes outside the class, say: - template <class T> struct S { + template <class T> struct S { template <class U> friend void f(); }; template <class U> friend void f() {} @@ -11061,10 +12003,9 @@ template_for_substitution (tree decl) cannot restructure the loop to just keep going until we find a template with a definition, since that might go too far if a specialization was declared, but not defined. */ - my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL - && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))), - 0); - + gcc_assert (TREE_CODE (decl) != VAR_DECL + || DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))); + /* Fetch the more general template. */ tmpl = DECL_TI_TEMPLATE (tmpl); } @@ -11074,10 +12015,14 @@ template_for_substitution (tree decl) /* Produce the definition of D, a _DECL generated from a template. If DEFER_OK is nonzero, then we don't have to actually do the - instantiation now; we just have to do it sometime. */ + instantiation now; we just have to do it sometime. Normally it is + an error if this is an explicit instantiation but D is undefined. + EXPL_INST_CLASS_MEM_P is true iff D is a member of an + explicitly instantiated class template. */ tree -instantiate_decl (tree d, int defer_ok) +instantiate_decl (tree d, int defer_ok, + bool expl_inst_class_mem_p) { tree tmpl = DECL_TI_TEMPLATE (d); tree gen_args; @@ -11086,14 +12031,16 @@ instantiate_decl (tree d, int defer_ok) tree code_pattern; tree spec; tree gen_tmpl; - int pattern_defined; + bool pattern_defined; int need_push; location_t saved_loc = input_location; - + int saved_in_system_header = in_system_header; + bool external_p; + /* This function should only be used to instantiate templates for functions and static member variables. */ - my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL - || TREE_CODE (d) == VAR_DECL, 0); + gcc_assert (TREE_CODE (d) == FUNCTION_DECL + || TREE_CODE (d) == VAR_DECL); /* Variables are never deferred; if instantiation is required, they are instantiated right away. That allows for better code in the @@ -11123,7 +12070,8 @@ instantiate_decl (tree d, int defer_ok) DECL_TEMPLATE_SPECIALIZATION. */ gen_tmpl = most_general_template (tmpl); gen_args = DECL_TI_ARGS (d); - spec = retrieve_specialization (gen_tmpl, gen_args); + spec = retrieve_specialization (gen_tmpl, gen_args, + /*class_specializations_p=*/false); if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec)) return spec; @@ -11133,14 +12081,15 @@ instantiate_decl (tree d, int defer_ok) timevar_push (TV_PARSE); - /* We may be in the middle of deferred access check. Disable it now. */ - push_deferring_access_checks (dk_no_deferred); - /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern for the instantiation. */ td = template_for_substitution (d); code_pattern = DECL_TEMPLATE_RESULT (td); + /* We should never be trying to instantiate a member of a class + template or partial specialization. */ + gcc_assert (d != code_pattern); + if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d)) || DECL_TEMPLATE_SPECIALIZATION (td)) /* In the case of a friend template whose definition is provided @@ -11156,32 +12105,29 @@ instantiate_decl (tree d, int defer_ok) else pattern_defined = ! DECL_IN_AGGR_P (code_pattern); - input_location = DECL_SOURCE_LOCATION (d); - - if (pattern_defined) - { - /* Let the repository code that this template definition is - available. + /* We may be in the middle of deferred access check. Disable it now. */ + push_deferring_access_checks (dk_no_deferred); - The repository doesn't need to know about cloned functions - because they never actually show up in the object file. It - does need to know about the clones; those are the symbols - that the linker will be emitting error messages about. */ - if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (d) - || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (d)) - { - tree t; + /* Unless an explicit instantiation directive has already determined + the linkage of D, remember that a definition is available for + this entity. */ + if (pattern_defined + && !DECL_INTERFACE_KNOWN (d) + && !DECL_NOT_REALLY_EXTERN (d)) + mark_definable (d); - for (t = TREE_CHAIN (d); - t && DECL_CLONED_FUNCTION_P (t); - t = TREE_CHAIN (t)) - repo_template_used (t); - } - else - repo_template_used (d); + input_location = DECL_SOURCE_LOCATION (d); + in_system_header = DECL_IN_SYSTEM_HEADER (d); - if (at_eof) - import_export_decl (d); + /* If D is a member of an explicitly instantiated class template, + and no definition is available, treat it like an implicit + instantiation. */ + if (!pattern_defined && expl_inst_class_mem_p + && DECL_EXPLICIT_INSTANTIATION (d)) + { + DECL_NOT_REALLY_EXTERN (d) = 0; + DECL_INTERFACE_KNOWN (d) = 0; + SET_DECL_IMPLICIT_INSTANTIATION (d); } if (!defer_ok) @@ -11198,38 +12144,75 @@ instantiate_decl (tree d, int defer_ok) if (TREE_CODE (gen) == FUNCTION_DECL) { - tsubst (DECL_ARGUMENTS (gen), gen_args, tf_error | tf_warning, d); + tsubst (DECL_ARGUMENTS (gen), gen_args, tf_warning_or_error, d); tsubst (TYPE_RAISES_EXCEPTIONS (type), gen_args, - tf_error | tf_warning, d); + tf_warning_or_error, d); /* Don't simply tsubst the function type, as that will give duplicate warnings about poor parameter qualifications. The function arguments are the same as the decl_arguments without the top level cv qualifiers. */ type = TREE_TYPE (type); } - tsubst (type, gen_args, tf_error | tf_warning, d); + tsubst (type, gen_args, tf_warning_or_error, d); pop_access_scope (d); } - - if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d) - && DECL_INITIAL (d) == NULL_TREE) - /* We should have set up DECL_INITIAL in instantiate_class_template. */ - abort (); - /* Reject all external templates except inline functions. */ - else if (DECL_INTERFACE_KNOWN (d) - && ! DECL_NOT_REALLY_EXTERN (d) - && ! (TREE_CODE (d) == FUNCTION_DECL - && DECL_INLINE (d))) + + /* Check to see whether we know that this template will be + instantiated in some other file, as with "extern template" + extension. */ + external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d)); + /* In general, we do not instantiate such templates... */ + if (external_p + /* ... but we instantiate inline functions so that we can inline + them and ... */ + && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)) + /* ... we instantiate static data members whose values are + needed in integral constant expressions. */ + && ! (TREE_CODE (d) == VAR_DECL + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d))) goto out; /* Defer all other templates, unless we have been explicitly - forbidden from doing so. We restore the source position here - because it's used by add_pending_template. */ - else if (! pattern_defined || defer_ok) - { + forbidden from doing so. */ + if (/* If there is no definition, we cannot instantiate the + template. */ + ! pattern_defined + /* If it's OK to postpone instantiation, do so. */ + || defer_ok + /* If this is a static data member that will be defined + elsewhere, we don't want to instantiate the entire data + member, but we do want to instantiate the initializer so that + we can substitute that elsewhere. */ + || (external_p && TREE_CODE (d) == VAR_DECL)) + { + /* The definition of the static data member is now required so + we must substitute the initializer. */ + if (TREE_CODE (d) == VAR_DECL + && !DECL_INITIAL (d) + && DECL_INITIAL (code_pattern)) + { + tree ns; + tree init; + + ns = decl_namespace_context (d); + push_nested_namespace (ns); + push_nested_class (DECL_CONTEXT (d)); + init = tsubst_expr (DECL_INITIAL (code_pattern), + args, + tf_warning_or_error, NULL_TREE, + /*integral_constant_expression_p=*/false); + cp_finish_decl (d, init, /*init_const_expr_p=*/false, + /*asmspec_tree=*/NULL_TREE, + LOOKUP_ONLYCONVERTING); + pop_nested_class (); + pop_nested_namespace (ns); + } + + /* We restore the source position here because it's used by + add_pending_template. */ input_location = saved_loc; - if (at_eof && !pattern_defined + if (at_eof && !pattern_defined && DECL_EXPLICIT_INSTANTIATION (d)) /* [temp.explicit] @@ -11239,13 +12222,34 @@ instantiate_decl (tree d, int defer_ok) shall be present in every translation unit in which it is explicitly instantiated. */ pedwarn - ("explicit instantiation of `%D' but no definition available", d); + ("explicit instantiation of %qD but no definition available", d); - add_pending_template (d); + /* ??? Historically, we have instantiated inline functions, even + when marked as "extern template". */ + if (!(external_p && TREE_CODE (d) == VAR_DECL)) + add_pending_template (d); goto out; } + /* Tell the repository that D is available in this translation unit + -- and see if it is supposed to be instantiated here. */ + if (TREE_PUBLIC (d) && !DECL_REALLY_EXTERN (d) && !repo_emit_p (d)) + { + /* In a PCH file, despite the fact that the repository hasn't + requested instantiation in the PCH it is still possible that + an instantiation will be required in a file that includes the + PCH. */ + if (pch_file) + add_pending_template (d); + /* Instantiate inline functions so that the inliner can do its + job, even though we'll not be emitting a copy of this + function. */ + if (!(TREE_CODE (d) == FUNCTION_DECL + && flag_inline_trees + && DECL_DECLARED_INLINE_P (d))) + goto out; + } - need_push = !global_bindings_p (); + need_push = !cfun || !global_bindings_p (); if (need_push) push_to_top_level (); @@ -11256,64 +12260,36 @@ instantiate_decl (tree d, int defer_ok) /* Regenerate the declaration in case the template has been modified by a subsequent redeclaration. */ regenerate_decl_from_template (d, td); - + /* We already set the file and line above. Reset them now in case - they changed as a result of calling - regenerate_decl_from_template. */ + they changed as a result of calling regenerate_decl_from_template. */ input_location = DECL_SOURCE_LOCATION (d); if (TREE_CODE (d) == VAR_DECL) { + tree init; + /* Clear out DECL_RTL; whatever was there before may not be right since we've reset the type of the declaration. */ SET_DECL_RTL (d, NULL_RTX); - DECL_IN_AGGR_P (d) = 0; - import_export_decl (d); - DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d); - - if (DECL_EXTERNAL (d)) - { - /* The fact that this code is executing indicates that: - - (1) D is a template static data member, for which a - definition is available. - (2) An implicit or explicit instantiation has occurred. + /* The initializer is placed in DECL_INITIAL by + regenerate_decl_from_template. Pull it out so that + finish_decl can process it. */ + init = DECL_INITIAL (d); + DECL_INITIAL (d) = NULL_TREE; + DECL_INITIALIZED_P (d) = 0; - (3) We are not going to emit a definition of the static - data member at this time. + /* Clear DECL_EXTERNAL so that cp_finish_decl will process the + initializer. That function will defer actual emission until + we have a chance to determine linkage. */ + DECL_EXTERNAL (d) = 0; - This situation is peculiar, but it occurs on platforms - without weak symbols when performing an implicit - instantiation. There, we cannot implicitly instantiate a - defined static data member in more than one translation - unit, so import_export_decl marks the declaration as - external; we must rely on explicit instantiation. - - Reset instantiated marker to make sure that later - explicit instantiation will be processed. */ - DECL_TEMPLATE_INSTANTIATED (d) = 0; - } - else - { - /* This is done in analogous to `start_decl'. It is - required for correct access checking. */ - push_nested_class (DECL_CONTEXT (d)); - cp_finish_decl (d, - (!DECL_INITIALIZED_IN_CLASS_P (d) - ? DECL_INITIAL (d) : NULL_TREE), - NULL_TREE, 0); - /* Normally, pop_nested_class is called by cp_finish_decl - above. But when instantiate_decl is triggered during - instantiate_class_template processing, its DECL_CONTEXT - is still not completed yet, and pop_nested_class isn't - called. */ - if (!COMPLETE_TYPE_P (DECL_CONTEXT (d))) - pop_nested_class (); - } - /* We're not deferring instantiation any more. */ - TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0; + /* Enter the scope of D so that access-checking works correctly. */ + push_nested_class (DECL_CONTEXT (d)); + finish_decl (d, init, NULL_TREE); + pop_nested_class (); } else if (TREE_CODE (d) == FUNCTION_DECL) { @@ -11322,23 +12298,18 @@ instantiate_decl (tree d, int defer_ok) tree tmpl_parm; tree spec_parm; - /* Mark D as instantiated so that recursive calls to - instantiate_decl do not try to instantiate it again. */ - DECL_TEMPLATE_INSTANTIATED (d) = 1; - /* Save away the current list, in case we are instantiating one template from within the body of another. */ saved_local_specializations = local_specializations; /* Set up the list of local specializations. */ - local_specializations = htab_create (37, + local_specializations = htab_create (37, hash_local_specialization, eq_local_specializations, NULL); /* Set up context. */ - import_export_decl (d); - start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED); + start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED); /* Create substitution entries for the parameters. */ subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d)); @@ -11356,29 +12327,31 @@ instantiate_decl (tree d, int defer_ok) tmpl_parm = TREE_CHAIN (tmpl_parm); spec_parm = TREE_CHAIN (spec_parm); } - my_friendly_assert (!spec_parm, 20020813); + gcc_assert (!spec_parm); /* Substitute into the body of the function. */ tsubst_expr (DECL_SAVED_TREE (code_pattern), args, - tf_error | tf_warning, tmpl); + tf_warning_or_error, tmpl, + /*integral_constant_expression_p=*/false); /* We don't need the local specializations any more. */ htab_delete (local_specializations); local_specializations = saved_local_specializations; - /* We're not deferring instantiation any more. */ - TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0; - /* Finish the function. */ d = finish_function (0); expand_or_defer_fn (d); } + /* We're not deferring instantiation any more. */ + TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0; + if (need_push) pop_from_top_level (); out: input_location = saved_loc; + in_system_header = saved_in_system_header; pop_deferring_access_checks (); pop_tinst_level (); @@ -11388,18 +12361,36 @@ out: } /* Run through the list of templates that we wish we could - instantiate, and instantiate any we can. */ + instantiate, and instantiate any we can. RETRIES is the + number of times we retry pending template instantiation. */ -int -instantiate_pending_templates (void) +void +instantiate_pending_templates (int retries) { tree *t; tree last = NULL_TREE; - int instantiated_something = 0; int reconsider; location_t saved_loc = input_location; - - do + int saved_in_system_header = in_system_header; + + /* Instantiating templates may trigger vtable generation. This in turn + may require further template instantiations. We place a limit here + to avoid infinite loop. */ + if (pending_templates && retries >= max_tinst_depth) + { + tree decl = TREE_VALUE (pending_templates); + + error ("template instantiation depth exceeds maximum of %d" + " instantiating %q+D, possibly from virtual table generation" + " (use -ftemplate-depth-NN to increase the maximum)", + max_tinst_depth, decl); + if (TREE_CODE (decl) == FUNCTION_DECL) + /* Pretend that we defined it. */ + DECL_INITIAL (decl) = error_mark_node; + return; + } + + do { reconsider = 0; @@ -11418,16 +12409,15 @@ instantiate_pending_templates (void) { instantiate_class_template (instantiation); if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation)) - for (fn = TYPE_METHODS (instantiation); + for (fn = TYPE_METHODS (instantiation); fn; fn = TREE_CHAIN (fn)) if (! DECL_ARTIFICIAL (fn)) - instantiate_decl (fn, /*defer_ok=*/0); + instantiate_decl (fn, + /*defer_ok=*/0, + /*expl_inst_class_mem_p=*/false); if (COMPLETE_TYPE_P (instantiation)) - { - instantiated_something = 1; - reconsider = 1; - } + reconsider = 1; } if (COMPLETE_TYPE_P (instantiation)) @@ -11445,13 +12435,12 @@ instantiate_pending_templates (void) if (!DECL_TEMPLATE_SPECIALIZATION (instantiation) && !DECL_TEMPLATE_INSTANTIATED (instantiation)) { - instantiation = instantiate_decl (instantiation, - /*defer_ok=*/0); + instantiation + = instantiate_decl (instantiation, + /*defer_ok=*/0, + /*expl_inst_class_mem_p=*/false); if (DECL_TEMPLATE_INSTANTIATED (instantiation)) - { - instantiated_something = 1; - reconsider = 1; - } + reconsider = 1; } if (DECL_TEMPLATE_SPECIALIZATION (instantiation) @@ -11469,11 +12458,11 @@ instantiate_pending_templates (void) current_tinst_level = NULL_TREE; } last_pending_template = last; - } + } while (reconsider); input_location = saved_loc; - return instantiated_something; + in_system_header = saved_in_system_header; } /* Substitute ARGVEC into T, which is a list of initializers for @@ -11490,24 +12479,16 @@ tsubst_initializer_list (tree t, tree argvec) { tree decl; tree init; - tree val; - decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning, + decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_warning_or_error, NULL_TREE); decl = expand_member_init (decl); if (decl && !DECL_P (decl)) in_base_initializer = 1; - - init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning, - NULL_TREE); - if (!init) - ; - else if (TREE_CODE (init) == TREE_LIST) - for (val = init; val; val = TREE_CHAIN (val)) - TREE_VALUE (val) = convert_from_reference (TREE_VALUE (val)); - else if (init != void_type_node) - init = convert_from_reference (init); + init = tsubst_expr (TREE_VALUE (t), argvec, tf_warning_or_error, + NULL_TREE, + /*integral_constant_expression_p=*/false); in_base_initializer = 0; if (decl) @@ -11550,15 +12531,15 @@ tsubst_enum (tree tag, tree newtag, tree args) decl = TREE_VALUE (e); /* Note that in a template enum, the TREE_VALUE is the CONST_DECL, not the corresponding INTEGER_CST. */ - value = tsubst_expr (DECL_INITIAL (decl), - args, tf_error | tf_warning, - NULL_TREE); + value = tsubst_expr (DECL_INITIAL (decl), + args, tf_warning_or_error, NULL_TREE, + /*integral_constant_expression_p=*/true); /* Give this enumeration constant the correct access. */ set_current_access_from_decl (decl); /* Actually build the enumerator itself. */ - build_enumerator (DECL_NAME (decl), value, newtag); + build_enumerator (DECL_NAME (decl), value, newtag); } finish_enum (newtag); @@ -11571,7 +12552,7 @@ tsubst_enum (tree tag, tree newtag, tree args) arguments. So, innermost set of template parameters will appear in the type. */ -tree +tree get_mostly_instantiated_function_type (tree decl) { tree fn_type; @@ -11587,7 +12568,7 @@ get_mostly_instantiated_function_type (tree decl) /* There should be as many levels of arguments as there are levels of parameters. */ - my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0); + gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs)); fn_type = TREE_TYPE (tmpl); @@ -11596,7 +12577,7 @@ get_mostly_instantiated_function_type (tree decl) ; else { - int i; + int i, save_access_control; tree partial_args; /* Replace the innermost level of the TARGS with NULL_TREEs to @@ -11609,12 +12590,10 @@ get_mostly_instantiated_function_type (tree decl) TMPL_ARGS_DEPTH (targs), make_tree_vec (DECL_NTPARMS (tmpl))); - /* Make sure that we can see identifiers, and compute access - correctly. We can just use the context of DECL for the - partial substitution here. It depends only on outer template - parameters, regardless of whether the innermost level is - specialized or not. */ - push_access_scope (decl); + /* Disable access control as this function is used only during + name-mangling. */ + save_access_control = flag_access_control; + flag_access_control = 0; ++processing_template_decl; /* Now, do the (partial) substitution to figure out the @@ -11629,7 +12608,7 @@ get_mostly_instantiated_function_type (tree decl) TREE_VEC_LENGTH (partial_args)--; tparms = tsubst_template_parms (tparms, partial_args, tf_error); - pop_access_scope (decl); + flag_access_control = save_access_control; } return fn_type; @@ -11673,10 +12652,9 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain) return 0; else if (TREE_CODE (type) == TYPENAME_TYPE) return 0; - + if (complain & tf_error) - error ("`%#T' is not a valid type for a template constant parameter", - type); + error ("%q#T is not a valid type for a template constant parameter", type); return 1; } @@ -11692,24 +12670,24 @@ dependent_type_p_r (tree type) A type is dependent if it is: - -- a template parameter. Template template parameters are - types for us (since TYPE_P holds true for them) so we - handle them here. */ - if (TREE_CODE (type) == TEMPLATE_TYPE_PARM + -- a template parameter. Template template parameters are types + for us (since TYPE_P holds true for them) so we handle + them here. */ + if (TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) return true; /* -- a qualified-id with a nested-name-specifier which contains a - class-name that names a dependent type or whose unqualified-id + class-name that names a dependent type or whose unqualified-id names a dependent type. */ if (TREE_CODE (type) == TYPENAME_TYPE) return true; /* -- a cv-qualified type where the cv-unqualified type is - dependent. */ + dependent. */ type = TYPE_MAIN_VARIANT (type); /* -- a compound type constructed from any dependent type. */ if (TYPE_PTR_TO_MEMBER_P (type)) return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) - || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE + || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))); else if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE) @@ -11721,27 +12699,27 @@ dependent_type_p_r (tree type) if (dependent_type_p (TREE_TYPE (type))) return true; - for (arg_type = TYPE_ARG_TYPES (type); - arg_type; + for (arg_type = TYPE_ARG_TYPES (type); + arg_type; arg_type = TREE_CHAIN (arg_type)) if (dependent_type_p (TREE_VALUE (arg_type))) return true; return false; } /* -- an array type constructed from any dependent type or whose - size is specified by a constant expression that is + size is specified by a constant expression that is value-dependent. */ if (TREE_CODE (type) == ARRAY_TYPE) { if (TYPE_DOMAIN (type) - && ((value_dependent_expression_p + && ((value_dependent_expression_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) || (type_dependent_expression_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))))) return true; return dependent_type_p (TREE_TYPE (type)); } - + /* -- a template-id in which either the template name is a template parameter ... */ if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) @@ -11749,22 +12727,22 @@ dependent_type_p_r (tree type) /* ... or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent. */ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type) - && (any_dependent_template_arguments_p + && (any_dependent_template_arguments_p (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type))))) return true; - + /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof' expression is not type-dependent, then it should already been have resolved. */ if (TREE_CODE (type) == TYPEOF_TYPE) return true; - + /* The standard does not specifically mention types that are local to template functions or local classes, but they should be considered dependent too. For example: - template <int I> void f() { - enum E { a = I }; + template <int I> void f() { + enum E { a = I }; S<sizeof (E)> s; } @@ -11789,7 +12767,13 @@ dependent_type_p (tree type) /* If there are no template parameters in scope, then there can't be any dependent types. */ if (!processing_template_decl) - return false; + { + /* If we are not processing a template, then nobody should be + providing us with a dependent type. */ + gcc_assert (type); + gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM); + return false; + } /* If the type is NULL, we have not computed a type for the entity in question; in that case, the type is dependent. */ @@ -11819,7 +12803,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) tree scope; tree name; - my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714); + gcc_assert (TREE_CODE (expression) == SCOPE_REF); if (!TYPE_P (TREE_OPERAND (expression, 0))) return true; @@ -11835,7 +12819,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) /* The suggested resolution to Core Issue 2 implies that if the qualifying type is the current class, then we must peek inside it. */ - if (DECL_P (name) + if (DECL_P (name) && currently_open_class (scope) && !criterion (name)) return false; @@ -11846,7 +12830,8 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) } /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of - [temp.dep.constexpr] */ + [temp.dep.constexpr]. EXPRESSION is already known to be a constant + expression. */ bool value_dependent_expression_p (tree expression) @@ -11855,94 +12840,118 @@ value_dependent_expression_p (tree expression) return false; /* A name declared with a dependent type. */ - if (TREE_CODE (expression) == IDENTIFIER_NODE - || (DECL_P (expression) - && type_dependent_expression_p (expression))) + if (DECL_P (expression) && type_dependent_expression_p (expression)) return true; - /* A non-type template parameter. */ - if ((TREE_CODE (expression) == CONST_DECL - && DECL_TEMPLATE_PARM_P (expression)) - || TREE_CODE (expression) == TEMPLATE_PARM_INDEX) - return true; - /* A constant with integral or enumeration type and is initialized - with an expression that is value-dependent. */ - if (TREE_CODE (expression) == VAR_DECL - && DECL_INITIAL (expression) - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression)) - && value_dependent_expression_p (DECL_INITIAL (expression))) - return true; - /* These expressions are value-dependent if the type to which the - cast occurs is dependent or the expression being casted is - value-dependent. */ - if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR - || TREE_CODE (expression) == STATIC_CAST_EXPR - || TREE_CODE (expression) == CONST_CAST_EXPR - || TREE_CODE (expression) == REINTERPRET_CAST_EXPR - || TREE_CODE (expression) == CAST_EXPR) + + switch (TREE_CODE (expression)) { - tree type = TREE_TYPE (expression); - if (dependent_type_p (type)) + case IDENTIFIER_NODE: + /* A name that has not been looked up -- must be dependent. */ + return true; + + case TEMPLATE_PARM_INDEX: + /* A non-type template parm. */ + return true; + + case CONST_DECL: + /* A non-type template parm. */ + if (DECL_TEMPLATE_PARM_P (expression)) return true; - /* A functional cast has a list of operands. */ - expression = TREE_OPERAND (expression, 0); - if (!expression) - { - /* If there are no operands, it must be an expression such - as "int()". This should not happen for aggregate types - because it would form non-constant expressions. */ - my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type), - 20040318); + return false; - return false; - } - if (TREE_CODE (expression) == TREE_LIST) - { - do - { + case VAR_DECL: + /* A constant with integral or enumeration type and is initialized + with an expression that is value-dependent. */ + if (DECL_INITIAL (expression) + && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression)) + && value_dependent_expression_p (DECL_INITIAL (expression))) + return true; + return false; + + case DYNAMIC_CAST_EXPR: + case STATIC_CAST_EXPR: + case CONST_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CAST_EXPR: + /* These expressions are value-dependent if the type to which + the cast occurs is dependent or the expression being casted + is value-dependent. */ + { + tree type = TREE_TYPE (expression); + + if (dependent_type_p (type)) + return true; + + /* A functional cast has a list of operands. */ + expression = TREE_OPERAND (expression, 0); + if (!expression) + { + /* If there are no operands, it must be an expression such + as "int()". This should not happen for aggregate types + because it would form non-constant expressions. */ + gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type)); + + return false; + } + + if (TREE_CODE (expression) == TREE_LIST) + { + for (; expression; expression = TREE_CHAIN (expression)) if (value_dependent_expression_p (TREE_VALUE (expression))) return true; - expression = TREE_CHAIN (expression); - } - while (expression); - return false; - } - else + return false; + } + return value_dependent_expression_p (expression); - } - /* A `sizeof' expression is value-dependent if the operand is - type-dependent. */ - if (TREE_CODE (expression) == SIZEOF_EXPR - || TREE_CODE (expression) == ALIGNOF_EXPR) - { + } + + case SIZEOF_EXPR: + case ALIGNOF_EXPR: + /* A `sizeof' expression is value-dependent if the operand is + type-dependent. */ expression = TREE_OPERAND (expression, 0); if (TYPE_P (expression)) return dependent_type_p (expression); return type_dependent_expression_p (expression); - } - if (TREE_CODE (expression) == SCOPE_REF) - return dependent_scope_ref_p (expression, value_dependent_expression_p); - if (TREE_CODE (expression) == COMPONENT_REF) - return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) - || value_dependent_expression_p (TREE_OPERAND (expression, 1))); - /* A constant expression is value-dependent if any subexpression is - value-dependent. */ - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression)))) - { + + case SCOPE_REF: + return dependent_scope_ref_p (expression, value_dependent_expression_p); + + case COMPONENT_REF: + return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) + || value_dependent_expression_p (TREE_OPERAND (expression, 1))); + + case CALL_EXPR: + /* A CALL_EXPR may appear in a constant expression if it is a + call to a builtin function, e.g., __builtin_constant_p. All + such calls are value-dependent. */ + return true; + + case MODOP_EXPR: + return ((value_dependent_expression_p (TREE_OPERAND (expression, 0))) + || (value_dependent_expression_p (TREE_OPERAND (expression, 2)))); + + default: + /* A constant expression is value-dependent if any subexpression is + value-dependent. */ switch (TREE_CODE_CLASS (TREE_CODE (expression))) { - case '1': - return (value_dependent_expression_p + case tcc_reference: + case tcc_unary: + return (value_dependent_expression_p (TREE_OPERAND (expression, 0))); - case '<': - case '2': - return ((value_dependent_expression_p + + case tcc_comparison: + case tcc_binary: + return ((value_dependent_expression_p (TREE_OPERAND (expression, 0))) - || (value_dependent_expression_p + || (value_dependent_expression_p (TREE_OPERAND (expression, 1)))); - case 'e': + + case tcc_expression: { int i; - for (i = 0; i < first_rtl_op (TREE_CODE (expression)); ++i) + for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expression)); ++i) /* In some cases, some of the operands may be missing. (For example, in the case of PREDECREMENT_EXPR, the amount to increment by may be missing.) That doesn't @@ -11953,6 +12962,9 @@ value_dependent_expression_p (tree expression) return true; return false; } + + default: + break; } } @@ -11973,9 +12985,10 @@ type_dependent_expression_p (tree expression) return false; /* An unresolved name is always dependent. */ - if (TREE_CODE (expression) == IDENTIFIER_NODE) + if (TREE_CODE (expression) == IDENTIFIER_NODE + || TREE_CODE (expression) == USING_DECL) return true; - + /* Some expression forms are never type-dependent. */ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR || TREE_CODE (expression) == SIZEOF_EXPR @@ -12046,9 +13059,10 @@ type_dependent_expression_p (tree expression) /* SCOPE_REF with non-null TREE_TYPE is always non-dependent. */ if (TREE_CODE (expression) == SCOPE_REF) return false; - + if (TREE_CODE (expression) == BASELINK) expression = BASELINK_FUNCTIONS (expression); + if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { if (any_dependent_template_arguments_p @@ -12056,22 +13070,20 @@ type_dependent_expression_p (tree expression) return true; expression = TREE_OPERAND (expression, 0); } - if (TREE_CODE (expression) == OVERLOAD - || TREE_CODE (expression) == FUNCTION_DECL) + gcc_assert (TREE_CODE (expression) == OVERLOAD + || TREE_CODE (expression) == FUNCTION_DECL); + + while (expression) { - while (expression) - { - if (type_dependent_expression_p (OVL_CURRENT (expression))) - return true; - expression = OVL_NEXT (expression); - } - return false; + if (type_dependent_expression_p (OVL_CURRENT (expression))) + return true; + expression = OVL_NEXT (expression); } - abort (); + return false; } - - my_friendly_assert (TREE_CODE (expression) != TYPE_DECL, 20051116); - + + gcc_assert (TREE_CODE (expression) != TYPE_DECL); + return (dependent_type_p (TREE_TYPE (expression))); } @@ -12121,6 +13133,8 @@ any_dependent_template_arguments_p (tree args) if (!args) return false; + if (args == error_mark_node) + return true; for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i) { @@ -12153,7 +13167,7 @@ dependent_template_p (tree tmpl) if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl) || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM) return true; - /* So arenames that have not been looked up. */ + /* So are names that have not been looked up. */ if (TREE_CODE (tmpl) == SCOPE_REF || TREE_CODE (tmpl) == IDENTIFIER_NODE) return true; @@ -12176,7 +13190,8 @@ dependent_template_id_p (tree tmpl, tree args) TYPENAME_TYPE corresponds. Returns ERROR_MARK_NODE if no such TYPE can be found. Note that this function peers inside uninstantiated templates and therefore should be used only in extremely limited - situations. */ + situations. ONLY_CURRENT_P restricts this peering to the currently + open classes hierarchy (which is required when comparing types). */ tree resolve_typename_type (tree type, bool only_current_p) @@ -12185,10 +13200,9 @@ resolve_typename_type (tree type, bool only_current_p) tree name; tree decl; int quals; - bool pop_p; + tree pushed_scope; - my_friendly_assert (TREE_CODE (type) == TYPENAME_TYPE, - 20010702); + gcc_assert (TREE_CODE (type) == TYPENAME_TYPE); scope = TYPE_CONTEXT (type); name = TYPE_IDENTIFIER (type); @@ -12215,7 +13229,7 @@ resolve_typename_type (tree type, bool only_current_p) /* Enter the SCOPE so that name lookup will be resolved as if we were in the class definition. In particular, SCOPE will no longer be considered a dependent type. */ - pop_p = push_scope (scope); + pushed_scope = push_scope (scope); /* Look up the declaration. */ decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true); /* Obtain the set of qualifiers applied to the TYPE. */ @@ -12245,8 +13259,8 @@ resolve_typename_type (tree type, bool only_current_p) if (type != error_mark_node && quals) type = cp_build_qualified_type (type, quals); /* Leave the SCOPE. */ - if (pop_p) - pop_scope (scope); + if (pushed_scope) + pop_scope (pushed_scope); return type; } @@ -12260,20 +13274,23 @@ build_non_dependent_expr (tree expr) { tree inner_expr; - /* Preserve null pointer constants so that the type of things like + /* Preserve null pointer constants so that the type of things like "p == 0" where "p" is a pointer can be determined. */ if (null_ptr_cst_p (expr)) return expr; /* Preserve OVERLOADs; the functions must be available to resolve types. */ - inner_expr = (TREE_CODE (expr) == ADDR_EXPR ? - TREE_OPERAND (expr, 0) : expr); - if (TREE_CODE (inner_expr) == OVERLOAD - || TREE_CODE (inner_expr) == FUNCTION_DECL - || TREE_CODE (inner_expr) == TEMPLATE_DECL - || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR + inner_expr = expr; + if (TREE_CODE (inner_expr) == ADDR_EXPR) + inner_expr = TREE_OPERAND (inner_expr, 0); + if (TREE_CODE (inner_expr) == COMPONENT_REF) + inner_expr = TREE_OPERAND (inner_expr, 1); + if (is_overloaded_fn (inner_expr) || TREE_CODE (inner_expr) == OFFSET_REF) return expr; + /* There is no need to return a proxy for a variable. */ + if (TREE_CODE (expr) == VAR_DECL) + return expr; /* Preserve string constants; conversions from string constants to "char *" are allowed, even though normally a "const char *" cannot be used to initialize a "char *". */ @@ -12287,32 +13304,35 @@ build_non_dependent_expr (tree expr) There is at least one place where we want to know that a particular expression is a throw-expression: when checking a ?: expression, there are special rules if the second or third - argument is a throw-expresion. */ + argument is a throw-expression. */ if (TREE_CODE (expr) == THROW_EXPR) return expr; if (TREE_CODE (expr) == COND_EXPR) - return build (COND_EXPR, - TREE_TYPE (expr), - TREE_OPERAND (expr, 0), - (TREE_OPERAND (expr, 1) - ? build_non_dependent_expr (TREE_OPERAND (expr, 1)) - : build_non_dependent_expr (TREE_OPERAND (expr, 0))), - build_non_dependent_expr (TREE_OPERAND (expr, 2))); + return build3 (COND_EXPR, + TREE_TYPE (expr), + TREE_OPERAND (expr, 0), + (TREE_OPERAND (expr, 1) + ? build_non_dependent_expr (TREE_OPERAND (expr, 1)) + : build_non_dependent_expr (TREE_OPERAND (expr, 0))), + build_non_dependent_expr (TREE_OPERAND (expr, 2))); if (TREE_CODE (expr) == COMPOUND_EXPR && !COMPOUND_EXPR_OVERLOADED (expr)) - return build (COMPOUND_EXPR, - TREE_TYPE (expr), - TREE_OPERAND (expr, 0), - build_non_dependent_expr (TREE_OPERAND (expr, 1))); - - /* Otherwise, build a NON_DEPENDENT_EXPR. + return build2 (COMPOUND_EXPR, + TREE_TYPE (expr), + TREE_OPERAND (expr, 0), + build_non_dependent_expr (TREE_OPERAND (expr, 1))); + + /* If the type is unknown, it can't really be non-dependent */ + gcc_assert (TREE_TYPE (expr) != unknown_type_node); + + /* Otherwise, build a NON_DEPENDENT_EXPR. REFERENCE_TYPEs are not stripped for expressions in templates because doing so would play havoc with mangling. Consider, for example: - template <typename T> void f<T& g>() { g(); } + template <typename T> void f<T& g>() { g(); } In the body of "f", the expression for "g" will have REFERENCE_TYPE, even though the standard says that it should @@ -12335,7 +13355,7 @@ build_non_dependent_args (tree args) new_args = NULL_TREE; for (a = args; a; a = TREE_CHAIN (a)) - new_args = tree_cons (NULL_TREE, + new_args = tree_cons (NULL_TREE, build_non_dependent_expr (TREE_VALUE (a)), new_args); return nreverse (new_args); |