static GTY(()) tree saved_access_scope;
+/* Live only within one (recursive) call to tsubst_expr. We use
+ this to pass the statement expression node from the STMT_EXPR
+ to the EXPR_STMT that is its result. */
+static tree cur_stmt_expr;
+
/* A map from local variable declarations in the body of the template
presently being instantiated to the corresponding instantiated
local variables. */
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
#define UNIFY_ALLOW_MAX_CORRECTION 128
-#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
- virtual, or a base class of a virtual
- base. */
-#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
- type with the desired type. */
-
static void push_access_scope (tree);
static void pop_access_scope (tree);
static int resolve_overloaded_unification (tree, tree, tree, tree,
static tree build_template_parm_index (int, int, int, tree, tree);
static int inline_needs_template_parms (tree);
static void push_inline_template_parms_recursive (tree, int);
-static tree retrieve_specialization (tree, tree);
static tree retrieve_local_specialization (tree);
-static tree register_specialization (tree, tree, tree);
static void register_local_specialization (tree, tree);
static tree reduce_template_parm_level (tree, tree, int);
-static tree build_template_decl (tree, tree);
static int mark_template_parm (tree, void *);
static int template_parm_this_level_p (tree, void *);
static tree tsubst_friend_function (tree, tree);
static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
-static tree get_template_base_recursive (tree, tree, tree, tree, tree, int);
static tree get_template_base (tree, tree, tree, tree);
static int verify_class_unification (tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
static void
push_access_scope (tree t)
{
- my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
- || TREE_CODE (t) == VAR_DECL,
- 0);
+ gcc_assert (TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == VAR_DECL);
if (DECL_CLASS_SCOPE_P (t))
push_nested_class (DECL_CONTEXT (t));
if (decl == error_mark_node)
return error_mark_node;
- my_friendly_assert (DECL_P (decl), 20020812);
+ gcc_assert (DECL_P (decl));
if (TREE_CODE (decl) == TYPE_DECL)
{
return NULL_TREE;
}
else if (TREE_CODE (decl) == FIELD_DECL)
- error ("data member `%D' cannot be a member template", decl);
+ error ("data member %qD cannot be a member template", decl);
else if (DECL_TEMPLATE_INFO (decl))
{
if (!DECL_TEMPLATE_SPECIALIZATION (decl))
return decl;
}
else
- error ("invalid member template declaration `%D'", decl);
+ error ("invalid member template declaration %qD", decl);
return error_mark_node;
}
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
- my_friendly_assert (DECL_P (parm), 0);
+ gcc_assert (DECL_P (parm));
switch (TREE_CODE (parm))
{
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
}
}
}
-/* Returns nonzero iff T is a member template function. We must be
- careful as in
-
- template <class T> class C { void f(); }
-
- Here, f is a template function, and a member, but not a member
- template. This function does not concern itself with the origin of
- T, only its present state. So if we have
-
- template <class T> class C { template <class U> void f(U); }
-
- then neither C<int>::f<char> nor C<T>::f<double> is considered
- to be a member template. But, `template <class U> void
- C<int>::f(U)' is considered a member template. */
-
-int
-is_member_template (tree t)
-{
- if (!DECL_FUNCTION_TEMPLATE_P (t))
- /* Anything that isn't a function or a template function is
- certainly not a member template. */
- return 0;
-
- /* A local class can't have member templates. */
- if (decl_function_context (t))
- return 0;
-
- return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))
- /* If there are more levels of template parameters than
- there are template classes surrounding the declaration,
- then we have a member template. */
- && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
- template_class_depth (DECL_CONTEXT (t))));
-}
-
-#if 0 /* UNUSED */
-/* Returns nonzero iff T is a member template class. See
- is_member_template for a description of what precisely constitutes
- a member template. */
-
-int
-is_member_template_class (tree t)
-{
- if (!DECL_CLASS_TEMPLATE_P (t))
- /* Anything that isn't a class template, is certainly not a member
- template. */
- return 0;
-
- if (!DECL_CLASS_SCOPE_P (t))
- /* Anything whose context isn't a class type is surely not a
- member template. */
- return 0;
-
- /* If there are more levels of template parameters than there are
- template classes surrounding the declaration, then we have a
- member template. */
- return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
- template_class_depth (DECL_CONTEXT (t)));
-}
-#endif
-
/* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. */
/* If there are more levels of EXTRA_ARGS than there are ARGS,
something very fishy is going on. */
- my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args),
- 0);
+ gcc_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args));
/* If *all* the new arguments will be the EXTRA_ARGS, just return
them. */
int extra_levels;
int i;
- my_friendly_assert (n >= 0, 20000603);
+ gcc_assert (n >= 0);
/* If N is 1, just return the innermost set of template arguments. */
if (n == 1)
/* If we're not removing anything, just return the arguments we were
given. */
extra_levels = TMPL_ARGS_DEPTH (args) - n;
- my_friendly_assert (extra_levels >= 0, 20000603);
+ gcc_assert (extra_levels >= 0);
if (extra_levels == 0)
return args;
shall be declared in the namespace of which the class template
is a member. */
if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
- error ("explicit specialization in non-namespace scope `%D'",
- scope);
+ error ("explicit specialization in non-namespace scope %qD", scope);
/* [temp.expl.spec]
void
begin_explicit_instantiation (void)
{
- my_friendly_assert (!processing_explicit_instantiation, 20020913);
+ gcc_assert (!processing_explicit_instantiation);
processing_explicit_instantiation = true;
}
void
end_explicit_instantiation (void)
{
- my_friendly_assert(processing_explicit_instantiation, 20020913);
+ gcc_assert (processing_explicit_instantiation);
processing_explicit_instantiation = false;
}
return true;
else
{
- pedwarn ("specialization of `%D' in different namespace", tmpl);
- cp_pedwarn_at (" from definition of `%#D'", tmpl);
+ pedwarn ("specialization of %qD in different namespace", tmpl);
+ cp_pedwarn_at (" from definition of %q#D", tmpl);
return false;
}
}
push_template_decl (TYPE_MAIN_DECL (type));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
- error ("specialization of `%T' after instantiation", type);
+ error ("specialization of %qT after instantiation", type);
}
else if (CLASS_TYPE_P (type)
&& !CLASSTYPE_USE_TEMPLATE (type)
if (current_namespace
!= decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
{
- pedwarn ("specializing `%#T' in different namespace", type);
- cp_pedwarn_at (" from definition of `%#D'",
+ pedwarn ("specializing %q#T in different namespace", type);
+ cp_pedwarn_at (" from definition of %q#D",
CLASSTYPE_TI_TEMPLATE (type));
}
t; t = TREE_CHAIN (t))
if (TREE_VALUE (t) != type
&& TYPE_CONTEXT (TREE_VALUE (t)) == context)
- error ("specialization `%T' after instantiation `%T'",
+ error ("specialization %qT after instantiation %qT",
type, TREE_VALUE (t));
/* Mark TYPE as a specialization. And as a result, we only
}
}
else if (processing_specialization)
- error ("explicit specialization of non-template `%T'", type);
+ error ("explicit specialization of non-template %qT", type);
+}
+
+/* Returns onzero if we can optimize the retrieval of specializations
+ for TMPL, a TEMPLATE_DECL. In particular, for such a template, we
+ do not use DECL_TEMPLATE_SPECIALIZATIONS at all. */
+
+static inline bool
+optimize_specialization_lookup_p (tree tmpl)
+{
+ return (DECL_FUNCTION_TEMPLATE_P (tmpl)
+ && DECL_CLASS_SCOPE_P (tmpl)
+ /* DECL_CLASS_SCOPE_P holds of T::f even if T is a template
+ parameter. */
+ && CLASS_TYPE_P (DECL_CONTEXT (tmpl))
+ && !DECL_MEMBER_TEMPLATE_P (tmpl)
+ && !DECL_CONV_FN_P (tmpl)
+ /* It is possible to have a template that is not a member
+ template and is not a member of a template class:
+
+ template <typename T>
+ struct S { friend A::f(); };
+
+ Here, the friend function is a template, but the context does
+ not have template information. The optimized lookup relies
+ on having ARGS be the template arguments for both the class
+ and the function template. */
+ && !DECL_FRIEND_P (DECL_TEMPLATE_RESULT (tmpl)));
}
/* Retrieve the specialization (in the sense of [temp.spec] - a
specialization) of TMPL for the given template ARGS. If there is
no such specialization, return NULL_TREE. The ARGS are a vector of
arguments, or a vector of vectors of arguments, in the case of
- templates with more than one level of parameters. */
+ templates with more than one level of parameters.
+
+ If TMPL is a type template and CLASS_SPECIALIZATIONS_P is true,
+ then we search for a partial specialization matching ARGS. This
+ parameter is ignored if TMPL is not a class template. */
static tree
-retrieve_specialization (tree tmpl, tree args)
+retrieve_specialization (tree tmpl, tree args,
+ bool class_specializations_p)
{
- tree s;
-
- my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
/* There should be as many levels of arguments as there are
levels of parameters. */
- my_friendly_assert (TMPL_ARGS_DEPTH (args)
- == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)),
- 0);
-
- for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
- s != NULL_TREE;
- s = TREE_CHAIN (s))
- if (comp_template_args (TREE_PURPOSE (s), args))
- return TREE_VALUE (s);
+ gcc_assert (TMPL_ARGS_DEPTH (args)
+ == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
+
+ if (optimize_specialization_lookup_p (tmpl))
+ {
+ tree class_template;
+ tree class_specialization;
+ VEC(tree) *methods;
+ tree fns;
+ int idx;
+
+ /* The template arguments actually apply to the containing
+ class. Find the class specialization with those
+ arguments. */
+ class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl));
+ class_specialization
+ = retrieve_specialization (class_template, args,
+ /*class_specializations_p=*/false);
+ if (!class_specialization)
+ return NULL_TREE;
+ /* Now, find the appropriate entry in the CLASSTYPE_METHOD_VEC
+ for the specialization. */
+ idx = class_method_index_for_fn (class_specialization, tmpl);
+ if (idx == -1)
+ return NULL_TREE;
+ /* Iterate through the methods with the indicated name, looking
+ for the one that has an instance of TMPL. */
+ methods = CLASSTYPE_METHOD_VEC (class_specialization);
+ for (fns = VEC_index (tree, methods, idx); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl)
+ return fn;
+ }
+ return NULL_TREE;
+ }
+ else
+ {
+ tree *sp;
+ tree *head;
+
+ /* Class templates store their instantiations on the
+ DECL_TEMPLATE_INSTANTIATIONS list; other templates use the
+ DECL_TEMPLATE_SPECIALIZATIONS list. */
+ if (!class_specializations_p
+ && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL)
+ sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl);
+ else
+ sp = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
+ head = sp;
+ /* Iterate through the list until we find a matching template. */
+ while (*sp != NULL_TREE)
+ {
+ tree spec = *sp;
+
+ if (comp_template_args (TREE_PURPOSE (spec), args))
+ {
+ /* Use the move-to-front heuristic to speed up future
+ searches. */
+ if (spec != *head)
+ {
+ *sp = TREE_CHAIN (*sp);
+ TREE_CHAIN (spec) = *head;
+ *head = spec;
+ }
+ return TREE_VALUE (spec);
+ }
+ sp = &TREE_CHAIN (spec);
+ }
+ }
return NULL_TREE;
}
}
else
{
- my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 0);
+ gcc_assert (TREE_CODE (decl) == TYPE_DECL);
for (t = TREE_TYPE (decl);
t != NULL_TREE;
bool need_template = true;
int template_depth;
- my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
/* For [temp.friend/6] when FRIEND is an ordinary member function
of a template class, we want to check if DECL is a specialization
static tree
register_specialization (tree spec, tree tmpl, tree args)
{
- tree s;
+ tree fn;
- my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
if (TREE_CODE (spec) == FUNCTION_DECL
&& uses_template_parms (DECL_TI_ARGS (spec)))
/* There should be as many levels of arguments as there are
levels of parameters. */
- my_friendly_assert (TMPL_ARGS_DEPTH (args)
- == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)),
- 0);
-
- for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
- s != NULL_TREE;
- s = TREE_CHAIN (s))
- {
- tree fn = TREE_VALUE (s);
-
- /* We can sometimes try to re-register a specialization that we've
- already got. In particular, regenerate_decl_from_template
- calls duplicate_decls which will update the specialization
- list. But, we'll still get called again here anyhow. It's
- more convenient to simply allow this than to try to prevent it. */
- if (fn == spec)
- return spec;
- else if (comp_template_args (TREE_PURPOSE (s), args)
- && DECL_TEMPLATE_SPECIALIZATION (spec))
+ 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
+ already got. In particular, regenerate_decl_from_template calls
+ duplicate_decls which will update the specialization list. But,
+ we'll still get called again here anyhow. It's more convenient
+ to simply allow this than to try to prevent it. */
+ if (fn == spec)
+ return spec;
+ else if (fn && DECL_TEMPLATE_SPECIALIZATION (spec))
+ {
+ if (DECL_TEMPLATE_INSTANTIATION (fn))
{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
+ if (TREE_USED (fn)
+ || DECL_EXPLICIT_INSTANTIATION (fn))
{
- if (TREE_USED (fn)
- || DECL_EXPLICIT_INSTANTIATION (fn))
- {
- error ("specialization of %D after instantiation",
- fn);
- return spec;
- }
- else
- {
- /* This situation should occur only if the first
- specialization is an implicit instantiation, the
- second is an explicit specialization, and the
- implicit instantiation has not yet been used.
- That situation can occur if we have implicitly
- instantiated a member function and then
- specialized it later.
-
- We can also wind up here if a friend declaration
- that looked like an instantiation turns out to be
- a specialization:
-
- template <class T> void foo(T);
- class S { friend void foo<>(int) };
- template <> void foo(int);
-
- We transform the existing DECL in place so that
- any pointers to it become pointers to the updated
- declaration.
-
- If there was a definition for the template, but
- not for the specialization, we want this to look
- as if there were no definition, and vice
- versa. */
- DECL_INITIAL (fn) = NULL_TREE;
- duplicate_decls (spec, fn);
-
- return fn;
- }
+ error ("specialization of %qD after instantiation",
+ fn);
+ return spec;
}
- else if (DECL_TEMPLATE_SPECIALIZATION (fn))
+ else
{
- if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
- /* Dup decl failed, but this is a new definition. Set
- the line number so any errors match this new
- definition. */
- DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+ /* This situation should occur only if the first
+ specialization is an implicit instantiation, the
+ second is an explicit specialization, and the
+ implicit instantiation has not yet been used. That
+ situation can occur if we have implicitly
+ instantiated a member function and then specialized
+ it later.
+
+ We can also wind up here if a friend declaration that
+ looked like an instantiation turns out to be a
+ specialization:
+
+ template <class T> void foo(T);
+ class S { friend void foo<>(int) };
+ template <> void foo(int);
+
+ We transform the existing DECL in place so that any
+ pointers to it become pointers to the updated
+ declaration.
+
+ If there was a definition for the template, but not
+ for the specialization, we want this to look as if
+ there were no definition, and vice versa. */
+ DECL_INITIAL (fn) = NULL_TREE;
+ duplicate_decls (spec, fn);
return fn;
}
}
+ else if (DECL_TEMPLATE_SPECIALIZATION (fn))
+ {
+ if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
+ /* Dup decl failed, but this is a new definition. Set the
+ line number so any errors match this new
+ definition. */
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+
+ return fn;
+ }
}
/* A specialization must be declared in the same namespace as the
&& !check_specialization_namespace (tmpl))
DECL_CONTEXT (spec) = decl_namespace_context (tmpl);
- DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
- = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
+ if (!optimize_specialization_lookup_p (tmpl))
+ DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
+ = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
return spec;
}
if (!is_overloaded_fn (fns))
{
- error ("`%D' is not a function template", fns);
+ error ("%qD is not a function template", fns);
return error_mark_node;
}
if (templates == NULL_TREE && candidates == NULL_TREE)
{
- cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
+ cp_error_at ("template-id %qD for %q+D does not match any template "
+ "declaration",
template_id, decl);
return error_mark_node;
}
|| (candidates && TREE_CHAIN (candidates))
|| (templates && candidates))
{
- cp_error_at ("ambiguous template specialization `%D' for `%+D'",
+ cp_error_at ("ambiguous template specialization %qD for %q+D",
template_id, decl);
chainon (candidates, templates);
print_candidates (candidates);
/* This case handles bogus declarations like template <>
template <class T> void f<int>(); */
- error ("template-id `%D' in declaration of primary template",
- declarator);
+ error ("template-id %qD in declaration of primary template",
+ declarator);
return decl;
}
}
case tsk_excessive_parms:
case tsk_insufficient_parms:
if (tsk == tsk_excessive_parms)
- error ("too many template parameter lists in declaration of `%D'",
+ 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 `%D'",
- decl);
+ error("too few template parameter lists in declaration of %qD", decl);
else
- error("explicit specialization of `%D' must be introduced by "
+ error("explicit specialization of %qD must be introduced by "
"`template <>'", decl);
/* Fall through. */
template <class T> void f<int>(); */
if (uses_template_parms (declarator))
- error ("function template partial specialization `%D' "
+ error ("function template partial specialization %qD "
"is not allowed", declarator);
else
- error ("template-id `%D' in declaration of primary template",
- declarator);
+ error ("template-id %qD in declaration of primary template",
+ declarator);
return decl;
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (specialization || member_specialization)
{
tree fns;
- my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 0);
+ gcc_assert (TREE_CODE (declarator) == IDENTIFIER_NODE);
if (ctype)
fns = dname;
else
{
/* If there is no class context, the explicit instantiation
must be at namespace scope. */
- my_friendly_assert (DECL_NAMESPACE_SCOPE_P (decl), 20030625);
+ gcc_assert (DECL_NAMESPACE_SCOPE_P (decl));
/* Find the namespace binding, using the declaration
context. */
if (fns == NULL_TREE)
{
- error ("no member function `%D' declared in `%T'",
- name, ctype);
+ error ("no member function %qD declared in %qT", name, ctype);
return error_mark_node;
}
else
;
else if (template_header_count > context_depth + 1)
/* There are two many template parameter lists. */
- error ("too many template parameter lists in declaration of `%T'", type);
+ error ("too many template parameter lists in declaration of %qT", type);
}
}
parameters. These are represented in the same format used for
DECL_TEMPLATE_PARMS. */
-int comp_template_parms (tree parms1, tree parms2)
+int
+comp_template_parms (tree parms1, tree parms2)
{
tree p1;
tree p2;
tree t2 = TREE_VALUE (p2);
int i;
- my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0);
- my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0);
+ gcc_assert (TREE_CODE (t1) == TREE_VEC);
+ gcc_assert (TREE_CODE (t2) == TREE_VEC);
if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
return 0;
|| TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
return;
- cp_error_at ("declaration of `%#D'", decl);
- cp_error_at (" shadows template parm `%#D'", olddecl);
+ cp_error_at ("declaration of %q#D", decl);
+ cp_error_at (" shadows template parm %q#D", olddecl);
}
/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
int idx;
parm = next;
- my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
+ gcc_assert (TREE_CODE (parm) == TREE_LIST);
defval = TREE_PURPOSE (parm);
if (list)
}
/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated
- template PARMS. Used by push_template_decl below. */
+ template PARMS. If MEMBER_TEMPLATE_P is true, the new template is
+ a mebmer template. Used by push_template_decl below. */
static tree
-build_template_decl (tree decl, tree parms)
+build_template_decl (tree decl, tree parms, bool member_template_p)
{
tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
DECL_TEMPLATE_PARMS (tmpl) = parms;
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
+ DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
if (DECL_LANG_SPECIFIC (decl))
{
DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
did_error_intro = 1;
}
- error (" `%D'",
- TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
+ error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
}
/* [temp.class.spec]
(inner_args,
INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE
(maintmpl)))))
- error ("partial specialization `%T' does not specialize any template arguments", type);
+ error ("partial specialization %qT does not specialize any template arguments", type);
/* [temp.class.spec]
The type of a template parameter corresponding to a specialized
non-type argument shall not be dependent on a parameter of the
specialization. */
- my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0);
+ gcc_assert (nargs == DECL_NTPARMS (maintmpl));
tpd2.parms = 0;
for (i = 0; i < nargs; ++i)
{
&& TREE_CODE (arg) != TEMPLATE_PARM_INDEX)
{
if (tpd.arg_uses_template_parms[i])
- error ("template argument `%E' involves template parameter(s)", arg);
+ error ("template argument %qE involves template parameter(s)", arg);
else
{
/* Look at the corresponding template parameter,
if (tpd2.parms[j] != 0
&& tpd.arg_uses_template_parms [j])
{
- error ("type `%T' of template argument `%E' depends on template parameter(s)",
- type,
- arg);
+ error ("type %qT of template argument %qE depends "
+ "on template parameter(s)",
+ type,
+ arg);
break;
}
}
}
}
- if (retrieve_specialization (maintmpl, specargs))
+ if (retrieve_specialization (maintmpl, specargs,
+ /*class_specializations_p=*/true))
/* We've already got this specialization. */
return decl;
seen_def_arg_p = 1;
else if (seen_def_arg_p)
{
- error ("no default argument for `%D'", TREE_VALUE (parm));
+ error ("no default argument for %qD", TREE_VALUE (parm));
/* For better subsequent error-recovery, we indicate that
there should have been a default argument. */
TREE_PURPOSE (parm) = error_mark_node;
else if (is_partial)
msg = "default template arguments may not be used in partial specializations";
else
- msg = "default argument for template parameter for class enclosing `%D'";
+ msg = "default argument for template parameter for class enclosing %qD";
if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
/* If we're inside a class definition, there's no need to
/* At this point, if we're still interested in issuing messages,
they must apply to classes surrounding the object declared. */
if (msg)
- msg = "default argument for template parameter for class enclosing `%D'";
+ msg = "default argument for template parameter for class enclosing %qD";
}
}
int primary;
int is_partial;
int new_template_p = 0;
+ /* True if the template is a member template, in the sense of
+ [temp.mem]. */
+ bool member_template_p = false;
if (decl == error_mark_node)
return decl;
if (primary)
{
+ if (DECL_CLASS_SCOPE_P (decl))
+ member_template_p = true;
if (current_lang_name == lang_name_c)
error ("template with C linkage");
else if (TREE_CODE (decl) == TYPE_DECL
&& ANON_AGGRNAME_P (DECL_NAME (decl)))
error ("template class without a name");
- else if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_DESTRUCTOR_P (decl))
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
{
- /* [temp.mem]
-
- A destructor shall not be a member template. */
- error ("destructor `%D' declared as member template", decl);
- return error_mark_node;
+ if (DECL_DESTRUCTOR_P (decl))
+ {
+ /* [temp.mem]
+
+ A destructor shall not be a member template. */
+ error ("destructor %qD declared as member template", decl);
+ return error_mark_node;
+ }
+ if (NEW_DELETE_OPNAME_P (DECL_NAME (decl))
+ && (!TYPE_ARG_TYPES (TREE_TYPE (decl))
+ || TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node
+ || !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl))))
+ == void_list_node)))
+ {
+ /* [basic.stc.dynamic.allocation]
+
+ An allocation function can be a function
+ template. ... Template allocation functions shall
+ have two or more parameters. */
+ error ("invalid template declaration of %qD", decl);
+ return decl;
+ }
}
else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
&& CLASS_TYPE_P (TREE_TYPE (decl)))
- || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
- || TREE_CODE (decl) == FUNCTION_DECL)
+ || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)))
/* OK */;
else
{
- error ("template declaration of `%#D'", decl);
+ error ("template declaration of %q#D", decl);
return error_mark_node;
}
}
}
else
{
- tmpl = build_template_decl (decl, current_template_parms);
+ tmpl = build_template_decl (decl, current_template_parms,
+ member_template_p);
new_template_p = 1;
if (DECL_LANG_SPECIFIC (decl)
tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
else
{
- error ("`%D' does not declare a template type", decl);
+ error ("%qD does not declare a template type", decl);
return decl;
}
}
else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl))
{
- error ("template definition of non-template `%#D'", decl);
+ error ("template definition of non-template %q#D", decl);
return decl;
}
else
if (DECL_FUNCTION_TEMPLATE_P (tmpl)
&& DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl)
- && is_member_template (tmpl))
+ && DECL_MEMBER_TEMPLATE_P (tmpl))
{
tree new_tmpl;
args = DECL_TI_ARGS (decl);
new_tmpl
- = build_template_decl (decl, current_template_parms);
+ = build_template_decl (decl, current_template_parms,
+ member_template_p);
DECL_TEMPLATE_RESULT (new_tmpl) = decl;
TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
DECL_TI_TEMPLATE (decl) = new_tmpl;
i = TMPL_PARMS_DEPTH (parms);
if (TMPL_ARGS_DEPTH (args) != i)
{
- error ("expected %d levels of template parms for `%#D', got %d",
- i, decl, TMPL_ARGS_DEPTH (args));
+ error ("expected %d levels of template parms for %q#D, got %d",
+ i, decl, TMPL_ARGS_DEPTH (args));
}
else
for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
{
if (current == decl)
- error ("got %d template parameters for `%#D'",
- TREE_VEC_LENGTH (a), decl);
+ error ("got %d template parameters for %q#D",
+ TREE_VEC_LENGTH (a), decl);
else
- error ("got %d template parameters for `%#T'",
- TREE_VEC_LENGTH (a), current);
+ error ("got %d template parameters for %q#T",
+ TREE_VEC_LENGTH (a), current);
error (" but %d required", TREE_VEC_LENGTH (t));
}
if (!TYPE_TEMPLATE_INFO (type))
{
- error ("`%T' is not a template type", type);
+ error ("%qT is not a template type", type);
return;
}
if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
{
- cp_error_at ("previous declaration `%D'", tmpl);
+ cp_error_at ("previous declaration %qD", tmpl);
error ("used %d template parameter%s instead of %d",
TREE_VEC_LENGTH (tmpl_parms),
TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
- if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
+ /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
+ TEMPLATE_DECL. */
+ if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+ || (TREE_CODE (tmpl_parm) != TYPE_DECL
+ && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
{
- cp_error_at ("template parameter `%#D'", tmpl_parm);
- error ("redeclared here as `%#D'", parm);
+ cp_error_at ("template parameter %q#D", tmpl_parm);
+ error ("redeclared here as %q#D", parm);
return;
}
A template-parameter may not be given default arguments
by two different declarations in the same scope. */
- error ("redefinition of default argument for `%#D'", parm);
+ error ("redefinition of default argument for %q#D", parm);
error ("%J original definition appeared here", tmpl_parm);
return;
}
if (TREE_CODE (e) != ADDR_EXPR)
{
bad_argument:
- error ("`%E' is not a valid template argument", expr);
+ error ("%qE is not a valid template argument", expr);
if (TYPE_PTR_P (expr_type))
{
if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE)
error ("it must be the address of an object with external linkage");
}
else if (TYPE_PTR_TO_MEMBER_P (expr_type))
- error ("it must be a pointer-to-member of the form `&X::Y'");
+ error ("it must be a pointer-to-member of the form %<&X::Y%>");
return NULL_TREE;
}
if (TREE_CODE (referent) == STRING_CST)
{
- error ("string literal %E is not a valid template argument because it is the address of an object with static linkage",
- referent);
+ error ("string literal %qE is not a valid template argument "
+ "because it is the address of an object with static linkage",
+ referent);
return NULL_TREE;
}
goto bad_argument;
else if (!DECL_EXTERNAL_LINKAGE_P (referent))
{
- error ("address of non-extern `%E' cannot be used as template argument", referent);
+ error ("address of non-extern %qE cannot be used as "
+ "template argument", referent);
return error_mark_node;
}
}
if (! TREE_CONSTANT (expr))
{
non_constant:
- error ("non-constant `%E' cannot be used as template argument",
- expr);
+ error ("non-constant %qE cannot be used as template argument", expr);
return NULL_TREE;
}
}
else
{
if (TYPE_P (expr))
- error ("type '%T' cannot be used as a value for a non-type "
+ error ("type %qT cannot be used as a value for a non-type "
"template-parameter", expr);
else if (DECL_P (expr))
- error ("invalid use of '%D' as a non-type template-argument", expr);
+ error ("invalid use of %qD as a non-type template-argument", expr);
else
- error ("invalid use of '%E' as a non-type template-argument", expr);
+ error ("invalid use of %qE as a non-type template-argument", expr);
return NULL_TREE;
}
switch (TREE_CODE (type))
{
+ HOST_WIDE_INT saved_processing_template_decl;
+
case INTEGER_TYPE:
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
return error_mark_node;
/* It's safe to call digest_init in this case; we know we're
- just converting one integral constant expression to another. */
+ just converting one integral constant expression to another.
+ */
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
expr = digest_init (type, expr, (tree*) 0);
+ processing_template_decl = saved_processing_template_decl;
if (TREE_CODE (expr) != INTEGER_CST)
/* Curiously, some TREE_CONSTANT integral expressions do not
expr = build_unary_op (ADDR_EXPR, fn, 0);
- my_friendly_assert (same_type_p (type, TREE_TYPE (expr)),
- 0);
+ gcc_assert (same_type_p (type, TREE_TYPE (expr)));
return expr;
}
else
if (TREE_CODE (expr) == NOP_EXPR
&& TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
STRIP_NOPS (expr);
- my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
+ gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
expr = TREE_OPERAND (expr, 0);
expr_type = TREE_TYPE (expr);
}
goto bad_argument;
}
- my_friendly_assert (same_type_p (type_referred_to,
- TREE_TYPE (fn)),
- 0);
-
+ gcc_assert (same_type_p (type_referred_to, TREE_TYPE (fn)));
expr = fn;
}
else
case RECORD_TYPE:
{
- my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112);
+ gcc_assert (TYPE_PTRMEMFUNC_P (type));
/* For a non-type template-parameter of type pointer to member
function, no conversions apply. If the template-argument
default:
/* All non-type parameters must have one of these types. */
- abort ();
- break;
+ gcc_unreachable ();
}
return error_mark_node;
int nparms, nargs, i;
tree parm, arg;
- my_friendly_assert (TREE_CODE (parm_parms) == TREE_VEC, 0);
- my_friendly_assert (TREE_CODE (arg_parms) == TREE_VEC, 0);
+ gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
+ gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
nparms = TREE_VEC_LENGTH (parm_parms);
nargs = TREE_VEC_LENGTH (arg_parms);
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
return 1;
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
{
- pedwarn ("to refer to a type member of a template parameter, use `typename %E'", arg);
+ pedwarn ("to refer to a type member of a template parameter, "
+ "use %<typename %E%>", arg);
arg = make_typename_type (TREE_OPERAND (arg, 0),
TREE_OPERAND (arg, 1),
{
if (complain & tf_error)
{
- error ("type/value mismatch at argument %d in template parameter list for `%D'",
- i + 1, in_decl);
+ error ("type/value mismatch at argument %d in template "
+ "parameter list for %qD",
+ i + 1, in_decl);
if (is_type)
- error (" expected a constant of type `%T', got `%T'",
- TREE_TYPE (parm),
- (is_tmpl_type ? DECL_NAME (arg) : arg));
+ error (" expected a constant of type %qT, got %qT",
+ TREE_TYPE (parm),
+ (is_tmpl_type ? DECL_NAME (arg) : arg));
else if (requires_tmpl_type)
- error (" expected a class template, got `%E'", arg);
+ error (" expected a class template, got %qE", arg);
else
- error (" expected a type, got `%E'", arg);
+ error (" expected a type, got %qE", arg);
}
}
return error_mark_node;
{
if (in_decl && (complain & tf_error))
{
- error ("type/value mismatch at argument %d in template parameter list for `%D'",
- i + 1, in_decl);
+ error ("type/value mismatch at argument %d in template "
+ "parameter list for %qD",
+ i + 1, in_decl);
if (is_tmpl_type)
- error (" expected a type, got `%T'", DECL_NAME (arg));
+ error (" expected a type, got %qT", DECL_NAME (arg));
else
- error (" expected a class template, got `%T'", arg);
+ error (" expected a class template, got %qT", arg);
}
return error_mark_node;
}
{
if (in_decl && (complain & tf_error))
{
- error ("type/value mismatch at argument %d in template parameter list for `%D'",
- i + 1, in_decl);
- error (" expected a template of type `%D', got `%D'", parm, arg);
+ error ("type/value mismatch at argument %d in "
+ "template parameter list for %qD",
+ i + 1, in_decl);
+ error (" expected a template of type %qD, got %qD",
+ parm, arg);
}
val = error_mark_node;
if (val == NULL_TREE)
val = error_mark_node;
else if (val == error_mark_node && (complain & tf_error))
- error ("could not convert template argument `%E' to `%T'",
- arg, t);
+ error ("could not convert template argument %qE to %qT", arg, t);
}
return val;
if (complain & tf_error)
{
error ("wrong number of template arguments (%d, should be %d)",
- nargs, nparms);
+ nargs, nparms);
if (in_decl)
- cp_error_at ("provided for `%D'", in_decl);
+ cp_error_at ("provided for %qD", in_decl);
}
return error_mark_node;
else
break;
- my_friendly_assert (arg, 20030727);
+ gcc_assert (arg);
if (arg == error_mark_node)
error ("template argument %d is invalid", i + 1);
else
ccat ('<');
nparms = TREE_VEC_LENGTH (parms);
arglist = INNERMOST_TEMPLATE_ARGS (arglist);
- my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
+ gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
for (i = 0; i < nparms; i++)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
{
/* The template may be defined in a namespace, or
may be a member template. */
- my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL
- || CLASS_TYPE_P (context),
- 980422);
- cat(decl_as_string (DECL_CONTEXT (arg), TFF_PLAIN_IDENTIFIER));
- cat("::");
+ gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
+ || CLASS_TYPE_P (context));
+ cat (decl_as_string (DECL_CONTEXT (arg),
+ TFF_PLAIN_IDENTIFIER));
+ cat ("::");
}
cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
}
continue;
}
else
- my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
+ gcc_assert (TREE_CODE (parm) == PARM_DECL);
/* No need to check arglist against parmlist here; we did that
in coerce_template_parms, called from lookup_template_class. */
if (fns == error_mark_node || arglist == error_mark_node)
return error_mark_node;
- my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
+ gcc_assert (!arglist || TREE_CODE (arglist) == TREE_VEC);
if (fns == NULL_TREE
|| TREE_CODE (fns) == FUNCTION_DECL)
{
return error_mark_node;
}
- my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
- || TREE_CODE (fns) == OVERLOAD
- || BASELINK_P (fns)
- || TREE_CODE (fns) == IDENTIFIER_NODE,
- 20020730);
+ gcc_assert (TREE_CODE (fns) == TEMPLATE_DECL
+ || TREE_CODE (fns) == OVERLOAD
+ || BASELINK_P (fns)
+ || TREE_CODE (fns) == IDENTIFIER_NODE);
if (BASELINK_P (fns))
{
if (! template)
{
if (complain & tf_error)
- error ("`%T' is not a template", d1);
+ error ("%qT is not a template", d1);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
{
if (complain & tf_error)
{
- error ("non-template type `%T' used as a template", d1);
+ error ("non-template type %qT used as a template", d1);
if (in_decl)
- cp_error_at ("for template declaration `%D'", in_decl);
+ cp_error_at ("for template declaration %qD", in_decl);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
tree gen_tmpl;
tree type_decl;
tree found = NULL_TREE;
- tree *tp;
int arg_depth;
int parm_depth;
int is_partial_instantiation;
}
/* Now we should have enough arguments. */
- my_friendly_assert (parm_depth == arg_depth, 0);
+ gcc_assert (parm_depth == arg_depth);
/* From here on, we're only interested in the most general
template. */
if (found)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
- for (tp = &DECL_TEMPLATE_INSTANTIATIONS (template);
- *tp;
- tp = &TREE_CHAIN (*tp))
- if (comp_template_args (TREE_PURPOSE (*tp), arglist))
- {
- found = *tp;
-
- /* Use the move-to-front heuristic to speed up future
- searches. */
- *tp = TREE_CHAIN (*tp);
- TREE_CHAIN (found)
- = DECL_TEMPLATE_INSTANTIATIONS (template);
- DECL_TEMPLATE_INSTANTIATIONS (template) = found;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (found));
- }
+ /* If we already have this specialization, return it. */
+ found = retrieve_specialization (template, arglist,
+ /*class_specializations_p=*/false);
+ if (found)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
/* This type is a "partial instantiation" if any of the template
arguments still involve template parameters. Note that we set
|| TREE_CODE (t) == TEMPLATE_PARM_INDEX
|| TREE_CODE (t) == OVERLOAD
|| TREE_CODE (t) == BASELINK
- || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
+ || CONSTANT_CLASS_P (t))
dependent_p = (type_dependent_expression_p (t)
|| value_dependent_expression_p (t));
- else if (t == error_mark_node)
- dependent_p = false;
- else
- abort ();
+ else
+ {
+ gcc_assert (t == error_mark_node);
+ dependent_p = false;
+ }
+
processing_template_decl = saved_processing_template_decl;
return dependent_p;
return 0;
last_template_error_tick = tinst_level_tick;
- error ("template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'",
+ error ("template instantiation depth exceeds maximum of %d (use "
+ "-ftemplate-depth-NN to increase the maximum) instantiating %qD",
max_tinst_depth, d);
print_instantiation_context ();
/* Restore the filename and line number stashed away when we started
this instantiation. */
input_location = TINST_LOCATION (old);
- extract_interface_info ();
-
current_tinst_level = TREE_CHAIN (old);
--tinst_depth;
++tinst_level_tick;
/* Figure out which template is being instantiated. */
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
- my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
+ gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
/* Figure out which arguments are being used to do the
instantiation. */
if (t == error_mark_node)
{
const char *str = "candidates are:";
- error ("ambiguous class template instantiation for `%#T'", type);
+ error ("ambiguous class template instantiation for %q#T", type);
for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
t = TREE_CHAIN (t))
{
TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern);
TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern);
TYPE_HAS_CONVERSION (type) = TYPE_HAS_CONVERSION (pattern);
- TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
- = TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (pattern);
- TYPE_USES_MULTIPLE_INHERITANCE (type)
- = TYPE_USES_MULTIPLE_INHERITANCE (pattern);
- TYPE_USES_VIRTUAL_BASECLASSES (type)
- = TYPE_USES_VIRTUAL_BASECLASSES (pattern);
TYPE_PACKED (type) = TYPE_PACKED (pattern);
TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
pbinfo = TYPE_BINFO (pattern);
-#ifdef ENABLE_CHECKING
- if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
- && ! COMPLETE_TYPE_P (TYPE_CONTEXT (type))
- && ! TYPE_BEING_DEFINED (TYPE_CONTEXT (type)))
- /* We should never instantiate a nested class before its enclosing
- class; we need to look up the nested class by name before we can
- instantiate it, and that lookup should instantiate the enclosing
- class. */
- abort ();
-#endif
+ /* We should never instantiate a nested class before its enclosing
+ class; we need to look up the nested class by name before we can
+ instantiate it, and that lookup should instantiate the enclosing
+ class. */
+ gcc_assert (!DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
+ || COMPLETE_TYPE_P (TYPE_CONTEXT (type))
+ || TYPE_BEING_DEFINED (TYPE_CONTEXT (type)));
base_list = NULL_TREE;
if (BINFO_N_BASE_BINFOS (pbinfo))
/* tsubst_template_args doesn't copy the vector if
nothing changed. But, *something* should have
changed. */
- my_friendly_assert (full_args != tmpl_args, 0);
+ gcc_assert (full_args != tmpl_args);
- spec = retrieve_specialization (t, full_args);
+ spec = retrieve_specialization (t, full_args,
+ /*class_specializations_p=*/true);
if (spec != NULL_TREE)
{
r = spec;
like the old one, but points to this new template, rather
than the old one. */
r = copy_decl (t);
- my_friendly_assert (DECL_LANG_SPECIFIC (r) != 0, 0);
+ gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
TREE_CHAIN (r) = NULL_TREE;
if (is_template_template_parm)
int parms_depth;
/* Nobody should be tsubst'ing into non-template functions. */
- my_friendly_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE, 0);
+ gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE);
if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
{
args, complain, in_decl);
/* Check to see if we already have this specialization. */
- spec = retrieve_specialization (gen_tmpl, argvec);
+ spec = retrieve_specialization (gen_tmpl, argvec,
+ /*class_specializations_p=*/false);
if (spec)
{
complain, in_decl);
TREE_CHAIN (r) = NULL_TREE;
if (VOID_TYPE_P (type))
- cp_error_at ("instantiation of `%D' as type `%T'", r, type);
+ cp_error_at ("instantiation of %qD as type %qT", r, type);
}
break;
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);
+ spec = retrieve_specialization (gen_tmpl, argvec,
+ /*class_specializations_p=*/false);
}
else
spec = retrieve_local_specialization (t);
TREE_CHAIN (r) = NULL_TREE;
if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
- cp_error_at ("instantiation of `%D' as type `%T'", r, type);
+ cp_error_at ("instantiation of %qD as type %qT", r, type);
/* Compute the size, alignment, etc. of R. */
layout_decl (r, 0);
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
/* Restore the file and line information. */
{
if (complain & tf_error)
{
- error ("invalid parameter type `%T'", type);
+ error ("invalid parameter type %qT", type);
if (in_decl)
- cp_error_at ("in declaration `%D'", in_decl);
+ cp_error_at ("in declaration %qD", in_decl);
}
return error_mark_node;
}
tree fntype;
/* The TYPE_CONTEXT is not used for function/method types. */
- my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
+ gcc_assert (TYPE_CONTEXT (t) == NULL_TREE);
/* Substitute the return type. */
return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-- Attempting to create "pointer to member of T" when T
is not a class type. */
if (complain & tf_error)
- error ("creating pointer to member function of non-class type `%T'",
+ error ("creating pointer to member function of non-class type %qT",
r);
return error_mark_node;
}
return fntype;
}
+/* FNTYPE is a FUNCTION_TYPE or METHOD_TYPE. Substitute the template
+ ARGS into that specification, and return the substituted
+ specification. If there is no specification, return NULL_TREE. */
+
+static tree
+tsubst_exception_specification (tree fntype,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ tree specs;
+ tree new_specs;
+
+ specs = TYPE_RAISES_EXCEPTIONS (fntype);
+ new_specs = NULL_TREE;
+ if (specs)
+ {
+ if (! TREE_VALUE (specs))
+ new_specs = specs;
+ else
+ while (specs)
+ {
+ tree spec;
+ spec = tsubst (TREE_VALUE (specs), args, complain, in_decl);
+ if (spec == error_mark_node)
+ return spec;
+ new_specs = add_exception_specifier (new_specs, spec, complain);
+ specs = TREE_CHAIN (specs);
+ }
+ }
+ return new_specs;
+}
+
/* Substitute into the PARMS of a call-declarator. */
static tree
else
type = TREE_TYPE (t);
- my_friendly_assert (type != unknown_type_node, 20030716);
+ gcc_assert (type != unknown_type_node);
if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE
Attempting to create an array with a size that is
zero or negative. */
if (complain & tf_error)
- error ("creating array with size zero (`%E')", max);
+ error ("creating array with size zero (%qE)", max);
return error_mark_node;
}
int idx;
int level;
int levels;
+ tree arg = NULL_TREE;
r = NULL_TREE;
+ gcc_assert (TREE_VEC_LENGTH (args) > 0);
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
|| TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
level = TEMPLATE_PARM_LEVEL (t);
}
- if (TREE_VEC_LENGTH (args) > 0)
- {
- tree arg = NULL_TREE;
-
- levels = TMPL_ARGS_DEPTH (args);
- if (level <= levels)
- arg = TMPL_ARG (args, level, idx);
+ levels = TMPL_ARGS_DEPTH (args);
+ if (level <= levels)
+ arg = TMPL_ARG (args, level, idx);
- if (arg == error_mark_node)
- return error_mark_node;
- else if (arg != NULL_TREE)
+ if (arg == error_mark_node)
+ return error_mark_node;
+ else if (arg != NULL_TREE)
+ {
+ if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
{
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
- {
- my_friendly_assert (TYPE_P (arg), 0);
- return cp_build_qualified_type_real
- (arg, cp_type_quals (arg) | cp_type_quals (t),
- complain | tf_ignore_bad_quals);
- }
- else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
- {
- /* We are processing a type constructed from
- a template template parameter. */
- tree argvec = tsubst (TYPE_TI_ARGS (t),
- args, complain, in_decl);
- if (argvec == error_mark_node)
- return error_mark_node;
+ gcc_assert (TYPE_P (arg));
+ return cp_build_qualified_type_real
+ (arg, cp_type_quals (arg) | cp_type_quals (t),
+ complain | tf_ignore_bad_quals);
+ }
+ else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ {
+ /* We are processing a type constructed from a
+ template template parameter. */
+ tree argvec = tsubst (TYPE_TI_ARGS (t),
+ args, complain, in_decl);
+ if (argvec == error_mark_node)
+ return error_mark_node;
- /* We can get a TEMPLATE_TEMPLATE_PARM here when
- we are resolving nested-types in the signature of
- a member function templates.
- Otherwise ARG is a TEMPLATE_DECL and is the real
- template to be instantiated. */
- if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
- arg = TYPE_NAME (arg);
-
- r = lookup_template_class (arg,
- argvec, in_decl,
- DECL_CONTEXT (arg),
- /*entering_scope=*/0,
- complain);
- return cp_build_qualified_type_real
- (r, TYPE_QUALS (t), complain);
- }
- else
- /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */
- return arg;
+ /* We can get a TEMPLATE_TEMPLATE_PARM here when we
+ are resolving nested-types in the signature of a
+ member function templates. Otherwise ARG is a
+ TEMPLATE_DECL and is the real template to be
+ instantiated. */
+ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ arg = TYPE_NAME (arg);
+
+ r = lookup_template_class (arg,
+ argvec, in_decl,
+ DECL_CONTEXT (arg),
+ /*entering_scope=*/0,
+ complain);
+ return cp_build_qualified_type_real
+ (r, TYPE_QUALS (t), complain);
}
+ else
+ /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */
+ return arg;
}
- else
- abort ();
if (level == 1)
/* This can happen during the attempted tsubst'ing in
break;
default:
- abort ();
+ gcc_unreachable ();
}
return r;
case TREE_BINFO:
/* We should never be tsubsting a binfo. */
- abort ();
+ gcc_unreachable ();
case TREE_VEC:
/* A vector of template arguments. */
- my_friendly_assert (!type, 20040628);
+ gcc_assert (!type);
return tsubst_template_args (t, args, complain, in_decl);
case POINTER_TYPE:
single bad template instantiation. */
if (complain & tf_error
#ifdef USE_MAPPED_LOCATION
- && last_loc != input_location)
+ && last_loc != input_location
#else
&& (last_loc.line != input_line
- || last_loc.file != input_filename))
+ || last_loc.file != input_filename)
#endif
+ )
{
if (TREE_CODE (type) == VOID_TYPE)
error ("forming reference to void");
else
- error ("forming %s to reference type `%T'",
- (code == POINTER_TYPE) ? "pointer" : "reference",
- type);
+ error ("forming %s to reference type %qT",
+ (code == POINTER_TYPE) ? "pointer" : "reference",
+ type);
last_loc = input_location;
}
-- Attempting to create "pointer to member of T" when T
is not a class type. */
if (complain & tf_error)
- error ("creating pointer to member of non-class type `%T'", r);
+ error ("creating pointer to member of non-class type %qT", r);
return error_mark_node;
}
if (TREE_CODE (type) == REFERENCE_TYPE)
{
if (complain & tf_error)
- error ("creating pointer to member reference type `%T'", type);
+ error ("creating pointer to member reference type %qT", type);
return error_mark_node;
}
- my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
+ gcc_assert (TREE_CODE (type) != METHOD_TYPE);
if (TREE_CODE (type) == FUNCTION_TYPE)
{
/* This is really a method type. The cv qualifiers of the
case METHOD_TYPE:
{
tree fntype;
- tree raises;
-
+ tree specs;
fntype = tsubst_function_type (t, args, complain, in_decl);
if (fntype == error_mark_node)
return error_mark_node;
/* Substitute the exception specification. */
- raises = TYPE_RAISES_EXCEPTIONS (t);
- if (raises)
- {
- tree list = NULL_TREE;
-
- if (! TREE_VALUE (raises))
- list = raises;
- else
- for (; raises != NULL_TREE; raises = TREE_CHAIN (raises))
- {
- tree spec = TREE_VALUE (raises);
-
- spec = tsubst (spec, args, complain, in_decl);
- if (spec == error_mark_node)
- return spec;
- list = add_exception_specifier (list, spec, complain);
- }
- fntype = build_exception_variant (fntype, list);
- }
+ specs = tsubst_exception_specification (t, args, complain,
+ in_decl);
+ if (specs)
+ fntype = build_exception_variant (fntype, specs);
return fntype;
}
case ARRAY_TYPE:
|| TREE_CODE (type) == REFERENCE_TYPE)
{
if (complain & tf_error)
- error ("creating array of `%T'", type);
+ error ("creating array of %qT", type);
return error_mark_node;
}
if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
{
if (complain & tf_error)
- error ("creating array of `%T', which is an abstract class type",
+ error ("creating array of %qT, which is an abstract class type",
type);
return error_mark_node;
}
if (!IS_AGGR_TYPE (ctx))
{
if (complain & tf_error)
- error ("`%T' is not a class, struct, or union type",
- ctx);
+ error ("%qT is not a class, struct, or union type", ctx);
return error_mark_node;
}
else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
case INDIRECT_REF:
case ADDR_EXPR:
case CALL_EXPR:
- abort ();
+ gcc_unreachable ();
case ARRAY_REF:
{
}
name = DECL_NAME (get_first_fn (fns));
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
+
+ /* If lookup found a single function, mark it as used at this
+ point. (If it lookup found multiple functions the one selected
+ later by overload resolution will be marked as used at that
+ point.) */
+ if (BASELINK_P (baselink))
+ fns = BASELINK_FUNCTIONS (baselink);
+ if (!template_id_p && !really_overloaded_fn (fns))
+ mark_used (OVL_CURRENT (fns));
+
+ /* Add back the template arguments, if present. */
if (BASELINK_P (baselink) && template_id_p)
BASELINK_FUNCTIONS (baselink)
= build_nt (TEMPLATE_ID_EXPR,
BASELINK_FUNCTIONS (baselink),
template_args);
+
if (!object_type)
object_type = current_class_type;
return adjust_result_of_qualified_name_lookup (baselink,
bool is_template;
tree template_args;
- my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706);
+ gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF);
/* Figure out what name to look up. */
name = TREE_OPERAND (qualified_id, 1);
{
if (complain & tf_error)
{
- error ("dependent-name `%E' is parsed as a non-type, but "
+ error ("dependent-name %qE is parsed as a non-type, but "
"instantiation yields a type", qualified_id);
- inform ("say `typename %E' if a type is meant", qualified_id);
+ inform ("say %<typename %E%> if a type is meant", qualified_id);
}
return error_mark_node;
}
{
case PARM_DECL:
r = retrieve_local_specialization (t);
- my_friendly_assert (r != NULL, 20020903);
+ gcc_assert (r != NULL);
mark_used (r);
return r;
/* We didn't find the name. That should never happen; if
name-lookup found it during preliminary parsing, we
should find it again here during instantiation. */
- abort ();
+ gcc_unreachable ();
}
return t;
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
args, complain, in_decl);
- else if (is_member_template (t))
+ else if (DECL_FUNCTION_TEMPLATE_P (t) && DECL_MEMBER_TEMPLATE_P (t))
return tsubst (t, args, complain, in_decl);
else if (DECL_CLASS_SCOPE_P (t)
&& uses_template_parms (DECL_CONTEXT (t)))
(code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+ TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
return r;
}
/* We shouldn't have built any of these during initial template
generation. Instead, they should be built during instantiation
in response to the saved STMT_IS_FULL_EXPR_P setting. */
- abort ();
+ gcc_unreachable ();
default:
return t;
static tree
tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- /* Live only within one (recursive) call to tsubst_expr. We use
- this to pass the statement expression node from the STMT_EXPR
- to the EXPR_STMT that is its result. */
- static tree cur_stmt_expr;
-
tree stmt, tmp;
if (t == NULL_TREE || t == error_mark_node)
args, complain, in_decl));
break;
- case STMT_EXPR:
- {
- tree old_stmt_expr = cur_stmt_expr;
- tree stmt_expr = begin_stmt_expr ();
-
- cur_stmt_expr = stmt_expr;
- tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
- stmt_expr = finish_stmt_expr (stmt_expr, false);
- cur_stmt_expr = old_stmt_expr;
-
- return stmt_expr;
- }
-
case EXPR_STMT:
tmp = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
if (EXPR_STMT_STMT_EXPR_RESULT (t))
break;
default:
- if (!STATEMENT_CODE_P (TREE_CODE (t)))
- return tsubst_copy_and_build (t, args, complain, in_decl,
- /*function_p=*/false);
- abort ();
+ gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
+
+ return tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
}
return NULL_TREE;
return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
case MODOP_EXPR:
- return build_x_modify_expr
- (RECUR (TREE_OPERAND (t, 0)),
- TREE_CODE (TREE_OPERAND (t, 1)),
- RECUR (TREE_OPERAND (t, 2)));
+ {
+ tree r = build_x_modify_expr
+ (RECUR (TREE_OPERAND (t, 0)),
+ TREE_CODE (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
+ /* TREE_NO_WARNING must be set if either the expression was
+ parenthesized or it uses an operator such as >>= rather
+ than plain assignment. In the former case, it was already
+ set and must be copied. In the latter case,
+ build_x_modify_expr sets it and it must not be reset
+ here. */
+ if (TREE_NO_WARNING (t))
+ TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+ return r;
+ }
case ARROW_EXPR:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
if (complain & tf_error)
{
if (TYPE_P (TREE_OPERAND (member, 0)))
- error ("`%T' is not a class or namespace",
+ error ("%qT is not a class or namespace",
TREE_OPERAND (member, 0));
else
- error ("`%D' is not a class or namespace",
+ error ("%qD is not a class or namespace",
TREE_OPERAND (member, 0));
}
return error_mark_node;
tsubst_copy (TREE_TYPE (t), args, complain,
in_decl));
+ case OFFSETOF_EXPR:
+ return fold_offsetof (RECUR (TREE_OPERAND (t, 0)));
+
+ case STMT_EXPR:
+ {
+ tree old_stmt_expr = cur_stmt_expr;
+ tree stmt_expr = begin_stmt_expr ();
+
+ cur_stmt_expr = stmt_expr;
+ tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
+ stmt_expr = finish_stmt_expr (stmt_expr, false);
+ cur_stmt_expr = old_stmt_expr;
+
+ return stmt_expr;
+ }
+
default:
return tsubst_copy (t, args, complain, in_decl);
}
if (!(complain & tf_error))
/*OK*/;
else if (TYPE_ANONYMOUS_P (nt))
- error ("`%T' uses anonymous type", t);
+ error ("%qT uses anonymous type", t);
else
- error ("`%T' uses local type `%T'", t, nt);
+ error ("%qT uses local type %qT", t, nt);
result = true;
}
/* In order to avoid all sorts of complications, we do not
else if (variably_modified_type_p (t, NULL_TREE))
{
if (complain & tf_error)
- error ("`%T' is a variably modified type", t);
+ error ("%qT is a variably modified type", t);
result = true;
}
}
&& !TREE_CONSTANT (t))
{
if (complain & tf_error)
- error ("integral expression `%E' is not constant", t);
+ error ("integral expression %qE is not constant", t);
result = true;
}
}
if (result && complain & tf_error)
- error (" trying to instantiate `%D'", tmpl);
+ error (" trying to instantiate %qD", tmpl);
return result;
}
if (tmpl == error_mark_node)
return error_mark_node;
- my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
/* If this function is a clone, handle it specially. */
if (DECL_CLONED_FUNCTION_P (tmpl))
if (DECL_NAME (clone) == DECL_NAME (tmpl))
return clone;
/* We should always have found the clone by now. */
- abort ();
+ gcc_unreachable ();
return NULL_TREE;
}
/* Check to see if we already have this specialization. */
- spec = retrieve_specialization (tmpl, targ_ptr);
+ spec = retrieve_specialization (tmpl, targ_ptr,
+ /*class_specializations_p=*/false);
if (spec != NULL_TREE)
return spec;
targ_ptr);
/* Check to see if we already have this specialization. */
- spec = retrieve_specialization (gen_tmpl, targ_ptr);
+ spec = retrieve_specialization (gen_tmpl, targ_ptr,
+ /*class_specializations_p=*/false);
if (spec != NULL_TREE)
return spec;
}
tree fntype;
int result;
- my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
+ gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
fntype = TREE_TYPE (fn);
if (explicit_targs)
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (TREE_CODE (*parm) != REFERENCE_TYPE)
tree parms, args;
int len;
- my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
- my_friendly_assert (xparms == NULL_TREE
- || TREE_CODE (xparms) == TREE_LIST, 290);
- my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291);
- my_friendly_assert (ntparms > 0, 292);
+ gcc_assert (TREE_CODE (tparms) == TREE_VEC);
+ gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
+ gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
+ gcc_assert (ntparms > 0);
switch (strict)
{
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (xlen == 0)
if (!TYPE_P (arg))
{
- my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
+ gcc_assert (TREE_TYPE (arg) != NULL_TREE);
if (type_unknown_p (arg))
{
/* [temp.deduct.type] A template-argument can be deduced from
}
}
}
- else if (TREE_CODE (arg) == OVERLOAD
- || TREE_CODE (arg) == FUNCTION_DECL)
+ else
{
+ gcc_assert (TREE_CODE (arg) == OVERLOAD
+ || TREE_CODE (arg) == FUNCTION_DECL);
+
for (; arg; arg = OVL_NEXT (arg))
good += try_one_overload (tparms, targs, tempargs, parm,
TREE_TYPE (OVL_CURRENT (arg)),
strict, sub_strict, addr_p);
}
- else
- abort ();
/* [temp.deduct.type] A template-argument can be deduced from a pointer
to function or pointer to member function argument if the set of
return arg;
}
-/* Subroutine of get_template_base. RVAL, if non-NULL, is a base we
- have already discovered to be satisfactory. ARG_BINFO is the binfo
- for the base class of ARG that we are currently examining. */
-
-static tree
-get_template_base_recursive (tree tparms,
- tree targs,
- tree parm,
- tree arg_binfo,
- tree rval,
- int flags)
-{
- tree base_binfo;
- int i;
- tree arg = BINFO_TYPE (arg_binfo);
-
- if (!(flags & GTB_IGNORE_TYPE))
- {
- tree r = try_class_unification (tparms, targs,
- parm, arg);
-
- /* If there is more than one satisfactory baseclass, then:
-
- [temp.deduct.call]
-
- If they yield more than one possible deduced A, the type
- deduction fails.
-
- applies. */
- if (r && rval && !same_type_p (r, rval))
- return error_mark_node;
- else if (r)
- rval = r;
- }
-
- /* Process base types. */
- for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
- {
- int this_virtual;
-
- /* Skip this base, if we've already seen it. */
- if (BINFO_MARKED (base_binfo))
- continue;
-
- this_virtual =
- (flags & GTB_VIA_VIRTUAL) || BINFO_VIRTUAL_P (base_binfo);
-
- /* When searching for a non-virtual, we cannot mark virtually
- found binfos. */
- if (! this_virtual)
- BINFO_MARKED (base_binfo) = 1;
-
- rval = get_template_base_recursive (tparms, targs,
- parm,
- base_binfo,
- rval,
- GTB_VIA_VIRTUAL * this_virtual);
-
- /* If we discovered more than one matching base class, we can
- stop now. */
- if (rval == error_mark_node)
- return error_mark_node;
- }
-
- return rval;
-}
-
/* Given a template type PARM and a class type ARG, find the unique
base type in ARG that is an instance of PARM. We do not examine
- ARG itself; only its base-classes. If there is no appropriate base
- class, return NULL_TREE. If there is more than one, return
- error_mark_node. PARM may be the type of a partial specialization,
- as well as a plain template type. Used by unify. */
+ ARG itself; only its base-classes. If there is not exactly one
+ appropriate base class, return NULL_TREE. PARM may be the type of
+ a partial specialization, as well as a plain template type. Used
+ by unify. */
static tree
get_template_base (tree tparms, tree targs, tree parm, tree arg)
{
- tree rval;
- tree arg_binfo;
+ tree rval = NULL_TREE;
+ tree binfo;
- my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92);
+ gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
- arg_binfo = TYPE_BINFO (complete_type (arg));
- if (!arg_binfo)
+ binfo = TYPE_BINFO (complete_type (arg));
+ if (!binfo)
/* The type could not be completed. */
return NULL_TREE;
-
- rval = get_template_base_recursive (tparms, targs,
- parm, arg_binfo,
- NULL_TREE,
- GTB_IGNORE_TYPE);
- /* Since get_template_base_recursive marks the bases classes, we
- must unmark them here. */
- dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
+ /* Walk in inheritance graph order. The search order is not
+ important, and this avoids multiple walks of virtual bases. */
+ for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo))
+ {
+ tree r = try_class_unification (tparms, targs, parm, BINFO_TYPE (binfo));
+
+ if (r)
+ {
+ /* If there is more than one satisfactory baseclass, then:
+
+ [temp.deduct.call]
+
+ If they yield more than one possible deduced A, the type
+ deduction fails.
+
+ applies. */
+ if (rval && !same_type_p (r, rval))
+ return NULL_TREE;
+
+ rval = r;
+ }
+ }
return rval;
}
return TEMPLATE_PARM_LEVEL (DECL_INITIAL (decl));
default:
- abort ();
- return 0;
+ gcc_unreachable ();
}
+ return 0;
}
/* Decide whether ARG can be unified with PARM, considering only the
case VECTOR_TYPE:
case INTEGER_TYPE:
case BOOLEAN_TYPE:
+ case ENUMERAL_TYPE:
case VOID_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
a class of the form template-id, A can be a
pointer to a derived class pointed to by the
deduced A. */
- t = get_template_base (tparms, targs,
- parm, arg);
+ t = get_template_base (tparms, targs, parm, arg);
- if (! t || t == error_mark_node)
+ if (!t)
return 1;
}
}
return 1;
default:
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
- {
-
- /* We're looking at an expression. This can happen with
- something like:
+ gcc_assert (EXPR_P (parm));
+
+ /* We must be looking at an expression. This can happen with
+ something like:
- template <int I>
- void foo(S<I>, S<I + 2>);
+ template <int I>
+ void foo(S<I>, S<I + 2>);
- This is a "nondeduced context":
+ This is a "nondeduced context":
- [deduct.type]
+ [deduct.type]
- The nondeduced contexts are:
+ The nondeduced contexts are:
- --A type that is a template-id in which one or more of
- the template-arguments is an expression that references
- a template-parameter.
+ --A type that is a template-id in which one or more of
+ the template-arguments is an expression that references
+ a template-parameter.
- In these cases, we assume deduction succeeded, but don't
- actually infer any unifications. */
+ In these cases, we assume deduction succeeded, but don't
+ actually infer any unifications. */
- if (!uses_template_parms (parm)
- && !template_args_equal (parm, arg))
- return 1;
- else
- return 0;
- }
+ if (!uses_template_parms (parm)
+ && !template_args_equal (parm, arg))
+ return 1;
else
- sorry ("use of `%s' in template type unification",
- tree_code_name [(int) TREE_CODE (parm)]);
-
- return 1;
+ return 0;
}
}
\f
return;
else if (! DECL_LANG_SPECIFIC (decl))
{
- error ("explicit instantiation of non-template `%#D'", decl);
+ error ("explicit instantiation of non-template %q#D", decl);
return;
}
else if (TREE_CODE (decl) == VAR_DECL)
result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false);
if (!result || TREE_CODE (result) != VAR_DECL)
{
- error ("no matching template for `%D' found", decl);
+ error ("no matching template for %qD found", decl);
return;
}
}
else if (TREE_CODE (decl) != FUNCTION_DECL)
{
- error ("explicit instantiation of `%#D'", decl);
+ error ("explicit instantiation of %q#D", decl);
return;
}
else
the first instantiation was `extern' and the second is not,
and EXTERN_P for the opposite case. */
if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
- pedwarn ("duplicate explicit instantiation of `%#D'", result);
+ pedwarn ("duplicate explicit instantiation of %q#D", result);
/* If an "extern" explicit instantiation follows an ordinary
explicit instantiation, the template is instantiated. */
if (extern_p)
}
else if (!DECL_IMPLICIT_INSTANTIATION (result))
{
- error ("no matching template for `%D' found", result);
+ error ("no matching template for %qD found", result);
return;
}
else if (!DECL_TEMPLATE_INFO (result))
{
- pedwarn ("explicit instantiation of non-template `%#D'", result);
+ pedwarn ("explicit instantiation of non-template %q#D", result);
return;
}
else if (storage == ridpointers[(int) RID_EXTERN])
{
if (pedantic && !in_system_header)
- pedwarn ("ISO C++ forbids the use of `extern' on explicit instantiations");
+ pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
+ "instantiations");
extern_p = 1;
}
else
- error ("storage class `%D' applied to template instantiation",
- storage);
+ error ("storage class %qD applied to template instantiation", storage);
mark_decl_instantiated (result, extern_p);
if (! extern_p)
if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
{
- error ("explicit instantiation of non-template type `%T'", t);
+ error ("explicit instantiation of non-template type %qT", t);
return;
}
if (!COMPLETE_TYPE_P (t))
{
if (complain & tf_error)
- error ("explicit instantiation of `%#T' before definition of template",
- t);
+ error ("explicit instantiation of %q#T before definition of template",
+ t);
return;
}
static_p = 1;
else
{
- error ("storage class `%D' applied to template instantiation",
- storage);
+ error ("storage class %qD applied to template instantiation",
+ storage);
extern_p = 0;
}
}
if (!previous_instantiation_extern_p && !extern_p
&& (complain & tf_error))
- pedwarn ("duplicate explicit instantiation of `%#T'", t);
+ pedwarn ("duplicate explicit instantiation of %q#T", t);
/* If we've already instantiated the template, just return now. */
if (!CLASSTYPE_INTERFACE_ONLY (t))
static void
regenerate_decl_from_template (tree decl, tree tmpl)
{
- /* The most general version of TMPL. */
- tree gen_tmpl;
/* The arguments used to instantiate DECL, from the most general
template. */
tree args;
tree code_pattern;
- tree new_decl;
- bool unregistered;
args = DECL_TI_ARGS (decl);
code_pattern = DECL_TEMPLATE_RESULT (tmpl);
- /* Unregister the specialization so that when we tsubst we will not
- just return DECL. We don't have to unregister DECL from TMPL
- because if would only be registered there if it were a partial
- instantiation of a specialization, which it isn't: it's a full
- instantiation. */
- gen_tmpl = most_general_template (tmpl);
- unregistered = reregister_specialization (decl, gen_tmpl,
- /*new_spec=*/NULL_TREE);
-
- /* If the DECL was not unregistered then something peculiar is
- happening: we created a specialization but did not call
- register_specialization for it. */
- my_friendly_assert (unregistered, 0);
-
/* Make sure that we can see identifiers, and compute access
correctly. */
push_access_scope (decl);
- /* Do the substitution to get the new declaration. */
- new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ tree decl_parm;
+ tree pattern_parm;
+ tree specs;
+ int args_depth;
+ int parms_depth;
+
+ args_depth = TMPL_ARGS_DEPTH (args);
+ parms_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+ if (args_depth > parms_depth)
+ args = get_innermost_template_args (args, parms_depth);
+
+ specs = tsubst_exception_specification (TREE_TYPE (code_pattern),
+ args, tf_error, NULL_TREE);
+ if (specs)
+ TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl),
+ specs);
+
+ /* Merge parameter declarations. */
+ decl_parm = skip_artificial_parms_for (decl,
+ DECL_ARGUMENTS (decl));
+ pattern_parm
+ = skip_artificial_parms_for (code_pattern,
+ DECL_ARGUMENTS (code_pattern));
+ while (decl_parm)
+ {
+ tree parm_type;
+
+ if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
+ DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
+ parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
+ NULL_TREE);
+ if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
+ TREE_TYPE (decl_parm) = parm_type;
+ decl_parm = TREE_CHAIN (decl_parm);
+ pattern_parm = TREE_CHAIN (pattern_parm);
+ }
- if (TREE_CODE (decl) == VAR_DECL)
+ /* Merge additional specifiers from the CODE_PATTERN. */
+ if (DECL_DECLARED_INLINE_P (code_pattern)
+ && !DECL_DECLARED_INLINE_P (decl))
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ if (DECL_INLINE (code_pattern) && !DECL_INLINE (decl))
+ DECL_INLINE (decl) = 1;
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
{
- /* Set up DECL_INITIAL, since tsubst doesn't. */
- if (!DECL_INITIALIZED_IN_CLASS_P (decl))
- DECL_INITIAL (new_decl) =
+ if (!DECL_INITIALIZED_IN_CLASS_P (decl)
+ && DECL_INITIAL (code_pattern))
+ DECL_INITIAL (decl) =
tsubst_expr (DECL_INITIAL (code_pattern), args,
tf_error, DECL_TI_TEMPLATE (decl));
}
- else if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- /* Convince duplicate_decls to use the DECL_ARGUMENTS from the
- new decl. */
- DECL_INITIAL (new_decl) = error_mark_node;
- /* And don't complain about a duplicate definition. */
- DECL_INITIAL (decl) = NULL_TREE;
- }
+ else
+ gcc_unreachable ();
pop_access_scope (decl);
-
- /* The immediate parent of the new template is still whatever it was
- before, even though tsubst sets DECL_TI_TEMPLATE up as the most
- general template. We also reset the DECL_ASSEMBLER_NAME since
- tsubst always calculates the name as if the function in question
- were really a template instance, and sometimes, with friend
- functions, this is not so. See tsubst_friend_function for
- details. */
- DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl);
- COPY_DECL_ASSEMBLER_NAME (decl, new_decl);
- COPY_DECL_RTL (decl, new_decl);
- DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
-
- /* Call duplicate decls to merge the old and new declarations. */
- duplicate_decls (new_decl, decl);
-
- /* Now, re-register the specialization. */
- register_specialization (decl, gen_tmpl, args);
}
/* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be
cannot restructure the loop to just keep going until we find
a template with a definition, since that might go too far if
a specialization was declared, but not defined. */
- my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
- && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))),
- 0);
+ gcc_assert (TREE_CODE (decl) != VAR_DECL
+ || DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl)));
/* Fetch the more general template. */
tmpl = DECL_TI_TEMPLATE (tmpl);
/* This function should only be used to instantiate templates for
functions and static member variables. */
- my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
- || TREE_CODE (d) == VAR_DECL, 0);
+ gcc_assert (TREE_CODE (d) == FUNCTION_DECL
+ || TREE_CODE (d) == VAR_DECL);
/* Variables are never deferred; if instantiation is required, they
are instantiated right away. That allows for better code in the
DECL_TEMPLATE_SPECIALIZATION. */
gen_tmpl = most_general_template (tmpl);
gen_args = DECL_TI_ARGS (d);
- spec = retrieve_specialization (gen_tmpl, gen_args);
+ spec = retrieve_specialization (gen_tmpl, gen_args,
+ /*class_specializations_p=*/false);
if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
return spec;
/* We should have set up DECL_INITIAL in instantiate_class_template
for in-class definitions of static data members. */
- my_friendly_assert (!(TREE_CODE (d) == VAR_DECL
- && DECL_INITIALIZED_IN_CLASS_P (d)
- && DECL_INITIAL (d) == NULL_TREE),
- 20040726);
+ gcc_assert (!(TREE_CODE (d) == VAR_DECL
+ && DECL_INITIALIZED_IN_CLASS_P (d)
+ && DECL_INITIAL (d) == NULL_TREE));
/* Do not instantiate templates that we know will be defined
elsewhere. */
shall be present in every translation unit in which it is
explicitly instantiated. */
pedwarn
- ("explicit instantiation of `%D' but no definition available", d);
+ ("explicit instantiation of %qD but no definition available", d);
add_pending_template (d);
goto out;
/* Instantiate inline functions so that the inliner can do its
job, even though we'll not be emitting a copy of this
function. */
- if (!flag_inline_trees || !DECL_DECLARED_INLINE_P (d))
+ if (!(TREE_CODE (d) == FUNCTION_DECL
+ && flag_inline_trees
+ && DECL_DECLARED_INLINE_P (d)))
goto out;
}
tmpl_parm = TREE_CHAIN (tmpl_parm);
spec_parm = TREE_CHAIN (spec_parm);
}
- my_friendly_assert (!spec_parm, 20020813);
+ gcc_assert (!spec_parm);
/* Substitute into the body of the function. */
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
{
cp_error_at ("template instantiation depth exceeds maximum of %d"
" (use -ftemplate-depth-NN to increase the maximum)"
- " instantiating `%+D', possibly from virtual table"
+ " instantiating %q+D, possibly from virtual table"
" generation",
max_tinst_depth, TREE_VALUE (pending_templates));
return;
/* There should be as many levels of arguments as there are levels
of parameters. */
- my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0);
+ gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs));
fn_type = TREE_TYPE (tmpl);
return 0;
if (complain & tf_error)
- error ("`%#T' is not a valid type for a template constant parameter",
- type);
+ error ("%q#T is not a valid type for a template constant parameter", type);
return 1;
}
A type is dependent if it is:
- -- a template parameter. Template template parameters are
- types for us (since TYPE_P holds true for them) so we
- handle them here. */
+ -- a template parameter. Template template parameters are types
+ for us (since TYPE_P holds true for them) so we handle
+ them here. */
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
return true;
tree scope;
tree name;
- my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714);
+ gcc_assert (TREE_CODE (expression) == SCOPE_REF);
if (!TYPE_P (TREE_OPERAND (expression, 0)))
return true;
/* If there are no operands, it must be an expression such
as "int()". This should not happen for aggregate types
because it would form non-constant expressions. */
- my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type),
- 20040318);
+ gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
return false;
}
|| value_dependent_expression_p (TREE_OPERAND (expression, 1)));
/* A constant expression is value-dependent if any subexpression is
value-dependent. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
+ if (EXPR_P (expression))
{
switch (TREE_CODE_CLASS (TREE_CODE (expression)))
{
- case '1':
+ case tcc_unary:
return (value_dependent_expression_p
(TREE_OPERAND (expression, 0)));
- case '<':
- case '2':
+ case tcc_comparison:
+ case tcc_binary:
return ((value_dependent_expression_p
(TREE_OPERAND (expression, 0)))
|| (value_dependent_expression_p
(TREE_OPERAND (expression, 1))));
- case 'e':
+ case tcc_expression:
{
int i;
for (i = 0; i < first_rtl_op (TREE_CODE (expression)); ++i)
return true;
return false;
}
+ case tcc_reference:
+ case tcc_statement:
+ /* These cannot be value dependent. */
+ return false;
+
+ default:
+ gcc_unreachable ();
}
}
if (TREE_CODE (expression) == BASELINK)
expression = BASELINK_FUNCTIONS (expression);
+
if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
{
if (any_dependent_template_arguments_p
return true;
expression = TREE_OPERAND (expression, 0);
}
- if (TREE_CODE (expression) == OVERLOAD)
+ gcc_assert (TREE_CODE (expression) == OVERLOAD);
+
+ while (expression)
{
- while (expression)
- {
- if (type_dependent_expression_p (OVL_CURRENT (expression)))
- return true;
- expression = OVL_NEXT (expression);
- }
- return false;
+ if (type_dependent_expression_p (OVL_CURRENT (expression)))
+ return true;
+ expression = OVL_NEXT (expression);
}
- abort ();
+ return false;
}
return (dependent_type_p (TREE_TYPE (expression)));
int quals;
bool pop_p;
- my_friendly_assert (TREE_CODE (type) == TYPENAME_TYPE,
- 20010702);
+ gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
scope = TYPE_CONTEXT (type);
name = TYPE_IDENTIFIER (type);