This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] Use num_parm_types and nth_parm_type in build_op_delete_call.
- From: Kazu Hirata <kazu at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Wed, 5 Jul 2006 12:25:29 -0700
- Subject: [lto] Use num_parm_types and nth_parm_type in build_op_delete_call.
Hi,
Attached is a patch to Use num_parm_types and nth_parm_type in
build_op_delete_call.
The third hunk of This patch is not as obvious as other TREE_LIST
patches I've been posting, so here is some explanation.
add_function_candidate first checks whether we have too many
arguments. The existing code does so by walking parmlist while
looking for void_list_node. Once TYPE_ARG_TYPES starts using
TREE_VEC, we can quickly check whether void_type_node appears "too
early" in the type list. The patch implements this ideas as:
/* If PARMLIST ends with void_type_node and is shorter than the
argument list, then this candidate function is not viable because
we have too many arguments. */
if (skip < parm_types_len
&& nth_parm_type (parmlist, parm_types_len - 1) == void_type_node
&& parm_types_len - skip - 1 < len)
{
viable = 0;
goto out;
}
The rest of the patch should be fairly obvious.
Tested on x86_64-pc-linux-gnu. OK to apply to the LTO branch?
Kazu Hirata
2006-07-05 Kazu Hirata <kazu@codesourcery.com>
* call.c (build_op_delete_call): Use nth_parm_type.
Index: cp/call.c
===================================================================
*** cp/call.c (revision 115150)
--- cp/call.c (working copy)
*************** add_function_candidate (struct z_candida
*** 1312,1323 ****
int flags)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
tree decllist = DECL_ARGUMENTS (fn);
int i, len;
conversion **convs;
! tree parmnode, argnode, declnode;
tree orig_arglist;
int viable = 1;
/* At this point we should not see any functions which haven't been
explicitly declared, except for friend functions which will have
--- 1312,1325 ----
int flags)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ int parm_types_len = num_parm_types (parmlist);
tree decllist = DECL_ARGUMENTS (fn);
int i, len;
conversion **convs;
! tree argnode, declnode;
tree orig_arglist;
int viable = 1;
+ int skip = 0;
/* At this point we should not see any functions which haven't been
explicitly declared, except for friend functions which will have
*************** add_function_candidate (struct z_candida
*** 1328,1334 ****
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
! parmlist = skip_artificial_parms_for (fn, parmlist);
decllist = skip_artificial_parms_for (fn, decllist);
orig_arglist = arglist;
arglist = skip_artificial_parms_for (fn, arglist);
--- 1330,1336 ----
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
! skip = num_artificial_parms_for (fn);
decllist = skip_artificial_parms_for (fn, decllist);
orig_arglist = arglist;
arglist = skip_artificial_parms_for (fn, arglist);
*************** add_function_candidate (struct z_candida
*** 1346,1377 ****
We need to check this first; otherwise, checking the ICSes might cause
us to produce an ill-formed template instantiation. */
! parmnode = parmlist;
! declnode = decllist;
! for (i = 0; i < len; ++i)
{
! if (parmnode == NULL_TREE || parmnode == void_list_node)
! break;
! parmnode = TREE_CHAIN (parmnode);
! if (declnode)
! declnode = TREE_CHAIN (declnode);
}
! if (i < len && parmnode)
! viable = 0;
/* Make sure there are default args for the rest of the parms. */
! else if (!sufficient_parms_p (declnode))
! viable = 0;
!
! if (! viable)
! goto out;
/* Second, for F to be a viable function, there shall exist for each
argument an implicit conversion sequence that converts that argument
to the corresponding parameter of F. */
- parmnode = parmlist;
argnode = arglist;
for (i = 0; i < len; ++i)
--- 1348,1381 ----
We need to check this first; otherwise, checking the ICSes might cause
us to produce an ill-formed template instantiation. */
! /* If PARMLIST ends with void_type_node and is shorter than the
! argument list, then this candidate function is not viable because
! we have too many arguments. */
! if (skip < parm_types_len
! && nth_parm_type (parmlist, parm_types_len - 1) == void_type_node
! && parm_types_len - skip - 1 < len)
{
! viable = 0;
! goto out;
}
! /* Skip those PARM_DECLs for which we have explicit arguments. */
! declnode = decllist;
! i = (len < parm_types_len - skip) ? len : parm_types_len - skip;
! while (i-- && declnode)
! declnode = TREE_CHAIN (declnode);
/* Make sure there are default args for the rest of the parms. */
! if (!sufficient_parms_p (declnode))
! {
! viable = 0;
! goto out;
! }
/* Second, for F to be a viable function, there shall exist for each
argument an implicit conversion sequence that converts that argument
to the corresponding parameter of F. */
argnode = arglist;
for (i = 0; i < len; ++i)
*************** add_function_candidate (struct z_candida
*** 1381,1394 ****
conversion *t;
int is_this;
- gcc_assert (parmnode != void_list_node);
-
is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& ! DECL_CONSTRUCTOR_P (fn));
! if (parmnode)
{
! tree parmtype = TREE_VALUE (parmnode);
/* The type of the implicit object parameter ('this') for
overload resolution is not always the same as for the
--- 1385,1398 ----
conversion *t;
int is_this;
is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& ! DECL_CONSTRUCTOR_P (fn));
! if (skip + i < parm_types_len)
{
! tree parmtype = nth_parm_type (parmlist, skip + i);
!
! gcc_assert (parmtype != void_type_node);
/* The type of the implicit object parameter ('this') for
overload resolution is not always the same as for the
*************** add_function_candidate (struct z_candida
*** 1429,1436 ****
if (t->bad_p)
viable = -1;
- if (parmnode)
- parmnode = TREE_CHAIN (parmnode);
argnode = TREE_CHAIN (argnode);
}
--- 1433,1438 ----