Commit 104bf76a by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (most_specialized_instantiation): New function.

	* cp-tree.h (most_specialized_instantiation): New function.
	(print_candidates): Likewise.
	* class.c (validate_lhs): Remove.
	(resolve_address_of_overloaded_function): New function, split out
	and then substantially reworked, from ...
	(instantiate_type): Use it.  Simplify.
	* cvt.c (convert_to_reference): Complain when caller has indicated
	that's the right thing to do.  Don't crash if instantiate_type
	fails.
	* pt.c: Substitute `parameters' for `paramters' throughout.
	(print_candidates): Don't make it static.
	(most_specialized_instantiation): Split out from ...
	(most_specialized): Here.

From-SVN: r24225
parent f8976021
1998-12-09 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (most_specialized_instantiation): New function.
(print_candidates): Likewise.
* class.c (validate_lhs): Remove.
(resolve_address_of_overloaded_function): New function, split out
and then substantially reworked, from ...
(instantiate_type): Use it. Simplify.
* cvt.c (convert_to_reference): Complain when caller has indicated
that's the right thing to do. Don't crash if instantiate_type
fails.
* pt.c: Substitute `parameters' for `paramters' throughout.
(print_candidates): Don't make it static.
(most_specialized_instantiation): Split out from ...
(most_specialized): Here.
Wed Dec 9 15:33:01 1998 Dave Brolley <brolley@cygnus.com> Wed Dec 9 15:33:01 1998 Dave Brolley <brolley@cygnus.com>
* lex.c (lang_init_options): Initialize cpplib. * lex.c (lang_init_options): Initialize cpplib.
......
...@@ -3030,6 +3030,8 @@ extern int is_specialization_of PROTO((tree, tree)); ...@@ -3030,6 +3030,8 @@ extern int is_specialization_of PROTO((tree, tree));
extern int comp_template_args PROTO((tree, tree)); extern int comp_template_args PROTO((tree, tree));
extern void maybe_process_partial_specialization PROTO((tree)); extern void maybe_process_partial_specialization PROTO((tree));
extern void maybe_check_template_type PROTO((tree)); extern void maybe_check_template_type PROTO((tree));
extern tree most_specialized_instantiation PROTO((tree, tree));
extern void print_candidates PROTO((tree));
extern int processing_specialization; extern int processing_specialization;
extern int processing_explicit_instantiation; extern int processing_explicit_instantiation;
......
...@@ -414,7 +414,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -414,7 +414,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node) if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node)
{ {
expr = instantiate_type (type, expr, 0); expr = instantiate_type (type, expr,
(flags & LOOKUP_COMPLAIN) != 0);
if (expr == error_mark_node)
return error_mark_node;
intype = TREE_TYPE (expr); intype = TREE_TYPE (expr);
} }
......
...@@ -112,7 +112,6 @@ static void push_inline_template_parms_recursive PROTO((tree, int)); ...@@ -112,7 +112,6 @@ static void push_inline_template_parms_recursive PROTO((tree, int));
static tree retrieve_specialization PROTO((tree, tree)); static tree retrieve_specialization PROTO((tree, tree));
static tree register_specialization PROTO((tree, tree, tree)); static tree register_specialization PROTO((tree, tree, tree));
static int unregister_specialization PROTO((tree, tree)); static int unregister_specialization PROTO((tree, tree));
static void print_candidates PROTO((tree));
static tree reduce_template_parm_level PROTO((tree, tree, int)); static tree reduce_template_parm_level PROTO((tree, tree, int));
static tree build_template_decl PROTO((tree, tree)); static tree build_template_decl PROTO((tree, tree));
static int mark_template_parm PROTO((tree, void *)); static int mark_template_parm PROTO((tree, void *));
...@@ -883,7 +882,7 @@ unregister_specialization (spec, tmpl) ...@@ -883,7 +882,7 @@ unregister_specialization (spec, tmpl)
/* Print the list of candidate FNS in an error message. */ /* Print the list of candidate FNS in an error message. */
static void void
print_candidates (fns) print_candidates (fns)
tree fns; tree fns;
{ {
...@@ -1996,7 +1995,7 @@ process_partial_specialization (decl) ...@@ -1996,7 +1995,7 @@ process_partial_specialization (decl)
/* We haven't yet initialized TPD2. Do so now. */ /* We haven't yet initialized TPD2. Do so now. */
tpd2.arg_uses_template_parms tpd2.arg_uses_template_parms
= (int*) alloca (sizeof (int) * nargs); = (int*) alloca (sizeof (int) * nargs);
/* The number of paramters here is the number in the /* The number of parameters here is the number in the
main template, which, as checked in the assertion main template, which, as checked in the assertion
above, is NARGS. */ above, is NARGS. */
tpd2.parms = (int*) alloca (sizeof (int) * nargs); tpd2.parms = (int*) alloca (sizeof (int) * nargs);
...@@ -2004,7 +2003,7 @@ process_partial_specialization (decl) ...@@ -2004,7 +2003,7 @@ process_partial_specialization (decl)
TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
} }
/* Mark the template paramters. But this time, we're /* Mark the template parameters. But this time, we're
looking for the template parameters of the main looking for the template parameters of the main
template, not in the specialization. */ template, not in the specialization. */
tpd2.current_arg = i; tpd2.current_arg = i;
...@@ -2024,7 +2023,7 @@ process_partial_specialization (decl) ...@@ -2024,7 +2023,7 @@ process_partial_specialization (decl)
if (tpd2.parms[j] != 0 if (tpd2.parms[j] != 0
&& tpd.arg_uses_template_parms [j]) && tpd.arg_uses_template_parms [j])
{ {
cp_error ("type `%T' of template argument `%E' depends on template paramter(s)", cp_error ("type `%T' of template argument `%E' depends on template parameter(s)",
type, type,
arg); arg);
break; break;
...@@ -2106,7 +2105,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial) ...@@ -2106,7 +2105,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
/* If we're inside a class definition, there's no need to /* If we're inside a class definition, there's no need to
examine the paramters to the class itself. On the one examine the parameters to the class itself. On the one
hand, they will be checked when the class is defined, and, hand, they will be checked when the class is defined, and,
on the other, default arguments are legal in things like: on the other, default arguments are legal in things like:
template <class T = double> template <class T = double>
...@@ -8024,35 +8023,30 @@ get_class_bindings (tparms, parms, args) ...@@ -8024,35 +8023,30 @@ get_class_bindings (tparms, parms, args)
return vec; return vec;
} }
/* Return the most specialized of the list of templates in FNS that can /* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
produce an instantiation matching DECL, given the explicit template Pick the most specialized template, and return the corresponding
arguments EXPLICIT_ARGS. */ instantiation, or if there is no corresponding instantiation, the
template itself. EXPLICIT_ARGS is any template arguments explicity
mentioned in a template-id. If there is no most specialized
tempalte, error_mark_node is returned. If there are no templates
at all, NULL_TREE is returned. */
tree tree
most_specialized (fns, decl, explicit_args) most_specialized_instantiation (instantiations, explicit_args)
tree fns, decl, explicit_args; tree instantiations;
tree explicit_args;
{ {
tree candidates = NULL_TREE; tree fn, champ;
tree fn, champ, args;
int fate; int fate;
for (fn = fns; fn; fn = TREE_CHAIN (fn)) if (!instantiations)
{
tree candidate = TREE_VALUE (fn);
args = get_bindings (candidate, decl, explicit_args);
if (args)
candidates = scratch_tree_cons (NULL_TREE, candidate,
candidates);
}
if (!candidates)
return NULL_TREE; return NULL_TREE;
champ = TREE_VALUE (candidates); champ = instantiations;
for (fn = TREE_CHAIN (candidates); fn; fn = TREE_CHAIN (fn)) for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
{ {
fate = more_specialized (champ, TREE_VALUE (fn), explicit_args); fate = more_specialized (TREE_VALUE (champ),
TREE_VALUE (fn), explicit_args);
if (fate == 1) if (fate == 1)
; ;
else else
...@@ -8063,18 +8057,43 @@ most_specialized (fns, decl, explicit_args) ...@@ -8063,18 +8057,43 @@ most_specialized (fns, decl, explicit_args)
if (! fn) if (! fn)
return error_mark_node; return error_mark_node;
} }
champ = TREE_VALUE (fn); champ = fn;
} }
} }
for (fn = candidates; fn && TREE_VALUE (fn) != champ; fn = TREE_CHAIN (fn)) for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
{ {
fate = more_specialized (champ, TREE_VALUE (fn), explicit_args); fate = more_specialized (TREE_VALUE (champ),
TREE_VALUE (fn), explicit_args);
if (fate != 1) if (fate != 1)
return error_mark_node; return error_mark_node;
} }
return champ; return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ);
}
/* Return the most specialized of the list of templates in FNS that can
produce an instantiation matching DECL, given the explicit template
arguments EXPLICIT_ARGS. */
tree
most_specialized (fns, decl, explicit_args)
tree fns, decl, explicit_args;
{
tree candidates = NULL_TREE;
tree fn, args;
for (fn = fns; fn; fn = TREE_CHAIN (fn))
{
tree candidate = TREE_VALUE (fn);
args = get_bindings (candidate, decl, explicit_args);
if (args)
candidates = scratch_tree_cons (NULL_TREE, candidate,
candidates);
}
return most_specialized_instantiation (candidates, explicit_args);
} }
/* If DECL is a specialization of some template, return the most /* If DECL is a specialization of some template, return the most
......
class a {
public:
int f() { return 0; }
int f() const { return 1; }
};
class b : public a {
};
int main()
{
int (b::* ptr1)() = &b::f;
int (b::* ptr2)() const = &b::f;
b ao;
if ((ao.*ptr1)() != 0)
return 1;
if ((ao.*ptr2)() != 1)
return 1;
}
struct B {
int f(int) { return 1; }
};
struct D {
template <class T>
int f(T) { return 0; }
};
int main()
{
int (D::*g)(int) = &D::f;
D d;
return (d.*g)(0);
}
template <class T>
int f(T)
{
return 1;
}
template <class T>
int f(T*)
{
return 0;
}
int main()
{
int (*h)(int*) = &f;
int (&k)(int*) = f;
return (*h)(0) || (*k)(0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment