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:
parent
e42e502895
commit
161c12b0bf
@ -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>
|
||||
|
||||
* Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).
|
||||
|
@ -5227,8 +5227,6 @@ instantiate_type (lhstype, rhs, complain)
|
||||
|
||||
case TREE_LIST:
|
||||
{
|
||||
tree elem, baselink, name = NULL_TREE;
|
||||
|
||||
if (TREE_PURPOSE (rhs) == error_mark_node)
|
||||
{
|
||||
/* 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. */
|
||||
my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
|
||||
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_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
|
||||
|| TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
|
||||
182);
|
||||
|
||||
for (baselink = rhs; baselink;
|
||||
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;
|
||||
return instantiate_type (lhstype, TREE_VALUE (rhs), complain);
|
||||
}
|
||||
|
||||
case CALL_EXPR:
|
||||
|
@ -9692,7 +9692,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
}
|
||||
|
||||
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",
|
||||
dname);
|
||||
|
@ -1425,8 +1425,8 @@ check_classfn (ctype, function)
|
||||
}
|
||||
break; /* loser */
|
||||
}
|
||||
else if (TREE_CODE (fndecl) == TEMPLATE_DECL
|
||||
&& DECL_CONV_FN_P (fndecl)
|
||||
else if (TREE_CODE (OVL_CURRENT (fndecl)) == TEMPLATE_DECL
|
||||
&& DECL_CONV_FN_P (OVL_CURRENT (fndecl))
|
||||
&& DECL_CONV_FN_P (function))
|
||||
/* The method in the class is a member template
|
||||
conversion operator. We are declaring another
|
||||
|
@ -2809,6 +2809,10 @@ identifier_type (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))
|
||||
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
|
||||
return PFUNCNAME;
|
||||
|
1151
gcc/cp/parse.c
1151
gcc/cp/parse.c
File diff suppressed because it is too large
Load Diff
@ -1316,7 +1316,16 @@ notype_unqualified_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:
|
||||
PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
|
||||
|
31
gcc/cp/pt.c
31
gcc/cp/pt.c
@ -75,6 +75,7 @@ static tree saved_trees;
|
||||
#define UNIFY_ALLOW_MORE_CV_QUAL 1
|
||||
#define UNIFY_ALLOW_LESS_CV_QUAL 2
|
||||
#define UNIFY_ALLOW_DERIVED 4
|
||||
#define UNIFY_ALLOW_INTEGER 8
|
||||
|
||||
static int unify PROTO((tree, tree, tree, tree, int, int*));
|
||||
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:
|
||||
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
|
||||
ARG. */
|
||||
ARG.
|
||||
UNIFY_ALLOW_INTEGER:
|
||||
Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX
|
||||
case for more information. */
|
||||
|
||||
int
|
||||
unify (tparms, targs, parm, arg, strict, explicit_mask)
|
||||
@ -7487,6 +7491,22 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
|
||||
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);
|
||||
return 0;
|
||||
|
||||
@ -7560,11 +7580,13 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
|
||||
{
|
||||
if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
|
||||
&& 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;
|
||||
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
|
||||
&& 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;
|
||||
}
|
||||
/* 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,
|
||||
arg, t2));
|
||||
|
||||
return unify (tparms, targs, t1, t, UNIFY_ALLOW_NONE,
|
||||
explicit_mask);
|
||||
return unify (tparms, targs, t1, t, strict, explicit_mask);
|
||||
}
|
||||
/* else fall through */
|
||||
|
||||
|
@ -3311,6 +3311,12 @@ add_conversions (binfo)
|
||||
if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
|
||||
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
|
||||
in this class; we could be overloading on the quals of 'this'. */
|
||||
if (name && name != DECL_NAME (tmp))
|
||||
|
@ -1370,9 +1370,9 @@ build_overload (decl, chain)
|
||||
tree decl;
|
||||
tree chain;
|
||||
{
|
||||
if (!chain)
|
||||
if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
|
||||
return decl;
|
||||
if (TREE_CODE (chain) != OVERLOAD)
|
||||
if (chain && TREE_CODE (chain) != OVERLOAD)
|
||||
chain = ovl_cons (chain, NULL_TREE);
|
||||
return ovl_cons (decl, chain);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user