This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: Make template args always be vectors
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: Mark Mitchell <mitchell at codesourcery dot com>, gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 Jul 2003 18:57:09 +0100
- Subject: [C++ PATCH]: Make template args always be vectors
- Organization: Codesourcery LLC
This patch changes the representation of a set of template arguments to
always be a vector (rather than either a vector or a list).
Booted & tested on i686-pc-linux-gnu, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
The voices in my head said this was stupid too
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): NODE is always a
TREE_VEC.
(NUM_TMPL_ARGS): Likewise.
* 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): Rename to ...
(cp_parser_template_id): Adjust.
(cp_parser_template_argument_list_opt): ... here. Produce a
vector, not a list.
* pt.c (check_explicit_specialization): Adjust.
(coerce_template_parms): Args are always vectors.
(mangle_class_name_for_template): Likewise.
(lookup_template_function, lookup_template_class): Likewise.
(tsubst_baselink): Use tsubst_template_args.
(tsubst_qualified_id): Likewise.
(tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
(fn_type_unification): We might get a zero length vector of
explicit args.
(type_unification_real): Args are always vectors.
(any_dependent_template_args_p): Likewise.
* tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.893
diff -c -3 -p -r1.893 cp-tree.h
*** cp/cp-tree.h 30 Jul 2003 17:27:13 -0000 1.893
--- cp/cp-tree.h 31 Jul 2003 16:48:08 -0000
*************** struct lang_decl GTY(())
*** 2206,2215 ****
/* 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 \
&& TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
/* The depth of a template argument vector. When called directly by
--- 2206,2212 ----
/* Nonzero if the template arguments is actually a vector of vectors,
rather than just a vector. */
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
! (TREE_VEC_LENGTH (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
*************** struct lang_decl GTY(())
*** 2243,2251 ****
/* 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)))
/* Returns the innermost level of template arguments in ARGS. */
#define INNERMOST_TEMPLATE_ARGS(NODE) \
--- 2240,2246 ----
/* Given a single level of template arguments in NODE, return the
number of arguments. */
#define NUM_TMPL_ARGS(NODE) \
! (TREE_VEC_LENGTH (NODE))
/* Returns the innermost level of template arguments in ARGS. */
#define INNERMOST_TEMPLATE_ARGS(NODE) \
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.653
diff -c -3 -p -r1.653 decl2.c
*** cp/decl2.c 30 Jul 2003 23:47:59 -0000 1.653
--- cp/decl2.c 31 Jul 2003 16:48:17 -0000
*************** arg_assoc (struct arg_lookup *k, tree n)
*** 3715,3721 ****
tree template = TREE_OPERAND (n, 0);
tree args = TREE_OPERAND (n, 1);
tree ctx;
! tree arg;
if (TREE_CODE (template) == COMPONENT_REF)
template = TREE_OPERAND (template, 1);
--- 3715,3721 ----
tree template = TREE_OPERAND (n, 0);
tree args = TREE_OPERAND (n, 1);
tree ctx;
! int ix;
if (TREE_CODE (template) == COMPONENT_REF)
template = TREE_OPERAND (template, 1);
*************** arg_assoc (struct arg_lookup *k, tree n)
*** 3738,3745 ****
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)
return true;
}
else
--- 3738,3745 ----
return true;
/* Now the arguments. */
! for (ix = TREE_VEC_LENGTH (args); ix--;)
! if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
return true;
}
else
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.227
diff -c -3 -p -r1.227 error.c
*** cp/error.c 28 Jul 2003 11:06:28 -0000 1.227
--- cp/error.c 31 Jul 2003 16:48:23 -0000
*************** dump_decl (tree t, int flags)
*** 920,937 ****
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);
! }
pp_template_argument_list_end (cxx_pp);
}
break;
--- 920,932 ----
case TEMPLATE_ID_EXPR:
{
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);
! dump_template_argument_list (TREE_OPERAND (t, 1), flags);
pp_template_argument_list_end (cxx_pp);
}
break;
*************** dump_template_parms (tree info, int prim
*** 1256,1296 ****
to crash producing error messages. */
if (args && !primary)
{
! int len = 0;
! int ix = 0;
! int need_comma = 0;
! 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);
! len = TREE_VEC_LENGTH (args);
! }
! else if (TREE_CODE (args) == TREE_LIST)
! len = -1;
! while (ix != len && args)
{
! tree arg;
! if (len >= 0)
! {
! 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);
if (!arg)
pp_identifier (cxx_pp, "<template parameter error>");
else
dump_template_argument (arg, flags);
- need_comma = 1;
}
}
else if (primary)
--- 1251,1274 ----
to crash producing error messages. */
if (args && !primary)
{
! int len, ix;
! if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
! args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
!
! len = TREE_VEC_LENGTH (args);
! for (ix = 0; ix != len; ix++)
{
! 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);
}
}
else if (primary)
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.93
diff -c -3 -p -r1.93 parser.c
*** cp/parser.c 29 Jul 2003 23:36:52 -0000 1.93
--- cp/parser.c 31 Jul 2003 16:48:52 -0000
*************** static tree cp_parser_template_id
*** 1547,1553 ****
(cp_parser *, bool, bool);
static tree cp_parser_template_name
(cp_parser *, bool, bool);
! static tree cp_parser_template_argument_list
(cp_parser *);
static tree cp_parser_template_argument
(cp_parser *);
--- 1547,1553 ----
(cp_parser *, bool, bool);
static tree cp_parser_template_name
(cp_parser *, bool, bool);
! static tree cp_parser_template_argument_list_opt
(cp_parser *);
static tree cp_parser_template_argument
(cp_parser *);
*************** cp_parser_template_id (cp_parser *parser
*** 7477,7486 ****
saved_qualifying_scope = parser->qualifying_scope;
saved_object_scope = parser->object_scope;
/* Parse the template-argument-list itself. */
! if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
! arguments = NULL_TREE;
! else
! arguments = cp_parser_template_argument_list (parser);
/* Look for the `>' that ends the template-argument-list. */
cp_parser_require (parser, CPP_GREATER, "`>'");
/* The `>' token might be a greater-than operator again now. */
--- 7477,7483 ----
saved_qualifying_scope = parser->qualifying_scope;
saved_object_scope = parser->object_scope;
/* Parse the template-argument-list itself. */
! arguments = cp_parser_template_argument_list_opt (parser);
/* Look for the `>' that ends the template-argument-list. */
cp_parser_require (parser, CPP_GREATER, "`>'");
/* The `>' token might be a greater-than operator again now. */
*************** cp_parser_template_name (cp_parser* pars
*** 7663,7700 ****
return decl;
}
! /* Parse a template-argument-list.
template-argument-list:
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. */
static tree
! cp_parser_template_argument_list (cp_parser* parser)
{
! tree arguments = NULL_TREE;
!
! while (true)
{
tree argument;
/* 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);
}
! /* We built up the arguments in reverse order. */
! return nreverse (arguments);
}
/* Parse a template-argument.
--- 7660,7719 ----
return decl;
}
! /* Parse a template-argument-list-opt
template-argument-list:
template-argument
template-argument-list , template-argument
! Returns a TREE_VEC containing the arguments. */
static tree
! cp_parser_template_argument_list_opt (cp_parser* parser)
{
! tree fixed_args[10];
! unsigned n_args = 0;
! unsigned alloced = 10;
! tree *arg_ary = fixed_args;
! tree vec;
!
! while (cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER))
{
tree argument;
+ if (n_args)
+ {
+ /* If it is not a `,', then there are no more arguments. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ }
+
/* Parse the template-argument. */
argument = cp_parser_template_argument (parser);
! 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;
}
! 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.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.745
diff -c -3 -p -r1.745 pt.c
*** cp/pt.c 31 Jul 2003 09:16:29 -0000 1.745
--- cp/pt.c 31 Jul 2003 16:49:18 -0000
*************** check_explicit_specialization (tree decl
*** 1606,1612 ****
fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
}
! declarator = lookup_template_function (fns, NULL_TREE);
}
if (declarator == error_mark_node)
--- 1606,1614 ----
fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
}
! declarator = lookup_template_function (fns, tsk != tsk_template
! ? make_tree_vec (0)
! : NULL_TREE);
}
if (declarator == error_mark_node)
*************** coerce_template_parms (tree parms,
*** 3632,3643 ****
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)
arg = TREE_VEC_ELT (inner_args, i);
else if (require_all_arguments)
/* There must be a default arg in this case. */
--- 3634,3640 ----
parm = TREE_VEC_ELT (parms, i);
/* Calculate the Ith argument. */
! if (i < nargs)
arg = TREE_VEC_ELT (inner_args, i);
else if (require_all_arguments)
/* There must be a default arg in this case. */
*************** mangle_class_name_for_template (const ch
*** 3770,3782 ****
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));
--- 3767,3772 ----
*************** lookup_template_function (tree fns, tree
*** 3872,3877 ****
--- 3862,3868 ----
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");
*************** maybe_get_template_decl_from_type_decl (
*** 3922,3930 ****
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.
--- 3913,3918 ----
*************** lookup_template_class (tree d1,
*** 3950,3957 ****
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)
{
--- 3938,3943 ----
*************** tsubst_baselink (tree baselink, tree obj
*** 7070,7078 ****
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);
}
name = DECL_NAME (get_first_fn (fns));
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
--- 7056,7063 ----
template_id_p = true;
template_args = TREE_OPERAND (fns, 1);
fns = TREE_OPERAND (fns, 0);
! 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);
*************** tsubst_qualified_id (tree qualified_id,
*** 7112,7120 ****
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);
name = TREE_OPERAND (name, 0);
}
else
--- 7097,7105 ----
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
is_template = true;
! template_args = TREE_OPERAND (name, 1);
! template_args = tsubst_template_args (template_args, args,
! complain, in_decl);
name = TREE_OPERAND (name, 0);
}
else
*************** tsubst_copy_and_build (tree t,
*** 7933,7939 ****
{
tree object;
tree template = RECUR (TREE_OPERAND (t, 0));
! tree targs = RECUR (TREE_OPERAND (t, 1));
if (TREE_CODE (template) == COMPONENT_REF)
{
--- 7918,7925 ----
{
tree object;
tree template = RECUR (TREE_OPERAND (t, 0));
! tree targs = tsubst_template_args (TREE_OPERAND (t, 1), args,
! complain, in_decl);
if (TREE_CODE (template) == COMPONENT_REF)
{
*************** fn_type_unification (tree fn,
*** 8549,8555 ****
my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
fntype = TREE_TYPE (fn);
! if (explicit_targs)
{
/* [temp.deduct]
--- 8535,8541 ----
my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
fntype = TREE_TYPE (fn);
! if (explicit_targs && TREE_VEC_LENGTH (explicit_targs))
{
/* [temp.deduct]
*************** type_unification_real (tree tparms,
*** 8771,8779 ****
my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
my_friendly_assert (xparms == NULL_TREE
|| TREE_CODE (xparms) == TREE_LIST, 290);
! /* ARGS could be NULL. */
! if (xargs)
! my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
my_friendly_assert (ntparms > 0, 292);
switch (strict)
--- 8757,8763 ----
my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
my_friendly_assert (xparms == NULL_TREE
|| TREE_CODE (xparms) == TREE_LIST, 290);
! my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291);
my_friendly_assert (ntparms > 0, 292);
switch (strict)
*************** type_dependent_expression_p (tree expres
*** 11623,11630 ****
expression = BASELINK_FUNCTIONS (expression);
if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
{
! if (any_dependent_template_arguments_p (TREE_OPERAND (expression,
! 1)))
return true;
expression = TREE_OPERAND (expression, 0);
}
--- 11607,11614 ----
expression = BASELINK_FUNCTIONS (expression);
if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
{
! if (any_dependent_template_arguments_p
! (TREE_OPERAND (expression, 1)))
return true;
expression = TREE_OPERAND (expression, 0);
}
*************** dependent_template_arg_p (tree arg)
*** 11685,11713 ****
bool
any_dependent_template_arguments_p (tree args)
{
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;
! }
return false;
}
--- 11669,11682 ----
bool
any_dependent_template_arguments_p (tree args)
{
+ int i;
+
if (!args)
return false;
! for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
! if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
! return true;
return false;
}
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.339
diff -c -3 -p -r1.339 tree.c
*** cp/tree.c 22 Jul 2003 23:30:21 -0000 1.339
--- cp/tree.c 31 Jul 2003 16:49:22 -0000
*************** cp_tree_equal (tree t1, tree t2)
*** 1587,1592 ****
--- 1587,1613 ----
&& 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 (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:
{