You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* Known bugs or deficiencies include:
TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec,
- NULL);
+ NULL);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
e.g.:
template <class T> struct S1 {
- template <class T> struct S2 {};
+ template <class T> struct S2 {};
};
pushtag contains special code to call pushdecl_with_scope on the
with default function arguments. In particular, given
something like this:
- template <class T> void f(T t1, T t = T())
+ template <class T> void f(T t1, T t = T())
the default argument expression is not substituted for in an
instantiation unless and until it is actually needed. */
return spec;
- /* There should be as many levels of arguments as there are
- levels of parameters. */
- gcc_assert (TMPL_ARGS_DEPTH (args)
- == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
-
fn = retrieve_specialization (tmpl, args,
/*class_specializations_p=*/false);
/* We can sometimes try to re-register a specialization that we've
static tree
determine_specialization (tree template_id,
- tree decl,
- tree* targs_out,
+ tree decl,
+ tree* targs_out,
int need_member_template,
int template_count)
{
the function template to which a function template
specialization refers:
- -- when an explicit specialization refers to a function
+ -- when an explicit specialization refers to a function
template.
So, we do use the partial ordering rules, at least for now.
if (templates == NULL_TREE && candidates == NULL_TREE)
{
cp_error_at ("template-id %qD for %q+D does not match any template "
- "declaration",
+ "declaration",
template_id, decl);
return error_mark_node;
}
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
{
/* Remove the this pointer, but remember the object's type for
- CV quals. */
+ CV quals. */
object_type = TREE_TYPE (TREE_VALUE (spec_types));
spec_types = TREE_CHAIN (spec_types);
tmpl_types = TREE_CHAIN (tmpl_types);
if (DECL_HAS_IN_CHARGE_PARM_P (decl))
- {
- /* DECL may contain more parameters than TMPL due to the extra
- in-charge parameter in constructors and destructors. */
- in_charge = spec_types;
+ {
+ /* DECL may contain more parameters than TMPL due to the extra
+ in-charge parameter in constructors and destructors. */
+ in_charge = spec_types;
spec_types = TREE_CHAIN (spec_types);
}
if (DECL_HAS_VTT_PARM_P (decl))
if (object_type)
{
if (vtt)
- new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
- TREE_VALUE (vtt),
- new_spec_types);
+ new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+ TREE_VALUE (vtt),
+ new_spec_types);
if (in_charge)
- /* Put the in-charge parameter back. */
- new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
- TREE_VALUE (in_charge),
- new_spec_types);
+ /* Put the in-charge parameter back. */
+ new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
+ TREE_VALUE (in_charge),
+ new_spec_types);
new_type = build_method_type_directly (object_type,
TREE_TYPE (old_type),
tree
check_explicit_specialization (tree declarator,
- tree decl,
- int template_count,
- int flags)
+ tree decl,
+ int template_count,
+ int flags)
{
int have_def = flags & 2;
int is_friend = flags & 4;
template <class T> void f<int>(); */
error ("template-id %qD in declaration of primary template",
- declarator);
+ declarator);
return decl;
}
}
case tsk_excessive_parms:
case tsk_insufficient_parms:
if (tsk == tsk_excessive_parms)
- error ("too many template parameter lists in declaration of %qD",
+ error ("too many template parameter lists in declaration of %qD",
decl);
else if (template_header_count)
error("too few template parameter lists in declaration of %qD", decl);
"is not allowed", declarator);
else
error ("template-id %qD in declaration of primary template",
- declarator);
+ declarator);
return decl;
}
template <class T> struct S {
template <class U> void f (U);
- };
+ };
template <> template <class U> void S<int>::f(U) {}
That's a specialization -- but of the entire template. */
else
{
/* If there is no class context, the explicit instantiation
- must be at namespace scope. */
+ must be at namespace scope. */
gcc_assert (DECL_NAMESPACE_SCOPE_P (decl));
/* Find the namespace binding, using the declaration
- context. */
+ context. */
fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
if (!fns || !is_overloaded_fn (fns))
{
/* It's not valid to write an explicit instantiation in
class scope, e.g.:
- class C { template void f(); }
+ class C { template void f(); }
This case is caught by the parser. However, on
something like:
static tree
build_template_parm_index (int index,
- int level,
- int orig_level,
- tree decl,
- tree type)
+ int level,
+ int orig_level,
+ tree decl,
+ tree type)
{
tree t = make_node (TEMPLATE_PARM_INDEX);
TEMPLATE_PARM_IDX (t) = index;
TREE_INVARIANT (parm) = 1;
TREE_READONLY (parm) = 1;
if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
- TREE_TYPE (parm) = void_type_node;
+ TREE_TYPE (parm) = void_type_node;
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
TREE_CONSTANT (decl) = 1;
TREE_INVARIANT (decl) = 1;
&& tpd.arg_uses_template_parms [j])
{
error ("type %qT of template argument %qE depends "
- "on template parameter(s)",
- type,
- arg);
+ "on template parameter(s)",
+ type,
+ arg);
break;
}
}
if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary)
/* For an ordinary class template, default template arguments are
allowed at the innermost level, e.g.:
- template <class T = int>
+ template <class T = int>
struct S {};
but, in a partial specialization, they're not allowed even
there, as we have in [temp.class.spec]:
examine the parameters to the class itself. On the one
hand, they will be checked when the class is defined, and,
on the other, default arguments are valid in things like:
- template <class T = double>
- struct S { template <class U> void f(U); };
+ template <class T = double>
+ struct S { template <class U> void f(U); };
Here the default argument for `S' has no bearing on the
declaration of `f'. */
last_level_to_check = template_class_depth (current_class_type) + 1;
{
/* [temp.mem]
- A destructor shall not be a member template. */
+ A destructor shall not be a member template. */
error ("destructor %qD declared as member template", decl);
return error_mark_node;
}
{
/* [basic.stc.dynamic.allocation]
- An allocation function can be a function
+ An allocation function can be a function
template. ... Template allocation functions shall
have two or more parameters. */
error ("invalid template declaration of %qD", decl);
if (TMPL_ARGS_DEPTH (args) != i)
{
error ("expected %d levels of template parms for %q#D, got %d",
- i, decl, TMPL_ARGS_DEPTH (args));
+ i, decl, TMPL_ARGS_DEPTH (args));
}
else
for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
{
if (current == decl)
error ("got %d template parameters for %q#D",
- TREE_VEC_LENGTH (a), decl);
+ TREE_VEC_LENGTH (a), decl);
else
error ("got %d template parameters for %q#T",
- TREE_VEC_LENGTH (a), current);
+ TREE_VEC_LENGTH (a), current);
error (" but %d required", TREE_VEC_LENGTH (t));
}
/* Perhaps we should also check that the parms are used in the
- appropriate qualifying scopes in the declarator? */
+ appropriate qualifying scopes in the declarator? */
if (current == decl)
current = ctx;
if (!real_lvalue_p (expr))
{
error ("%qE is not a valid template argument for type %qT "
- "because it is not a lvalue", expr, type);
+ "because it is not a lvalue", expr, type);
return NULL_TREE;
}
else if (TYPE_PTRFN_P (type))
{
/* If the argument is a template-id, we might not have enough
- context information to decay the pointer.
+ context information to decay the pointer.
??? Why static5.C requires decay and subst1.C works fine
even without it? */
if (!type_unknown_p (expr_type))
static int
coerce_template_template_parms (tree parm_parms,
- tree arg_parms,
- tsubst_flags_t complain,
+ tree arg_parms,
+ tsubst_flags_t complain,
tree in_decl,
- tree outer_args)
+ tree outer_args)
{
int nparms, nargs, i;
tree parm, arg;
arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
if (arg == NULL_TREE || arg == error_mark_node
- || parm == NULL_TREE || parm == error_mark_node)
+ || parm == NULL_TREE || parm == error_mark_node)
return 0;
if (TREE_CODE (arg) != TREE_CODE (parm))
- return 0;
+ return 0;
switch (TREE_CODE (parm))
{
static tree
convert_template_argument (tree parm,
- tree arg,
- tree args,
- tsubst_flags_t complain,
- int i,
- tree in_decl)
+ tree arg,
+ tree args,
+ tsubst_flags_t complain,
+ int i,
+ tree in_decl)
{
tree val;
tree inner_args;
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
{
pedwarn ("to refer to a type member of a template parameter, "
- "use %<typename %E%>", arg);
+ "use %<typename %E%>", arg);
arg = make_typename_type (TREE_OPERAND (arg, 0),
TREE_OPERAND (arg, 1),
if (complain & tf_error)
{
error ("type/value mismatch at argument %d in template "
- "parameter list for %qD",
- i + 1, in_decl);
+ "parameter list for %qD",
+ i + 1, in_decl);
if (is_type)
error (" expected a constant of type %qT, got %qT",
- TREE_TYPE (parm),
- (is_tmpl_type ? DECL_NAME (arg) : arg));
+ TREE_TYPE (parm),
+ (is_tmpl_type ? DECL_NAME (arg) : arg));
else if (requires_tmpl_type)
error (" expected a class template, got %qE", arg);
else
if (in_decl && (complain & tf_error))
{
error ("type/value mismatch at argument %d in template "
- "parameter list for %qD",
- i + 1, in_decl);
+ "parameter list for %qD",
+ i + 1, in_decl);
if (is_tmpl_type)
error (" expected a type, got %qT", DECL_NAME (arg));
else
if (in_decl && (complain & tf_error))
{
error ("type/value mismatch at argument %d in "
- "template parameter list for %qD",
- i + 1, in_decl);
+ "template parameter list for %qD",
+ i + 1, in_decl);
error (" expected a template of type %qD, got %qD",
- parm, arg);
+ parm, arg);
}
val = error_mark_node;
tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
if (invalid_nontype_parm_type_p (t, complain))
- return error_mark_node;
+ return error_mark_node;
if (!uses_template_parms (arg) && !uses_template_parms (t))
/* We used to call digest_init here. However, digest_init
static tree
coerce_template_parms (tree parms,
- tree args,
- tree in_decl,
+ tree args,
+ tree in_decl,
tsubst_flags_t complain,
int require_all_arguments)
{
if (complain & tf_error)
{
error ("wrong number of template arguments (%d, should be %d)",
- nargs, nparms);
+ nargs, nparms);
if (in_decl)
cp_error_at ("provided for %qD", in_decl);
{
/* Already substituted with real template. Just output
the template name here */
- tree context = DECL_CONTEXT (arg);
- if (context)
- {
- /* The template may be defined in a namespace, or
- may be a member template. */
- gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
+ tree context = DECL_CONTEXT (arg);
+ if (context)
+ {
+ /* The template may be defined in a namespace, or
+ may be a member template. */
+ gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
|| CLASS_TYPE_P (context));
cat (decl_as_string (DECL_CONTEXT (arg),
TFF_PLAIN_IDENTIFIER));
tree
lookup_template_class (tree d1,
- tree arglist,
- tree in_decl,
- tree context,
- int entering_scope,
- tsubst_flags_t complain)
+ tree arglist,
+ tree in_decl,
+ tree context,
+ int entering_scope,
+ tsubst_flags_t complain)
{
tree template = NULL_TREE, parmlist;
tree t;
if (! template)
{
if (complain & tf_error)
- error ("%qT is not a template", d1);
+ error ("%qT is not a template", d1);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
if (TREE_CODE (template) != TEMPLATE_DECL
- /* Make sure it's a user visible template, if it was named by
+ /* Make sure it's a user visible template, if it was named by
the user. */
|| ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
&& !PRIMARY_TEMPLATE_P (template)))
{
if (complain & tf_error)
- {
- error ("non-template type %qT used as a template", d1);
- if (in_decl)
+ {
+ error ("non-template type %qT used as a template", d1);
+ if (in_decl)
cp_error_at ("for template declaration %qD", in_decl);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
- template arguments */
+ template arguments */
tree parm;
tree arglist2;
arglist = add_to_template_args (current_template_args (), arglist);
arglist2 = coerce_template_parms (parmlist, arglist, template,
- complain, /*require_all_args=*/1);
+ complain, /*require_all_args=*/1);
if (arglist2 == error_mark_node
|| (!uses_template_parms (arglist2)
&& check_instantiated_args (template, arglist2, complain)))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
For example, given:
template <class T> struct S1 {
- template <class U> struct S2 {};
+ template <class U> struct S2 {};
template <class U> struct S2<U*> {};
- };
+ };
we will be called with an ARGLIST of `U*', but the
TEMPLATE will be `template <class T> template
{
tree a = coerce_template_parms (TREE_VALUE (t),
arglist, template,
- complain, /*require_all_args=*/1);
+ complain, /*require_all_args=*/1);
/* Don't process further if one of the levels fails. */
if (a == error_mark_node)
= coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
INNERMOST_TEMPLATE_ARGS (arglist),
template,
- complain, /*require_all_args=*/1);
+ complain, /*require_all_args=*/1);
if (arglist == error_mark_node)
/* We were unable to bind the arguments. */
}
}
if (found)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
/* If we already have this specialization, return it. */
found = retrieve_specialization (template, arglist,
if (!found)
{
/* There was no partial instantiation. This happens
- where C<T> is a member template of A<T> and it's used
- in something like
+ where C<T> is a member template of A<T> and it's used
+ in something like
- template <typename T> struct B { A<T>::C<int> m; };
- B<float>;
+ template <typename T> struct B { A<T>::C<int> m; };
+ B<float>;
- Create the partial instantiation.
- */
- TREE_VEC_LENGTH (arglist)--;
- found = tsubst (template, arglist, complain, NULL_TREE);
- TREE_VEC_LENGTH (arglist)++;
- }
+ Create the partial instantiation.
+ */
+ TREE_VEC_LENGTH (arglist)--;
+ found = tsubst (template, arglist, complain, NULL_TREE);
+ TREE_VEC_LENGTH (arglist)++;
+ }
}
SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
{
/* If the instantiation in question still has unbound template parms,
we don't really care if we can't instantiate it, so just return.
- This happens with base instantiation for implicit `typename'. */
+ This happens with base instantiation for implicit `typename'. */
if (uses_template_parms (d))
return 0;
last_template_error_tick = tinst_level_tick;
error ("template instantiation depth exceeds maximum of %d (use "
- "-ftemplate-depth-NN to increase the maximum) instantiating %qD",
+ "-ftemplate-depth-NN to increase the maximum) instantiating %qD",
max_tinst_depth, d);
print_instantiation_context ();
tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type));
/* Friend functions are looked up in the containing namespace scope.
- We must enter that scope, to avoid finding member functions of the
- current cless with same name. */
+ We must enter that scope, to avoid finding member functions of the
+ current cless with same name. */
push_nested_namespace (ns);
fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
- tf_error | tf_warning, NULL_TREE);
+ tf_error | tf_warning, NULL_TREE);
pop_nested_namespace (ns);
arglist = tsubst (DECL_TI_ARGS (decl), args,
- tf_error | tf_warning, NULL_TREE);
+ tf_error | tf_warning, NULL_TREE);
template_id = lookup_template_function (fns, arglist);
new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
friend void f(int);
template <class T> class C {
- friend void f(T) {}
- };
+ friend void f(T) {}
+ };
when `C<int>' is instantiated. Now, `f(int)' is defined
in the class. */
tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE);
/* The new TMPL is not an instantiation of anything, so we
- forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for
+ forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for
the new type because that is supposed to be the corresponding
template decl, i.e., TMPL. */
DECL_USE_TEMPLATE (tmpl) = 0;
if (!COMPLETE_TYPE_P (rtype))
{
cxx_incomplete_type_error (r, rtype);
- r = error_mark_node;
+ r = error_mark_node;
}
}
set_current_access_from_decl (r);
finish_member_declaration (r);
}
- }
+ }
}
}
else
{
/* template <class T> friend class C; */
friend_type = tsubst_friend_class (friend_type, args);
- adjust_processing_template_decl = true;
+ adjust_processing_template_decl = true;
}
else if (TREE_CODE (friend_type) == UNBOUND_CLASS_TEMPLATE)
{
tf_error | tf_warning, NULL_TREE);
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
friend_type = TREE_TYPE (friend_type);
- adjust_processing_template_decl = true;
+ adjust_processing_template_decl = true;
}
else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
{
friend class C<int>;
- We don't have to do anything in these cases. */
+ We don't have to do anything in these cases. */
if (adjust_processing_template_decl)
/* Trick make_friend_class into realizing that the friend
++processing_template_decl;
if (friend_type != error_mark_node)
- make_friend_class (type, friend_type, /*complain=*/false);
+ make_friend_class (type, friend_type, /*complain=*/false);
if (adjust_processing_template_decl)
--processing_template_decl;
static tree
tsubst_aggr_type (tree t,
- tree args,
- tsubst_flags_t complain,
- tree in_decl,
- int entering_scope)
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ int entering_scope)
{
if (t == NULL_TREE)
return NULL_TREE;
if (argvec == error_mark_node)
return error_mark_node;
- r = lookup_template_class (t, argvec, in_decl, context,
+ r = lookup_template_class (t, argvec, in_decl, context,
entering_scope, complain);
return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
there was a specialization of a member template, like
this:
- template <class T> struct S { template <class U> void f(); }
+ template <class T> struct S { template <class U> void f(); }
template <> template <class U> void S<int>::f(U);
Here, we'll be substituting into the specialization,
{
/* This special case arises when we have something like this:
- template <class T> struct S {
+ template <class T> struct S {
friend void f<int>(int, double);
};
return error_mark_node;
/* We do NOT check for matching decls pushed separately at this
- point, as they may not represent instantiations of this
- template, and in any case are considered separate under the
- discrete model. */
+ point, as they may not represent instantiations of this
+ template, and in any case are considered separate under the
+ discrete model. */
r = copy_decl (t);
DECL_USE_TEMPLATE (r) = 0;
TREE_TYPE (r) = type;
until they are called, for a template. But, for a
declaration like:
- template <class T> void f ()
- { extern void g(int i = T()); }
+ template <class T> void f ()
+ { extern void g(int i = T()); }
we should do the substitution when the template is
instantiated. We handle the member function case in
static tree
tsubst_arg_types (tree arg_types,
- tree args,
- tsubst_flags_t complain,
- tree in_decl)
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree remaining_arg_types;
tree type;
if (VOID_TYPE_P (type))
{
if (complain & tf_error)
- {
- error ("invalid parameter type %qT", type);
- if (in_decl)
- cp_error_at ("in declaration %qD", in_decl);
- }
+ {
+ error ("invalid parameter type %qT", type);
+ if (in_decl)
+ cp_error_at ("in declaration %qD", in_decl);
+ }
return error_mark_node;
}
if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
{
/* We've instantiated a template before its default arguments
- have been parsed. This can happen for a nested template
- class, and is not an error unless we require the default
- argument in a call of this function. */
+ have been parsed. This can happen for a nested template
+ class, and is not an error unless we require the default
+ argument in a call of this function. */
result = tree_cons (default_arg, type, remaining_arg_types);
VEC_safe_push (tree, gc, DEFARG_INSTANTIATIONS (default_arg), result);
}
static tree
tsubst_function_type (tree t,
- tree args,
- tsubst_flags_t complain,
- tree in_decl)
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree return_type;
tree arg_types;
static tree
tsubst_call_declarator_parms (tree parms,
- tree args,
- tsubst_flags_t complain,
- tree in_decl)
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree new_parms;
tree type;
if (cp_type_quals (t))
{
r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
- r = cp_build_qualified_type_real
- (r, cp_type_quals (t),
+ r = cp_build_qualified_type_real
+ (r, cp_type_quals (t),
complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM
? tf_ignore_bad_quals : 0));
}
error ("forming reference to void");
else
error ("forming %s to reference type %qT",
- (code == POINTER_TYPE) ? "pointer" : "reference",
- type);
+ (code == POINTER_TYPE) ? "pointer" : "reference",
+ type);
last_loc = input_location;
}
reasons:
-- Attempting to create "pointer to member of T" when T
- is not a class type. */
+ is not a class type. */
if (complain & tf_error)
error ("creating pointer to member of non-class type %qT", r);
return error_mark_node;
gcc_assert (TREE_CODE (type) != METHOD_TYPE);
if (TREE_CODE (type) == FUNCTION_TYPE)
{
- /* The type of the implicit object parameter gets its
- cv-qualifiers from the FUNCTION_TYPE. */
+ /* The type of the implicit object parameter gets its
+ cv-qualifiers from the FUNCTION_TYPE. */
tree method_type;
- tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
- cp_type_quals (type));
- tree memptr;
- method_type = build_method_type_directly (this_type,
+ tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
+ cp_type_quals (type));
+ tree memptr;
+ method_type = build_method_type_directly (this_type,
TREE_TYPE (type),
TYPE_ARG_TYPES (type));
- memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
- return cp_build_qualified_type_real (memptr, cp_type_quals (t),
- complain);
+ memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
+ return cp_build_qualified_type_real (memptr, cp_type_quals (t),
+ complain);
}
else
return cp_build_qualified_type_real (build_ptrmem_type (r, type),
/* Normally, make_typename_type does not require that the CTX
have complete type in order to allow things like:
- template <class T> struct S { typename S<T>::X Y; };
+ template <class T> struct S { typename S<T>::X Y; };
But, such constructs have already been resolved by this
point, so here CTX really should have complete type, unless
(complain & tf_error) | tf_keep_type_decl);
if (f == error_mark_node)
return f;
- if (TREE_CODE (f) == TYPE_DECL)
- {
+ if (TREE_CODE (f) == TYPE_DECL)
+ {
complain |= tf_ignore_bad_quals;
- f = TREE_TYPE (f);
- }
+ f = TREE_TYPE (f);
+ }
if (TREE_CODE (f) != TYPENAME_TYPE)
{
t, f);
}
- return cp_build_qualified_type_real
- (f, cp_type_quals (f) | cp_type_quals (t), complain);
+ return cp_build_qualified_type_real
+ (f, cp_type_quals (f) | cp_type_quals (t), complain);
}
case UNBOUND_CLASS_TEMPLATE:
template <template <class> class TT> struct C {};
template <class T> struct D {
template <class U> struct E {};
- C<E> c; // #1
+ C<E> c; // #1
};
D<int> d; // #2
case TEMPLATE_ID_EXPR:
{
- /* Substituted template arguments */
+ /* Substituted template arguments */
tree fn = TREE_OPERAND (t, 0);
tree targs = TREE_OPERAND (t, 1);
decl = tsubst (decl, args, complain, in_decl);
if (decl != error_mark_node)
{
- if (init)
- DECL_INITIAL (decl) = error_mark_node;
- /* By marking the declaration as instantiated, we avoid
- trying to instantiate it. Since instantiate_decl can't
- handle local variables, and since we've already done
- all that needs to be done, that's the right thing to
- do. */
- if (TREE_CODE (decl) == VAR_DECL)
- DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+ if (init)
+ DECL_INITIAL (decl) = error_mark_node;
+ /* By marking the declaration as instantiated, we avoid
+ trying to instantiate it. Since instantiate_decl can't
+ handle local variables, and since we've already done
+ all that needs to be done, that's the right thing to
+ do. */
+ if (TREE_CODE (decl) == VAR_DECL)
+ DECL_TEMPLATE_INSTANTIATED (decl) = 1;
if (TREE_CODE (decl) == VAR_DECL
&& ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
/* Anonymous aggregates are a special case. */
tree
tsubst_copy_and_build (tree t,
- tree args,
- tsubst_flags_t complain,
- tree in_decl,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
bool function_p)
{
#define RECUR(NODE) \
int
fn_type_unification (tree fn,
- tree explicit_targs,
- tree targs,
- tree args,
- tree return_type,
+ tree explicit_targs,
+ tree targs,
+ tree args,
+ tree return_type,
unification_kind_t strict)
{
tree parms;
return 1;
/* Substitute the explicit args into the function type. This is
- necessary so that, for instance, explicitly declared function
- arguments can match null pointed constants. If we were given
- an incomplete set of explicit args, we must not do semantic
- processing during substitution as we could create partial
- instantiations. */
+ necessary so that, for instance, explicitly declared function
+ arguments can match null pointed constants. If we were given
+ an incomplete set of explicit args, we must not do semantic
+ processing during substitution as we could create partial
+ instantiations. */
incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
processing_template_decl += incomplete;
fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
static int
maybe_adjust_types_for_deduction (unification_kind_t strict,
- tree* parm,
- tree* arg)
+ tree* parm,
+ tree* arg)
{
int result = 0;
static int
type_unification_real (tree tparms,
- tree targs,
- tree xparms,
- tree xargs,
- int subr,
+ tree targs,
+ tree xparms,
+ tree xargs,
+ int subr,
unification_kind_t strict,
- int allow_incomplete)
+ int allow_incomplete)
{
tree parm, arg;
int i;
{
case DEDUCE_CALL:
sub_strict = (UNIFY_ALLOW_OUTER_LEVEL | UNIFY_ALLOW_MORE_CV_QUAL
- | UNIFY_ALLOW_DERIVED);
+ | UNIFY_ALLOW_DERIVED);
break;
case DEDUCE_CONV:
else
type = arg;
- if (strict == DEDUCE_EXACT)
- {
- if (same_type_p (parm, type))
- continue;
- }
- else
- /* It might work; we shouldn't check now, because we might
- get into infinite recursion. Overload resolution will
- handle it. */
+ if (same_type_p (parm, type))
continue;
-
+ if (strict != DEDUCE_EXACT
+ && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg))
+ continue;
+
return 1;
}
}
{
- int arg_strict = sub_strict;
+ int arg_strict = sub_strict;
- if (!subr)
+ if (!subr)
arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
- if (unify (tparms, targs, parm, arg, arg_strict))
- return 1;
+ if (unify (tparms, targs, parm, arg, arg_strict))
+ return 1;
}
}
static int
resolve_overloaded_unification (tree tparms,
- tree targs,
- tree parm,
- tree arg,
- unification_kind_t strict,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
int sub_strict)
{
tree tempargs = copy_node (targs);
static int
try_one_overload (tree tparms,
- tree orig_targs,
- tree targs,
- tree parm,
- tree arg,
- unification_kind_t strict,
+ tree orig_targs,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
int sub_strict,
bool addr_p)
{
verify_class_unification (tree targs, tree parms, tree args)
{
parms = tsubst (parms, add_outermost_template_args (args, targs),
- tf_none, NULL_TREE);
+ tf_none, NULL_TREE);
if (parms == error_mark_node)
return 1;
void f(S<I, J, K>, S<I, I, I>);
void g() {
- S<0, 0, 0> s0;
- S<0, 1, 2> s2;
+ S<0, 0, 0> s0;
+ S<0, 1, 2> s2;
- f(s0, s2);
+ f(s0, s2);
}
Now, by the time we consider the unification involving `s2', we
&& !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
{
/* Although a CVR qualifier is ignored when being applied to a
- substituted template parameter ([8.3.2]/1 for example), that
- does not apply during deduction [14.8.2.4]/1, (even though
- that is not explicitly mentioned, [14.8.2.4]/9 indicates
- this). Except when we're allowing additional CV qualifiers
- at the outer level [14.8.2.1]/3,1st bullet. */
+ substituted template parameter ([8.3.2]/1 for example), that
+ does not apply during deduction [14.8.2.4]/1, (even though
+ that is not explicitly mentioned, [14.8.2.4]/9 indicates
+ this). Except when we're allowing additional CV qualifiers
+ at the outer level [14.8.2.1]/3,1st bullet. */
if ((TREE_CODE (arg) == REFERENCE_TYPE
|| TREE_CODE (arg) == FUNCTION_TYPE
|| TREE_CODE (arg) == METHOD_TYPE)
if (TREE_CODE (arg) == TREE_CODE (parm)
&& TYPE_P (arg)
/* It is the elements of the array which hold the cv quals of an array
- type, and the elements might be template type parms. We'll check
- when we recurse. */
+ type, and the elements might be template type parms. We'll check
+ when we recurse. */
&& TREE_CODE (arg) != ARRAY_TYPE
/* We check the cv-qualifiers when unifying with template type
parameters below. We want to allow ARG `const T' to unify with
class vector. */
if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
- == error_mark_node)
+ == error_mark_node)
return 1;
/* Deduce arguments T, i from TT<T> or TT<i>.
for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
{
- if (unify (tparms, targs,
+ if (unify (tparms, targs,
TREE_VEC_ELT (parmvec, i),
TREE_VEC_ELT (argvec, i),
UNIFY_ALLOW_NONE))
case PTRMEM_CST:
{
- /* A pointer-to-member constant can be unified only with
- another constant. */
+ /* A pointer-to-member constant can be unified only with
+ another constant. */
if (TREE_CODE (arg) != PTRMEM_CST)
- return 1;
+ return 1;
/* Just unify the class member. It would be useless (and possibly
- wrong, depending on the strict flags) to unify also
- PTRMEM_CST_CLASS, because we want to be sure that both parm and
- arg refer to the same variable, even if through different
- classes. For instance:
+ wrong, depending on the strict flags) to unify also
+ PTRMEM_CST_CLASS, because we want to be sure that both parm and
+ arg refer to the same variable, even if through different
+ classes. For instance:
- struct A { int x; };
- struct B : A { };
+ struct A { int x; };
+ struct B : A { };
- Unification of &A::x and &B::x must succeed. */
+ Unification of &A::x and &B::x must succeed. */
return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
- PTRMEM_CST_MEMBER (arg), strict);
+ PTRMEM_CST_MEMBER (arg), strict);
}
case POINTER_TYPE:
case OFFSET_TYPE:
/* Unify a pointer to member with a pointer to member function, which
- deduces the type of the member as a function type. */
+ deduces the type of the member as a function type. */
if (TYPE_PTRMEMFUNC_P (arg))
- {
- tree method_type;
- tree fntype;
- cp_cv_quals cv_quals;
-
- /* Check top-level cv qualifiers */
- if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
- return 1;
-
- if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
- TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
- return 1;
-
- /* Determine the type of the function we are unifying against. */
- method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
- fntype =
- build_function_type (TREE_TYPE (method_type),
- TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
-
- /* Extract the cv-qualifiers of the member function from the
- implicit object parameter and place them on the function
- type to be restored later. */
- cv_quals =
- cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
- fntype = build_qualified_type (fntype, cv_quals);
- return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
- }
+ {
+ tree method_type;
+ tree fntype;
+ cp_cv_quals cv_quals;
+
+ /* Check top-level cv qualifiers */
+ if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
+ return 1;
+
+ if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
+ return 1;
+
+ /* Determine the type of the function we are unifying against. */
+ method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
+ fntype =
+ build_function_type (TREE_TYPE (method_type),
+ TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
+
+ /* Extract the cv-qualifiers of the member function from the
+ implicit object parameter and place them on the function
+ type to be restored later. */
+ cv_quals =
+ cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
+ fntype = build_qualified_type (fntype, cv_quals);
+ return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
+ }
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
(check_rettype || DECL_CONV_FN_P (fn)
- ? TREE_TYPE (decl_type) : NULL_TREE),
+ ? TREE_TYPE (decl_type) : NULL_TREE),
DEDUCE_EXACT))
return NULL_TREE;
tree vec = make_tree_vec (ntparms);
if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
- UNIFY_ALLOW_NONE))
+ UNIFY_ALLOW_NONE))
return NULL_TREE;
for (i = 0; i < ntparms; ++i)
{
if (pedantic && !in_system_header)
pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
- "instantiations");
+ "instantiations");
extern_p = 1;
}
else
{
if (complain & tf_error)
error ("explicit instantiation of %q#T before definition of template",
- t);
+ t);
return;
}
{
if (pedantic && !in_system_header)
pedwarn("ISO C++ forbids the use of %qE on explicit instantiations",
- storage);
+ storage);
if (storage == ridpointers[(int) RID_INLINE])
nomem_p = 1;
else
{
error ("storage class %qD applied to template instantiation",
- storage);
+ storage);
extern_p = 0;
}
}
No program shall explicitly instantiate any template more
than once.
- If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
+ If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
instantiation was `extern'. If EXTERN_P then the second is.
These cases are OK. */
previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
declarations, and not the definitions, of members are
instantiated, we have here:
- [temp.explicit]
+ [temp.explicit]
The explicit instantiation of a class template specialization
implies the instantiation of all of its members not
if (CLASSTYPE_NESTED_UTDS (t))
binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
- bt_instantiate_type_proc, &storage);
+ bt_instantiate_type_proc, &storage);
}
}
for the instantiation. This is not always the most general
template. Consider, for example:
- template <class T>
+ template <class T>
struct S { template <class U> void f();
- template <> void f<int>(); };
+ template <> void f<int>(); };
and an instantiation of S<double>::f<int>. We want TD to be the
specialization S<T>::f<int>, not the more general S<T>::f<U>. */
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
return true;
/* -- a qualified-id with a nested-name-specifier which contains a
- class-name that names a dependent type or whose unqualified-id
+ class-name that names a dependent type or whose unqualified-id
names a dependent type. */
if (TREE_CODE (type) == TYPENAME_TYPE)
return true;
/* -- a cv-qualified type where the cv-unqualified type is
- dependent. */
+ dependent. */
type = TYPE_MAIN_VARIANT (type);
/* -- a compound type constructed from any dependent type. */
if (TYPE_PTR_TO_MEMBER_P (type))
return false;
}
/* -- an array type constructed from any dependent type or whose
- size is specified by a constant expression that is
+ size is specified by a constant expression that is
value-dependent. */
if (TREE_CODE (type) == ARRAY_TYPE)
{
considered dependent too. For example:
template <int I> void f() {
- enum E { a = I };
+ enum E { a = I };
S<sizeof (E)> s;
}
case VAR_DECL:
/* A constant with integral or enumeration type and is initialized
- with an expression that is value-dependent. */
+ with an expression that is value-dependent. */
if (DECL_INITIAL (expression)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
&& value_dependent_expression_p (DECL_INITIAL (expression)))
case REINTERPRET_CAST_EXPR:
case CAST_EXPR:
/* These expressions are value-dependent if the type to which
- the cast occurs is dependent or the expression being casted
- is value-dependent. */
+ the cast occurs is dependent or the expression being casted
+ is value-dependent. */
{
tree type = TREE_TYPE (expression);
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
/* A `sizeof' expression is value-dependent if the operand is
- type-dependent. */
+ type-dependent. */
expression = TREE_OPERAND (expression, 0);
if (TYPE_P (expression))
return dependent_type_p (expression);
case CALL_EXPR:
/* A CALL_EXPR is value-dependent if any argument is
- value-dependent. Why do we have to handle CALL_EXPRs in this
- function at all? First, some function calls, those for which
- value_dependent_expression_p is true, man appear in constant
- expressions. Second, there appear to be bugs which result in
- other CALL_EXPRs reaching this point. */
+ value-dependent. Why do we have to handle CALL_EXPRs in this
+ function at all? First, some function calls, those for which
+ value_dependent_expression_p is true, man appear in constant
+ expressions. Second, there appear to be bugs which result in
+ other CALL_EXPRs reaching this point. */
{
tree function = TREE_OPERAND (expression, 0);
tree args = TREE_OPERAND (expression, 1);
default:
/* A constant expression is value-dependent if any subexpression is
- value-dependent. */
+ value-dependent. */
switch (TREE_CODE_CLASS (TREE_CODE (expression)))
{
case tcc_reference: