cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL NODE is always a TREE_VEC of non-zero size.

cp:
	* cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL
	NODE is always a TREE_VEC of non-zero size.
	(NUM_TMPL_ARGS): NODE is always a TREE_VEC.
	* decl2.c (arg_assoc): Template args will be a vec.
	* error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call
	dump_template_argument_list.
	(dump_template_parms): Args will be a vec.
	* parser.c (cp_parser_template_argument_list): Produce a
	vector, not a list.
	* pt.c (coerce_template_parms): Args are always vectors.
	(mangle_class_name_for_template): Likewise.
	(lookup_template_function): Likewise.
	(lookup_template_class): Likewise.
	(tsubst_template_args): Likewise.
	(tsubst_baselink): Use tsubst_template_args.
	(tsubst_qualified_id): Likewise.
	(tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise.
	(tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
	(any_dependent_template_args_p):  Args are always vectors.
	* tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.

From-SVN: r70295
This commit is contained in:
Nathan Sidwell 2003-08-10 15:10:35 +00:00 committed by Nathan Sidwell
parent ffc7656178
commit bf12d54dac
8 changed files with 129 additions and 139 deletions

View File

@ -1,5 +1,26 @@
2003-08-10 Nathan Sidwell <nathan@codesourcery.com> 2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL
NODE is always a TREE_VEC of non-zero size.
(NUM_TMPL_ARGS): NODE is always a TREE_VEC.
* decl2.c (arg_assoc): Template args will be a vec.
* error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call
dump_template_argument_list.
(dump_template_parms): Args will be a vec.
* parser.c (cp_parser_template_argument_list): Produce a
vector, not a list.
* pt.c (coerce_template_parms): Args are always vectors.
(mangle_class_name_for_template): Likewise.
(lookup_template_function): Likewise.
(lookup_template_class): Likewise.
(tsubst_template_args): Likewise.
(tsubst_baselink): Use tsubst_template_args.
(tsubst_qualified_id): Likewise.
(tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise.
(tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
(any_dependent_template_args_p): Args are always vectors.
* tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.
PR c++/11670 PR c++/11670
* call.c (convert_like_real): Add rvalue binding error message. * call.c (convert_like_real): Add rvalue binding error message.
* error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is * error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is

View File

@ -207,10 +207,10 @@ DEFTREECODE (USING_STMT, "using_directive", 'e', 1)
DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0) DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0)
/* A template-id, like foo<int>. The first operand is the template. /* A template-id, like foo<int>. The first operand is the template.
The second is the TREE_LIST or TREE_VEC of explicitly specified The second is NULL if there are no explicit arguments, or a
arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or TREE_VEC of arguments. The template will be a FUNCTION_DECL,
an OVERLOAD. If the template-id refers to a member template, the TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
template may be an IDENTIFIER_NODE. */ member template, the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is /* A list-like node for chaining overloading candidates. TREE_TYPE is

View File

@ -2203,11 +2203,8 @@ struct lang_decl GTY(())
/* Nonzero if the template arguments is actually a vector of vectors, /* Nonzero if the template arguments is actually a vector of vectors,
rather than just a vector. */ rather than just a vector. */
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ #define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
((NODE) != NULL_TREE \ (NODE && TREE_VEC_ELT (NODE, 0) \
&& TREE_CODE (NODE) == TREE_VEC \
&& TREE_VEC_LENGTH (NODE) > 0 \
&& TREE_VEC_ELT (NODE, 0) != NULL_TREE \
&& TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
/* The depth of a template argument vector. When called directly by /* The depth of a template argument vector. When called directly by
@ -2241,9 +2238,7 @@ struct lang_decl GTY(())
/* Given a single level of template arguments in NODE, return the /* Given a single level of template arguments in NODE, return the
number of arguments. */ number of arguments. */
#define NUM_TMPL_ARGS(NODE) \ #define NUM_TMPL_ARGS(NODE) \
((NODE) == NULL_TREE ? 0 \ (TREE_VEC_LENGTH (NODE))
: (TREE_CODE (NODE) == TREE_VEC \
? TREE_VEC_LENGTH (NODE) : list_length (NODE)))
/* Returns the innermost level of template arguments in ARGS. */ /* Returns the innermost level of template arguments in ARGS. */
#define INNERMOST_TEMPLATE_ARGS(NODE) \ #define INNERMOST_TEMPLATE_ARGS(NODE) \

View File

@ -3716,7 +3716,7 @@ arg_assoc (struct arg_lookup *k, tree n)
tree template = TREE_OPERAND (n, 0); tree template = TREE_OPERAND (n, 0);
tree args = TREE_OPERAND (n, 1); tree args = TREE_OPERAND (n, 1);
tree ctx; tree ctx;
tree arg; int ix;
if (TREE_CODE (template) == COMPONENT_REF) if (TREE_CODE (template) == COMPONENT_REF)
template = TREE_OPERAND (template, 1); template = TREE_OPERAND (template, 1);
@ -3739,8 +3739,8 @@ arg_assoc (struct arg_lookup *k, tree n)
return true; return true;
/* Now the arguments. */ /* Now the arguments. */
for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) for (ix = TREE_VEC_LENGTH (args); ix--;)
if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1) if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
return true; return true;
} }
else else

