/* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001 Free Software Foundation, Inc.
+ 2001, 2002 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
#include "config.h"
#include "system.h"
#include "obstack.h"
-
#include "tree.h"
#include "flags.h"
#include "cp-tree.h"
+#include "tree-inline.h"
#include "decl.h"
#include "parse.h"
#include "lex.h"
#define UNIFY_ALLOW_OUTER_LEVEL 16
#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
+#define UNIFY_ALLOW_MAX_CORRECTION 128
#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
virtual, or a base class of a virtual
unification_kind_t, int));
static int unify PARAMS ((tree, tree, tree, tree, int));
static void add_pending_template PARAMS ((tree));
-static int push_tinst_level PARAMS ((tree));
static void reopen_tinst_level PARAMS ((tree));
static tree classtype_mangled_name PARAMS ((tree));
static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
static int template_args_equal PARAMS ((tree, tree));
static void tsubst_default_arguments PARAMS ((tree));
static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
-static tree instantiate_clone PARAMS ((tree, tree));
static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
static void copy_default_args_to_explicit_spec PARAMS ((tree));
static int invalid_nontype_parm_type_p PARAMS ((tree, int));
return NULL_TREE;
}
else if (TREE_CODE (decl) == FIELD_DECL)
- cp_error ("data member `%D' cannot be a member template", decl);
+ error ("data member `%D' cannot be a member template", decl);
else if (DECL_TEMPLATE_INFO (decl))
{
if (!DECL_TEMPLATE_SPECIALIZATION (decl))
return decl;
}
else
- cp_error ("invalid member template declaration `%D'", decl);
+ error ("invalid member template declaration `%D'", decl);
return error_mark_node;
}
shall be declared in the namespace of which the class template
is a member. */
if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
- cp_error ("explicit specialization in non-namespace scope `%D'",
+ error ("explicit specialization in non-namespace scope `%D'",
scope);
/* [temp.expl.spec]
explicitly specialize a class member template if its enclosing
class templates are not explicitly specialized as well. */
if (current_template_parms)
- cp_error ("enclosing class templates are not explicitly specialized");
+ error ("enclosing class templates are not explicitly specialized");
}
/* We've just seen template <>. */
if (current_namespace
!= decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
{
- cp_pedwarn ("specializing `%#T' in different namespace", type);
+ pedwarn ("specializing `%#T' in different namespace", type);
cp_pedwarn_at (" from definition of `%#D'",
CLASSTYPE_TI_TEMPLATE (type));
}
push_template_decl (TYPE_MAIN_DECL (type));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
- cp_error ("specialization of `%T' after instantiation", type);
+ error ("specialization of `%T' after instantiation", type);
}
else if (processing_specialization)
- cp_error ("explicit specialization of non-template `%T'", type);
+ error ("explicit specialization of non-template `%T'", type);
}
/* Retrieve the specialization (in the sense of [temp.spec] - a
if (TREE_USED (fn)
|| DECL_EXPLICIT_INSTANTIATION (fn))
{
- cp_error ("specialization of %D after instantiation",
+ error ("specialization of %D after instantiation",
fn);
return spec;
}
if (!is_overloaded_fn (fns))
{
- cp_error ("`%D' is not a function template", fns);
+ error ("`%D' is not a function template", fns);
return error_mark_node;
}
Here, S<int>::f is a non-template, but S<int> is a
template class. If FN has the same type as DECL, we
might be in business. */
+
+ if (!DECL_TEMPLATE_INFO (fn))
+ /* Its enclosing class is an explicit specialization
+ of a template class. This is not a candidate. */
+ continue;
+
if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
TREE_TYPE (TREE_TYPE (fn))))
/* The return types differ. */
/* This case handles bogus declarations like template <>
template <class T> void f<int>(); */
- cp_error ("template-id `%D' in declaration of primary template",
+ error ("template-id `%D' in declaration of primary template",
declarator);
return decl;
}
return error_mark_node;
case tsk_invalid_expl_inst:
- cp_error ("template parameter list used in explicit instantiation");
+ error ("template parameter list used in explicit instantiation");
/* Fall through. */
case tsk_expl_inst:
if (have_def)
- cp_error ("definition provided for explicit instantiation");
+ error ("definition provided for explicit instantiation");
explicit_instantiation = 1;
break;
case tsk_excessive_parms:
- cp_error ("too many template parameter lists in declaration of `%D'",
+ error ("too many template parameter lists in declaration of `%D'",
decl);
return error_mark_node;
case tsk_insufficient_parms:
if (template_header_count)
{
- cp_error("too few template parameter lists in declaration of `%D'",
+ error("too few template parameter lists in declaration of `%D'",
decl);
return decl;
}
That used to be legal C++. */
if (pedantic)
- cp_pedwarn
+ pedwarn
("explicit specialization not preceded by `template <>'");
specialization = 1;
SET_DECL_TEMPLATE_SPECIALIZATION (decl);
template <class T> void f<int>(); */
if (uses_template_parms (declarator))
- cp_error ("partial specialization `%D' of function template",
+ error ("partial specialization `%D' of function template",
declarator);
else
- cp_error ("template-id `%D' in declaration of primary template",
+ error ("template-id `%D' in declaration of primary template",
declarator);
return decl;
}
for (; t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t))
{
- cp_pedwarn
+ pedwarn
("default argument specified in explicit specialization");
break;
}
if (current_lang_name == lang_name_c)
- cp_error ("template specialization with C linkage");
+ error ("template specialization with C linkage");
}
if (specialization || member_specialization || explicit_instantiation)
program is ill-formed.
Similar language is found in [temp.explicit]. */
- cp_error ("specialization of implicitly-declared special member function");
+ error ("specialization of implicitly-declared special member function");
return error_mark_node;
}
if (fns == NULL_TREE)
{
- cp_error ("no member function `%D' declared in `%T'",
+ error ("no member function `%D' declared in `%T'",
name, ctype);
return error_mark_node;
}
;
else if (template_header_count > context_depth + 1)
/* There are two many template parameter lists. */
- cp_error ("too many template parameter lists in declaration of `%T'", type);
+ error ("too many template parameter lists in declaration of `%T'", type);
}
}
my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
/* is a const-param */
parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
- PARM, 0, NULL_TREE);
+ PARM, 0, NULL);
+ SET_DECL_TEMPLATE_PARM_P (parm);
/* [temp.param]
tree parms;
{
int nparms;
- tree parm;
+ tree parm, next;
tree saved_parmlist = make_tree_vec (list_length (parms));
current_template_parms
= tree_cons (size_int (processing_template_decl),
saved_parmlist, current_template_parms);
- for (parm = parms, nparms = 0;
- parm;
- parm = TREE_CHAIN (parm), nparms++)
- TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+ for (parm = parms, nparms = 0; parm; parm = next, nparms++)
+ {
+ next = TREE_CHAIN (parm);
+ TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+ TREE_CHAIN (parm) = NULL_TREE;
+ }
--processing_template_parmlist;
specialization. */
if (!did_error_intro)
{
- cp_error ("template parameters not used in partial specialization:");
+ error ("template parameters not used in partial specialization:");
did_error_intro = 1;
}
- cp_error (" `%D'",
+ error (" `%D'",
TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
}
(inner_args,
INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE
(maintmpl)))))
- cp_error ("partial specialization `%T' does not specialize any template arguments", type);
+ error ("partial specialization `%T' does not specialize any template arguments", type);
/* [temp.class.spec]
&& TREE_CODE (arg) != TEMPLATE_PARM_INDEX)
{
if (tpd.arg_uses_template_parms[i])
- cp_error ("template argument `%E' involves template parameter(s)", arg);
+ error ("template argument `%E' involves template parameter(s)", arg);
else
{
/* Look at the corresponding template parameter,
if (tpd2.parms[j] != 0
&& tpd.arg_uses_template_parms [j])
{
- cp_error ("type `%T' of template argument `%E' depends on template parameter(s)",
+ error ("type `%T' of template argument `%E' depends on template parameter(s)",
type,
arg);
break;
seen_def_arg_p = 1;
else if (seen_def_arg_p)
{
- cp_error ("no default argument for `%D'", TREE_VALUE (parm));
+ error ("no default argument for `%D'", TREE_VALUE (parm));
/* For better subsequent error-recovery, we indicate that
there should have been a default argument. */
TREE_PURPOSE (parm) = error_mark_node;
{
if (msg)
{
- cp_error (msg, decl);
+ error (msg, decl);
msg = 0;
}
if (primary)
{
if (current_lang_name == lang_name_c)
- cp_error ("template with C linkage");
+ error ("template with C linkage");
else if (TREE_CODE (decl) == TYPE_DECL
&& ANON_AGGRNAME_P (DECL_NAME (decl)))
- cp_error ("template class without a name");
+ error ("template class without a name");
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)
/* OK */;
else
- cp_error ("template declaration of `%#D'", decl);
+ error ("template declaration of `%#D'", decl);
}
/* Check to see that the rules regarding the use of default
tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
else
{
- cp_error ("`%D' does not declare a template type", decl);
+ error ("`%D' does not declare a template type", decl);
return decl;
}
}
- else if (! DECL_TEMPLATE_INFO (decl))
+ else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl))
{
- cp_error ("template definition of non-template `%#D'", decl);
+ error ("template definition of non-template `%#D'", decl);
return decl;
}
else
i = TMPL_PARMS_DEPTH (parms);
if (TMPL_ARGS_DEPTH (args) != i)
{
- cp_error ("expected %d levels of template parms for `%#D', got %d",
+ error ("expected %d levels of template parms for `%#D', got %d",
i, decl, TMPL_ARGS_DEPTH (args));
}
else
if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
{
if (current == decl)
- cp_error ("got %d template parameters for `%#D'",
+ error ("got %d template parameters for `%#D'",
TREE_VEC_LENGTH (a), decl);
else
- cp_error ("got %d template parameters for `%#T'",
+ error ("got %d template parameters for `%#T'",
TREE_VEC_LENGTH (a), current);
- cp_error (" but %d required", TREE_VEC_LENGTH (t));
+ error (" but %d required", TREE_VEC_LENGTH (t));
}
/* Perhaps we should also check that the parms are used in the
if (!TYPE_TEMPLATE_INFO (type))
{
- cp_error ("`%T' is not a template type", type);
+ error ("`%T' 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 ("used %d template parameter%s instead of %d",
+ error ("used %d template parameter%s instead of %d",
TREE_VEC_LENGTH (tmpl_parms),
TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
TREE_VEC_LENGTH (parms));
if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
{
cp_error_at ("template parameter `%#D'", tmpl_parm);
- cp_error ("redeclared here as `%#D'", parm);
+ error ("redeclared here as `%#D'", parm);
return;
}
A template-parameter may not be given default arguments
by two different declarations in the same scope. */
- cp_error ("redefinition of default argument for `%#D'", parm);
+ error ("redefinition of default argument for `%#D'", parm);
cp_error_at (" original definition appeared here", tmpl_parm);
return;
}
if (TREE_CODE (e) != ADDR_EXPR)
{
bad_argument:
- cp_error ("`%E' is not a valid template argument", expr);
+ error ("`%E' is not a valid template argument", expr);
if (TYPE_PTR_P (expr_type))
{
if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE)
- cp_error ("it must be the address of a function with external linkage");
+ error ("it must be the address of a function with external linkage");
else
- cp_error ("it must be the address of an object with external linkage");
+ error ("it must be the address of an object with external linkage");
}
else if (TYPE_PTRMEM_P (expr_type)
|| TYPE_PTRMEMFUNC_P (expr_type))
- cp_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)
{
- cp_error ("string literal %E is not a valid template argument because it is the address of an object with static linkage",
+ error ("string literal %E is not a valid template argument because it is the address of an object with static linkage",
referent);
return NULL_TREE;
}
goto bad_argument;
else if (!DECL_EXTERNAL_LINKAGE_P (referent))
{
- cp_error ("address of non-extern `%E' cannot be used as template argument", referent);
+ error ("address of non-extern `%E' cannot be used as template argument", referent);
return error_mark_node;
}
}
if (! TREE_CONSTANT (expr))
{
non_constant:
- cp_error ("non-constant `%E' cannot be used as template argument",
+ error ("non-constant `%E' cannot be used as template argument",
expr);
return NULL_TREE;
}
}
else
{
- cp_error ("object `%E' cannot be used as template argument", expr);
+ error ("object `%E' cannot be used as template argument", expr);
return NULL_TREE;
}
requires_type = (TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type);
- /* Check if it is a class template. If REQUIRES_TMPL_TYPE is true,
- we also accept implicitly created TYPE_DECL as a valid argument.
- This is necessary to handle the case where we pass a template name
- to a template template parameter in a scope where we've derived from
- in instantiation of that template, so the template name refers to that
- instantiation. We really ought to handle this better. */
- is_tmpl_type
- = ((TREE_CODE (arg) == TEMPLATE_DECL
- && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
- || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
- || (TREE_CODE (arg) == RECORD_TYPE
- && CLASSTYPE_TEMPLATE_INFO (arg)
- && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
- && DECL_ARTIFICIAL (TYPE_NAME (arg))
- && requires_tmpl_type
- && is_base_of_enclosing_class (arg, current_class_type)));
- if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ if (TREE_CODE (arg) != RECORD_TYPE)
+ is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+ && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
+ else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
+ {
+ if (is_base_of_enclosing_class (arg, current_class_type))
+ /* This is a template name used within the scope of the
+ template. It could be the template, or it could be the
+ instantiation. Choose whichever makes sense. */
+ is_tmpl_type = requires_tmpl_type;
+ else
+ is_tmpl_type = 1;
+ }
+ else
+ /* It is a non-template class, or a specialization of a template
+ class, or a non-template member of a template class. */
+ is_tmpl_type = 0;
+
+ if (is_tmpl_type
+ && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
arg = TYPE_STUB_DECL (arg);
else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
arg = CLASSTYPE_TI_TEMPLATE (arg);
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
{
- cp_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)
{
- cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
+ error ("type/value mismatch at argument %d in template parameter list for `%D'",
i + 1, in_decl);
if (is_type)
- cp_error (" expected a constant of type `%T', got `%T'",
+ error (" expected a constant of type `%T', got `%T'",
TREE_TYPE (parm),
(is_tmpl_type ? DECL_NAME (arg) : arg));
else
- cp_error (" expected a type, got `%E'", arg);
+ error (" expected a type, got `%E'", arg);
}
}
return error_mark_node;
{
if (in_decl && complain)
{
- cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
+ error ("type/value mismatch at argument %d in template parameter list for `%D'",
i + 1, in_decl);
if (is_tmpl_type)
- cp_error (" expected a type, got `%T'", DECL_NAME (arg));
+ error (" expected a type, got `%T'", DECL_NAME (arg));
else
- cp_error (" expected a class template, got `%T'", arg);
+ error (" expected a class template, got `%T'", arg);
}
return error_mark_node;
}
{
if (requires_tmpl_type)
{
- tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
- tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
-
- if (coerce_template_template_parms (parmparm, argparm, complain,
- in_decl, inner_args))
- {
- val = arg;
-
- /* TEMPLATE_TEMPLATE_PARM node is preferred over
- TEMPLATE_DECL. */
- if (val != error_mark_node
- && DECL_TEMPLATE_TEMPLATE_PARM_P (val))
- val = TREE_TYPE (val);
- }
+ if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
+ /* The number of argument required is not known yet.
+ Just accept it for now. */
+ val = TREE_TYPE (arg);
else
{
- if (in_decl && complain)
+ tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+ tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+
+ if (coerce_template_template_parms (parmparm, argparm,
+ complain, in_decl,
+ inner_args))
{
- cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
- i + 1, in_decl);
- cp_error (" expected a template of type `%D', got `%D'", parm, arg);
+ val = arg;
+
+ /* TEMPLATE_TEMPLATE_PARM node is preferred over
+ TEMPLATE_DECL. */
+ if (val != error_mark_node
+ && DECL_TEMPLATE_TEMPLATE_PARM_P (val))
+ val = TREE_TYPE (val);
}
+ else
+ {
+ if (in_decl && complain)
+ {
+ 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);
+ }
- val = error_mark_node;
+ val = error_mark_node;
+ }
}
}
else
if (t)
{
if (TYPE_ANONYMOUS_P (t))
- cp_pedwarn
+ pedwarn
("template-argument `%T' uses anonymous type", val);
else
- cp_error
+ error
("template-argument `%T' uses local type `%T'",
val, t);
return error_mark_node;
if (val == NULL_TREE)
val = error_mark_node;
else if (val == error_mark_node && complain)
- cp_error ("could not convert template argument `%E' to `%T'",
+ error ("could not convert template argument `%E' to `%T'",
arg, t);
}
{
if (complain)
{
- cp_error ("wrong number of template arguments (%d, should be %d)",
+ error ("wrong number of template arguments (%d, should be %d)",
nargs, nparms);
if (in_decl)
}
else if (arg == error_mark_node)
{
- cp_error ("template argument %d is invalid", i + 1);
+ error ("template argument %d is invalid", i + 1);
arg = error_mark_node;
}
else
if (fns == NULL_TREE)
{
- cp_error ("non-template used as template");
+ error ("non-template used as template");
return error_mark_node;
}
if (! template)
{
if (complain)
- cp_error ("`%T' is not a template", d1);
+ error ("`%T' is not a template", d1);
return error_mark_node;
}
{
if (complain)
{
- cp_error ("non-template type `%T' used as a template", d1);
+ error ("non-template type `%T' used as a template", d1);
if (in_decl)
cp_error_at ("for template declaration `%D'", in_decl);
}
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
+ /* Consider an example where a template template parameter declared as
+
+ template <class T, class U = std::allocator<T> > class TT
+
+ The template parameter level of T and U are one level larger than
+ of TT. To proper process the default argument of U, say when an
+ instantiation `TT<int>' is seen, we need to build the full
+ arguments containing {int} as the innermost level. Outer levels
+ can be obtained from `current_template_args ()'. */
+
+ if (processing_template_decl)
+ arglist = add_to_template_args (current_template_args (), arglist);
+
arglist2 = coerce_template_parms (parmlist, arglist, template,
complain, /*require_all_args=*/1);
if (arglist2 == error_mark_node)
return error_mark_node;
- parm = copy_template_template_parm (TREE_TYPE (template), arglist2);
- TYPE_SIZE (parm) = 0;
+ parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
return parm;
}
else
arg_depth = TMPL_ARGS_DEPTH (arglist);
}
- /* Now we should enough arguments. */
+ /* Now we should have enough arguments. */
my_friendly_assert (parm_depth == arg_depth, 0);
/* From here on, we're only interested in the most general
Create the partial instantiation.
*/
TREE_VEC_LENGTH (arglist)--;
- template = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
+ found = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
TREE_VEC_LENGTH (arglist)++;
- found = template;
}
}
/* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */
-static int
+int
push_tinst_level (d)
tree d;
{
return 0;
last_template_error_tick = tinst_level_tick;
- cp_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 `%D'",
max_tinst_depth, d);
print_instantiation_context ();
if (t == error_mark_node)
{
const char *str = "candidates are:";
- cp_error ("ambiguous class template instantiation for `%#T'", type);
+ error ("ambiguous class template instantiation for `%#T'", type);
for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
t = TREE_CHAIN (t))
{
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
- TYPE_VEC_DELETE_TAKES_SIZE (type) = TYPE_VEC_DELETE_TAKES_SIZE (pattern);
TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);
{
tree r = tsubst (t, args, /*complain=*/1, NULL_TREE);
set_current_access_from_decl (r);
+ grok_special_member_properties (r);
finish_member_declaration (r);
}
maybe_fold_nontype_arg (arg)
tree arg;
{
- /* If we're not in a template, ARG is already as simple as it's going to
- get, and trying to reprocess the trees will break. */
- if (! processing_template_decl)
- return arg;
-
- if (!TYPE_P (arg) && !uses_template_parms (arg))
+ if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
{
/* Sometimes, one of the args was an expression involving a
template constant parameter, like N - 1. Now that we've
fool build_expr_from_tree() into building an actual
tree. */
- int saved_processing_template_decl = processing_template_decl;
- processing_template_decl = 0;
- arg = fold (build_expr_from_tree (arg));
- processing_template_decl = saved_processing_template_decl;
+ /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+ as simple as it's going to get, and trying to reprocess
+ the trees will break. */
+ if (!TREE_TYPE (arg))
+ {
+ int saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ arg = build_expr_from_tree (arg);
+ processing_template_decl = saved_processing_template_decl;
+ }
+
+ arg = fold (arg);
}
return arg;
}
for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
{
- tree default_value =
- TREE_PURPOSE (TREE_VEC_ELT (TREE_VALUE (parms), i));
- tree parm_decl =
- TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i));
-
- TREE_VEC_ELT (new_vec, i)
- = build_tree_list (tsubst (default_value, args, complain,
- NULL_TREE),
- tsubst (parm_decl, args, complain,
- NULL_TREE));
+ tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
+ tree default_value = TREE_PURPOSE (tuple);
+ tree parm_decl = TREE_VALUE (tuple);
+
+ parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+ default_value = tsubst_expr (default_value, args,
+ complain, NULL_TREE);
+ tuple = build_tree_list (maybe_fold_nontype_arg (default_value),
+ parm_decl);
+ TREE_VEC_ELT (new_vec, i) = tuple;
}
*new_parms =
{
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
- {
- tree r = build_ptrmemfunc_type
- (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl));
- return cp_build_qualified_type_real (r, TYPE_QUALS (t),
- complain);
- }
+ return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl);
/* else fall through */
case ENUMERAL_TYPE:
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
if (PRIMARY_TEMPLATE_P (gen_tmpl))
- clone_function_decl(r, /*update_method_vec_p=*/0);
+ clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
- grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
+ grok_op_properties (r, DECL_FRIEND_P (r));
}
break;
case PARM_DECL:
{
r = copy_node (t);
+ if (DECL_TEMPLATE_PARM_P (t))
+ SET_DECL_TEMPLATE_PARM_P (r);
+
TREE_TYPE (r) = type;
- c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+ c_apply_type_quals_to_decl (cp_type_quals (type), r);
if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
DECL_INITIAL (r) = TREE_TYPE (r);
/*complain=*/1, in_decl);
DECL_CONTEXT (r) = NULL_TREE;
- if (PROMOTE_PROTOTYPES
+ if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (r) = integer_type_node;
{
r = copy_decl (t);
TREE_TYPE (r) = type;
- c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+ c_apply_type_quals_to_decl (cp_type_quals (type), r);
/* We don't have to set DECL_CONTEXT here; it is set by
finish_member_declaration. */
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
/*complain=*/1,
in_decl, /*entering_scope=*/1);
+ else if (DECL_NAMESPACE_SCOPE_P (t))
+ ctx = DECL_CONTEXT (t);
else
{
/* Subsequent calls to pushdecl will fill this in. */
ctx = NULL_TREE;
- if (!DECL_NAMESPACE_SCOPE_P (t))
- local_p = 1;
+ local_p = 1;
}
/* Check to see if we already have this specialization. */
r = copy_decl (t);
TREE_TYPE (r) = type;
- c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+ c_apply_type_quals_to_decl (cp_type_quals (type), r);
DECL_CONTEXT (r) = ctx;
/* Clear out the mangled name and RTL for the instantiation. */
SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
/* For __PRETTY_FUNCTION__ we have to adjust the initializer. */
if (DECL_PRETTY_FUNCTION_P (r))
{
- const char *name = (*decl_printable_name)
+ const char *const name = (*decl_printable_name)
(current_function_decl, 2);
DECL_INITIAL (r) = cp_fname_init (name);
TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
{
if (complain)
{
- cp_error ("invalid parameter type `%T'", type);
+ error ("invalid parameter type `%T'", type);
if (in_decl)
cp_error_at ("in declaration `%D'", in_decl);
}
/* The TYPE_CONTEXT is not used for function/method types. */
my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
- /* Substitue the return type. */
+ /* Substitute the return type. */
return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
if (return_type == error_mark_node)
return error_mark_node;
-- Attempting to create "pointer to member of T" when T
is not a class type. */
if (complain)
- cp_error ("creating pointer to member function of non-class type `%T'",
+ error ("creating pointer to member function of non-class type `%T'",
r);
return error_mark_node;
}
case ERROR_MARK:
case IDENTIFIER_NODE:
- case OP_IDENTIFIER:
case VOID_TYPE:
case REAL_TYPE:
case COMPLEX_TYPE:
Attempting to create an array with a size that is
zero or negative. */
if (complain)
- cp_error ("creating array with size zero (`%E')", max);
+ error ("creating array with size zero (`%E')", max);
return error_mark_node;
}
{
my_friendly_assert (TYPE_P (arg), 0);
return cp_build_qualified_type_real
- (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
+ (arg, cp_type_quals (arg) | cp_type_quals (t),
complain);
}
else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
- if (CP_TYPE_QUALS (t))
+ 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);
}
else
{
- r = copy_node (t);
+ r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r, levels);
{
enum tree_code code;
- if (type == TREE_TYPE (t))
+ if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
return t;
code = TREE_CODE (t);
last_file != input_filename))
{
if (TREE_CODE (type) == VOID_TYPE)
- cp_error ("forming reference to void");
+ error ("forming reference to void");
else
- cp_error ("forming %s to reference type `%T'",
+ error ("forming %s to reference type `%T'",
(code == POINTER_TYPE) ? "pointer" : "reference",
type);
last_line = lineno;
return error_mark_node;
}
else if (code == POINTER_TYPE)
- r = build_pointer_type (type);
+ {
+ r = build_pointer_type (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ r = build_ptrmemfunc_type (r);
+ }
else
r = build_reference_type (type);
r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
-- Attempting to create "pointer to member of T" when T
is not a class type. */
if (complain)
- cp_error ("creating pointer to member of non-class type `%T'",
+ error ("creating pointer to member of non-class type `%T'",
r);
return error_mark_node;
}
- return build_offset_type (r, type);
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain)
+ error ("creating pointer to member reference type `%T'", type);
+
+ return error_mark_node;
+ }
+ my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ /* This is really a method type. The cv qualifiers of the
+ this pointer should _not_ be determined by the cv
+ qualifiers of the class type. They should be held
+ somewhere in the FUNCTION_TYPE, but we don't do that at
+ the moment. Consider
+ typedef void (Func) () const;
+
+ template <typename T1> void Foo (Func T1::*);
+
+ */
+ return build_cplus_method_type (TYPE_MAIN_VARIANT (r),
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
+ else
+ return build_offset_type (r, type);
}
case FUNCTION_TYPE:
case METHOD_TYPE:
|| TREE_CODE (type) == REFERENCE_TYPE)
{
if (complain)
- cp_error ("creating array of `%T'", type);
+ error ("creating array of `%T'", type);
return error_mark_node;
}
if (!IS_AGGR_TYPE (ctx))
{
if (complain)
- cp_error ("`%T' is not a class, struct, or union type",
+ error ("`%T' is not a class, struct, or union type",
ctx);
return error_mark_node;
}
if (f == error_mark_node)
return f;
return cp_build_qualified_type_real (f,
- CP_TYPE_QUALS (f)
- | CP_TYPE_QUALS (t),
+ cp_type_quals (f)
+ | cp_type_quals (t),
complain);
}
+ case UNBOUND_CLASS_TEMPLATE:
+ {
+ tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
+ in_decl, /*entering_scope=*/1);
+ tree name = TYPE_IDENTIFIER (t);
+
+ if (ctx == error_mark_node || name == error_mark_node)
+ return error_mark_node;
+
+ return make_unbound_class_template (ctx, name, complain);
+ }
+
case INDIRECT_REF:
{
tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
case METHOD_TYPE:
case ARRAY_TYPE:
case TYPENAME_TYPE:
+ case UNBOUND_CLASS_TEMPLATE:
+ case TYPEOF_TYPE:
case TYPE_DECL:
return tsubst (t, args, complain, in_decl);
int complain;
tree in_decl;
{
- tree stmt;
+ tree stmt, tmp;
if (t == NULL_TREE || t == error_mark_node)
return t;
if (processing_template_decl)
return tsubst_copy (t, args, complain, in_decl);
+ if (!statement_code_p (TREE_CODE (t)))
+ return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+
switch (TREE_CODE (t))
{
case RETURN_INIT:
finish_named_return_value
(TREE_OPERAND (t, 0),
tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
- tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
break;
case CTOR_INITIALIZER:
base_init_list
= tsubst_initializer_list (TREE_OPERAND (t, 1), args);
setup_vtbl_ptr (member_init_list, base_init_list);
- tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
break;
}
cp_finish_decl (decl, init, NULL_TREE, 0);
}
}
- return decl;
+
+ /* A DECL_STMT can also be used as an expression, in the condition
+ clause of a if/for/while construct. If we aren't followed by
+ another statement, return our decl. */
+ if (TREE_CHAIN (t) == NULL_TREE)
+ return decl;
}
+ break;
case FOR_STMT:
{
- tree tmp;
prep_stmt (t);
stmt = begin_for_stmt ();
- for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
- tsubst_expr (tmp, args, complain, in_decl);
+ tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
finish_for_init_stmt (stmt);
finish_for_cond (tsubst_expr (FOR_COND (t), args,
complain, in_decl),
case IF_STMT:
{
- tree tmp;
-
prep_stmt (t);
stmt = begin_if_stmt ();
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
case COMPOUND_STMT:
{
- tree substmt;
-
prep_stmt (t);
- stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
- for (substmt = COMPOUND_BODY (t);
- substmt != NULL_TREE;
- substmt = TREE_CHAIN (substmt))
- tsubst_expr (substmt, args, complain, in_decl);
- return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+ if (COMPOUND_STMT_BODY_BLOCK (t))
+ stmt = begin_function_body ();
+ else
+ stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
+
+ tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+
+ if (COMPOUND_STMT_BODY_BLOCK (t))
+ finish_function_body (stmt);
+ else
+ finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
}
break;
case GOTO_STMT:
prep_stmt (t);
- t = GOTO_DESTINATION (t);
- if (TREE_CODE (t) != LABEL_DECL)
+ tmp = GOTO_DESTINATION (t);
+ if (TREE_CODE (tmp) != LABEL_DECL)
/* Computed goto's must be tsubst'd into. On the other hand,
non-computed gotos must not be; the identifier in question
will have no binding. */
- t = tsubst_expr (t, args, complain, in_decl);
+ tmp = tsubst_expr (tmp, args, complain, in_decl);
else
- t = DECL_NAME (t);
- finish_goto_stmt (t);
+ tmp = DECL_NAME (tmp);
+ finish_goto_stmt (tmp);
break;
case ASM_STMT:
}
else
{
- tree handler;
-
if (FN_TRY_BLOCK_P (t))
stmt = begin_function_try_block ();
else
else
finish_try_block (stmt);
- handler = TRY_HANDLERS (t);
- for (; handler; handler = TREE_CHAIN (handler))
- tsubst_expr (handler, args, complain, in_decl);
+ tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
if (FN_TRY_BLOCK_P (t))
finish_function_handler_sequence (stmt);
else
case TAG_DEFN:
prep_stmt (t);
- t = TREE_TYPE (t);
- tsubst (t, args, complain, NULL_TREE);
+ tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+ break;
+
+ case CTOR_STMT:
+ add_stmt (copy_node (t));
break;
default:
- return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+ abort ();
}
- return NULL_TREE;
-}
-
-/* TMPL is a TEMPLATE_DECL for a cloned constructor or destructor.
- Instantiate it with the ARGS. */
-static tree
-instantiate_clone (tmpl, args)
- tree tmpl;
- tree args;
-{
- tree spec;
- tree clone;
-
- /* Instantiated the cloned function, rather than the clone. */
- spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), args);
-
- /* Then, see if we've already cloned the instantiation. */
- for (clone = TREE_CHAIN (spec);
- clone && DECL_CLONED_FUNCTION_P (clone);
- clone = TREE_CHAIN (clone))
- if (DECL_NAME (clone) == DECL_NAME (tmpl))
- return clone;
-
- /* If we haven't, do so know. */
- if (!clone)
- clone_function_decl (spec, /*update_method_vec_p=*/0);
-
- /* Look again. */
- for (clone = TREE_CHAIN (spec);
- clone && DECL_CLONED_FUNCTION_P (clone);
- clone = TREE_CHAIN (clone))
- if (DECL_NAME (clone) == DECL_NAME (tmpl))
- return clone;
-
- /* We should always have found the clone by now. */
- my_friendly_abort (20000411);
- return NULL_TREE;
+ return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
}
/* Instantiate the indicated variable or function template TMPL with
instantiate_template (tmpl, targ_ptr)
tree tmpl, targ_ptr;
{
- tree clone;
tree fndecl;
tree gen_tmpl;
tree spec;
/* If this function is a clone, handle it specially. */
if (DECL_CLONED_FUNCTION_P (tmpl))
- return instantiate_clone (tmpl, targ_ptr);
-
+ {
+ tree spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr);
+ tree clone;
+
+ /* Look for the clone. */
+ for (clone = TREE_CHAIN (spec);
+ clone && DECL_CLONED_FUNCTION_P (clone);
+ clone = TREE_CHAIN (clone))
+ if (DECL_NAME (clone) == DECL_NAME (tmpl))
+ return clone;
+ /* We should always have found the clone by now. */
+ my_friendly_abort (20000411);
+ return NULL_TREE;
+ }
+
/* Check to see if we already have this specialization. */
spec = retrieve_specialization (tmpl, targ_ptr);
if (spec != NULL_TREE)
tree nt = target_type (t);
if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt)))
{
- cp_error ("type `%T' composed from a local class is not a valid template-argument", t);
- cp_error (" trying to instantiate `%D'", gen_tmpl);
+ error ("type `%T' composed from a local class is not a valid template-argument", t);
+ error (" trying to instantiate `%D'", gen_tmpl);
return error_mark_node;
}
}
add_pending_template (fndecl);
/* If we've just instantiated the main entry point for a function,
- instantiate all the alternate entry points as well. */
- for (clone = TREE_CHAIN (gen_tmpl);
- clone && DECL_CLONED_FUNCTION_P (clone);
- clone = TREE_CHAIN (clone))
- instantiate_template (clone, targ_ptr);
+ instantiate all the alternate entry points as well. We do this
+ by cloning the instantiation of the main entry point, not by
+ instantiating the template clones. */
+ if (TREE_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (gen_tmpl)))
+ clone_function_decl (fndecl, /*update_method_vec_p=*/0);
return fndecl;
}
qualified at this point.
UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
This is the outermost level of a deduction, and PARM can be less CV
- qualified at this point. */
+ qualified at this point.
+ UNIFY_ALLOW_MAX_CORRECTION:
+ This is an INTEGER_TYPE's maximum value. Used if the range may
+ have been derived from a size specification, such as an array size.
+ If the size was given by a nontype template parameter N, the maximum
+ value will have the form N-1. The flag says that we can (and indeed
+ must) unify N with (ARG + 1), an exception to the normal rules on
+ folding PARM. */
static int
unify (tparms, targs, parm, arg, strict)
return 1;
if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
- && TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
+ && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
strict &= ~UNIFY_ALLOW_DERIVED;
strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
+ strict &= ~UNIFY_ALLOW_MAX_CORRECTION;
switch (TREE_CODE (parm))
{
case TYPENAME_TYPE:
+ case SCOPE_REF:
+ case UNBOUND_CLASS_TEMPLATE:
/* In a type which contains a nested-name-specifier, template
argument values cannot be deduced for template parameters used
within the nested-name-specifier. */
PARM is `const T'. Then, T should be `volatile int'. */
arg =
cp_build_qualified_type_real (arg,
- CP_TYPE_QUALS (arg)
- & ~CP_TYPE_QUALS (parm),
+ cp_type_quals (arg)
+ & ~cp_type_quals (parm),
/*complain=*/0);
if (arg == error_mark_node)
return 1;
level of pointers. */
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
+ if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
+ && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+ {
+ /* Avoid getting confused about cv-quals; don't recurse here.
+ Pointers to members should really be just OFFSET_TYPE, not
+ this two-level nonsense... */
+
+ parm = TREE_TYPE (parm);
+ arg = TREE_TYPE (arg);
+ goto offset;
+ }
+
return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), strict);
}
return 1;
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
&& unify (tparms, targs, TYPE_MAX_VALUE (parm),
- TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER))
+ TYPE_MAX_VALUE (arg),
+ UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION))
return 1;
}
/* We have already checked cv-qualification at the top of the
DEDUCE_EXACT, 0, -1);
case OFFSET_TYPE:
+ offset:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
return 1;
case MINUS_EXPR:
- if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST)
+ if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node)
+ && (strict_in & UNIFY_ALLOW_MAX_CORRECTION))
{
/* We handle this case specially, since it comes up with
arrays. In particular, something like:
/* Return the innermost template arguments that, when applied to a
template specialization whose innermost template parameters are
- TPARMS, and whose specialization arguments are ARGS, yield the
+ TPARMS, and whose specialization arguments are PARMS, yield the
ARGS.
For example, suppose we have:
do_decl_instantiation (declspecs, declarator, storage)
tree declspecs, declarator, storage;
{
- tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
+ tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
tree result = NULL_TREE;
int extern_p = 0;
return;
else if (! DECL_LANG_SPECIFIC (decl))
{
- cp_error ("explicit instantiation of non-template `%#D'", decl);
+ error ("explicit instantiation of non-template `%#D'", decl);
return;
}
else if (TREE_CODE (decl) == VAR_DECL)
result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0);
if (result && TREE_CODE (result) != VAR_DECL)
{
- cp_error ("no matching template for `%D' found", result);
+ error ("no matching template for `%D' found", result);
return;
}
}
else if (TREE_CODE (decl) != FUNCTION_DECL)
{
- cp_error ("explicit instantiation of `%#D'", decl);
+ error ("explicit instantiation of `%#D'", decl);
return;
}
else
No program shall both explicitly instantiate and explicitly
specialize a template. */
- cp_pedwarn ("explicit instantiation of `%#D' after", result);
+ pedwarn ("explicit instantiation of `%#D' after", result);
cp_pedwarn_at ("explicit specialization here", result);
return;
}
the opposite case. If -frepo, chances are we already got marked
as an explicit instantiation because of the repo file. */
if (DECL_INTERFACE_KNOWN (result) && !extern_p && !flag_use_repository)
- cp_pedwarn ("duplicate explicit instantiation of `%#D'", result);
+ pedwarn ("duplicate explicit instantiation of `%#D'", result);
/* If we've already instantiated the template, just return now. */
if (DECL_INTERFACE_KNOWN (result))
}
else if (!DECL_IMPLICIT_INSTANTIATION (result))
{
- cp_error ("no matching template for `%D' found", result);
+ error ("no matching template for `%D' found", result);
return;
}
else if (!DECL_TEMPLATE_INFO (result))
{
- cp_pedwarn ("explicit instantiation of non-template `%#D'", result);
+ pedwarn ("explicit instantiation of non-template `%#D'", result);
return;
}
else if (storage == ridpointers[(int) RID_EXTERN])
{
if (pedantic)
- cp_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
- cp_error ("storage class `%D' applied to template instantiation",
+ error ("storage class `%D' applied to template instantiation",
storage);
SET_DECL_EXPLICIT_INSTANTIATION (result);
if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
{
- cp_error ("explicit instantiation of non-template type `%T'", t);
+ error ("explicit instantiation of non-template type `%T'", t);
return;
}
if (!COMPLETE_TYPE_P (t))
{
if (complain)
- cp_error ("explicit instantiation of `%#T' before definition of template",
+ error ("explicit instantiation of `%#T' before definition of template",
t);
return;
}
if (storage != NULL_TREE)
{
if (pedantic)
- cp_pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations",
+ pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations",
IDENTIFIER_POINTER (storage));
if (storage == ridpointers[(int) RID_INLINE])
static_p = 1;
else
{
- cp_error ("storage class `%D' applied to template instantiation",
+ error ("storage class `%D' applied to template instantiation",
storage);
extern_p = 0;
}
specialize a template. */
if (complain)
{
- cp_error ("explicit instantiation of `%#T' after", t);
+ error ("explicit instantiation of `%#T' after", t);
cp_error_at ("explicit specialization here", t);
}
return;
If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation
was `extern'. If EXTERN_P then the second is. If -frepo, chances
- are we already got marked as an explicit instantion because of the
+ are we already got marked as an explicit instantiation because of the
repo file. All these cases are OK. */
if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
&& complain)
- cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
+ pedwarn ("duplicate explicit instantiation of `%#T'", t);
/* If we've already instantiated the template, just return now. */
if (!CLASSTYPE_INTERFACE_ONLY (t))
/* Reject all external templates except inline functions. */
else if (DECL_INTERFACE_KNOWN (d)
&& ! DECL_NOT_REALLY_EXTERN (d)
- && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)))
+ && ! (TREE_CODE (d) == FUNCTION_DECL
+ && DECL_INLINE (d)))
goto out;
/* Defer all other templates, unless we have been explicitly
forbidden from doing so. We restore the source position here
member function or static data member of a class template
shall be present in every translation unit in which it is
explicitly instantiated. */
- cp_pedwarn
+ pedwarn
("explicit instantiation of `%D' but no definition available", d);
add_pending_template (d);
return 0;
if (complain)
- cp_error ("`%#T' is not a valid type for a template constant parameter",
+ error ("`%#T' is not a valid type for a template constant parameter",
type);
return 1;
}