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>
* 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
* call.c (convert_like_real): Add rvalue binding error message.
* 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)
/* A template-id, like foo<int>. The first operand is the template.
The second is the TREE_LIST or TREE_VEC of explicitly specified
arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or
an OVERLOAD. If the template-id refers to a member template, the
template may be an IDENTIFIER_NODE. */
The second is NULL if there are no explicit arguments, or a
TREE_VEC of arguments. The template will be a FUNCTION_DECL,
TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
member template, the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* 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,
rather than just a vector. */
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
((NODE) != NULL_TREE \
&& TREE_CODE (NODE) == TREE_VEC \
&& TREE_VEC_LENGTH (NODE) > 0 \
&& TREE_VEC_ELT (NODE, 0) != NULL_TREE \
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
(NODE && TREE_VEC_ELT (NODE, 0) \
&& TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
/* 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
number of arguments. */
#define NUM_TMPL_ARGS(NODE) \
((NODE) == NULL_TREE ? 0 \
: (TREE_CODE (NODE) == TREE_VEC \
? TREE_VEC_LENGTH (NODE) : list_length (NODE)))
(TREE_VEC_LENGTH (NODE))
/* Returns the innermost level of template arguments in ARGS. */
#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 args = TREE_OPERAND (n, 1);
tree ctx;
tree arg;
int ix;
if (TREE_CODE (template) == COMPONENT_REF)
template = TREE_OPERAND (template, 1);
@ -3739,8 +3739,8 @@ arg_assoc (struct arg_lookup *k, tree n)
return true;
/* Now the arguments. */
for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg))
if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1)
for (ix = TREE_VEC_LENGTH (args); ix--;)
if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
return true;
}
else

View File

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

View File

@ -7675,32 +7675,51 @@ cp_parser_template_name (cp_parser* parser,
template-argument
template-argument-list , template-argument
Returns a TREE_LIST representing the arguments, in the order they
appeared. The TREE_VALUE of each node is a representation of the
argument. */
Returns a TREE_VEC containing the arguments. */
static tree
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;
if (n_args)
/* Consume the comma. */
cp_lexer_consume_token (parser->lexer);
/* Parse the template-argument. */
argument = cp_parser_template_argument (parser);
/* Add it to the list. */
arguments = tree_cons (NULL_TREE, argument, arguments);
/* If it is not a `,', then there are no more arguments. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
break;
/* Otherwise, consume the ','. */
cp_lexer_consume_token (parser->lexer);
if (n_args == alloced)
{
alloced *= 2;
if (arg_ary == fixed_args)
{
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. */
return nreverse (arguments);
vec = make_tree_vec (n_args);
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.

View File

@ -3583,7 +3583,7 @@ coerce_template_parms (tree parms,
tree new_inner_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);
if (nargs > nparms
@ -3614,12 +3614,7 @@ coerce_template_parms (tree parms,
parm = TREE_VEC_ELT (parms, i);
/* Calculate the Ith argument. */
if (inner_args && TREE_CODE (inner_args) == TREE_LIST)
{
arg = TREE_VALUE (inner_args);
inner_args = TREE_CHAIN (inner_args);
}
else if (i < nargs)
if (i < nargs)
arg = TREE_VEC_ELT (inner_args, i);
else if (require_all_arguments)
/* 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
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
in coerce_template_parms, called from lookup_template_class. */
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)
return error_mark_node;
my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
if (fns == NULL_TREE)
{
error ("non-template used as template");
@ -3904,9 +3893,6 @@ maybe_get_template_decl_from_type_decl (tree decl)
parameters, find the desired type.
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
instantiate.
@ -3932,8 +3918,6 @@ lookup_template_class (tree d1,
tree t;
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)
{
@ -5492,30 +5476,18 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
static tree
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 = is_list ? list_length (t) : TREE_VEC_LENGTH (t);
int len = TREE_VEC_LENGTH (t);
int need_new = 0, i;
tree position = t;
tree *elts = alloca (len * sizeof (tree));
for (i = 0; i < len; i++)
{
tree orig_arg;
tree new_arg = NULL_TREE;
tree orig_arg = TREE_VEC_ELT (t, i);
tree new_arg;
if (is_list)
{
orig_arg = TREE_VALUE (position);
position = TREE_CHAIN (position);
}
if (TREE_CODE (orig_arg) == TREE_VEC)
new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
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);
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)
return t;
if (is_list)
{
t = NULL_TREE;
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];
}
t = make_tree_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
return t;
}
@ -7052,9 +7014,9 @@ tsubst_baselink (tree baselink, tree object_type,
template_id_p = true;
template_args = TREE_OPERAND (fns, 1);
fns = TREE_OPERAND (fns, 0);
template_args = tsubst_copy_and_build (template_args, args,
complain, in_decl,
/*function_p=*/false);
if (template_args)
template_args = tsubst_template_args (template_args, args,
complain, in_decl);
}
name = DECL_NAME (get_first_fn (fns));
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)
{
is_template = true;
template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1),
args, complain, in_decl,
/*function_p=*/false);
template_args = TREE_OPERAND (name, 1);
if (template_args)
template_args = tsubst_template_args (template_args, args,
complain, in_decl);
name = TREE_OPERAND (name, 0);
}
else
@ -7431,7 +7394,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree targs = TREE_OPERAND (t, 1);
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);
}
@ -7930,7 +7894,10 @@ tsubst_copy_and_build (tree t,
{
tree object;
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)
{
@ -11697,29 +11664,14 @@ dependent_template_arg_p (tree arg)
bool
any_dependent_template_arguments_p (tree args)
{
int i;
if (!args)
return false;
my_friendly_assert (TREE_CODE (args) == TREE_LIST
|| TREE_CODE (args) == TREE_VEC,
20030707);
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;
}
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
return false;
}

View File

@ -1587,6 +1587,30 @@ cp_tree_equal (tree t1, tree t2)
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
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 ALIGNOF_EXPR:
{