View File

@ -920,18 +920,14 @@ dump_decl (tree t, int flags)
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
{ {
tree args;
tree name = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (t, 0);
if (is_overloaded_fn (name)) if (is_overloaded_fn (name))
name = DECL_NAME (get_first_fn (name)); name = DECL_NAME (get_first_fn (name));
dump_decl (name, flags); dump_decl (name, flags);
pp_template_argument_list_start (cxx_pp); pp_template_argument_list_start (cxx_pp);
for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) if (TREE_OPERAND (t, 1))
{ dump_template_argument_list (TREE_OPERAND (t, 1), flags);
dump_template_argument (TREE_VALUE (args), flags);
if (TREE_CHAIN (args))
pp_separate_with_comma (cxx_pp);
}
pp_template_argument_list_end (cxx_pp); pp_template_argument_list_end (cxx_pp);
} }
break; break;
@ -1256,41 +1252,24 @@ dump_template_parms (tree info, int primary, int flags)
to crash producing error messages. */ to crash producing error messages. */
if (args && !primary) if (args && !primary)
{ {
int len = 0; int len, ix;
int ix = 0;
int need_comma = 0;
if (TREE_CODE (args) == TREE_VEC) if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
{ args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
if (TREE_VEC_LENGTH (args) > 0
&& TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) len = TREE_VEC_LENGTH (args);
args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
len = TREE_VEC_LENGTH (args); for (ix = 0; ix != len; ix++)
}
else if (TREE_CODE (args) == TREE_LIST)
len = -1;
while (ix != len && args)
{ {
tree arg; tree arg = TREE_VEC_ELT (args, ix);
if (len >= 0)
{ if (ix)
arg = TREE_VEC_ELT (args, ix);
ix++;
}
else
{
arg = TREE_VALUE (args);
args = TREE_CHAIN (args);
}
if (need_comma)
pp_separate_with_comma (cxx_pp); pp_separate_with_comma (cxx_pp);
if (!arg) if (!arg)
pp_identifier (cxx_pp, "<template parameter error>"); pp_identifier (cxx_pp, "<template parameter error>");
else else
dump_template_argument (arg, flags); dump_template_argument (arg, flags);
need_comma = 1;
} }
} }
else if (primary) else if (primary)

View File

