Handle specifying template args to member function templates.

* tree.c (build_overload): Always create an OVERLOAD for a template.
	* search.c (add_conversions): Handle finding an OVERLOAD.
	* decl2.c (check_classfn): Likewise.
	* lex.c (identifier_type): See through a baselink.
	* parse.y (do_id): Don't call do_identifier if we got a baselink.
	* class.c (instantiate_type, case TREE_LIST): Recurse.
	* decl.c (grokdeclarator): Allow a boolean constant for array
	bounds, odd as that sounds.
	* pt.c (unify): Be more strict about non-type parms, except for
	array bounds.
	(UNIFY_ALLOW_INTEGER): New macro.

From-SVN: r23740
This commit is contained in:
Jason Merrill 1998-11-21 05:42:20 +00:00 committed by Jason Merrill
parent e42e502895
commit 161c12b0bf
10 changed files with 650 additions and 614 deletions

View File

@ -1,3 +1,20 @@
1998-11-21 Jason Merrill <jason@yorick.cygnus.com>
Handle specifying template args to member function templates.
* tree.c (build_overload): Always create an OVERLOAD for a template.
* search.c (add_conversions): Handle finding an OVERLOAD.
* decl2.c (check_classfn): Likewise.
* lex.c (identifier_type): See through a baselink.
* parse.y (do_id): Don't call do_identifier if we got a baselink.
* class.c (instantiate_type, case TREE_LIST): Recurse.
* decl.c (grokdeclarator): Allow a boolean constant for array
bounds, odd as that sounds.
* pt.c (unify): Be more strict about non-type parms, except for
array bounds.
(UNIFY_ALLOW_INTEGER): New macro.
1998-11-19 Manfred Hollstein <manfred@s-direktnet.de> 1998-11-19 Manfred Hollstein <manfred@s-direktnet.de>
* Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir). * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).

View File

@ -5227,8 +5227,6 @@ instantiate_type (lhstype, rhs, complain)
case TREE_LIST: case TREE_LIST:
{ {
tree elem, baselink, name = NULL_TREE;
if (TREE_PURPOSE (rhs) == error_mark_node) if (TREE_PURPOSE (rhs) == error_mark_node)
{ {
/* Make sure we don't drop the non-local flag, as the old code /* Make sure we don't drop the non-local flag, as the old code
@ -5242,41 +5240,12 @@ instantiate_type (lhstype, rhs, complain)
/* Now we should have a baselink. */ /* Now we should have a baselink. */
my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC, my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
980331); 980331);
/* First look for an exact match. Search member functions.
May have to undo what `default_conversion' might do to
lhstype. */
lhstype = validate_lhs (lhstype, complain);
if (lhstype == error_mark_node)
return lhstype;
my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181); my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
|| TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD, || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
182); 182);
for (baselink = rhs; baselink; return instantiate_type (lhstype, TREE_VALUE (rhs), complain);
baselink = next_baselink (baselink))
{
elem = TREE_VALUE (baselink);
while (elem)
if (same_type_p (lhstype, TREE_TYPE (OVL_CURRENT (elem))))
{
mark_used (OVL_CURRENT (elem));
return OVL_CURRENT (elem);
}
else
elem = OVL_NEXT (elem);
}
name = rhs;
while (TREE_CODE (name) == TREE_LIST)
name = TREE_VALUE (name);
name = DECL_NAME (OVL_CURRENT (name));
if (complain)
cp_error ("no compatible member functions named `%D'", name);
return error_mark_node;
} }
case CALL_EXPR: case CALL_EXPR:

View File

@ -9692,7 +9692,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
} }
if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE) && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE
&& TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE)
{ {
cp_error ("size of array `%D' has non-integer type", cp_error ("size of array `%D' has non-integer type",
dname); dname);

View File

@ -1425,8 +1425,8 @@ check_classfn (ctype, function)
} }
break; /* loser */ break; /* loser */
} }
else if (TREE_CODE (fndecl) == TEMPLATE_DECL else if (TREE_CODE (OVL_CURRENT (fndecl)) == TEMPLATE_DECL
&& DECL_CONV_FN_P (fndecl) && DECL_CONV_FN_P (OVL_CURRENT (fndecl))
&& DECL_CONV_FN_P (function)) && DECL_CONV_FN_P (function))
/* The method in the class is a member template /* The method in the class is a member template
conversion operator. We are declaring another conversion operator. We are declaring another

View File

@ -2809,6 +2809,10 @@ identifier_type (decl)
} }
if (looking_for_template && really_overloaded_fn (decl)) if (looking_for_template && really_overloaded_fn (decl))
{ {
/* See through a baselink. */
if (TREE_CODE (decl) == TREE_LIST)
decl = TREE_VALUE (decl);
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME; return PFUNCNAME;

File diff suppressed because it is too large Load Diff

View File

