X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=6b98956d6e61bf841ed6d1cc2d84ac9f7b619e37;hp=5bb18d99e88591e5140247a8cc09a3ca0e109827;hb=6ce8bd0cf37a9cc3a42fb258b537c15ff6189a5a;hpb=ac785357337a7e170d547963987890e6284185b0 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5bb18d99e88..6b98956d6e6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,6 +1,7 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -53,7 +54,7 @@ typedef int (*tree_fn_t) (tree, void*); /* The PENDING_TEMPLATES is a TREE_LIST of templates whose instantiations have been deferred, either because their definitions were not yet available, or because we were putting off doing the work. */ -struct pending_template GTY (()) { +struct GTY (()) pending_template { struct pending_template *next; struct tinst_level *tinst; }; @@ -81,6 +82,19 @@ static tree cur_stmt_expr; local variables. */ static htab_t local_specializations; +typedef struct GTY(()) spec_entry +{ + tree tmpl; + tree args; + tree spec; +} spec_entry; + +static GTY ((param_is (spec_entry))) + htab_t decl_specializations; + +static GTY ((param_is (spec_entry))) + htab_t type_specializations; + /* Contains canonical template parameter types. The vector is indexed by the TEMPLATE_TYPE_IDX of the template parameter. Each element is a TREE_LIST, whose TREE_VALUEs contain the canonical template @@ -117,8 +131,8 @@ 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*, tree); -static int type_unification_real (tree, tree, tree, tree, - int, unification_kind_t, int); +static int type_unification_real (tree, tree, tree, const tree *, + unsigned 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); @@ -132,6 +146,7 @@ static bool inline_needs_template_parms (tree); static void push_inline_template_parms_recursive (tree, int); static tree retrieve_local_specialization (tree); static void register_local_specialization (tree, tree); +static hashval_t hash_specialization (const void *p); static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t); static int mark_template_parm (tree, void *); static int template_parm_this_level_p (tree, void *); @@ -169,10 +184,16 @@ static int eq_local_specializations (const void *, const void *); static bool dependent_template_arg_p (tree); static bool any_template_arguments_need_structural_equality_p (tree); static bool dependent_type_p_r (tree); -static tree tsubst (tree, tree, tsubst_flags_t, tree); static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); +static tree tsubst_decl (tree, tree, tsubst_flags_t); +static void perform_typedefs_access_check (tree tmpl, tree targs); +static void append_type_to_template_for_access_check_1 (tree, tree, tree); +static hashval_t iterative_hash_template_arg (tree arg, hashval_t val); +static bool primary_template_instantiation_p (const_tree); +static tree listify (tree); +static tree listify_autos (tree, tree); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -269,14 +290,17 @@ finish_member_template_decl (tree decl) /* Return the template info node corresponding to T, whatever T is. */ tree -get_template_info (tree t) +get_template_info (const_tree t) { tree tinfo = NULL_TREE; + if (!t || t == error_mark_node) + return NULL; + if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) tinfo = DECL_TEMPLATE_INFO (t); - if (!tinfo && TREE_CODE (t) == TYPE_DECL) + if (!tinfo && DECL_IMPLICIT_TYPEDEF_P (t)) t = TREE_TYPE (t); if (TAGGED_TYPE_P (t)) @@ -380,7 +404,8 @@ push_inline_template_parms_recursive (tree parmlist, int levels) It is ugly that we recreate this here; the original version built in process_template_parm is no longer available. */ - tree decl = build_decl (CONST_DECL, DECL_NAME (parm), + tree decl = build_decl (DECL_SOURCE_LOCATION (parm), + CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); DECL_ARTIFICIAL (decl) = 1; TREE_CONSTANT (decl) = 1; @@ -807,13 +832,13 @@ maybe_process_partial_specialization (tree type) && !COMPLETE_TYPE_P (type)) { tree t; + tree tmpl = CLASSTYPE_TI_TEMPLATE (type); if (current_namespace - != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) + != decl_namespace_context (tmpl)) { permerror (input_location, "specializing %q#T in different namespace", type); - permerror (input_location, " from definition of %q+#D", - CLASSTYPE_TI_TEMPLATE (type)); + permerror (input_location, " from definition of %q+#D", tmpl); } /* Check for invalid specialization after instantiation: @@ -821,13 +846,38 @@ maybe_process_partial_specialization (tree type) template <> template <> class C::D; template <> template class C::D; */ - for (t = DECL_TEMPLATE_INSTANTIATIONS - (most_general_template (CLASSTYPE_TI_TEMPLATE (type))); + for (t = DECL_TEMPLATE_INSTANTIATIONS (tmpl); t; t = TREE_CHAIN (t)) - if (TREE_VALUE (t) != type - && TYPE_CONTEXT (TREE_VALUE (t)) == context) - error ("specialization %qT after instantiation %qT", - type, TREE_VALUE (t)); + { + tree inst = TREE_VALUE (t); + if (CLASSTYPE_TEMPLATE_SPECIALIZATION (inst)) + { + /* We already have a full specialization of this partial + instantiation. Reassign it to the new member + specialization template. */ + spec_entry elt; + spec_entry **slot; + + elt.tmpl = most_general_template (tmpl); + elt.args = CLASSTYPE_TI_ARGS (inst); + elt.spec = inst; + + htab_remove_elt (type_specializations, &elt); + + elt.tmpl = tmpl; + elt.args = INNERMOST_TEMPLATE_ARGS (elt.args); + + slot = (spec_entry **) + htab_find_slot (type_specializations, &elt, INSERT); + *slot = GGC_NEW (spec_entry); + **slot = elt; + } + else if (COMPLETE_TYPE_P (inst) || TYPE_BEING_DEFINED (inst)) + /* But if we've had an implicit instantiation, that's a + problem ([temp.expl.spec]/6). */ + error ("specialization %qT after instantiation %qT", + type, inst); + } /* Mark TYPE as a specialization. And as a result, we only have one level of template argument for the innermost @@ -891,8 +941,7 @@ optimize_specialization_lookup_p (tree tmpl) parameter is ignored if TMPL is not a class template. */ static tree -retrieve_specialization (tree tmpl, tree args, - bool class_specializations_p) +retrieve_specialization (tree tmpl, tree args, hashval_t hash) { if (args == error_mark_node) return NULL_TREE; @@ -917,8 +966,7 @@ retrieve_specialization (tree tmpl, tree args, arguments. */ class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl)); class_specialization - = retrieve_specialization (class_template, args, - /*class_specializations_p=*/false); + = retrieve_specialization (class_template, args, 0); if (!class_specialization) return NULL_TREE; /* Now, find the appropriate entry in the CLASSTYPE_METHOD_VEC @@ -932,45 +980,34 @@ retrieve_specialization (tree tmpl, tree args, 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) + if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl + /* using-declarations can add base methods to the method vec, + and we don't want those here. */ + && DECL_CONTEXT (fn) == class_specialization) return fn; } return NULL_TREE; } else { - tree *sp; - tree *head; + spec_entry *found; + spec_entry elt; + htab_t specializations; + + elt.tmpl = tmpl; + elt.args = args; + elt.spec = NULL_TREE; - /* 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 - && TAGGED_TYPE_P (TREE_TYPE (tmpl))) - sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl); + if (DECL_CLASS_TEMPLATE_P (tmpl)) + specializations = type_specializations; 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; + specializations = decl_specializations; - 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); - } + if (hash == 0) + hash = hash_specialization (&elt); + found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash); + if (found) + return found->spec; } return NULL_TREE; @@ -1209,11 +1246,14 @@ is_specialization_of_friend (tree decl, tree friend_decl) equivalent prior declaration, if available. */ static tree -register_specialization (tree spec, tree tmpl, tree args, bool is_friend) +register_specialization (tree spec, tree tmpl, tree args, bool is_friend, + hashval_t hash) { tree fn; + spec_entry **slot = NULL; + spec_entry elt; - gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)); if (TREE_CODE (spec) == FUNCTION_DECL && uses_template_parms (DECL_TI_ARGS (spec))) @@ -1230,8 +1270,27 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) instantiation unless and until it is actually needed. */ return spec; - fn = retrieve_specialization (tmpl, args, - /*class_specializations_p=*/false); + if (optimize_specialization_lookup_p (tmpl)) + /* We don't put these specializations in the hash table, but we might + want to give an error about a mismatch. */ + fn = retrieve_specialization (tmpl, args, 0); + else + { + elt.tmpl = tmpl; + elt.args = args; + elt.spec = spec; + + if (hash == 0) + hash = hash_specialization (&elt); + + slot = (spec_entry **) + htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT); + if (*slot) + fn = (*slot)->spec; + else + fn = NULL_TREE; + } + /* 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, @@ -1243,7 +1302,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) { if (DECL_TEMPLATE_INSTANTIATION (fn)) { - if (TREE_USED (fn) + if (DECL_ODR_USED (fn) || DECL_EXPLICIT_INSTANTIATION (fn)) { error ("specialization of %qD after instantiation", @@ -1289,8 +1348,12 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) to the primary function; now copy the inline bits to the various clones. */ FOR_EACH_CLONE (clone, fn) - DECL_DECLARED_INLINE_P (clone) - = DECL_DECLARED_INLINE_P (fn); + { + DECL_DECLARED_INLINE_P (clone) + = DECL_DECLARED_INLINE_P (fn); + DECL_SOURCE_LOCATION (clone) + = DECL_SOURCE_LOCATION (fn); + } check_specialization_namespace (fn); return fn; @@ -1307,40 +1370,224 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend) return fn; } } + else if (fn) + return duplicate_decls (spec, fn, is_friend); /* 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) = FROB_CONTEXT (decl_namespace_context (tmpl)); + DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl); if (!optimize_specialization_lookup_p (tmpl)) - DECL_TEMPLATE_SPECIALIZATIONS (tmpl) - = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); + { + gcc_assert (tmpl && args && spec); + *slot = GGC_NEW (spec_entry); + **slot = elt; + if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec) + && PRIMARY_TEMPLATE_P (tmpl) + && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE) + /* TMPL is a forward declaration of a template function; keep a list + of all specializations in case we need to reassign them to a friend + template later in tsubst_friend_function. */ + DECL_TEMPLATE_INSTANTIATIONS (tmpl) + = tree_cons (args, spec, DECL_TEMPLATE_INSTANTIATIONS (tmpl)); + } return spec; } +/* Returns true iff two spec_entry nodes are equivalent. Only compares the + TMPL and ARGS members, ignores SPEC. */ + +static int +eq_specializations (const void *p1, const void *p2) +{ + const spec_entry *e1 = (const spec_entry *)p1; + const spec_entry *e2 = (const spec_entry *)p2; + + return (e1->tmpl == e2->tmpl + && comp_template_args (e1->args, e2->args)); +} + +/* Returns a hash for a template TMPL and template arguments ARGS. */ + +static hashval_t +hash_tmpl_and_args (tree tmpl, tree args) +{ + hashval_t val = DECL_UID (tmpl); + return iterative_hash_template_arg (args, val); +} + +/* Returns a hash for a spec_entry node based on the TMPL and ARGS members, + ignoring SPEC. */ + +static hashval_t +hash_specialization (const void *p) +{ + const spec_entry *e = (const spec_entry *)p; + return hash_tmpl_and_args (e->tmpl, e->args); +} + +/* Recursively calculate a hash value for a template argument ARG, for use + in the hash tables of template specializations. */ + +static hashval_t +iterative_hash_template_arg (tree arg, hashval_t val) +{ + unsigned HOST_WIDE_INT i; + enum tree_code code; + char tclass; + + if (arg == NULL_TREE) + return iterative_hash_object (arg, val); + + if (!TYPE_P (arg)) + STRIP_NOPS (arg); + + code = TREE_CODE (arg); + tclass = TREE_CODE_CLASS (code); + + val = iterative_hash_object (code, val); + + switch (code) + { + case ERROR_MARK: + return val; + + case IDENTIFIER_NODE: + return iterative_hash_object (IDENTIFIER_HASH_VALUE (arg), val); + + case TREE_VEC: + { + int i, len = TREE_VEC_LENGTH (arg); + for (i = 0; i < len; ++i) + val = iterative_hash_template_arg (TREE_VEC_ELT (arg, i), val); + return val; + } + + case TYPE_PACK_EXPANSION: + case EXPR_PACK_EXPANSION: + return iterative_hash_template_arg (PACK_EXPANSION_PATTERN (arg), val); + + case ARGUMENT_PACK_SELECT: + /* We can get one of these when re-hashing a previous entry in the middle + of substituting into a pack expansion. Just look through it... */ + arg = ARGUMENT_PACK_SELECT_FROM_PACK (arg); + /* ...and fall through. */ + case TYPE_ARGUMENT_PACK: + case NONTYPE_ARGUMENT_PACK: + return iterative_hash_template_arg (ARGUMENT_PACK_ARGS (arg), val); + + case TREE_LIST: + for (; arg; arg = TREE_CHAIN (arg)) + val = iterative_hash_template_arg (TREE_VALUE (arg), val); + return val; + + case OVERLOAD: + for (; arg; arg = OVL_CHAIN (arg)) + val = iterative_hash_template_arg (OVL_FUNCTION (arg), val); + return val; + + case CONSTRUCTOR: + { + tree field, value; + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg), i, field, value) + { + val = iterative_hash_template_arg (field, val); + val = iterative_hash_template_arg (value, val); + } + return val; + } + + case PARM_DECL: + val = iterative_hash_object (DECL_PARM_INDEX (arg), val); + return iterative_hash_template_arg (TREE_TYPE (arg), val); + + case TARGET_EXPR: + return iterative_hash_template_arg (TARGET_EXPR_INITIAL (arg), val); + + case PTRMEM_CST: + val = iterative_hash_template_arg (PTRMEM_CST_CLASS (arg), val); + return iterative_hash_template_arg (PTRMEM_CST_MEMBER (arg), val); + + case TEMPLATE_PARM_INDEX: + val = iterative_hash_template_arg + (TREE_TYPE (TEMPLATE_PARM_DECL (arg)), val); + val = iterative_hash_object (TEMPLATE_PARM_LEVEL (arg), val); + return iterative_hash_object (TEMPLATE_PARM_IDX (arg), val); + + case TRAIT_EXPR: + val = iterative_hash_object (TRAIT_EXPR_KIND (arg), val); + val = iterative_hash_template_arg (TRAIT_EXPR_TYPE1 (arg), val); + return iterative_hash_template_arg (TRAIT_EXPR_TYPE2 (arg), val); + + case BASELINK: + val = iterative_hash_template_arg (BINFO_TYPE (BASELINK_BINFO (arg)), + val); + return iterative_hash_template_arg (DECL_NAME (get_first_fn (arg)), + val); + + case MODOP_EXPR: + val = iterative_hash_template_arg (TREE_OPERAND (arg, 0), val); + code = TREE_CODE (TREE_OPERAND (arg, 1)); + val = iterative_hash_object (code, val); + return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val); + + default: + switch (tclass) + { + case tcc_type: + if (TYPE_CANONICAL (arg)) + return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), + val); + else if (TREE_CODE (arg) == DECLTYPE_TYPE) + return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val); + /* Otherwise just compare the types during lookup. */ + return val; + + case tcc_declaration: + case tcc_constant: + return iterative_hash_expr (arg, val); + + default: + gcc_assert (IS_EXPR_CODE_CLASS (tclass)); + { + unsigned n = TREE_OPERAND_LENGTH (arg); + for (i = 0; i < n; ++i) + val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val); + return val; + } + } + } + gcc_unreachable (); + return 0; +} + /* Unregister the specialization SPEC as a specialization of TMPL. Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true - if the SPEC was listed as a specialization of TMPL. */ + if the SPEC was listed as a specialization of TMPL. + + Note that SPEC has been ggc_freed, so we can't look inside it. */ bool -reregister_specialization (tree spec, tree tmpl, tree new_spec) +reregister_specialization (tree spec, tree tinfo, tree new_spec) { - tree* s; + spec_entry **slot; + spec_entry elt; - for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - *s != NULL_TREE; - s = &TREE_CHAIN (*s)) - if (TREE_VALUE (*s) == spec) - { - if (!new_spec) - *s = TREE_CHAIN (*s); - else - TREE_VALUE (*s) = new_spec; - return 1; - } + elt.tmpl = most_general_template (TI_TEMPLATE (tinfo)); + elt.args = TI_ARGS (tinfo); + elt.spec = NULL_TREE; + + slot = (spec_entry **) htab_find_slot (decl_specializations, &elt, INSERT); + if (*slot) + { + gcc_assert ((*slot)->spec == spec || (*slot)->spec == new_spec); + gcc_assert (new_spec != NULL_TREE); + (*slot)->spec = new_spec; + return 1; + } return 0; } @@ -1696,12 +1943,13 @@ determine_specialization (tree template_id, if (candidates) { tree fn = TREE_VALUE (candidates); - /* DECL is a re-declaration of a template function. */ + *targs_out = copy_node (DECL_TI_ARGS (fn)); + /* DECL is a re-declaration or partial instantiation 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 (fn)); return DECL_TI_TEMPLATE (fn); } @@ -2216,19 +2464,24 @@ check_explicit_specialization (tree declarator, the specialization of it. */ if (tsk == tsk_template) { + tree result = DECL_TEMPLATE_RESULT (tmpl); SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); - DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE; + DECL_INITIAL (result) = NULL_TREE; if (have_def) { + tree parm; DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); - DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl)) + DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (decl); /* We want to use the argument list specified in the definition, not in the original declaration. */ - DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl)) - = DECL_ARGUMENTS (decl); + DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); + for (parm = DECL_ARGUMENTS (result); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = result; } - return tmpl; + return register_specialization (tmpl, gen_tmpl, targs, + is_friend, 0); } /* Set up the DECL_TEMPLATE_INFO for DECL. */ @@ -2306,7 +2559,7 @@ check_explicit_specialization (tree declarator, /* Register this specialization so that we can find it again. */ - decl = register_specialization (decl, gen_tmpl, targs, is_friend); + decl = register_specialization (decl, gen_tmpl, targs, is_friend, 0); } } @@ -2371,6 +2624,7 @@ comp_template_parms (const_tree parms1, const_tree parms2) } /* Determine whether PARM is a parameter pack. */ + bool template_parameter_pack_p (const_tree parm) { @@ -2389,8 +2643,50 @@ template_parameter_pack_p (const_tree parm) && TEMPLATE_TYPE_PARAMETER_PACK (parm)); } +/* Determine if T is a function parameter pack. */ + +bool +function_parameter_pack_p (const_tree t) +{ + if (t && TREE_CODE (t) == PARM_DECL) + return FUNCTION_PARAMETER_PACK_P (t); + return false; +} + +/* Return the function template declaration of PRIMARY_FUNC_TMPL_INST. + PRIMARY_FUNC_TMPL_INST is a primary function template instantiation. */ + +tree +get_function_template_decl (const_tree primary_func_tmpl_inst) +{ + if (! primary_func_tmpl_inst + || TREE_CODE (primary_func_tmpl_inst) != FUNCTION_DECL + || ! primary_template_instantiation_p (primary_func_tmpl_inst)) + return NULL; + + return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst)); +} + +/* Return true iff the function parameter PARAM_DECL was expanded + from the function parameter pack PACK. */ + +bool +function_parameter_expanded_from_pack_p (tree param_decl, tree pack) +{ + if (DECL_ARTIFICIAL (param_decl) + || !function_parameter_pack_p (pack)) + return false; + + gcc_assert (DECL_NAME (param_decl) && DECL_NAME (pack)); + + /* The parameter pack and its pack arguments have the same + DECL_PARM_INDEX. */ + return DECL_PARM_INDEX (pack) == DECL_PARM_INDEX (param_decl); +} + /* Determine whether ARGS describes a variadic template args list, i.e., one that is terminated by a template argument pack. */ + static bool template_args_variadic_p (tree args) { @@ -2413,19 +2709,96 @@ template_args_variadic_p (tree args) /* Generate a new name for the parameter pack name NAME (an IDENTIFIER_NODE) that incorporates its */ + static tree make_ith_pack_parameter_name (tree name, int i) { /* Munge the name to include the parameter index. */ - char numbuf[128]; +#define NUMBUF_LEN 128 + char numbuf[NUMBUF_LEN]; char* newname; - - sprintf(numbuf, "%i", i); - newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2); - sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i); + int newname_len; + + snprintf (numbuf, NUMBUF_LEN, "%i", i); + newname_len = IDENTIFIER_LENGTH (name) + + strlen (numbuf) + 2; + newname = (char*)alloca (newname_len); + snprintf (newname, newname_len, + "%s#%i", IDENTIFIER_POINTER (name), i); return get_identifier (newname); } +/* Return true if T is a primary function + or class template instantiation. */ + +static bool +primary_template_instantiation_p (const_tree t) +{ + if (!t) + return false; + + if (TREE_CODE (t) == FUNCTION_DECL) + return DECL_LANG_SPECIFIC (t) + && DECL_TEMPLATE_INSTANTIATION (t) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)); + else if (CLASS_TYPE_P (t)) + return CLASSTYPE_TEMPLATE_INSTANTIATION (t) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)); + return false; +} + +/* Return true if PARM is a template template parameter. */ + +bool +template_template_parameter_p (const_tree parm) +{ + return DECL_TEMPLATE_TEMPLATE_PARM_P (parm); +} + +/* Return the template parameters of T if T is a + primary template instantiation, NULL otherwise. */ + +tree +get_primary_template_innermost_parameters (const_tree t) +{ + tree parms = NULL, template_info = NULL; + + if ((template_info = get_template_info (t)) + && primary_template_instantiation_p (t)) + parms = INNERMOST_TEMPLATE_PARMS + (DECL_TEMPLATE_PARMS (TI_TEMPLATE (template_info))); + + return parms; +} + +/* Returns the template arguments of T if T is a template instantiation, + NULL otherwise. */ + +tree +get_template_innermost_arguments (const_tree t) +{ + tree args = NULL, template_info = NULL; + + if ((template_info = get_template_info (t)) + && TI_ARGS (template_info)) + args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (template_info)); + + return args; +} + +/* Return the argument pack elements of T if T is a template argument pack, + NULL otherwise. */ + +tree +get_template_argument_pack_elems (const_tree t) +{ + if (TREE_CODE (t) != TYPE_ARGUMENT_PACK + && TREE_CODE (t) != NONTYPE_ARGUMENT_PACK) + return NULL; + + return ARGUMENT_PACK_ARGS (t); +} + /* Structure used to track the progress of find_parameter_packs_r. */ struct find_parameter_pack_data { @@ -2645,7 +3018,7 @@ make_pack_expansion (tree arg) pointer_set_destroy (ppd.visited); /* Create the pack expansion type for the base type. */ - purpose = make_node (TYPE_PACK_EXPANSION); + purpose = cxx_make_type (TYPE_PACK_EXPANSION); SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg)); PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs; @@ -2660,7 +3033,9 @@ make_pack_expansion (tree arg) for_types = true; /* Build the PACK_EXPANSION_* node. */ - result = make_node (for_types ? TYPE_PACK_EXPANSION : EXPR_PACK_EXPANSION); + result = for_types + ? cxx_make_type (TYPE_PACK_EXPANSION) + : make_node (EXPR_PACK_EXPANSION); SET_PACK_EXPANSION_PATTERN (result, arg); if (TREE_CODE (result) == EXPR_PACK_EXPANSION) { @@ -2923,7 +3298,8 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args, tree orig_decl = TEMPLATE_PARM_DECL (index); tree decl, t; - decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type); + decl = build_decl (DECL_SOURCE_LOCATION (orig_decl), + TREE_CODE (orig_decl), DECL_NAME (orig_decl), type); TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl); TREE_READONLY (decl) = TREE_READONLY (orig_decl); DECL_ARTIFICIAL (decl) = 1; @@ -2950,10 +3326,11 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args, /* Process information from new template parameter PARM and append it to the LIST being built. This new parameter is a non-type parameter iff IS_NON_TYPE is true. This new parameter is a parameter - pack iff IS_PARAMETER_PACK is true. */ + pack iff IS_PARAMETER_PACK is true. The location of PARM is in + PARM_LOC. */ tree -process_template_parm (tree list, tree parm, bool is_non_type, +process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_type, bool is_parameter_pack) { tree decl = 0; @@ -3022,7 +3399,8 @@ process_template_parm (tree list, tree parm, bool is_non_type, /* A template parameter is not modifiable. */ TREE_CONSTANT (parm) = 1; TREE_READONLY (parm) = 1; - decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); + decl = build_decl (parm_loc, + CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); TREE_CONSTANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (parm) = DECL_INITIAL (decl) @@ -3051,7 +3429,8 @@ process_template_parm (tree list, tree parm, bool is_non_type, { t = cxx_make_type (TEMPLATE_TYPE_PARM); /* parm is either IDENTIFIER_NODE or NULL_TREE. */ - decl = build_decl (TYPE_DECL, parm, t); + decl = build_decl (parm_loc, + TYPE_DECL, parm, t); } TYPE_NAME (t) = decl; @@ -3166,7 +3545,7 @@ current_template_args (void) tree vec = make_tree_vec (1); TREE_VEC_ELT (vec, 0) = make_pack_expansion (t); - t = make_node (TYPE_ARGUMENT_PACK); + t = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (t, vec); } } @@ -3212,17 +3591,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p) 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); - DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl); - DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl); - 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, - DECL_OVERLOADED_OPERATOR_P (decl)); - } return tmpl; } @@ -3292,15 +3660,20 @@ process_partial_specialization (tree decl) tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); tree specargs = CLASSTYPE_TI_ARGS (type); tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); - tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); + tree inner_parms; int nargs = TREE_VEC_LENGTH (inner_args); - int ntparms = TREE_VEC_LENGTH (inner_parms); + int ntparms; int i; int did_error_intro = 0; struct template_parm_data tpd; struct template_parm_data tpd2; + gcc_assert (current_template_parms); + + inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); + ntparms = TREE_VEC_LENGTH (inner_parms); + /* We check that each of the template parameters given in the partial specialization is used in the argument list to the specialization. For example: @@ -3492,10 +3865,8 @@ process_partial_specialization (tree decl) } } - if (retrieve_specialization (maintmpl, specargs, - /*class_specializations_p=*/true)) - /* We've already got this specialization. */ - return decl; + /* We should only get here once. */ + gcc_assert (!COMPLETE_TYPE_P (type)); DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = tree_cons (specargs, inner_parms, @@ -3543,6 +3914,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) && DECL_LANG_SPECIFIC (decl) + && DECL_DECLARES_FUNCTION_P (decl) /* If this is either a friend defined in the scope of the class or a member function. */ && (DECL_FUNCTION_MEMBER_P (decl) @@ -3585,7 +3957,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, if (TREE_PURPOSE (parm)) seen_def_arg_p = 1; - else if (seen_def_arg_p) + else if (seen_def_arg_p + && !template_parameter_pack_p (TREE_VALUE (parm))) { error ("no default argument for %qD", TREE_VALUE (parm)); /* For better subsequent error-recovery, we indicate that @@ -3596,6 +3969,9 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, else if (is_primary && !is_partial && !is_friend_decl + /* Don't complain about an enclosing partial + specialization. */ + && parm_level == parms && TREE_CODE (decl) == TYPE_DECL && i < ntparms - 1 && template_parameter_pack_p (TREE_VALUE (parm))) @@ -3749,8 +4125,8 @@ push_template_decl_real (tree decl, bool is_friend) [temp.mem]. */ bool member_template_p = false; - if (decl == error_mark_node) - return decl; + if (decl == error_mark_node || !current_template_parms) + return error_mark_node; /* See if this is a partial specialization. */ is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl) @@ -3971,7 +4347,7 @@ push_template_decl_real (tree decl, bool is_friend) register_specialization (new_tmpl, most_general_template (tmpl), args, - is_friend); + is_friend, 0); return decl; } @@ -4186,8 +4562,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 %q#D", parm); - inform (input_location, "%Joriginal definition appeared here", tmpl_parm); + error_at (input_location, "redefinition of default argument for %q#D", parm); + inform (DECL_SOURCE_LOCATION (tmpl_parm), + "original definition appeared here"); return false; } @@ -4399,9 +4776,9 @@ convert_nontype_argument (tree type, tree expr) 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 (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { - if (!INTEGRAL_TYPE_P (expr_type)) + if (!INTEGRAL_OR_ENUMERATION_TYPE_P (expr_type)) return error_mark_node; expr = fold_decl_constant_value (expr); @@ -4557,6 +4934,13 @@ convert_nontype_argument (tree type, tree expr) expr = convert_nontype_argument_function (type, expr); if (!expr || expr == error_mark_node) return expr; + + if (TREE_CODE (expr) != ADDR_EXPR) + { + error ("%qE is not a valid template argument for type %qT", expr, type); + error ("it must be the address of a function with external linkage"); + return NULL_TREE; + } } /* [temp.arg.nontype]/5, bullet 5 @@ -4683,7 +5067,7 @@ coerce_template_template_parm (tree parm, D d; i.e. the parameter list of TT depends on earlier parameters. */ - if (!dependent_type_p (TREE_TYPE (arg)) + if (!uses_template_parms (TREE_TYPE (arg)) && !same_type_p (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), TREE_TYPE (arg))) @@ -4739,6 +5123,9 @@ coerce_template_template_parms (tree parm_parms, { parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, nparms - 1)); + if (parm == error_mark_node) + return 0; + switch (TREE_CODE (parm)) { case TEMPLATE_DECL: @@ -5046,7 +5433,7 @@ convert_template_argument (tree parm, 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); + val = strip_typedefs (val); } else { @@ -5055,7 +5442,19 @@ convert_template_argument (tree parm, if (invalid_nontype_parm_type_p (t, complain)) return error_mark_node; - if (!uses_template_parms (orig_arg) && !uses_template_parms (t)) + if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) + { + if (same_type_p (t, TREE_TYPE (orig_arg))) + val = orig_arg; + else + { + /* Not sure if this is reachable, but it doesn't hurt + to be robust. */ + error ("type mismatch in nontype parameter pack"); + val = error_mark_node; + } + } + else if (!uses_template_parms (orig_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 is zero. More importantly, digest_init will try too @@ -5183,7 +5582,7 @@ coerce_template_parameter_pack (tree parms, if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL) - argument_pack = make_node (TYPE_ARGUMENT_PACK); + argument_pack = cxx_make_type (TYPE_ARGUMENT_PACK); else { argument_pack = make_node (NONTYPE_ARGUMENT_PACK); @@ -5220,7 +5619,8 @@ coerce_template_parms (tree parms, tree inner_args; tree new_args; tree new_inner_args; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* When used as a boolean value, indicates whether this is a variadic template parameter list. Since it's an int, we can also @@ -5228,10 +5628,6 @@ coerce_template_parms (tree parms, parameters. */ int variadic_p = 0; - inner_args - = expand_template_argument_pack (INNERMOST_TEMPLATE_ARGS (args)); - - nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; nparms = TREE_VEC_LENGTH (parms); /* Determine if there are any parameter packs. */ @@ -5239,13 +5635,22 @@ coerce_template_parms (tree parms, { tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx)); if (template_parameter_pack_p (tparm)) - { - variadic_p = 1; - break; - } + ++variadic_p; } - if ((nargs > nparms - variadic_p && !variadic_p) + inner_args = INNERMOST_TEMPLATE_ARGS (args); + /* If there are 0 or 1 parameter packs, we need to expand any argument + packs so that we can deduce a parameter pack from some non-packed args + followed by an argument pack, as in variadic85.C. If there are more + than that, we need to leave argument packs intact so the arguments are + assigned to the right parameter packs. This should only happen when + dealing with a nested class inside a partial specialization of a class + template, as in variadic92.C. */ + if (variadic_p <= 1) + inner_args = expand_template_argument_pack (inner_args); + + nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; + if ((nargs > nparms && !variadic_p) || (nargs < nparms - variadic_p && require_all_args && (!use_default_args @@ -5273,8 +5678,10 @@ coerce_template_parms (tree parms, /* 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; + saved_unevaluated_operand = cp_unevaluated_operand; + cp_unevaluated_operand = 0; + saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + c_inhibit_evaluation_warnings = 0; new_inner_args = make_tree_vec (nparms); new_args = add_outermost_template_args (args, new_inner_args); for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++) @@ -5292,42 +5699,48 @@ coerce_template_parms (tree parms, } /* Calculate the next argument. */ - if (template_parameter_pack_p (TREE_VALUE (parm))) + if (arg_idx < nargs) + arg = TREE_VEC_ELT (inner_args, arg_idx); + else + arg = NULL_TREE; + + if (template_parameter_pack_p (TREE_VALUE (parm)) + && !(arg && ARGUMENT_PACK_P (arg))) { - /* All remaining arguments will be placed in the - template parameter pack PARM. */ - arg = coerce_template_parameter_pack (parms, parm_idx, args, - inner_args, arg_idx, - new_args, &lost, - in_decl, complain); - + /* All remaining arguments will be placed in the + template parameter pack PARM. */ + arg = coerce_template_parameter_pack (parms, parm_idx, args, + inner_args, arg_idx, + new_args, &lost, + in_decl, complain); + /* Store this argument. */ if (arg == error_mark_node) lost++; TREE_VEC_ELT (new_inner_args, parm_idx) = arg; - /* We are done with all of the arguments. */ - arg_idx = nargs; - + /* We are done with all of the arguments. */ + arg_idx = nargs; + continue; } - else if (arg_idx < nargs) - { - arg = TREE_VEC_ELT (inner_args, arg_idx); - - if (arg && PACK_EXPANSION_P (arg)) + else if (arg) + { + if (PACK_EXPANSION_P (arg)) { if (complain & tf_error) { + /* FIXME this restriction was removed by N2555; see + bug 35722. */ /* If ARG is a pack expansion, but PARM is not a template parameter pack (if it were, we would have handled it above), we're trying to expand into a fixed-length argument list. */ if (TREE_CODE (arg) == EXPR_PACK_EXPANSION) - error ("cannot expand %<%E%> into a fixed-length " + sorry ("cannot expand %<%E%> into a fixed-length " "argument list", arg); else - error ("cannot expand %<%T%> into a fixed-length " + sorry ("cannot expand %<%T%> into a fixed-length " "argument list", arg); } return error_mark_node; @@ -5361,7 +5774,8 @@ coerce_template_parms (tree parms, lost++; TREE_VEC_ELT (new_inner_args, arg_idx) = arg; } - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; if (lost) return error_mark_node; @@ -5384,6 +5798,25 @@ template_args_equal (tree ot, tree nt) return PACK_EXPANSION_P (nt) && template_args_equal (PACK_EXPANSION_PATTERN (ot), PACK_EXPANSION_PATTERN (nt)); + else if (ARGUMENT_PACK_P (ot)) + { + int i, len; + tree opack, npack; + + if (!ARGUMENT_PACK_P (nt)) + return 0; + + opack = ARGUMENT_PACK_ARGS (ot); + npack = ARGUMENT_PACK_ARGS (nt); + len = TREE_VEC_LENGTH (opack); + if (TREE_VEC_LENGTH (npack) != len) + return 0; + for (i = 0; i < len; ++i) + if (!template_args_equal (TREE_VEC_ELT (opack, i), + TREE_VEC_ELT (npack, i))) + return 0; + return 1; + } else if (TYPE_P (nt)) return TYPE_P (ot) && same_type_p (ot, nt); else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) @@ -5400,9 +5833,6 @@ comp_template_args (tree oldargs, tree newargs) { int i; - oldargs = expand_template_argument_pack (oldargs); - newargs = expand_template_argument_pack (newargs); - if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs)) return 0; @@ -5538,6 +5968,10 @@ lookup_template_class (tree d1, { tree templ = NULL_TREE, parmlist; tree t; + spec_entry **slot; + spec_entry *entry; + spec_entry elt; + hashval_t hash; timevar_push (TV_NAME_LOOKUP); @@ -5580,6 +6014,7 @@ lookup_template_class (tree d1, d1 = DECL_NAME (templ); } else if (TREE_CODE (d1) == TEMPLATE_DECL + && DECL_TEMPLATE_RESULT (d1) && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL) { templ = d1; @@ -5702,7 +6137,6 @@ lookup_template_class (tree d1, /* From here on, we're only interested in the most general template. */ - templ = gen_tmpl; /* Calculate the BOUND_ARGS. These will be the args that are actually tsubst'd into the definition to create the @@ -5716,12 +6150,12 @@ lookup_template_class (tree d1, tree bound_args = make_tree_vec (parm_depth); for (i = saved_depth, - t = DECL_TEMPLATE_PARMS (templ); + t = DECL_TEMPLATE_PARMS (gen_tmpl); i > 0 && t != NULL_TREE; --i, t = TREE_CHAIN (t)) { tree a = coerce_template_parms (TREE_VALUE (t), - arglist, templ, + arglist, gen_tmpl, complain, /*require_all_args=*/true, /*use_default_args=*/true); @@ -5752,7 +6186,7 @@ lookup_template_class (tree d1, arglist = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), INNERMOST_TEMPLATE_ARGS (arglist), - templ, + gen_tmpl, complain, /*require_all_args=*/true, /*use_default_args=*/true); @@ -5769,37 +6203,23 @@ lookup_template_class (tree d1, the `C' is just the same as `C'. Outside of the class, however, such a reference is an instantiation. */ - if (comp_template_args (TYPE_TI_ARGS (template_type), - arglist)) - { - found = template_type; - - if (!entering_scope && PRIMARY_TEMPLATE_P (templ)) - { - tree ctx; - - 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; - found_ctx:; - } - } - if (found) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); + if ((entering_scope + || !PRIMARY_TEMPLATE_P (gen_tmpl) + || currently_open_class (template_type)) + /* comp_template_args is expensive, check it last. */ + && comp_template_args (TYPE_TI_ARGS (template_type), + arglist)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, template_type); /* If we already have this specialization, return it. */ - found = retrieve_specialization (templ, arglist, - /*class_specializations_p=*/false); - if (found) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); + elt.tmpl = gen_tmpl; + elt.args = arglist; + hash = hash_specialization (&elt); + entry = (spec_entry *) htab_find_with_hash (type_specializations, + &elt, hash); + + if (entry) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec); /* This type is a "partial instantiation" if any of the template arguments still involve template parameters. Note that we set @@ -5810,22 +6230,23 @@ lookup_template_class (tree d1, /* If the deduced arguments are invalid, then the binding failed. */ if (!is_partial_instantiation - && check_instantiated_args (templ, + && check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (arglist), complain)) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); if (!is_partial_instantiation - && !PRIMARY_TEMPLATE_P (templ) - && TREE_CODE (CP_DECL_CONTEXT (templ)) == NAMESPACE_DECL) + && !PRIMARY_TEMPLATE_P (gen_tmpl) + && !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl)) + && TREE_CODE (CP_DECL_CONTEXT (gen_tmpl)) == NAMESPACE_DECL) { - found = xref_tag_from_type (TREE_TYPE (templ), - DECL_NAME (templ), + found = xref_tag_from_type (TREE_TYPE (gen_tmpl), + DECL_NAME (gen_tmpl), /*tag_scope=*/ts_global); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); } - context = tsubst (DECL_CONTEXT (templ), arglist, + context = tsubst (DECL_CONTEXT (gen_tmpl), arglist, complain, in_decl); if (!context) context = global_namespace; @@ -5847,7 +6268,7 @@ lookup_template_class (tree d1, the values for the enumeration constants may involve template parameters. And, no one should be interested in the enumeration constants for such a type. */ - t = make_node (ENUMERAL_TYPE); + t = cxx_make_type (ENUMERAL_TYPE); SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); } } @@ -5861,7 +6282,7 @@ lookup_template_class (tree d1, /* A local class. Make sure the decl gets registered properly. */ if (context == current_function_decl) - pushtag (DECL_NAME (templ), t, /*tag_scope=*/ts_current); + pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current); if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist)) /* This instantiation is another name for the primary @@ -5881,7 +6302,7 @@ lookup_template_class (tree d1, { TYPE_CONTEXT (t) = FROB_CONTEXT (context); - type_decl = create_implicit_typedef (DECL_NAME (templ), t); + type_decl = create_implicit_typedef (DECL_NAME (gen_tmpl), t); DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t); TYPE_STUB_DECL (t) = type_decl; DECL_SOURCE_LOCATION (type_decl) @@ -5904,65 +6325,32 @@ lookup_template_class (tree d1, template is the immediate parent if this is a full instantiation. */ if (parm_depth == 1 || is_partial_instantiation - || !PRIMARY_TEMPLATE_P (templ)) + || !PRIMARY_TEMPLATE_P (gen_tmpl)) /* This case is easy; there are no member templates involved. */ - found = templ; + found = gen_tmpl; else { - /* This is a full instantiation of a member template. Look - for a partial instantiation of which this is an instance. */ - - for (found = DECL_TEMPLATE_INSTANTIATIONS (templ); - found; found = TREE_CHAIN (found)) - { - int success; - tree tmpl = CLASSTYPE_TI_TEMPLATE (TREE_VALUE (found)); - - /* We only want partial instantiations, here, not - specializations or full instantiations. */ - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_VALUE (found)) - || !uses_template_parms (TREE_VALUE (found))) - continue; - - /* Temporarily reduce by one the number of levels in the - ARGLIST and in FOUND so as to avoid comparing the - last set of arguments. */ - TREE_VEC_LENGTH (arglist)--; - TREE_VEC_LENGTH (TREE_PURPOSE (found)) --; - - /* See if the arguments match. If they do, then TMPL is - the partial instantiation we want. */ - success = comp_template_args (TREE_PURPOSE (found), arglist); - - /* Restore the argument vectors to their full size. */ - TREE_VEC_LENGTH (arglist)++; - TREE_VEC_LENGTH (TREE_PURPOSE (found))++; - - if (success) - { - found = tmpl; - break; - } - } - - if (!found) - { - /* There was no partial instantiation. This happens - where C is a member template of A and it's used - in something like - - template struct B { A::C m; }; - B; - - Create the partial instantiation. - */ - TREE_VEC_LENGTH (arglist)--; - found = tsubst (templ, arglist, complain, NULL_TREE); - TREE_VEC_LENGTH (arglist)++; - } + /* This is a full instantiation of a member template. Find + the partial instantiation of which this is an instance. */ + + /* Temporarily reduce by one the number of levels in the ARGLIST + so as to avoid comparing the last set of arguments. */ + TREE_VEC_LENGTH (arglist)--; + found = tsubst (gen_tmpl, arglist, complain, NULL_TREE); + TREE_VEC_LENGTH (arglist)++; + found = CLASSTYPE_TI_TEMPLATE (found); } SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); + + elt.spec = t; + slot = (spec_entry **) htab_find_slot_with_hash (type_specializations, + &elt, hash, INSERT); + *slot = GGC_NEW (spec_entry); + **slot = elt; + + /* Note this use of the partial instantiation so we can check it + later in maybe_process_partial_specialization. */ DECL_TEMPLATE_INSTANTIATIONS (templ) = tree_cons (arglist, t, DECL_TEMPLATE_INSTANTIATIONS (templ)); @@ -6259,6 +6647,7 @@ uses_template_parms (tree t) || TREE_CODE (t) == BASELINK || TREE_CODE (t) == IDENTIFIER_NODE || TREE_CODE (t) == TRAIT_EXPR + || TREE_CODE (t) == CONSTRUCTOR || CONSTANT_CLASS_P (t)) dependent_p = (type_dependent_expression_p (t) || value_dependent_expression_p (t)); @@ -6378,6 +6767,30 @@ outermost_tinst_level (void) return level; } +/* Returns TRUE if PARM is a parameter of the template TEMPL. */ + +bool +parameter_of_template_p (tree parm, tree templ) +{ + tree parms; + int i; + + if (!parm || !templ) + return false; + + gcc_assert (DECL_TEMPLATE_PARM_P (parm)); + gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); + + parms = DECL_TEMPLATE_PARMS (templ); + parms = INNERMOST_TEMPLATE_PARMS (parms); + + for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) + if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i))) + return true; + + return false; +} + /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. @@ -6545,46 +6958,58 @@ tsubst_friend_function (tree decl, tree args) ; else { + tree new_template = TI_TEMPLATE (new_friend_template_info); + tree new_args = TI_ARGS (new_friend_template_info); + /* Overwrite whatever template info was there before, if any, with the new template information pertaining to the declaration. */ DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; if (TREE_CODE (old_decl) != TEMPLATE_DECL) - reregister_specialization (new_friend, - most_general_template (old_decl), - old_decl); + /* We should have called reregister_specialization in + duplicate_decls. */ + gcc_assert (retrieve_specialization (new_template, + new_args, 0) + == old_decl); else { tree t; - tree new_friend_args; + /* Indicate that the old function template is a partial + instantiation. */ 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); + gcc_assert (new_template + == most_general_template (new_template)); + gcc_assert (new_template != old_decl); + + /* Reassign any specializations already in the hash table + to the new more general template, and add the + additional template args. */ + for (t = DECL_TEMPLATE_INSTANTIATIONS (old_decl); t != NULL_TREE; t = TREE_CHAIN (t)) { tree spec = TREE_VALUE (t); + spec_entry elt; + + elt.tmpl = old_decl; + elt.args = DECL_TI_ARGS (spec); + elt.spec = NULL_TREE; + + htab_remove_elt (decl_specializations, &elt); DECL_TI_ARGS (spec) - = add_outermost_template_args (new_friend_args, + = add_outermost_template_args (new_args, DECL_TI_ARGS (spec)); - } - /* Now, since specializations are always supposed to - hang off of the most general template, we must move - them. */ - t = most_general_template (old_decl); - if (t != old_decl) - { - DECL_TEMPLATE_SPECIALIZATIONS (t) - = chainon (DECL_TEMPLATE_SPECIALIZATIONS (t), - DECL_TEMPLATE_SPECIALIZATIONS (old_decl)); - DECL_TEMPLATE_SPECIALIZATIONS (old_decl) = NULL_TREE; + register_specialization + (spec, new_template, DECL_TI_ARGS (spec), true, 0); + } + DECL_TEMPLATE_INSTANTIATIONS (old_decl) = NULL_TREE; } } @@ -6839,6 +7264,40 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, } } +/* Perform (or defer) access check for typedefs that were referenced + from within the template TMPL code. + This is a subroutine of instantiate_template and instantiate_class_template. + TMPL is the template to consider and TARGS is the list of arguments of + that template. */ + +static void +perform_typedefs_access_check (tree tmpl, tree targs) +{ + tree t; + + if (!tmpl + || (!CLASS_TYPE_P (tmpl) + && TREE_CODE (tmpl) != FUNCTION_DECL)) + return; + + for (t = get_types_needing_access_check (tmpl); t; t = TREE_CHAIN (t)) + { + tree type_decl = TREE_PURPOSE (t); + tree type_scope = TREE_VALUE (t); + + if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope)) + continue; + + if (uses_template_parms (type_decl)) + type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE); + if (uses_template_parms (type_scope)) + type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE); + + perform_or_defer_access_check (TYPE_BINFO (type_scope), + type_decl, type_decl); + } +} + tree instantiate_class_template (tree type) { @@ -6909,9 +7368,9 @@ instantiate_class_template (tree type) SET_CLASSTYPE_INTERFACE_UNKNOWN (type); - /* Set the input location to the template definition. This is needed - if tsubsting causes an error. */ - typedecl = TYPE_MAIN_DECL (type); + /* Set the input location to the most specialized template definition. + This is needed if tsubsting causes an error. */ + typedecl = TYPE_MAIN_DECL (pattern); input_location = DECL_SOURCE_LOCATION (typedecl); TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern); @@ -7314,6 +7773,12 @@ instantiate_class_template (tree type) && DECL_TEMPLATE_INFO (t)) tsubst_default_arguments (t); + /* Some typedefs referenced from within the template code need to be access + checked at template instantiation time, i.e now. These types were + added to the template at parsing time. Let's get those and perform + the access checks then. */ + perform_typedefs_access_check (pattern, args); + perform_deferred_access_checks (); pop_nested_class (); pop_from_top_level (); pop_deferring_access_checks (); @@ -7347,6 +7812,37 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) return r; } +/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a + NONTYPE_ARGUMENT_PACK. */ + +static tree +make_fnparm_pack (tree spec_parm) +{ + /* Collect all of the extra "packed" parameters into an + argument pack. */ + tree parmvec; + tree parmtypevec; + tree argpack = make_node (NONTYPE_ARGUMENT_PACK); + tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK); + int i, len = list_length (spec_parm); + + /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ + parmvec = make_tree_vec (len); + parmtypevec = make_tree_vec (len); + for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + { + TREE_VEC_ELT (parmvec, i) = spec_parm; + TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); + } + + /* Build the argument packs. */ + SET_ARGUMENT_PACK_ARGS (argpack, parmvec); + SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); + TREE_TYPE (argpack) = argtypepack; + + return argpack; +} + /* Substitute ARGS into T, which is an pack expansion (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node @@ -7361,6 +7857,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree first_arg_pack; int i, len = -1; tree result; int incomplete = 0; + bool very_local_specializations = false; gcc_assert (PACK_EXPANSION_P (t)); pattern = PACK_EXPANSION_PATTERN (t); @@ -7377,7 +7874,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree orig_arg = NULL_TREE; if (TREE_CODE (parm_pack) == PARM_DECL) - arg_pack = retrieve_local_specialization (parm_pack); + { + arg_pack = retrieve_local_specialization (parm_pack); + if (arg_pack == NULL_TREE) + { + /* This can happen for a parameter name used later in a function + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (cp_unevaluated_operand != 0); + arg_pack = tsubst_decl (parm_pack, args, complain); + arg_pack = make_fnparm_pack (arg_pack); + } + } else { int level, idx, levels; @@ -7464,13 +7972,31 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, and return a PACK_EXPANSION_*. The caller will need to deal with that. */ if (unsubstituted_packs) - return make_pack_expansion (tsubst (pattern, args, complain, - in_decl)); + { + tree new_pat; + if (TREE_CODE (t) == EXPR_PACK_EXPANSION) + new_pat = tsubst_expr (pattern, args, complain, in_decl, + /*integral_constant_expression_p=*/false); + else + new_pat = tsubst (pattern, args, complain, in_decl); + return make_pack_expansion (new_pat); + } /* We could not find any argument packs that work. */ if (len < 0) return error_mark_node; + if (!local_specializations) + { + /* We're in a late-specified return type, so we don't have a local + specializations table. Create one for doing this expansion. */ + very_local_specializations = true; + local_specializations = htab_create (37, + hash_local_specialization, + eq_local_specializations, + NULL); + } + /* For each argument in each argument pack, substitute into the pattern. */ result = make_tree_vec (len + incomplete); @@ -7532,7 +8058,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, break; } } - + /* Update ARGS to restore the substitution from parameter packs to their argument packs. */ for (pack = packs; pack; pack = TREE_CHAIN (pack)) @@ -7555,9 +8081,45 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } + if (very_local_specializations) + { + htab_delete (local_specializations); + local_specializations = NULL; + } + return result; } +/* Given PARM_DECL PARM, find the corresponding PARM_DECL in the template + TMPL. We do this using DECL_PARM_INDEX, which should work even with + parameter packs; all parms generated from a function parameter pack will + have the same DECL_PARM_INDEX. */ + +tree +get_pattern_parm (tree parm, tree tmpl) +{ + tree pattern = DECL_TEMPLATE_RESULT (tmpl); + tree patparm; + + if (DECL_ARTIFICIAL (parm)) + { + for (patparm = DECL_ARGUMENTS (pattern); + patparm; patparm = TREE_CHAIN (patparm)) + if (DECL_ARTIFICIAL (patparm) + && DECL_NAME (parm) == DECL_NAME (patparm)) + break; + } + else + { + patparm = FUNCTION_FIRST_USER_PARM (DECL_TEMPLATE_RESULT (tmpl)); + patparm = chain_index (DECL_PARM_INDEX (parm)-1, patparm); + gcc_assert (DECL_PARM_INDEX (patparm) + == DECL_PARM_INDEX (parm)); + } + + return patparm; +} + /* Substitute ARGS into the vector or list of template arguments T. */ static tree @@ -7592,7 +8154,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) else if (ARGUMENT_PACK_P (orig_arg)) { /* Substitute into each of the arguments. */ - new_arg = make_node (TREE_CODE (orig_arg)); + new_arg = TYPE_P (orig_arg) + ? cxx_make_type (TREE_CODE (orig_arg)) + : make_node (TREE_CODE (orig_arg)); SET_ARGUMENT_PACK_ARGS ( new_arg, @@ -7747,11 +8311,14 @@ tsubst_aggr_type (tree t, tree argvec; tree context; tree r; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* In "sizeof(X)" we need to evaluate "I". */ - saved_skip_evaluation = skip_evaluation; - skip_evaluation = false; + saved_unevaluated_operand = cp_unevaluated_operand; + cp_unevaluated_operand = 0; + saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + c_inhibit_evaluation_warnings = 0; /* First, determine the context for the type we are looking up. */ @@ -7786,7 +8353,8 @@ tsubst_aggr_type (tree t, r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); } - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; return r; } @@ -7850,11 +8418,11 @@ tsubst_default_argument (tree fn, tree type, tree arg) cp_function_chain->x_current_class_ref = saved_class_ref; } - pop_access_scope (fn); - /* Make sure the default argument is reasonable. */ arg = check_default_argument (type, arg); + pop_access_scope (fn); + return arg; } @@ -7892,6 +8460,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) location_t saved_loc; tree r = NULL_TREE; tree in_decl = t; + hashval_t hash = 0; /* Set the filename and linenumber to improve error-reporting. */ saved_loc = input_location; @@ -7902,8 +8471,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) case TEMPLATE_DECL: { /* We can get here when processing a member function template, - member class template, and template template parameter of - a template class. */ + member class template, or template template parameter. */ tree decl = DECL_TEMPLATE_RESULT (t); tree spec; tree tmpl_args; @@ -7920,7 +8488,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) TREE_CHAIN (r) = NULL_TREE; TREE_TYPE (r) = new_type; DECL_TEMPLATE_RESULT (r) - = build_decl (TYPE_DECL, DECL_NAME (decl), new_type); + = build_decl (DECL_SOURCE_LOCATION (decl), + TYPE_DECL, DECL_NAME (decl), new_type); DECL_TEMPLATE_PARMS (r) = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, complain); @@ -7946,13 +8515,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) 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); + /* If this is a default template template argument, + tsubst might not have changed anything. */ + if (full_args == tmpl_args) + return t; - spec = retrieve_specialization (t, full_args, - /*class_specializations_p=*/true); + hash = hash_tmpl_and_args (t, full_args); + spec = retrieve_specialization (t, full_args, hash); if (spec != NULL_TREE) { r = spec; @@ -8019,7 +8588,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Record this non-type partial instantiation. */ register_specialization (r, t, DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)), - false); + false, hash); } break; @@ -8061,8 +8630,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) args, complain, in_decl); /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, argvec, - /*class_specializations_p=*/false); + hash = hash_tmpl_and_args (gen_tmpl, argvec); + spec = retrieve_specialization (gen_tmpl, argvec, hash); if (spec) { @@ -8179,14 +8748,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) DECL_PENDING_INLINE_INFO (r) = 0; DECL_PENDING_INLINE_P (r) = 0; DECL_SAVED_TREE (r) = NULL_TREE; + DECL_STRUCT_FUNCTION (r) = NULL; TREE_USED (r) = 0; - if (DECL_CLONED_FUNCTION (r)) - { - DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t), - args, complain, t); - TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r)); - TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r; - } + /* We'll re-clone as appropriate in instantiate_template. */ + DECL_CLONED_FUNCTION (r) = NULL_TREE; /* Set up the DECL_TEMPLATE_INFO for R. There's no need to do this in the special friend case mentioned above where @@ -8196,7 +8761,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) DECL_TEMPLATE_INFO (r) = tree_cons (gen_tmpl, argvec, NULL_TREE); SET_DECL_IMPLICIT_INSTANTIATION (r); - register_specialization (r, gen_tmpl, argvec, false); + register_specialization (r, gen_tmpl, argvec, false, hash); /* We're not supposed to instantiate default arguments until they are called, for a template. But, for a @@ -8317,6 +8882,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (DECL_TEMPLATE_PARM_P (t)) SET_DECL_TEMPLATE_PARM_P (r); + /* An argument of a function parameter pack is not a parameter + pack. */ + FUNCTION_PARAMETER_PACK_P (r) = false; + if (expanded_types) /* We're on the Ith parameter of the function parameter pack. */ @@ -8411,6 +8980,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tsubst_copy (DECL_NAME (t), args, complain, in_decl)); if (!r) r = error_mark_node; + else + { + TREE_PROTECTED (r) = TREE_PROTECTED (t); + TREE_PRIVATE (r) = TREE_PRIVATE (t); + } } else { @@ -8481,9 +9055,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) 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)); + hash = hash_tmpl_and_args (gen_tmpl, argvec); + spec = retrieve_specialization (gen_tmpl, argvec, hash); } } else @@ -8595,10 +9168,26 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) processing here. */ DECL_EXTERNAL (r) = 1; - register_specialization (r, gen_tmpl, argvec, false); + register_specialization (r, gen_tmpl, argvec, false, hash); DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE); SET_DECL_IMPLICIT_INSTANTIATION (r); } + else if (cp_unevaluated_operand) + { + /* We're substituting this var in a decltype outside of its + scope, such as for a lambda return type. Don't add it to + local_specializations, do perform auto deduction. */ + tree auto_node = type_uses_auto (type); + tree init + = tsubst_expr (DECL_INITIAL (t), args, complain, in_decl, + /*constant_expression_p=*/false); + + if (auto_node && init && describable_type (init)) + { + type = do_auto_deduction (type, init, auto_node); + TREE_TYPE (r) = type; + } + } else register_local_specialization (r, t); @@ -8885,7 +9474,7 @@ tsubst_exception_specification (tree fntype, This function is used for dealing with types, decls and the like; for expressions, use tsubst_expr or tsubst_copy. */ -static tree +tree tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree type, r; @@ -8901,6 +9490,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (DECL_P (t)) return tsubst_decl (t, args, complain); + if (args == NULL_TREE) + return t; + if (TREE_CODE (t) == IDENTIFIER_NODE) type = IDENTIFIER_TYPE_VALUE (t); else @@ -8922,7 +9514,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl)); tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl); - r = retrieve_specialization (tmpl, gen_args, false); + r = retrieve_specialization (tmpl, gen_args, 0); } else if (DECL_FUNCTION_SCOPE_P (decl) && DECL_TEMPLATE_INFO (DECL_CONTEXT (decl)) @@ -8985,10 +9577,29 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) max = tsubst_expr (omax, args, complain, in_decl, /*integral_constant_expression_p=*/false); + + /* Fix up type of the magic NOP_EXPR with TREE_SIDE_EFFECTS if + needed. */ + if (TREE_CODE (max) == NOP_EXPR + && TREE_SIDE_EFFECTS (omax) + && !TREE_TYPE (max)) + TREE_TYPE (max) = TREE_TYPE (TREE_OPERAND (max, 0)); + max = fold_decl_constant_value (max); + /* If we're in a partial instantiation, preserve the magic NOP_EXPR + with TREE_SIDE_EFFECTS that indicates this is not an integral + constant expression. */ + if (processing_template_decl + && TREE_SIDE_EFFECTS (omax) && TREE_CODE (omax) == NOP_EXPR) + { + gcc_assert (TREE_CODE (max) == NOP_EXPR); + TREE_SIDE_EFFECTS (max) = 1; + } + if (TREE_CODE (max) != INTEGER_CST && !at_function_scope_p () + && !TREE_SIDE_EFFECTS (max) && !value_dependent_expression_p (max)) { if (complain & tf_error) @@ -9424,7 +10035,8 @@ 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_build2 (TREE_CODE (t), TREE_TYPE (t), e1, e2); + return fold_build2_loc (input_location, + TREE_CODE (t), TREE_TYPE (t), e1, e2); } case NEGATE_EXPR: @@ -9434,7 +10046,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (e == error_mark_node) return error_mark_node; - return fold_build1 (TREE_CODE (t), TREE_TYPE (t), e); + return fold_build1_loc (input_location, TREE_CODE (t), TREE_TYPE (t), e); } case TYPENAME_TYPE: @@ -9463,7 +10075,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) But, such constructs have already been resolved by this point, so here CTX really should have complete type, unless it's a partial instantiation. */ - ctx = complete_type (ctx); + if (!(complain & tf_no_class_instantiations)) + ctx = complete_type (ctx); if (!COMPLETE_TYPE_P (ctx)) { if (complain & tf_error) @@ -9556,12 +10169,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree type; - type = - finish_decltype_type (tsubst_expr - (DECLTYPE_TYPE_EXPR (t), args, - complain, in_decl, - /*integral_constant_expression_p=*/false), - DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t)); + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + + type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args, + complain, in_decl, + /*integral_constant_expression_p=*/false); + + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; + + if (DECLTYPE_FOR_LAMBDA_CAPTURE (t)) + type = lambda_capture_field_type (type); + else if (DECLTYPE_FOR_LAMBDA_RETURN (t)) + type = lambda_return_type (type); + else + type = finish_decltype_type + (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t)); return cp_build_qualified_type_real (type, cp_type_quals (t) | cp_type_quals (type), @@ -9571,7 +10195,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: { - tree r = make_node (TREE_CODE (t)); + tree r = TYPE_P (t) + ? cxx_make_type (TREE_CODE (t)) + : make_node (TREE_CODE (t)); tree packed_out = tsubst_template_args (ARGUMENT_PACK_ARGS (t), args, @@ -9709,16 +10335,29 @@ tsubst_qualified_id (tree qualified_id, tree args, expr = name; if (dependent_type_p (scope)) - return build_qualified_name (/*type=*/NULL_TREE, - scope, expr, - QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + { + tree type = NULL_TREE; + if (DECL_P (expr) && !dependent_scope_p (scope)) + type = TREE_TYPE (expr); + return build_qualified_name (type, scope, expr, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + } if (!BASELINK_P (name) && !DECL_P (expr)) { 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; + { + /* A BIT_NOT_EXPR is used to represent a destructor. */ + if (!check_dtor_name (scope, TREE_OPERAND (expr, 0))) + { + error ("qualifying type %qT does not match destructor name ~%qT", + scope, TREE_OPERAND (expr, 0)); + expr = error_mark_node; + } + else + expr = lookup_qualified_name (scope, complete_dtor_identifier, + /*is_type_p=*/0, false); + } else expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL @@ -9787,7 +10426,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) enum tree_code code; tree r; - if (t == NULL_TREE || t == error_mark_node) + if (t == NULL_TREE || t == error_mark_node || args == NULL_TREE) return t; code = TREE_CODE (t); @@ -9796,7 +10435,24 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) { case PARM_DECL: r = retrieve_local_specialization (t); - gcc_assert (r != NULL); + + if (r == NULL) + { + tree c; + /* This can happen for a parameter name used later in a function + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (cp_unevaluated_operand != 0); + /* We copy T because want to tsubst the PARM_DECL only, + not the following PARM_DECLs that are chained to T. */ + c = copy_node (t); + r = tsubst_decl (c, args, complain); + /* Give it the template pattern as its context; its true context + hasn't been instantiated yet and this is good enough for + mangling. */ + DECL_CONTEXT (r) = DECL_CONTEXT (t); + } + if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) r = ARGUMENT_PACK_SELECT_ARG (r); mark_used (r); @@ -10277,7 +10933,7 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain, if (purpose) purpose = RECUR (purpose); value = TREE_VALUE (t); - if (value) + if (value && TREE_CODE (value) != LABEL_DECL) value = RECUR (value); chain = TREE_CHAIN (t); if (chain && chain != void_type_node) @@ -10297,12 +10953,22 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv, #define RECUR(NODE) \ tsubst_expr ((NODE), args, complain, in_decl, \ integral_constant_expression_p) - tree decl, init, cond, incr; + tree decl, init, cond, incr, auto_node; init = TREE_VEC_ELT (OMP_FOR_INIT (t), i); gcc_assert (TREE_CODE (init) == MODIFY_EXPR); decl = RECUR (TREE_OPERAND (init, 0)); init = TREE_OPERAND (init, 1); + auto_node = type_uses_auto (TREE_TYPE (decl)); + if (auto_node && init) + { + tree init_expr = init; + if (TREE_CODE (init_expr) == DECL_EXPR) + init_expr = DECL_INITIAL (DECL_EXPR_DECL (init_expr)); + init_expr = RECUR (init_expr); + TREE_TYPE (decl) + = do_auto_deduction (TREE_TYPE (decl), init_expr, auto_node); + } gcc_assert (!type_dependent_expression_p (decl)); if (!CLASS_TYPE_P (TREE_TYPE (decl))) @@ -10340,7 +11006,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv, } if (c == NULL) { - c = build_omp_clause (OMP_CLAUSE_PRIVATE); + c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); OMP_CLAUSE_DECL (c) = decl; c = finish_omp_clauses (c); if (c) @@ -10533,13 +11199,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, pack expansion where the parameter packs used in that expansion were of length zero. */ - init = build_default_init (TREE_TYPE (decl), - NULL_TREE); + init = build_value_init (TREE_TYPE (decl)); else init = t; } - finish_decl (decl, init, NULL_TREE); + cp_finish_decl (decl, init, false, NULL_TREE, 0); } } } @@ -10626,12 +11291,20 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, break; case CASE_LABEL_EXPR: - finish_case_label (RECUR (CASE_LOW (t)), + finish_case_label (EXPR_LOCATION (t), + RECUR (CASE_LOW (t)), RECUR (CASE_HIGH (t))); break; case LABEL_EXPR: - finish_label_stmt (DECL_NAME (LABEL_EXPR_LABEL (t))); + { + tree decl = LABEL_EXPR_LABEL (t); + tree label; + + label = finish_label_stmt (DECL_NAME (decl)); + if (DECL_ATTRIBUTES (decl) != NULL_TREE) + cplus_decl_attributes (&label, DECL_ATTRIBUTES (decl), 0); + } break; case GOTO_EXPR: @@ -10652,7 +11325,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, 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)); + tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl), + tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl)); { tree asm_expr = tmp; if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR) @@ -11056,7 +11730,8 @@ tsubst_copy_and_build (tree t, 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)); + return finish_label_address_expr (DECL_NAME (op1), + EXPR_LOCATION (op1)); return build_x_unary_op (ADDR_EXPR, op1, complain); case PLUS_EXPR: @@ -11109,16 +11784,7 @@ tsubst_copy_and_build (tree t, case ARRAY_REF: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); - return build_x_binary_op (ARRAY_REF, op1, - (TREE_NO_WARNING (TREE_OPERAND (t, 0)) - ? ERROR_MARK - : TREE_CODE (TREE_OPERAND (t, 0))), - RECUR (TREE_OPERAND (t, 1)), - (TREE_NO_WARNING (TREE_OPERAND (t, 1)) - ? ERROR_MARK - : TREE_CODE (TREE_OPERAND (t, 1))), - /*overloaded_p=*/NULL, - complain); + return build_x_array_ref (op1, RECUR (TREE_OPERAND (t, 1)), complain); case SIZEOF_EXPR: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) @@ -11137,11 +11803,13 @@ tsubst_copy_and_build (tree t, } else { - ++skip_evaluation; + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; op1 = tsubst_copy_and_build (op1, args, complain, in_decl, /*function_p=*/false, /*integral_constant_expression_p=*/false); - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; } if (TYPE_P (op1)) return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), @@ -11178,24 +11846,54 @@ tsubst_copy_and_build (tree t, case NEW_EXPR: { + tree placement = RECUR (TREE_OPERAND (t, 0)); tree init = RECUR (TREE_OPERAND (t, 3)); + VEC(tree,gc) *placement_vec; + VEC(tree,gc) *init_vec; + tree ret; - if (TREE_OPERAND (t, 3) && !init) - /* If there was an initializer in the original tree, but - it instantiated to an empty list, then we should pass on - VOID_ZERO_NODE to tell build_new that it was an empty - initializer () rather than no initializer. This can only - happen when the initializer is a pack expansion whose - parameter packs are of length zero. */ - init = void_zero_node; + if (placement == NULL_TREE) + placement_vec = NULL; + else + { + placement_vec = make_tree_vector (); + for (; placement != NULL_TREE; placement = TREE_CHAIN (placement)) + VEC_safe_push (tree, gc, placement_vec, TREE_VALUE (placement)); + } - return build_new - (RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1)), - RECUR (TREE_OPERAND (t, 2)), - init, - NEW_EXPR_USE_GLOBAL (t), - complain); + /* If there was an initializer in the original tree, but it + instantiated to an empty list, then we should pass a + non-NULL empty vector to tell build_new that it was an + empty initializer() rather than no initializer. This can + only happen when the initializer is a pack expansion whose + parameter packs are of length zero. */ + if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE) + init_vec = NULL; + else + { + init_vec = make_tree_vector (); + if (init == void_zero_node) + gcc_assert (init_vec != NULL); + else + { + for (; init != NULL_TREE; init = TREE_CHAIN (init)) + VEC_safe_push (tree, gc, init_vec, TREE_VALUE (init)); + } + } + + ret = build_new (&placement_vec, + RECUR (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2)), + &init_vec, + NEW_EXPR_USE_GLOBAL (t), + complain); + + if (placement_vec != NULL) + release_tree_vector (placement_vec); + if (init_vec != NULL) + release_tree_vector (init_vec); + + return ret; } case DELETE_EXPR: @@ -11213,9 +11911,11 @@ tsubst_copy_and_build (tree t, case CALL_EXPR: { tree function; - tree call_args; + VEC(tree,gc) *call_args; + unsigned int nargs, i; bool qualified_p; bool koenig_p; + tree ret; function = CALL_EXPR_FN (t); /* When we parsed the expression, we determined whether or @@ -11250,8 +11950,40 @@ tsubst_copy_and_build (tree t, qualified_p = true; } - /* FIXME: Rewrite this so as not to construct an arglist. */ - call_args = RECUR (CALL_EXPR_ARGS (t)); + nargs = call_expr_nargs (t); + call_args = make_tree_vector (); + for (i = 0; i < nargs; ++i) + { + tree arg = CALL_EXPR_ARG (t, i); + + if (!PACK_EXPANSION_P (arg)) + VEC_safe_push (tree, gc, call_args, + RECUR (CALL_EXPR_ARG (t, i))); + else + { + /* Expand the pack expansion and push each entry onto + CALL_ARGS. */ + arg = tsubst_pack_expansion (arg, args, complain, in_decl); + if (TREE_CODE (arg) == TREE_VEC) + { + unsigned int len, j; + + len = TREE_VEC_LENGTH (arg); + for (j = 0; j < len; ++j) + { + tree value = TREE_VEC_ELT (arg, j); + if (value != NULL_TREE) + value = convert_from_reference (value); + VEC_safe_push (tree, gc, call_args, value); + } + } + else + { + /* A partial substitution. Add one entry. */ + VEC_safe_push (tree, gc, call_args, arg); + } + } + } /* We do not perform argument-dependent lookup if normal lookup finds a non-function, in accordance with the @@ -11262,12 +11994,17 @@ tsubst_copy_and_build (tree t, not appropriate, even if an unqualified-name was used to denote the function. */ && !DECL_FUNCTION_MEMBER_P (get_first_fn (function))) - || TREE_CODE (function) == IDENTIFIER_NODE)) + || TREE_CODE (function) == IDENTIFIER_NODE) + /* Only do this when substitution turns a dependent call + into a non-dependent call. */ + && type_dependent_expression_p_push (t) + && !any_type_dependent_arguments_p (call_args)) function = perform_koenig_lookup (function, call_args); if (TREE_CODE (function) == IDENTIFIER_NODE) { unqualified_name_lookup_error (function); + release_tree_vector (call_args); return error_mark_node; } @@ -11276,27 +12013,32 @@ tsubst_copy_and_build (tree t, mark_used (function); if (TREE_CODE (function) == OFFSET_REF) - return build_offset_ref_call_from_tree (function, call_args); - if (TREE_CODE (function) == COMPONENT_REF) + ret = build_offset_ref_call_from_tree (function, &call_args); + else if (TREE_CODE (function) == COMPONENT_REF) { if (!BASELINK_P (TREE_OPERAND (function, 1))) - return finish_call_expr (function, call_args, + ret = finish_call_expr (function, &call_args, /*disallow_virtual=*/false, /*koenig_p=*/false, complain); else - return (build_new_method_call + ret = (build_new_method_call (TREE_OPERAND (function, 0), TREE_OPERAND (function, 1), - call_args, NULL_TREE, + &call_args, NULL_TREE, qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, /*fn_p=*/NULL, complain)); } - return finish_call_expr (function, call_args, - /*disallow_virtual=*/qualified_p, - koenig_p, - complain); + else + ret = finish_call_expr (function, &call_args, + /*disallow_virtual=*/qualified_p, + koenig_p, + complain); + + release_tree_vector (call_args); + + return ret; } case COND_EXPR: @@ -11572,6 +12314,7 @@ tsubst_copy_and_build (tree t, } r = build_constructor (init_list_type_node, n); + CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t); if (TREE_HAS_CONSTRUCTOR (t)) return finish_compound_literal (type, r); @@ -11648,6 +12391,39 @@ tsubst_copy_and_build (tree t, } return t; + case LAMBDA_EXPR: + { + tree r = build_lambda_expr (); + + tree type = tsubst (TREE_TYPE (t), args, complain, NULL_TREE); + TREE_TYPE (r) = type; + CLASSTYPE_LAMBDA_EXPR (type) = r; + + LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (r) + = LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (t); + LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t); + LAMBDA_EXPR_DISCRIMINATOR (r) + = (LAMBDA_EXPR_DISCRIMINATOR (t)); + LAMBDA_EXPR_CAPTURE_LIST (r) + = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)); + LAMBDA_EXPR_THIS_CAPTURE (r) + = RECUR (LAMBDA_EXPR_THIS_CAPTURE (t)); + LAMBDA_EXPR_EXTRA_SCOPE (r) + = RECUR (LAMBDA_EXPR_EXTRA_SCOPE (t)); + + /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ + determine_visibility (TYPE_NAME (type)); + /* Now that we know visibility, instantiate the type so we have a + declaration of the op() for later calls to lambda_function. */ + complete_type (type); + + type = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl); + if (type) + apply_lambda_return_type (r, type); + + return build_lambda_object (r); + } + default: /* Handle Objective-C++ constructs, if appropriate. */ { @@ -11664,11 +12440,48 @@ tsubst_copy_and_build (tree t, } /* Verify that the instantiated ARGS are valid. For type arguments, - make sure that the type's linkage is ok. For non-type arguments, + make sure that the type is not variably modified. For non-type arguments, make sure they are constants if they are integral or enumerations. Emit an error under control of COMPLAIN, and return TRUE on error. */ static bool +check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain) +{ + if (ARGUMENT_PACK_P (t)) + { + tree vec = ARGUMENT_PACK_ARGS (t); + int len = TREE_VEC_LENGTH (vec); + bool result = false; + int i; + + for (i = 0; i < len; ++i) + if (check_instantiated_arg (tmpl, TREE_VEC_ELT (vec, i), complain)) + result = true; + return result; + } + else if (TYPE_P (t)) + { + if (variably_modified_type_p (t, NULL_TREE)) + { + if (complain & tf_error) + error ("%qT is a variably modified type", t); + return true; + } + } + /* A non-type argument of integral or enumerated type must be a + constant. */ + else if (TREE_TYPE (t) + && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) + && !TREE_CONSTANT (t)) + { + if (complain & tf_error) + error ("integral expression %qE is not constant", t); + return true; + } + return false; +} + +static bool check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) { int ix, len = DECL_NTPARMS (tmpl); @@ -11676,50 +12489,8 @@ 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 - of a class or enumeration declared in a local scope) - 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, /*relaxed_p=*/false); - - if (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, NULL_TREE)) - { - if (complain & tf_error) - error ("%qT is a variably modified type", t); - result = true; - } - } - /* A non-type argument of integral or enumerated type must be a - constant. */ - else if (TREE_TYPE (t) - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) - && !TREE_CONSTANT (t)) - { - if (complain & tf_error) - error ("integral expression %qE is not constant", t); - result = true; - } + if (check_instantiated_arg (tmpl, TREE_VEC_ELT (args, ix), complain)) + result = true; } if (result && (complain & tf_error)) error (" trying to instantiate %qD", tmpl); @@ -11730,8 +12501,9 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) the template arguments in TARG_PTR. */ tree -instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) +instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) { + tree targ_ptr = orig_args; tree fndecl; tree gen_tmpl; tree spec; @@ -11748,8 +12520,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) tree spec; tree clone; - spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr, - complain); + /* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have + DECL_CLONED_FUNCTION. */ + spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl), + targ_ptr, complain); if (spec == error_mark_node) return error_mark_node; @@ -11763,26 +12537,25 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) } /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (tmpl, targ_ptr, - /*class_specializations_p=*/false); - if (spec != NULL_TREE) - return spec; - gen_tmpl = most_general_template (tmpl); if (tmpl != gen_tmpl) - { - /* The TMPL is a partial instantiation. To get a full set of - arguments we must add the arguments used to perform the - partial instantiation. */ - targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl), - targ_ptr); + /* The TMPL is a partial instantiation. To get a full set of + arguments we must add the arguments used to perform the + partial instantiation. */ + targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl), + targ_ptr); - /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, targ_ptr, - /*class_specializations_p=*/false); - if (spec != NULL_TREE) - return spec; - } + /* It would be nice to avoid hashing here and then again in tsubst_decl, + but it doesn't seem to be on the hot path. */ + spec = retrieve_specialization (gen_tmpl, targ_ptr, 0); + + gcc_assert (tmpl == gen_tmpl + || ((fndecl = retrieve_specialization (tmpl, orig_args, 0)) + == spec) + || fndecl == NULL_TREE); + + if (spec != NULL_TREE) + return spec; if (check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (targ_ptr), complain)) @@ -11813,6 +12586,12 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) /* Now we know the specialization, compute access previously deferred. */ push_access_scope (fndecl); + + /* Some typedefs referenced from within the template code need to be access + checked at template instantiation time, i.e now. These types were + added to the template at parsing time. Let's get those and perfom + the acces checks then. */ + perform_typedefs_access_check (DECL_TEMPLATE_RESULT (tmpl), targ_ptr); perform_deferred_access_checks (); pop_access_scope (fndecl); pop_deferring_access_checks (); @@ -11831,9 +12610,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) return fndecl; } -/* 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. +/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with + NARGS elements of the arguments that are being used when calling + it. TARGS is a vector 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 @@ -11865,7 +12645,8 @@ int fn_type_unification (tree fn, tree explicit_targs, tree targs, - tree args, + const tree *args, + unsigned int nargs, tree return_type, unification_kind_t strict, int flags) @@ -11982,8 +12763,14 @@ fn_type_unification (tree fn, if (return_type) { + tree *new_args; + parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms); - args = tree_cons (NULL_TREE, return_type, args); + new_args = XALLOCAVEC (tree, nargs + 1); + new_args[0] = return_type; + memcpy (new_args + 1, args, nargs * sizeof (tree)); + args = new_args; + ++nargs; } /* We allow incomplete unification without an error message here @@ -11991,7 +12778,7 @@ fn_type_unification (tree fn, callers must be ready to deal with unification failures in any event. */ result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), - targs, parms, args, /*subr=*/0, + targs, parms, args, nargs, /*subr=*/0, strict, flags); if (result == 0 && incomplete_argument_packs_p) @@ -12046,9 +12833,27 @@ fn_type_unification (tree fn, the corresponding deduced argument values. If the substitution results in an invalid type, as described above, type deduction fails. */ - if (tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE) - == error_mark_node) - return 1; + { + tree substed = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE); + if (substed == error_mark_node) + return 1; + + /* If we're looking for an exact match, check that what we got + is indeed an exact match. It might not be if some template + parameters are used in non-deduced contexts. */ + if (strict == DEDUCE_EXACT) + { + unsigned int i; + + tree sarg + = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed)); + if (return_type) + sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg); + for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg)) + if (!same_type_p (args[i], TREE_VALUE (sarg))) + return 1; + } + } return result; } @@ -12160,7 +12965,8 @@ static int type_unification_real (tree tparms, tree targs, tree xparms, - tree xargs, + const tree *xargs, + unsigned int xnargs, int subr, unification_kind_t strict, int flags) @@ -12170,11 +12976,13 @@ type_unification_real (tree tparms, int ntparms = TREE_VEC_LENGTH (tparms); int sub_strict; int saw_undeduced = 0; - tree parms, args; + tree parms; + const tree *args; + unsigned int nargs; + unsigned int ia; 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) @@ -12199,17 +13007,19 @@ type_unification_real (tree tparms, again: parms = xparms; args = xargs; + nargs = xnargs; + ia = 0; while (parms && parms != void_list_node - && args && args != void_list_node) + && ia < nargs) { if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION) break; parm = TREE_VALUE (parms); parms = TREE_CHAIN (parms); - arg = TREE_VALUE (args); - args = TREE_CHAIN (args); + arg = args[ia]; + ++ia; arg_expr = NULL; if (arg == error_mark_node) @@ -12288,20 +13098,11 @@ type_unification_real (tree tparms, /* Unify the remaining arguments with the pack expansion type. */ tree argvec; tree parmvec = make_tree_vec (1); - int len = 0; - tree t; - /* Count the number of arguments that remain. */ - for (t = args; t && t != void_list_node; t = TREE_CHAIN (t)) - len++; - /* Allocate a TREE_VEC and copy in all of the arguments */ - argvec = make_tree_vec (len); - for (i = 0; args && args != void_list_node; args = TREE_CHAIN (args)) - { - TREE_VEC_ELT (argvec, i) = TREE_VALUE (args); - ++i; - } + argvec = make_tree_vec (nargs - ia); + for (i = 0; ia < nargs; ++ia, ++i) + TREE_VEC_ELT (argvec, i) = args[ia]; /* Copy the parameter into parmvec. */ TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms); @@ -12315,7 +13116,7 @@ type_unification_real (tree tparms, /* 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) + if (ia < nargs && parms == void_list_node) return 1; /* Fail if parms are left and they don't have default values. */ if (parms && parms != void_list_node @@ -12352,8 +13153,9 @@ type_unification_real (tree tparms, to explicitly check cxx_dialect here. */ if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i))) { - tree arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)), - targs, tf_none, NULL_TREE); + tree arg = tsubst_template_arg + (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)), + targs, tf_none, NULL_TREE); if (arg == error_mark_node) return 1; else @@ -12376,7 +13178,7 @@ type_unification_real (tree tparms, TREE_CONSTANT (arg) = 1; } else - arg = make_node (TYPE_ARGUMENT_PACK); + arg = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0)); @@ -12406,6 +13208,7 @@ resolve_overloaded_unification (tree tparms, { tree tempargs = copy_node (targs); int good = 0; + tree goodfn = NULL_TREE; bool addr_p; if (TREE_CODE (arg) == ADDR_EXPR) @@ -12451,8 +13254,13 @@ resolve_overloaded_unification (tree tparms, if (subargs) { elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE); - good += try_one_overload (tparms, targs, tempargs, parm, - elem, strict, sub_strict, addr_p); + if (try_one_overload (tparms, targs, tempargs, parm, + elem, strict, sub_strict, addr_p) + && (!goodfn || !decls_match (goodfn, elem))) + { + goodfn = elem; + ++good; + } } --processing_template_decl; } @@ -12465,9 +13273,14 @@ resolve_overloaded_unification (tree tparms, return false; else for (; arg; arg = OVL_NEXT (arg)) - good += try_one_overload (tparms, targs, tempargs, parm, - TREE_TYPE (OVL_CURRENT (arg)), - strict, sub_strict, addr_p); + if (try_one_overload (tparms, targs, tempargs, parm, + TREE_TYPE (OVL_CURRENT (arg)), + strict, sub_strict, addr_p) + && (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg)))) + { + goodfn = OVL_CURRENT (arg); + ++good; + } /* [temp.deduct.type] A template-argument can be deduced from a pointer to function or pointer to member function argument if the set of @@ -12846,7 +13659,9 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, match. */ if (resolve_overloaded_unification - (tparms, targs, parm, arg, strict, sub_strict) + (tparms, targs, parm, arg, + (unification_kind_t) strict, + sub_strict) != 0) return 1; skip_arg_p = true; @@ -12865,8 +13680,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, if (!subr) arg_strict |= - maybe_adjust_types_for_deduction (strict, &parm, &arg, - arg_expr); + maybe_adjust_types_for_deduction ((unification_kind_t) strict, + &parm, &arg, arg_expr); } if (!skip_arg_p) @@ -12940,7 +13755,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, TREE_CONSTANT (result) = 1; } else - result = make_node (TYPE_ARGUMENT_PACK); + result = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (result, new_args); @@ -13060,6 +13875,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) { tree elt, elttype; unsigned i; + tree orig_parm = parm; + + /* Replace T with std::initializer_list for deduction. */ + if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM + && flag_deduce_init_list) + parm = listify (parm); if (!is_std_init_list (parm)) /* We can only deduce from an initializer list argument if the @@ -13071,11 +13892,30 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt) { + int elt_strict = strict; if (!BRACE_ENCLOSED_INITIALIZER_P (elt)) - elt = TREE_TYPE (elt); - if (unify (tparms, targs, elttype, elt, UNIFY_ALLOW_NONE)) + { + tree type = TREE_TYPE (elt); + /* It should only be possible to get here for a call. */ + gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL); + elt_strict |= maybe_adjust_types_for_deduction + (DEDUCE_CALL, &elttype, &type, elt); + elt = type; + } + + if (unify (tparms, targs, elttype, elt, elt_strict)) return 1; } + + /* If the std::initializer_list deduction worked, replace the + deduced A with std::initializer_list. */ + if (orig_parm != parm) + { + idx = TEMPLATE_TYPE_IDX (orig_parm); + targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); + targ = listify (targ); + TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ; + } return 0; } @@ -13274,6 +14114,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ISO C++, so we can do as we please here. */ if (variably_modified_type_p (arg, NULL_TREE)) return 1; + + /* Strip typedefs as in convert_template_argument. */ + arg = strip_typedefs (arg); } /* If ARG is a parameter pack or an expansion, we cannot unify @@ -13282,6 +14125,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) && !template_parameter_pack_p (parm)) return 1; + /* If the argument deduction results is a METHOD_TYPE, + then there is a problem. + METHOD_TYPE doesn't map to any real C++ type the result of + the deduction can not be of that type. */ + if (TREE_CODE (arg) == METHOD_TYPE) + return 1; + TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; return 0; @@ -13324,7 +14174,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) /* Convert the ARG to the type of PARM; the deduced non-type template argument must exactly match the types of the corresponding parameter. */ - arg = fold (build_nop (TREE_TYPE (parm), arg)); + arg = fold (build_nop (tparm, arg)); else if (uses_template_parms (tparm)) /* We haven't deduced the type of this parameter yet. Try again later. */ @@ -13443,12 +14293,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) /* 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, + parm_max = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node, parm_max, integer_one_node); else if (arg_cst && !parm_cst) - arg_max = fold_build2 (PLUS_EXPR, + arg_max = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node, arg_max, integer_one_node); @@ -13565,26 +14415,42 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) case METHOD_TYPE: case FUNCTION_TYPE: - if (TREE_CODE (arg) != TREE_CODE (parm)) - return 1; + { + unsigned int nargs; + tree *args; + tree a; + unsigned int i; - /* 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 - cv-qualified 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 (TREE_CODE (arg) != TREE_CODE (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, - LOOKUP_NORMAL); + /* 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 + cv-qualified 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; + + nargs = list_length (TYPE_ARG_TYPES (arg)); + args = XALLOCAVEC (tree, nargs); + for (a = TYPE_ARG_TYPES (arg), i = 0; + a != NULL_TREE && a != void_list_node; + a = TREE_CHAIN (a), ++i) + args[i] = TREE_VALUE (a); + nargs = i; + + return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), + args, nargs, 1, DEDUCE_EXACT, + LOOKUP_NORMAL); + } case OFFSET_TYPE: /* Unify a pointer to member with a pointer to member function, which @@ -14138,6 +15004,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) tree targs = make_tree_vec (ntparms); tree decl_type; tree decl_arg_types; + tree *args; + unsigned int nargs, ix; + tree arg; /* Substitute the explicit template arguments into the type of DECL. The call to fn_type_unification will handle substitution into the @@ -14172,8 +15041,15 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) decl_arg_types = skip_artificial_parms_for (decl, TYPE_ARG_TYPES (decl_type)); + nargs = list_length (decl_arg_types); + args = XALLOCAVEC (tree, nargs); + for (arg = decl_arg_types, ix = 0; + arg != NULL_TREE && arg != void_list_node; + arg = TREE_CHAIN (arg), ++ix) + args[ix] = TREE_VALUE (arg); + if (fn_type_unification (fn, explicit_args, targs, - decl_arg_types, + args, ix, (check_rettype || DECL_CONV_FN_P (fn) ? TREE_TYPE (decl_type) : NULL_TREE), DEDUCE_EXACT, LOOKUP_NORMAL)) @@ -14184,7 +15060,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) /* 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 + TPARMS, and whose specialization arguments are SPEC_ARGS, yield the ARGS. For example, suppose we have: @@ -15000,6 +15876,27 @@ template_for_substitution (tree decl) return tmpl; } +/* Returns true if we need to instantiate this template instance even if we + know we aren't going to emit it.. */ + +bool +always_instantiate_p (tree decl) +{ + /* We always instantiate inline functions so that we can inline them. An + explicit instantiation declaration prohibits implicit instantiation of + non-inline functions. With high levels of optimization, we would + normally inline non-inline functions -- but we're not allowed to do + that for "extern template" functions. Therefore, we check + DECL_DECLARED_INLINE_P, rather than possibly_inlined_p. */ + return ((TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl)) + /* And we need to instantiate static data members so that + their initializers are available in integral constant + expressions. */ + || (TREE_CODE (decl) == VAR_DECL + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (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. Normally it is @@ -15041,25 +15938,37 @@ instantiate_decl (tree d, int defer_ok, if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d)) d = DECL_CLONED_FUNCTION (d); - if (DECL_TEMPLATE_INSTANTIATED (d)) - /* D has already been instantiated. It might seem reasonable to - check whether or not D is an explicit instantiation, and, if so, - stop here. But when an explicit instantiation is deferred - until the end of the compilation, DECL_EXPLICIT_INSTANTIATION - is set, even though we still need to do the instantiation. */ + if (DECL_TEMPLATE_INSTANTIATED (d) + || DECL_TEMPLATE_SPECIALIZATION (d)) + /* D has already been instantiated or explicitly specialized, so + there's nothing for us to do here. + + It might seem reasonable to check whether or not D is an explicit + instantiation, and, if so, stop here. But when an explicit + instantiation is deferred until the end of the compilation, + DECL_EXPLICIT_INSTANTIATION is set, even though we still need to do + the instantiation. */ + return 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 && !always_instantiate_p (d)) return d; - /* If we already have a specialization of this declaration, then - there's no reason to instantiate it. Note that - retrieve_specialization gives us both instantiations and - specializations, so we must explicitly check - DECL_TEMPLATE_SPECIALIZATION. */ gen_tmpl = most_general_template (tmpl); gen_args = DECL_TI_ARGS (d); - spec = retrieve_specialization (gen_tmpl, gen_args, - /*class_specializations_p=*/false); - if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec)) - return spec; + + if (tmpl != gen_tmpl) + /* We should already have the extra args. */ + gcc_assert (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl)) + == TMPL_ARGS_DEPTH (gen_args)); + /* And what's in the hash table should match D. */ + gcc_assert ((spec = retrieve_specialization (gen_tmpl, gen_args, 0)) == d + || spec == NULL_TREE); /* This needs to happen before any tsubsting. */ if (! push_tinst_level (d)) @@ -15115,10 +16024,11 @@ instantiate_decl (tree d, int defer_ok, SET_DECL_IMPLICIT_INSTANTIATION (d); } - if (!defer_ok) + /* Recheck the substitutions to obtain any warning messages + about ignoring cv qualifiers. Don't do this for artificial decls, + as it breaks the context-sensitive substitution for lambda op(). */ + if (!defer_ok && !DECL_ARTIFICIAL (d)) { - /* Recheck the substitutions to obtain any warning messages - about ignoring cv qualifiers. */ tree gen = DECL_TEMPLATE_RESULT (gen_tmpl); tree type = TREE_TYPE (gen); @@ -15143,21 +16053,6 @@ instantiate_decl (tree d, int defer_ok, pop_access_scope (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 - && possibly_inlined_p (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. */ if (/* If there is no definition, we cannot instantiate the @@ -15199,7 +16094,8 @@ instantiate_decl (tree d, int defer_ok, input_location = saved_loc; if (at_eof && !pattern_defined - && DECL_EXPLICIT_INSTANTIATION (d)) + && DECL_EXPLICIT_INSTANTIATION (d) + && DECL_NOT_REALLY_EXTERN (d)) /* [temp.explicit] The definition of a non-exported function template, a @@ -15260,7 +16156,7 @@ instantiate_decl (tree d, int defer_ok, /* The initializer is placed in DECL_INITIAL by regenerate_decl_from_template. Pull it out so that - finish_decl can process it. */ + cp_finish_decl can process it. */ init = DECL_INITIAL (d); DECL_INITIAL (d) = NULL_TREE; DECL_INITIALIZED_P (d) = 0; @@ -15272,7 +16168,7 @@ instantiate_decl (tree d, int defer_ok, /* Enter the scope of D so that access-checking works correctly. */ push_nested_class (DECL_CONTEXT (d)); - finish_decl (d, init, NULL_TREE); + cp_finish_decl (d, init, false, NULL_TREE, 0); pop_nested_class (); } else if (TREE_CODE (d) == FUNCTION_DECL) @@ -15313,37 +16209,12 @@ instantiate_decl (tree d, int defer_ok, } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { - /* Collect all of the extra "packed" parameters into an - argument pack. */ - tree parmvec; - tree parmtypevec; - tree argpack = make_node (NONTYPE_ARGUMENT_PACK); - tree argtypepack = make_node (TYPE_ARGUMENT_PACK); - int i, len = 0; - tree t; - - /* Count how many parameters remain. */ - for (t = spec_parm; t; t = TREE_CHAIN (t)) - len++; - - /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ - parmvec = make_tree_vec (len); - parmtypevec = make_tree_vec (len); - for(i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) - { - TREE_VEC_ELT (parmvec, i) = spec_parm; - TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); - } - - /* Build the argument packs. */ - SET_ARGUMENT_PACK_ARGS (argpack, parmvec); - SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); - TREE_TYPE (argpack) = argtypepack; - /* Register the (value) argument pack as a specialization of TMPL_PARM, then move on. */ + tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); tmpl_parm = TREE_CHAIN (tmpl_parm); + spec_parm = NULL_TREE; } gcc_assert (!spec_parm); @@ -15741,7 +16612,7 @@ current_instantiation (void) static int invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain) { - if (INTEGRAL_TYPE_P (type)) + if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) return 0; else if (POINTER_TYPE_P (type)) return 0; @@ -15819,9 +16690,9 @@ dependent_type_p_r (tree type) && !TREE_CONSTANT (TYPE_MAX_VALUE (type))) { /* If this is the TYPE_DOMAIN of an array type, consider it - dependent. */ - return (value_dependent_expression_p (TYPE_MAX_VALUE (type)) - || type_dependent_expression_p (TYPE_MAX_VALUE (type))); + dependent. We already checked for value-dependence in + compute_array_index_type. */ + return type_dependent_expression_p (TYPE_MAX_VALUE (type)); } /* -- a template-id in which either the template name is a template @@ -15916,6 +16787,17 @@ dependent_type_p (tree type) return TYPE_DEPENDENT_P (type); } +/* Returns TRUE if SCOPE is a dependent scope, in which we can't do any + lookup. In other words, a dependent type that is not the current + instantiation. */ + +bool +dependent_scope_p (tree scope) +{ + return (scope && TYPE_P (scope) && dependent_type_p (scope) + && !currently_open_class (scope)); +} + /* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ static bool @@ -15937,7 +16819,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) An id-expression is type-dependent if it contains a nested-name-specifier that contains a class-name that names a dependent type. */ - /* The suggested resolution to Core Issue 2 implies that if the + /* The suggested resolution to Core Issue 224 implies that if the qualifying type is the current class, then we must peek inside it. */ if (DECL_P (name) @@ -16244,19 +17126,31 @@ type_dependent_expression_p (tree expression) return (dependent_type_p (TREE_TYPE (expression))); } -/* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call) - contains a type-dependent expression. */ +/* Like type_dependent_expression_p, but it also works while not processing + a template definition, i.e. during substitution or mangling. */ bool -any_type_dependent_arguments_p (const_tree args) +type_dependent_expression_p_push (tree expr) { - while (args) - { - tree arg = TREE_VALUE (args); + bool b; + ++processing_template_decl; + b = type_dependent_expression_p (expr); + --processing_template_decl; + return b; +} + +/* Returns TRUE if ARGS contains a type-dependent expression. */ + +bool +any_type_dependent_arguments_p (const VEC(tree,gc) *args) +{ + unsigned int i; + tree arg; + for (i = 0; VEC_iterate (tree, args, i, arg); ++i) + { if (type_dependent_expression_p (arg)) return true; - args = TREE_CHAIN (args); } return false; } @@ -16498,7 +17392,15 @@ resolve_typename_type (tree type, bool only_current_p) gcc_assert (TREE_CODE (type) == TYPENAME_TYPE); scope = TYPE_CONTEXT (type); - name = TYPE_IDENTIFIER (type); + /* Usually the non-qualified identifier of a TYPENAME_TYPE is + TYPE_IDENTIFIER (type). But when 'type' is a typedef variant of + a TYPENAME_TYPE node, then TYPE_NAME (type) is set to the TYPE_DECL representing + the typedef. In that case TYPE_IDENTIFIER (type) is not the non-qualified + identifier of the TYPENAME_TYPE anymore. + So by getting the TYPE_IDENTIFIER of the _main declaration_ of the + TYPENAME_TYPE instead, we avoid messing up with a possible + typedef variant case. */ + name = TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type)); /* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve it first before we can figure out what NAME refers to. */ @@ -16668,22 +17570,22 @@ build_non_dependent_expr (tree expr) return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr); } -/* ARGS is a TREE_LIST of expressions as arguments to a function call. - Return a new TREE_LIST with the various arguments replaced with - equivalent non-dependent expressions. */ +/* ARGS is a vector of expressions as arguments to a function call. + Replace the arguments with equivalent non-dependent expressions. + This modifies ARGS in place. */ -tree -build_non_dependent_args (tree args) +void +make_args_non_dependent (VEC(tree,gc) *args) { - tree a; - tree new_args; + unsigned int ix; + tree arg; - new_args = NULL_TREE; - for (a = args; a; a = TREE_CHAIN (a)) - new_args = tree_cons (NULL_TREE, - build_non_dependent_expr (TREE_VALUE (a)), - new_args); - return nreverse (new_args); + for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix) + { + tree newarg = build_non_dependent_expr (arg); + if (newarg != arg) + VEC_replace (tree, args, ix, newarg); + } } /* Returns a type which represents 'auto'. We use a TEMPLATE_TYPE_PARM @@ -16696,7 +17598,8 @@ make_auto (void) /* ??? Is it worth caching this for multiple autos at the same level? */ au = cxx_make_type (TEMPLATE_TYPE_PARM); - TYPE_NAME (au) = build_decl (TYPE_DECL, get_identifier ("auto"), au); + TYPE_NAME (au) = build_decl (BUILTINS_LOCATION, + TYPE_DECL, get_identifier ("auto"), au); TYPE_STUB_DECL (au) = TYPE_NAME (au); TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index (0, processing_template_decl + 1, processing_template_decl + 1, @@ -16708,26 +17611,33 @@ make_auto (void) return au; } -/* Replace auto in TYPE with std::initializer_list. */ +/* Given type ARG, return std::initializer_list. */ static tree -listify_autos (tree type, tree auto_node) +listify (tree arg) { tree std_init_list = namespace_binding (get_identifier ("initializer_list"), std_node); tree argvec; - tree init_auto; if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list)) { - error ("deducing auto from brace-enclosed initializer list requires " + error ("deducing from brace-enclosed initializer list requires " "#include "); return error_mark_node; } argvec = make_tree_vec (1); - TREE_VEC_ELT (argvec, 0) = auto_node; - init_auto = lookup_template_class (std_init_list, argvec, NULL_TREE, - NULL_TREE, 0, tf_warning_or_error); + TREE_VEC_ELT (argvec, 0) = arg; + return lookup_template_class (std_init_list, argvec, NULL_TREE, + NULL_TREE, 0, tf_warning_or_error); +} +/* Replace auto in TYPE with std::initializer_list. */ + +static tree +listify_autos (tree type, tree auto_node) +{ + tree init_auto = listify (auto_node); + tree argvec = make_tree_vec (1); TREE_VEC_ELT (argvec, 0) = init_auto; if (processing_template_decl) argvec = add_to_template_args (current_template_args (), argvec); @@ -16740,7 +17650,8 @@ listify_autos (tree type, tree auto_node) tree do_auto_deduction (tree type, tree init, tree auto_node) { - tree parms, args, tparms, targs; + tree parms, tparms, targs; + tree args[1]; int val; /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto @@ -16751,12 +17662,12 @@ do_auto_deduction (tree type, tree init, tree auto_node) type = listify_autos (type, auto_node); parms = build_tree_list (NULL_TREE, type); - args = build_tree_list (NULL_TREE, init); + args[0] = init; tparms = make_tree_vec (1); targs = make_tree_vec (1); TREE_VEC_ELT (tparms, 0) = build_tree_list (NULL_TREE, TYPE_NAME (auto_node)); - val = type_unification_real (tparms, targs, parms, args, 0, + val = type_unification_real (tparms, targs, parms, args, 1, 0, DEDUCE_CALL, LOOKUP_NORMAL); if (val > 0) { @@ -16769,6 +17680,23 @@ do_auto_deduction (tree type, tree init, tree auto_node) return tsubst (type, targs, tf_warning_or_error, NULL_TREE); } +/* Substitutes LATE_RETURN_TYPE for 'auto' in TYPE and returns the + result. */ + +tree +splice_late_return_type (tree type, tree late_return_type) +{ + tree argvec; + + if (late_return_type == NULL_TREE) + return type; + argvec = make_tree_vec (1); + TREE_VEC_ELT (argvec, 0) = late_return_type; + if (processing_template_decl) + argvec = add_to_template_args (current_template_args (), argvec); + return tsubst (type, argvec, tf_warning_or_error, NULL_TREE); +} + /* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto'. */ bool @@ -16806,4 +17734,135 @@ type_uses_auto (tree type) return NULL_TREE; } +/* For a given template T, return the list of typedefs referenced + in T for which access check is needed at T instantiation time. + T is either a FUNCTION_DECL or a RECORD_TYPE. + Those typedefs were added to T by the function + append_type_to_template_for_access_check. */ + +tree +get_types_needing_access_check (tree t) +{ + tree ti, result = NULL_TREE; + + if (!t || t == error_mark_node) + return t; + + if (!(ti = get_template_info (t))) + return NULL_TREE; + + if (CLASS_TYPE_P (t) + || TREE_CODE (t) == FUNCTION_DECL) + { + if (!TI_TEMPLATE (ti)) + return NULL_TREE; + + result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti); + } + + return result; +} + +/* Append the typedef TYPE_DECL used in template T to a list of typedefs + tied to T. That list of typedefs will be access checked at + T instantiation time. + T is either a FUNCTION_DECL or a RECORD_TYPE. + TYPE_DECL is a TYPE_DECL node representing a typedef. + SCOPE is the scope through which TYPE_DECL is accessed. + + This function is a subroutine of + append_type_to_template_for_access_check. */ + +static void +append_type_to_template_for_access_check_1 (tree t, + tree type_decl, + tree scope) +{ + tree ti; + + if (!t || t == error_mark_node) + return; + + gcc_assert ((TREE_CODE (t) == FUNCTION_DECL + || CLASS_TYPE_P (t)) + && type_decl + && TREE_CODE (type_decl) == TYPE_DECL + && scope); + + if (!(ti = get_template_info (t))) + return; + + gcc_assert (TI_TEMPLATE (ti)); + + TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti) = + tree_cons (type_decl, scope, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti)); +} + +/* Append TYPE_DECL to the template TEMPL. + TEMPL is either a class type, a FUNCTION_DECL or a a TEMPLATE_DECL. + At TEMPL instanciation time, TYPE_DECL will be checked to see + if it can be accessed through SCOPE. + + e.g. consider the following code snippet: + + class C + { + typedef int myint; + }; + + template struct S + { + C::myint mi; + }; + + S s; + + At S instantiation time, we need to check the access of C::myint + In other words, we need to check the access of the myint typedef through + the C scope. For that purpose, this function will add the myint typedef + and the scope C through which its being accessed to a list of typedefs + tied to the template S. That list will be walked at template instantiation + time and access check performed on each typedefs it contains. + Note that this particular code snippet should yield an error because + myint is private to C. */ + +void +append_type_to_template_for_access_check (tree templ, + tree type_decl, + tree scope) +{ + tree node; + + gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL)); + + /* Make sure we don't append the type to the template twice. */ + for (node = get_types_needing_access_check (templ); + node; + node = TREE_CHAIN (node)) + { + tree decl = TREE_PURPOSE (node); + tree type_scope = TREE_VALUE (node); + + if (decl == type_decl && type_scope == scope) + return; + } + + append_type_to_template_for_access_check_1 (templ, type_decl, scope); +} + +/* Set up the hash tables for template instantiations. */ + +void +init_template_processing (void) +{ + decl_specializations = htab_create_ggc (37, + hash_specialization, + eq_specializations, + ggc_free); + type_specializations = htab_create_ggc (37, + hash_specialization, + eq_specializations, + ggc_free); +} + #include "gt-cp-pt.h"