* c-exp.y: Add new rule for resolving method overloads.

* eval.c (make_params): New function.
	(free_param_types): New function.
	(evaluate_subexp_standard): Pass expect_type to value_aggregate_elt.
	Handle case TYPE_INSTANCE.
	(evaluate_subexp_for_address): Pass expect_type to value_aggregate_elt.
	* expression.h (enum exp_opcode): Add TYPE_INSTANCE.
	(compare_parameters): Add declaration.
	* parse.c (operator_length_standard): Add TYPE_INSTANCE.
	* valops.c (value_aggregate_elt): Add new expect_type parameter.
	Pass expect_type to value_struct_elt_for_reference.
	(value_struct_elt_for_reference): Add expect_type parameter and use
	compare_parameters.
	Check for overload matches with and without artificial parameters.
	Skip artificial methods.
	(compare_parameters): New function.
	* value.h (value_aggregate_elt): Add new expect_type parameter.
This commit is contained in:
Keith Seitz
2009-11-10 22:17:58 +00:00
parent 85feb311d3
commit 072bba3b0f
7 changed files with 173 additions and 15 deletions

View File

@@ -2536,8 +2536,8 @@ check_field (struct type *type, const char *name)
the comment before value_struct_elt_for_reference. */
struct value *
value_aggregate_elt (struct type *curtype,
char *name, int want_address,
value_aggregate_elt (struct type *curtype, char *name,
struct type *expect_type, int want_address,
enum noside noside)
{
switch (TYPE_CODE (curtype))
@@ -2545,7 +2545,7 @@ value_aggregate_elt (struct type *curtype,
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
return value_struct_elt_for_reference (curtype, 0, curtype,
name, NULL,
name, expect_type,
want_address, noside);
case TYPE_CODE_NAMESPACE:
return value_namespace_elt (curtype, name,
@@ -2556,6 +2556,57 @@ value_aggregate_elt (struct type *curtype,
}
}
/* Compares the two method/function types T1 and T2 for "equality"
with respect to the the methods' parameters. If the types of the
two parameter lists are the same, returns 1; 0 otherwise. This
comparison may ignore any artificial parameters in T1 if
SKIP_ARTIFICIAL is non-zero. This function will ALWAYS skip
the first artificial parameter in T1, assumed to be a 'this' pointer.
The type T2 is expected to have come from make_params (in eval.c). */
static int
compare_parameters (struct type *t1, struct type *t2, int skip_artificial)
{
int start = 0;
if (TYPE_FIELD_ARTIFICIAL (t1, 0))
++start;
/* If skipping artificial fields, find the first real field
in T1. */
if (skip_artificial)
{
while (start < TYPE_NFIELDS (t1)
&& TYPE_FIELD_ARTIFICIAL (t1, start))
++start;
}
/* Now compare parameters */
/* Special case: a method taking void. T1 will contain no
non-artificial fields, and T2 will contain TYPE_CODE_VOID. */
if ((TYPE_NFIELDS (t1) - start) == 0 && TYPE_NFIELDS (t2) == 1
&& TYPE_CODE (TYPE_FIELD_TYPE (t2, 0)) == TYPE_CODE_VOID)
return 1;
if ((TYPE_NFIELDS (t1) - start) == TYPE_NFIELDS (t2))
{
int i;
for (i = 0; i < TYPE_NFIELDS (t2); ++i)
{
if (rank_one_type (TYPE_FIELD_TYPE (t1, start + i),
TYPE_FIELD_TYPE (t2, i))
!= 0)
return 0;
}
return 1;
}
return 0;
}
/* C++: Given an aggregate type CURTYPE, and a member name NAME,
return the address of this member as a "pointer to member" type.
If INTYPE is non-null, then it will be the type of the member we
@@ -2633,23 +2684,46 @@ value_struct_elt_for_reference (struct type *domain, int offset,
}
if (t_field_name && strcmp (t_field_name, name) == 0)
{
int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
int j;
int len = TYPE_FN_FIELDLIST_LENGTH (t, i);
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
check_stub_method_group (t, i);
if (intype == 0 && j > 1)
error (_("non-unique member `%s' requires type instantiation"), name);
if (intype)
{
while (j--)
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
break;
if (j < 0)
error (_("no member function matches that type instantiation"));
}
for (j = 0; j < len; ++j)
{
if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 0)
|| compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 1))
break;
}
if (j == len)
error (_("no member function matches that type instantiation")); }
else
j = 0;
{
int ii;
/* Skip artificial methods. This is necessary if, for example,
the user wants to "print subclass::subclass" with only
one user-defined constructor. There is no ambiguity in this
case. */
for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i);
++ii)
{
if (TYPE_FN_FIELD_ARTIFICIAL (f, ii))
--len;
}
/* Desired method is ambiguous if more than one method is
defined. */
if (len > 1)
error (_("non-unique member `%s' requires type instantiation"), name);
/* This assumes, of course, that all artificial methods appear
BEFORE any concrete methods. */
j = TYPE_FN_FIELDLIST_LENGTH (t, i) - 1;
}
if (TYPE_FN_FIELD_STATIC_P (f, j))
{