@ -1316,7 +1316,16 @@ notype_unqualified_id:
; ;
do_id: do_id:
{ $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); } {
/* If lastiddecl is a TREE_LIST, it's a baselink, which
means that we're in an expression like S::f<int>, so
don't do_identifier; we only do that for unqualified
identifiers. */
if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST)
$$ = do_identifier ($<ttype>-1, 1, NULL_TREE);
else
$$ = $<ttype>-1;
}
template_id: template_id:
PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket

View File

@ -75,6 +75,7 @@ static tree saved_trees;
#define UNIFY_ALLOW_MORE_CV_QUAL 1 #define UNIFY_ALLOW_MORE_CV_QUAL 1
#define UNIFY_ALLOW_LESS_CV_QUAL 2 #define UNIFY_ALLOW_LESS_CV_QUAL 2
#define UNIFY_ALLOW_DERIVED 4 #define UNIFY_ALLOW_DERIVED 4
#define UNIFY_ALLOW_INTEGER 8
static int unify PROTO((tree, tree, tree, tree, int, int*)); static int unify PROTO((tree, tree, tree, tree, int, int*));
static int resolve_overloaded_unification PROTO((tree, tree, tree, tree, static int resolve_overloaded_unification PROTO((tree, tree, tree, tree,
@ -7304,7 +7305,10 @@ check_cv_quals_for_unify (strict, arg, parm)
UNIFY_ALLOW_DERIVED: UNIFY_ALLOW_DERIVED:
Allow the deduced ARG to be a template base class of ARG, Allow the deduced ARG to be a template base class of ARG,
or a pointer to a template base class of the type pointed to by or a pointer to a template base class of the type pointed to by
ARG. */ ARG.
UNIFY_ALLOW_INTEGER:
Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX
case for more information. */
int int
unify (tparms, targs, parm, arg, strict, explicit_mask) unify (tparms, targs, parm, arg, strict, explicit_mask)
@ -7487,6 +7491,22 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
my_friendly_abort (42); my_friendly_abort (42);
} }
/* [temp.deduct.type] If, in the declaration of a function template
with a non-type template-parameter, the non-type
template-parameter is used in an expression in the function
parameter-list and, if the corresponding template-argument is
deduced, the template-argument type shall match the type of the
template-parameter exactly, except that a template-argument
deduced from an array bound may be of any integral type. */
if (same_type_p (TREE_TYPE (arg), TREE_TYPE (parm)))
/* OK */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
|| TREE_CODE (TREE_TYPE (parm)) == BOOLEAN_TYPE))
/* OK */;
else
return 1;
TREE_VEC_ELT (targs, idx) = copy_to_permanent (arg); TREE_VEC_ELT (targs, idx) = copy_to_permanent (arg);
return 0; return 0;
@ -7560,11 +7580,13 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
{ {
if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
&& unify (tparms, targs, TYPE_MIN_VALUE (parm), && unify (tparms, targs, TYPE_MIN_VALUE (parm),
TYPE_MIN_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask)) TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER,
explicit_mask))
return 1; return 1;
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg) if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
&& unify (tparms, targs, TYPE_MAX_VALUE (parm), && unify (tparms, targs, TYPE_MAX_VALUE (parm),
TYPE_MAX_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask)) TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER,
explicit_mask))
return 1; return 1;
} }
/* We use the TYPE_MAIN_VARIANT since we have already /* We use the TYPE_MAIN_VARIANT since we have already
@ -7695,8 +7717,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
integer_type_node, integer_type_node,
arg, t2)); arg, t2));
return unify (tparms, targs, t1, t, UNIFY_ALLOW_NONE, return unify (tparms, targs, t1, t, strict, explicit_mask);
explicit_mask);
} }
/* else fall through */ /* else fall through */

View File

@ -3311,6 +3311,12 @@ add_conversions (binfo)
if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp))) if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
break; break;
if (TREE_CODE (tmp) == OVERLOAD)
{
my_friendly_assert (TREE_CHAIN (tmp) == NULL_TREE, 981121);
tmp = OVL_FUNCTION (tmp);
}
/* We don't want to mark 'name' until we've seen all the overloads /* We don't want to mark 'name' until we've seen all the overloads
in this class; we could be overloading on the quals of 'this'. */ in this class; we could be overloading on the quals of 'this'. */
if (name && name != DECL_NAME (tmp)) if (name && name != DECL_NAME (tmp))

View File

@ -1370,9 +1370,9 @@ build_overload (decl, chain)
tree decl; tree decl;
tree chain; tree chain;
{ {
if (!chain) if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
return decl; return decl;
if (TREE_CODE (chain) != OVERLOAD) if (chain && TREE_CODE (chain) != OVERLOAD)
chain = ovl_cons (chain, NULL_TREE); chain = ovl_cons (chain, NULL_TREE);
return ovl_cons (decl, chain); return ovl_cons (decl, chain);
} }