/* 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, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
static int for_each_template_parm (tree, tree_fn_t, void*,
struct pointer_set_t*, bool);
static tree expand_template_argument_pack (tree);
-static tree build_template_parm_index (int, int, int, int, tree, tree);
+static tree build_template_parm_index (int, int, int, tree, tree);
static bool inline_needs_template_parms (tree);
static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree);
static void regenerate_decl_from_template (tree, tree);
static tree most_specialized_class (tree, tree, tsubst_flags_t);
static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
-static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
static tree template_parm_to_arg (tree t);
static bool arg_from_parm_pack_p (tree, tree);
static tree current_template_args (void);
-static tree fixup_template_type_parm_type (tree, int);
-static tree fixup_template_parm_index (tree, tree, int);
static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
/* Make the current scope suitable for access checking when we are
{
tree decl_arg_types;
tree fn_arg_types;
+ tree insttype;
/* In case of explicit specialization, we need to check if
the number of template headers appearing in the specialization
template <> void f<int>();
The specialization f<int> is invalid but is not caught
by get_bindings below. */
- if (list_length (fn_arg_types) != list_length (decl_arg_types))
+ if (cxx_dialect < cxx11
+ && list_length (fn_arg_types) != list_length (decl_arg_types))
continue;
/* Function templates cannot be specializations; there are
specialize TMPL will produce DECL. */
continue;
+ if (cxx_dialect >= cxx11)
+ {
+ /* Make sure that the deduced arguments actually work. */
+ insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
+ if (insttype == error_mark_node)
+ continue;
+ fn_arg_types
+ = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype));
+ if (!compparms (fn_arg_types, decl_arg_types))
+ continue;
+ }
+
/* Save this template, and the arguments deduced. */
templates = tree_cons (targs, fn, templates);
}
}
PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
+ PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+
return result;
}
}
/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
- ORIG_LEVEL, DECL, and TYPE. NUM_SIBLINGS is the total number of
- template parameters. */
+ ORIG_LEVEL, DECL, and TYPE. */
static tree
build_template_parm_index (int index,
int level,
int orig_level,
- int num_siblings,
tree decl,
tree type)
{
TEMPLATE_PARM_IDX (t) = index;
TEMPLATE_PARM_LEVEL (t) = level;
TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
- TEMPLATE_PARM_NUM_SIBLINGS (t) = num_siblings;
TEMPLATE_PARM_DECL (t) = decl;
TREE_TYPE (t) = type;
TREE_CONSTANT (t) = TREE_CONSTANT (decl);
t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
TEMPLATE_PARM_LEVEL (index) - levels,
TEMPLATE_PARM_ORIG_LEVEL (index),
- TEMPLATE_PARM_NUM_SIBLINGS (index),
decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = t;
TEMPLATE_PARM_PARAMETER_PACK (t)
tree
process_template_parm (tree list, location_t parm_loc, tree parm,
- bool is_non_type, bool is_parameter_pack,
- unsigned num_template_parms)
+ bool is_non_type, bool is_parameter_pack)
{
tree decl = 0;
tree defval;
DECL_INITIAL (parm) = DECL_INITIAL (decl)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
- num_template_parms,
decl, TREE_TYPE (parm));
TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))
TEMPLATE_TYPE_PARM_INDEX (t)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
- num_template_parms,
decl, TREE_TYPE (parm));
TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack;
TYPE_CANONICAL (t) = canonical_type_parameter (t);
return saved_parmlist;
}
-/* Create a new type almost identical to TYPE but which has the
- following differences:
-
- 1/ T has a new TEMPLATE_PARM_INDEX that carries the new number of
- template sibling parameters of T.
-
- 2/ T has a new canonical type that matches the new number
- of sibling parms.
-
- 3/ From now on, T is going to be what lookups referring to the
- name of TYPE will return. No lookup should return TYPE anymore.
-
- NUM_PARMS is the new number of sibling parms TYPE belongs to.
-
- This is a subroutine of fixup_template_parms. */
-
-static tree
-fixup_template_type_parm_type (tree type, int num_parms)
-{
- tree orig_idx = TEMPLATE_TYPE_PARM_INDEX (type), idx;
- tree t;
- /* This is the decl which name is inserted into the symbol table for
- the template parm type. So whenever we lookup the type name, this
- is the DECL we get. */
- tree decl;
-
- /* Do not fix up the type twice. */
- if (orig_idx && TEMPLATE_PARM_NUM_SIBLINGS (orig_idx) != 0)
- return type;
-
- t = copy_type (type);
- decl = TYPE_NAME (t);
-
- TYPE_MAIN_VARIANT (t) = t;
- TYPE_NEXT_VARIANT (t)= NULL_TREE;
- TYPE_POINTER_TO (t) = 0;
- TYPE_REFERENCE_TO (t) = 0;
-
- idx = build_template_parm_index (TEMPLATE_PARM_IDX (orig_idx),
- TEMPLATE_PARM_LEVEL (orig_idx),
- TEMPLATE_PARM_ORIG_LEVEL (orig_idx),
- num_parms,
- decl, t);
- TEMPLATE_PARM_DESCENDANTS (idx) = TEMPLATE_PARM_DESCENDANTS (orig_idx);
- TEMPLATE_PARM_PARAMETER_PACK (idx) = TEMPLATE_PARM_PARAMETER_PACK (orig_idx);
- TEMPLATE_TYPE_PARM_INDEX (t) = idx;
-
- TYPE_STUB_DECL (t) = decl;
- TEMPLATE_TYPE_DECL (t) = decl;
- if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
- TREE_TYPE (DECL_TEMPLATE_RESULT (decl)) = t;
-
- /* Update the type associated to the type name stored in the symbol
- table. Now, whenever the type name is looked up, the resulting
- type is properly fixed up. */
- TREE_TYPE (decl) = t;
-
- TYPE_CANONICAL (t) = canonical_type_parameter (t);
-
- return t;
-}
-
-/* Create and return a new TEMPLATE_PARM_INDEX that is almost
- identical to I, but that is fixed up as to:
-
- 1/ carry the number of sibling parms (NUM_PARMS) of the template
- parm represented by I.
-
- 2/ replace all references to template parm types declared before I
- (in the same template parm list as I) by references to template
- parm types contained in ARGS. ARGS should contain the list of
- template parms that have been fixed up so far, in a form suitable
- to be passed to tsubst.
-
- This is a subroutine of fixup_template_parms. */
-
-static tree
-fixup_template_parm_index (tree i, tree args, int num_parms)
-{
- tree index, decl, type;
-
- if (i == NULL_TREE
- || TREE_CODE (i) != TEMPLATE_PARM_INDEX
- /* Do not fix up the index twice. */
- || (TEMPLATE_PARM_NUM_SIBLINGS (i) != 0))
- return i;
-
- decl = TEMPLATE_PARM_DECL (i);
- type = TREE_TYPE (decl);
-
- index = build_template_parm_index (TEMPLATE_PARM_IDX (i),
- TEMPLATE_PARM_LEVEL (i),
- TEMPLATE_PARM_ORIG_LEVEL (i),
- num_parms,
- decl, type);
-
- TEMPLATE_PARM_DESCENDANTS (index) = TEMPLATE_PARM_DESCENDANTS (i);
- TEMPLATE_PARM_PARAMETER_PACK (index) = TEMPLATE_PARM_PARAMETER_PACK (i);
-
- type = tsubst (type, args, tf_none, NULL_TREE);
-
- TREE_TYPE (decl) = type;
- TREE_TYPE (index) = type;
-
- return index;
-}
-
-/*
- This is a subroutine of fixup_template_parms.
-
- It computes the canonical type of the type of the template
- parameter PARM_DESC and update all references to that type so that
- they use the newly computed canonical type. No access check is
- performed during the fixup. PARM_DESC is a TREE_LIST which
- TREE_VALUE is the template parameter and its TREE_PURPOSE is the
- default argument of the template parm if any. IDX is the index of
- the template parameter, starting at 0. NUM_PARMS is the number of
- template parameters in the set PARM_DESC belongs to. ARGLIST is a
- TREE_VEC containing the full set of template parameters in a form
- suitable to be passed to substs functions as their ARGS
- argument. This is what current_template_args returns for a given
- template. The innermost vector of args in ARGLIST is the set of
- template parms that have been fixed up so far. This function adds
- the fixed up parameter into that vector. */
-
-static void
-fixup_template_parm (tree parm_desc,
- int idx,
- int num_parms,
- tree arglist)
-{
- tree parm = TREE_VALUE (parm_desc);
- tree fixedup_args = INNERMOST_TEMPLATE_ARGS (arglist);
-
- push_deferring_access_checks (dk_no_check);
-
- if (TREE_CODE (parm) == TYPE_DECL)
- {
- /* PARM is a template type parameter. Fix up its type, add
- the fixed-up template parm to the vector of fixed-up
- template parms so far, and substitute the fixed-up
- template parms into the default argument of this
- parameter. */
- tree t =
- fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
- TREE_TYPE (parm) = t;
-
- TREE_VEC_ELT (fixedup_args, idx) = template_parm_to_arg (parm_desc);
- }
- else if (TREE_CODE (parm) == TEMPLATE_DECL)
- {
- /* PARM is a template template parameter. This is going to
- be interesting. */
- tree tparms, targs, innermost_args, t;
- int j;
-
- /* First, fix up the parms of the template template parm
- because the parms are involved in defining the new canonical
- type of the template template parm. */
-
- /* So we need to substitute the template parm types that have
- been fixed up so far into the template parms of this template
- template parm. E.g, consider this:
-
- template<class T, template<T u> class TT> class S;
-
- In this case we want to substitute T into the
- template parameters of TT.
-
- So let's walk the template parms of PARM here, and
- tsubst ARGLIST into into each of the template
- parms. */
-
- /* For this substitution we need to build the full set of
- template parameters and use that as arguments for the
- tsubsting function. */
- tparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (parm));
-
- /* This will contain the innermost parms of PARM into which
- we have substituted so far. */
- innermost_args = make_tree_vec (TREE_VEC_LENGTH (tparms));
- targs = add_to_template_args (arglist, innermost_args);
- for (j = 0; j < TREE_VEC_LENGTH (tparms); ++j)
- {
- tree parameter;
-
- parameter = TREE_VEC_ELT (tparms, j);
-
- /* INNERMOST_ARGS needs to have at least the same number
- of elements as the index PARAMETER, ortherwise
- tsubsting into PARAMETER will result in partially
- instantiating it, reducing its tempate parm
- level. Let's tactically fill INNERMOST_ARGS for that
- purpose. */
- TREE_VEC_ELT (innermost_args, j) =
- template_parm_to_arg (parameter);
-
- fixup_template_parm (parameter, j,
- TREE_VEC_LENGTH (tparms),
- targs);
- }
-
- /* Now fix up the type of the template template parm. */
-
- t = fixup_template_type_parm_type (TREE_TYPE (parm), num_parms);
- TREE_TYPE (parm) = t;
-
- TREE_VEC_ELT (fixedup_args, idx) =
- template_parm_to_arg (parm_desc);
- }
- else if (TREE_CODE (parm) == PARM_DECL)
- {
- /* PARM is a non-type template parameter. We need to:
-
- * Fix up its TEMPLATE_PARM_INDEX to make it carry the
- proper number of sibling parameters.
-
- * Make lookups of the template parameter return a reference
- to the fixed-up index. No lookup should return references
- to the former index anymore.
-
- * Substitute the template parms that got fixed up so far
-
- * into the type of PARM. */
-
- tree index = DECL_INITIAL (parm);
-
- /* PUSHED_DECL is the decl added to the symbol table with
- the name of the parameter. E,g:
-
- template<class T, T u> //#0
- auto my_function(T t) -> decltype(u); //#1
-
- Here, when looking up u at //#1, we get the decl of u
- resulting from the declaration in #0. This is what
- PUSHED_DECL is. We need to replace the reference to the
- old TEMPLATE_PARM_INDEX carried by PUSHED_DECL by the
- fixed-up TEMPLATE_PARM_INDEX. */
- tree pushed_decl = TEMPLATE_PARM_DECL (index);
-
- /* Let's fix up the TEMPLATE_PARM_INDEX then. Note that we must
- fixup the type of PUSHED_DECL as well and luckily
- fixup_template_parm_index does it for us too. */
- tree fixed_up_index =
- fixup_template_parm_index (index, arglist, num_parms);
-
- DECL_INITIAL (pushed_decl) = DECL_INITIAL (parm) = fixed_up_index;
-
- /* Add this fixed up PARM to the template parms we've fixed
- up so far and use that to substitute the fixed-up
- template parms into the type of PARM. */
- TREE_VEC_ELT (fixedup_args, idx) =
- template_parm_to_arg (parm_desc);
- TREE_TYPE (parm) = tsubst (TREE_TYPE (parm), arglist,
- tf_none, NULL_TREE);
- }
-
- TREE_PURPOSE (parm_desc) =
- tsubst_template_arg (TREE_PURPOSE (parm_desc),
- arglist, tf_none, parm);
-
- pop_deferring_access_checks ();
-}
-
-/* Walk the current template parms and properly compute the canonical
- types of the dependent types created during
- cp_parser_template_parameter_list. */
-
-void
-fixup_template_parms (void)
-{
- tree arglist;
- tree parameter_vec;
- tree fixedup_args;
- int i, num_parms;
-
- parameter_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms);
- if (parameter_vec == NULL_TREE)
- return;
-
- num_parms = TREE_VEC_LENGTH (parameter_vec);
-
- /* This vector contains the current innermost template parms that
- have been fixed up so far. The form of FIXEDUP_ARGS is suitable
- to be passed to tsubst* functions as their ARGS argument. */
- fixedup_args = make_tree_vec (num_parms);
-
- /* This vector contains the full set of template parms in a form
- suitable to be passed to substs functions as their ARGS
- argument. */
- arglist = current_template_args ();
- arglist = add_outermost_template_args (arglist, fixedup_args);
-
- /* Let's do the proper fixup now. */
- for (i = 0; i < num_parms; ++i)
- fixup_template_parm (TREE_VEC_ELT (parameter_vec, i),
- i, num_parms, arglist);
-}
-
/* end_template_decl is called after a template declaration is seen. */
void
{
tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
tree pattern = PACK_EXPANSION_PATTERN (expansion);
- /* So we have an argument_pack<P...>. We want to test if P
- is actually PARM_PACK. We will not use cp_tree_equal to
- test P and PARM_PACK because during type fixup (by
- fixup_template_parm) P can be a pre-fixup version of a
- type and PARM_PACK be its post-fixup version.
- cp_tree_equal would consider them as different even
- though we would want to consider them compatible for our
- precise purpose here.
-
- Thus we are going to consider that P and PARM_PACK are
- compatible if they have the same DECL. */
- if ((/* If ARG_PACK is a type parameter pack named by the
- same DECL as parm_pack ... */
- (TYPE_P (pattern)
- && TYPE_P (parm_pack)
- && TYPE_NAME (pattern) == TYPE_NAME (parm_pack))
- /* ... or if PARM_PACK is a non-type parameter named by the
- same DECL as ARG_PACK. Note that PARM_PACK being a
- non-type parameter means it's either a PARM_DECL or a
- TEMPLATE_PARM_INDEX. */
- || (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX
- && ((TREE_CODE (parm_pack) == PARM_DECL
- && (TEMPLATE_PARM_DECL (pattern)
- == TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack))))
- || (TREE_CODE (parm_pack) == TEMPLATE_PARM_INDEX
- && (TEMPLATE_PARM_DECL (pattern)
- == TEMPLATE_PARM_DECL (parm_pack))))))
- && template_parameter_pack_p (pattern))
+ if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
+ || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
+ /* The argument pack that the parameter maps to is just an
+ expansion of the parameter itself, such as one would
+ find in the implicit typedef of a class inside the
+ class itself. Consider this parameter "unsubstituted",
+ so that we will maintain the outer pack expansion. */
return true;
}
return false;
if (complain & tf_error)
{
int errs = errorcount, warns = warningcount;
+ if (processing_template_decl
+ && !require_potential_constant_expression (expr))
+ return NULL_TREE;
expr = cxx_constant_value (expr);
if (errorcount > errs || warningcount > warns)
inform (EXPR_LOC_OR_HERE (expr),
is_tmpl_type =
((TREE_CODE (arg) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+ || (requires_tmpl_type && TREE_CODE (arg) == TYPE_ARGUMENT_PACK)
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
{
if (requires_tmpl_type)
{
- if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
+ if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg))
+ val = orig_arg;
+ else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
/* The number of argument required is not known yet.
Just accept it for now. */
val = TREE_TYPE (arg);
argument specification is valid. */
val = convert_nontype_argument (t, orig_arg, complain);
else
- val = orig_arg;
+ val = strip_typedefs_expr (orig_arg);
if (val == NULL_TREE)
val = error_mark_node;
return argument_pack;
}
+/* Returns true if the template argument vector ARGS contains
+ any pack expansions, false otherwise. */
+
+static bool
+any_pack_expanson_args_p (tree args)
+{
+ int i;
+ if (args)
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ if (PACK_EXPANSION_P (TREE_VEC_ELT (args, i)))
+ return true;
+ return false;
+}
+
/* Convert all template arguments to their appropriate types, and
return a vector containing the innermost resulting template
arguments. If any error occurs, return error_mark_node. Error and
if ((nargs > nparms && !variadic_p)
|| (nargs < nparms - variadic_p
&& require_all_args
+ && !any_pack_expanson_args_p (inner_args)
&& (!use_default_args
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
&& !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
{
/* We don't know how many args we have yet, just
use the unconverted ones for now. */
- new_inner_args = args;
+ new_inner_args = inner_args;
break;
}
}
context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
complain, in_decl);
+ if (context == error_mark_node)
+ return error_mark_node;
+
if (!context)
context = global_namespace;
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
- pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current);
+ pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_global);
if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
/* This instantiation is another name for the primary
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
tree p = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ if (p == error_mark_node)
+ continue;
+
if (parm == p
|| (DECL_INITIAL (parm)
&& DECL_INITIAL (parm) == DECL_INITIAL (p)))
tree pbinfo;
tree base_list;
unsigned int saved_maximum_field_alignment;
+ tree fn_context;
if (type == error_mark_node)
return error_mark_node;
it now. */
push_deferring_access_checks (dk_no_deferred);
- push_to_top_level ();
+ fn_context = decl_function_context (TYPE_MAIN_DECL (type));
+ if (!fn_context)
+ push_to_top_level ();
/* Use #pragma pack from the template context. */
saved_maximum_field_alignment = maximum_field_alignment;
maximum_field_alignment = TYPE_PRECISION (pattern);
apply_lambda_return_type (lambda, void_type_node);
LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
}
+
instantiate_decl (decl, false, false);
maybe_add_lambda_conv_op (type);
}
perform_deferred_access_checks ();
pop_nested_class ();
maximum_field_alignment = saved_maximum_field_alignment;
- pop_from_top_level ();
+ if (!fn_context)
+ pop_from_top_level ();
pop_deferring_access_checks ();
pop_tinst_level ();
}
if (TREE_CODE (parm_pack) == PARM_DECL)
{
- if (at_function_scope_p ())
+ if (PACK_EXPANSION_LOCAL_P (t))
arg_pack = retrieve_local_specialization (parm_pack);
else
{
late-specified return type). Even if it exists, it might
have the wrong value for a recursive call. Just make a
dummy decl, since it's only used for its type. */
- arg_pack = tsubst_decl (parm_pack, args, complain);
+ /* Copy before tsubsting so that we don't recurse into any
+ later PARM_DECLs. */
+ arg_pack = tsubst_decl (copy_node (parm_pack), args, complain);
if (arg_pack && FUNCTION_PARAMETER_PACK_P (arg_pack))
/* Partial instantiation of the parm_pack, we can't build
up an argument pack yet. */
}
/* Substitute into the PATTERN with the altered arguments. */
- if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
+ if (!TYPE_P (pattern))
TREE_VEC_ELT (result, i) =
tsubst_expr (pattern, args, complain, in_decl,
/*integral_constant_expression_p=*/false);
}
}
- if (saved_local_specializations)
+ if (need_local_specializations)
{
htab_delete (local_specializations);
local_specializations = saved_local_specializations;
break;
case USING_DECL:
- /* We reach here only for member using decls. */
- if (DECL_DEPENDENT_P (t))
+ /* We reach here only for member using decls. We also need to check
+ uses_template_parms because DECL_DEPENDENT_P is not set for a
+ using-declaration that designates a member of the current
+ instantiation (c++/53549). */
+ if (DECL_DEPENDENT_P (t)
+ || uses_template_parms (USING_DECL_SCOPE (t)))
{
r = do_class_using_decl
(tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
tmpl = DECL_TI_TEMPLATE (t);
gen_tmpl = most_general_template (tmpl);
argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+ if (argvec == error_mark_node)
+ RETURN (error_mark_node);
hash = hash_tmpl_and_args (gen_tmpl, argvec);
spec = retrieve_specialization (gen_tmpl, argvec, hash);
}
break;
}
+ if (TREE_CODE (t) == VAR_DECL && DECL_ANON_UNION_VAR_P (t))
+ {
+ /* Just use name lookup to find a member alias for an anonymous
+ union, but then add it to the hash table. */
+ r = lookup_name (DECL_NAME (t));
+ gcc_assert (DECL_ANON_UNION_VAR_P (r));
+ register_local_specialization (r, t);
+ break;
+ }
+
/* Create a new node for the specialization we need. */
r = copy_decl (t);
if (type == NULL_TREE)
return r;
}
-/* Substitute into the ARG_TYPES of a function type. */
+/* Substitute into the ARG_TYPES of a function type.
+ If END is a TREE_CHAIN, leave it and any following types
+ un-substituted. */
static tree
tsubst_arg_types (tree arg_types,
tree args,
+ tree end,
tsubst_flags_t complain,
tree in_decl)
{
tree expanded_args = NULL_TREE;
tree default_arg;
- if (!arg_types || arg_types == void_list_node)
+ if (!arg_types || arg_types == void_list_node || arg_types == end)
return arg_types;
remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
- args, complain, in_decl);
+ args, end, complain, in_decl);
if (remaining_arg_types == error_mark_node)
return error_mark_node;
}
/* Substitute the argument types. */
- arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args,
+ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
complain, in_decl);
if (arg_types == error_mark_node)
return error_mark_node;
complain | tf_ignore_bad_quals);
return r;
}
- /* Else we must be instantiating the typedef, so fall through. */
+ else
+ {
+ /* We don't have an instantiation yet, so drop the typedef. */
+ int quals = cp_type_quals (t);
+ t = DECL_ORIGINAL_TYPE (decl);
+ t = cp_build_qualified_type_real (t, quals,
+ complain | tf_ignore_bad_quals);
+ }
}
if (type
tree optype;
tree template_args = 0;
bool template_id_p = false;
+ bool qualified = BASELINK_QUALIFIED_P (baselink);
/* A baselink indicates a function from a base class. Both the
BASELINK_ACCESS_BINFO and the base class referenced may
if (!object_type)
object_type = current_class_type;
- return adjust_result_of_qualified_name_lookup (baselink,
- qualifying_scope,
- object_type);
+
+ if (qualified)
+ baselink = adjust_result_of_qualified_name_lookup (baselink,
+ qualifying_scope,
+ object_type);
+ return baselink;
}
/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is
if (purpose)
purpose = RECUR (purpose);
value = TREE_VALUE (t);
- if (value && TREE_CODE (value) != LABEL_DECL)
- value = RECUR (value);
+ if (value)
+ {
+ if (TREE_CODE (value) != LABEL_DECL)
+ value = RECUR (value);
+ else
+ {
+ value = lookup_label (DECL_NAME (value));
+ gcc_assert (TREE_CODE (value) == LABEL_DECL);
+ TREE_USED (value) = 1;
+ }
+ }
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
chain = RECUR (chain);
else if (is_capture_proxy (DECL_EXPR_DECL (t)))
{
DECL_CONTEXT (decl) = current_function_decl;
+ if (DECL_NAME (decl) == this_identifier)
+ {
+ tree lam = DECL_CONTEXT (current_function_decl);
+ lam = CLASSTYPE_LAMBDA_EXPR (lam);
+ LAMBDA_EXPR_THIS_CAPTURE (lam) = decl;
+ }
insert_capture_proxy (decl);
}
else
wait until after we finish instantiating the type. */
LAMBDA_EXPR_CAPTURE_LIST (r)
= RECUR (LAMBDA_EXPR_CAPTURE_LIST (t));
+ LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
return build_lambda_object (r);
}
&& !TEMPLATE_PARM_PARAMETER_PACK (parm))
return unify_parameter_pack_mismatch (explain_p, parm, arg);
+ arg = strip_typedefs_expr (arg);
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return unify_success (explain_p);
}
if (found)
{
- for (; args != end; args = TREE_CHAIN (args))
- {
- tree substed = tsubst (TREE_VALUE (args), targs, tf_none, NULL_TREE);
- if (substed == error_mark_node)
- return true;
- }
+ tree substed = tsubst_arg_types (args, targs, end, tf_none, NULL_TREE);
+ if (substed == error_mark_node)
+ return true;
}
return false;
}
tree spec;
tree gen_tmpl;
bool pattern_defined;
- int need_push;
location_t saved_loc = input_location;
bool external_p;
+ tree fn_context;
+ bool nested;
/* This function should only be used to instantiate templates for
functions and static member variables. */
goto out;
}
- need_push = !cfun || !global_bindings_p ();
- if (need_push)
+ fn_context = decl_function_context (d);
+ nested = (current_function_decl != NULL_TREE);
+ if (!fn_context)
push_to_top_level ();
+ else if (nested)
+ push_function_context ();
/* Mark D as instantiated so that recursive calls to
instantiate_decl do not try to instantiate it again. */
/* We're not deferring instantiation any more. */
TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
- if (need_push)
+ if (!fn_context)
pop_from_top_level ();
+ else if (nested)
+ pop_function_context ();
out:
input_location = saved_loc;
/* Build a dummy EXPR_PACK_EXPANSION that will be used to
expand each argument in the TREE_VALUE of t. */
expr = make_node (EXPR_PACK_EXPANSION);
+ PACK_EXPANSION_LOCAL_P (expr) = true;
PACK_EXPANSION_PARAMETER_PACKS (expr) =
PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
}
else
{
+ tree tmp;
decl = tsubst_copy (TREE_PURPOSE (t), argvec,
tf_warning_or_error, NULL_TREE);
in_base_initializer = 1;
init = TREE_VALUE (t);
+ tmp = init;
if (init != void_type_node)
init = tsubst_expr (init, argvec,
tf_warning_or_error, NULL_TREE,
/*integral_constant_expression_p=*/false);
+ if (init == NULL_TREE && tmp != NULL_TREE)
+ /* If we had an initializer but it instantiated to nothing,
+ value-initialize the object. This will only occur when
+ the initializer was a pack expansion where the parameter
+ packs used in that expansion were of length zero. */
+ init = void_type_node;
in_base_initializer = 0;
}
case VAR_DECL:
/* A constant with literal type and is initialized
- with an expression that is value-dependent. */
+ with an expression that is value-dependent.
+
+ Note that a non-dependent parenthesized initializer will have
+ already been replaced with its constant value, so if we see
+ a TREE_LIST it must be dependent. */
if (DECL_INITIAL (expression)
&& decl_constant_var_p (expression)
- && value_dependent_expression_p (DECL_INITIAL (expression)))
+ && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST
+ || value_dependent_expression_p (DECL_INITIAL (expression))))
return true;
return false;
/* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
it first before we can figure out what NAME refers to. */
if (TREE_CODE (scope) == TYPENAME_TYPE)
- scope = resolve_typename_type (scope, only_current_p);
+ {
+ if (TYPENAME_IS_RESOLVING_P (scope))
+ /* Given a class template A with a dependent base with nested type C,
+ typedef typename A::C::C C will land us here, as trying to resolve
+ the initial A::C leads to the local C typedef, which leads back to
+ A::C::C. So we break the recursion now. */
+ return type;
+ else
+ scope = resolve_typename_type (scope, only_current_p);
+ }
/* If we don't know what SCOPE refers to, then we cannot resolve the
TYPENAME_TYPE. */
if (TREE_CODE (scope) == TYPENAME_TYPE)
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,
- 0, TYPE_NAME (au), NULL_TREE);
+ TYPE_NAME (au), NULL_TREE);
TYPE_CANONICAL (au) = canonical_type_parameter (au);
DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
tree decl;
int val;
- if (processing_template_decl
- && (TREE_TYPE (init) == NULL_TREE
- || BRACE_ENCLOSED_INITIALIZER_P (init)))
- /* Not enough information to try this yet. */
+ if (type_dependent_expression_p (init))
+ /* Defining a subset of type-dependent expressions that we can deduce
+ from ahead of time isn't worth the trouble. */
return type;
/* The name of the object being declared shall not appear in the