#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));
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);
/* [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))
{
- 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;
}
= ((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
|| (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 (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)
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))
{
{
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;
}
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;
{
r = copy_node (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);
if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
DECL_INITIAL (r) = TREE_TYPE (r);
{
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. */
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);
}
-- 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);
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;
-- 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;
}
|| 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;
+
+ return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
}
/* TMPL is a TEMPLATE_DECL for a cloned constructor or destructor.
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;
}
}
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)
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;
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
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;
}