@ -7675,32 +7675,51 @@ cp_parser_template_name (cp_parser* parser,
template-argument template-argument
template-argument-list , template-argument template-argument-list , template-argument
Returns a TREE_LIST representing the arguments, in the order they Returns a TREE_VEC containing the arguments. */
appeared. The TREE_VALUE of each node is a representation of the
argument. */
static tree static tree
cp_parser_template_argument_list (cp_parser* parser) cp_parser_template_argument_list (cp_parser* parser)
{ {
tree arguments = NULL_TREE; tree fixed_args[10];
unsigned n_args = 0;
unsigned alloced = 10;
tree *arg_ary = fixed_args;
tree vec;
while (true) do
{ {
tree argument; tree argument;
if (n_args)
/* Consume the comma. */
cp_lexer_consume_token (parser->lexer);
/* Parse the template-argument. */ /* Parse the template-argument. */
argument = cp_parser_template_argument (parser); argument = cp_parser_template_argument (parser);
/* Add it to the list. */ if (n_args == alloced)
arguments = tree_cons (NULL_TREE, argument, arguments); {
/* If it is not a `,', then there are no more arguments. */ alloced *= 2;
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
break; if (arg_ary == fixed_args)
/* Otherwise, consume the ','. */ {
cp_lexer_consume_token (parser->lexer); arg_ary = xmalloc (sizeof (tree) * alloced);
memcpy (arg_ary, fixed_args, sizeof (tree) * n_args);
}
else
arg_ary = xrealloc (arg_ary, sizeof (tree) * alloced);
}
arg_ary[n_args++] = argument;
} }
while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
/* We built up the arguments in reverse order. */ vec = make_tree_vec (n_args);
return nreverse (arguments);
while (n_args--)
TREE_VEC_ELT (vec, n_args) = arg_ary[n_args];
if (arg_ary != fixed_args)
free (arg_ary);
return vec;
} }
/* Parse a template-argument. /* Parse a template-argument.

View File

@ -3583,7 +3583,7 @@ coerce_template_parms (tree parms,
tree new_inner_args; tree new_inner_args;
inner_args = INNERMOST_TEMPLATE_ARGS (args); inner_args = INNERMOST_TEMPLATE_ARGS (args);
nargs = NUM_TMPL_ARGS (inner_args); nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
nparms = TREE_VEC_LENGTH (parms); nparms = TREE_VEC_LENGTH (parms);
if (nargs > nparms if (nargs > nparms
@ -3614,12 +3614,7 @@ coerce_template_parms (tree parms,
parm = TREE_VEC_ELT (parms, i); parm = TREE_VEC_ELT (parms, i);
/* Calculate the Ith argument. */ /* Calculate the Ith argument. */
if (inner_args && TREE_CODE (inner_args) == TREE_LIST) if (i < nargs)
{
arg = TREE_VALUE (inner_args);
inner_args = TREE_CHAIN (inner_args);
}
else if (i < nargs)
arg = TREE_VEC_ELT (inner_args, i); arg = TREE_VEC_ELT (inner_args, i);
else if (require_all_arguments) else if (require_all_arguments)
/* There must be a default arg in this case. */ /* There must be a default arg in this case. */
@ -3752,13 +3747,6 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
else else
my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
if (TREE_CODE (arg) == TREE_LIST)
{
/* New list cell was built because old chain link was in
use. */
my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);
arg = TREE_VALUE (arg);
}
/* No need to check arglist against parmlist here; we did that /* No need to check arglist against parmlist here; we did that
in coerce_template_parms, called from lookup_template_class. */ in coerce_template_parms, called from lookup_template_class. */
cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER)); cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
@ -3854,6 +3842,7 @@ lookup_template_function (tree fns, tree arglist)
if (fns == error_mark_node || arglist == error_mark_node) if (fns == error_mark_node || arglist == error_mark_node)
return error_mark_node; return error_mark_node;
my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
if (fns == NULL_TREE) if (fns == NULL_TREE)
{ {
error ("non-template used as template"); error ("non-template used as template");
@ -3904,9 +3893,6 @@ maybe_get_template_decl_from_type_decl (tree decl)
parameters, find the desired type. parameters, find the desired type.
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
(Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
be a TREE_LIST if called directly from the parser, and a TREE_VEC
otherwise.)
IN_DECL, if non-NULL, is the template declaration we are trying to IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate. instantiate.
@ -3932,8 +3918,6 @@ lookup_template_class (tree d1,
tree t; tree t;
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
my_friendly_assert ((!arglist || TREE_CODE (arglist) == TREE_LIST)
== ((complain & tf_user) != 0), 20030724);
if (TREE_CODE (d1) == IDENTIFIER_NODE) if (TREE_CODE (d1) == IDENTIFIER_NODE)
{ {
@ -5492,30 +5476,18 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
static tree static tree
tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{ {
int is_list = !(t && TREE_CODE (t) == TREE_VEC); int len = TREE_VEC_LENGTH (t);
int len = is_list ? list_length (t) : TREE_VEC_LENGTH (t);
int need_new = 0, i; int need_new = 0, i;
tree position = t;
tree *elts = alloca (len * sizeof (tree)); tree *elts = alloca (len * sizeof (tree));
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
tree orig_arg; tree orig_arg = TREE_VEC_ELT (t, i);
tree new_arg = NULL_TREE; tree new_arg;
if (is_list) if (TREE_CODE (orig_arg) == TREE_VEC)
{ new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
orig_arg = TREE_VALUE (position);
position = TREE_CHAIN (position);
}
else else
{
orig_arg = TREE_VEC_ELT (t, i);
if (TREE_CODE (orig_arg) == TREE_VEC)
new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
}
if (!new_arg)
new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl); new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
if (new_arg == error_mark_node) if (new_arg == error_mark_node)
@ -5529,19 +5501,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (!need_new) if (!need_new)
return t; return t;
if (is_list) t = make_tree_vec (len);
{ for (i = 0; i < len; i++)
t = NULL_TREE; TREE_VEC_ELT (t, i) = elts[i];
for (i = len; i--;)
t = tree_cons (NULL_TREE, elts[i], t);
}
else
{
t = make_tree_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
}
return t; return t;
} }
@ -7052,9 +7014,9 @@ tsubst_baselink (tree baselink, tree object_type,
template_id_p = true; template_id_p = true;
template_args = TREE_OPERAND (fns, 1); template_args = TREE_OPERAND (fns, 1);
fns = TREE_OPERAND (fns, 0); fns = TREE_OPERAND (fns, 0);
template_args = tsubst_copy_and_build (template_args, args, if (template_args)
complain, in_decl, template_args = tsubst_template_args (template_args, args,
/*function_p=*/false); complain, in_decl);
} }
name = DECL_NAME (get_first_fn (fns)); name = DECL_NAME (get_first_fn (fns));
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
@ -7094,9 +7056,10 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (TREE_CODE (name) == TEMPLATE_ID_EXPR) if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{ {
is_template = true; is_template = true;
template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1), template_args = TREE_OPERAND (name, 1);
args, complain, in_decl, if (template_args)
/*function_p=*/false); template_args = tsubst_template_args (template_args, args,
complain, in_decl);
name = TREE_OPERAND (name, 0); name = TREE_OPERAND (name, 0);
} }
else else
@ -7431,7 +7394,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree targs = TREE_OPERAND (t, 1); tree targs = TREE_OPERAND (t, 1);
fn = tsubst_copy (fn, args, complain, in_decl); fn = tsubst_copy (fn, args, complain, in_decl);
targs = tsubst_template_args (targs, args, complain, in_decl); if (targs)
targs = tsubst_template_args (targs, args, complain, in_decl);
return lookup_template_function (fn, targs); return lookup_template_function (fn, targs);
} }
@ -7930,7 +7894,10 @@ tsubst_copy_and_build (tree t,
{ {
tree object; tree object;
tree template = RECUR (TREE_OPERAND (t, 0)); tree template = RECUR (TREE_OPERAND (t, 0));
tree targs = RECUR (TREE_OPERAND (t, 1)); tree targs = TREE_OPERAND (t, 1);
if (targs)
targs = tsubst_template_args (targs, args, complain, in_decl);
if (TREE_CODE (template) == COMPONENT_REF) if (TREE_CODE (template) == COMPONENT_REF)
{ {
@ -11697,29 +11664,14 @@ dependent_template_arg_p (tree arg)
bool bool
any_dependent_template_arguments_p (tree args) any_dependent_template_arguments_p (tree args)
{ {
int i;
if (!args) if (!args)
return false; return false;
my_friendly_assert (TREE_CODE (args) == TREE_LIST for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
|| TREE_CODE (args) == TREE_VEC, if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
20030707); return true;
if (TREE_CODE (args) == TREE_LIST)
{
while (args)
{
if (dependent_template_arg_p (TREE_VALUE (args)))
return true;
args = TREE_CHAIN (args);
}
}
else
{
int i;
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
}
return false; return false;
} }

View File

@ -1587,6 +1587,30 @@ cp_tree_equal (tree t1, tree t2)
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)), && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
TREE_TYPE (TEMPLATE_PARM_DECL (t2)))); TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
case TEMPLATE_ID_EXPR:
{
unsigned ix;
tree vec1, vec2;
if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
return false;
vec1 = TREE_OPERAND (t1, 1);
vec2 = TREE_OPERAND (t2, 1);
if (!vec1 || !vec2)
return !vec1 && !vec2;
if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
return false;
for (ix = TREE_VEC_LENGTH (vec1); ix--;)
if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
TREE_VEC_ELT (vec2, ix)))
return false;
return true;
}
case SIZEOF_EXPR: case SIZEOF_EXPR:
case ALIGNOF_EXPR: case ALIGNOF_EXPR:
{ {