Fix derived class overload problem.
2010-11-04 Sami Wagiaalla <swagiaal@redhat.com> * gdbtypes.h (struct rank): Created subrank. * gdbtypes.c: Initialized subrank for all 'BADNESS' constants. (distance_to_ancestor): New function. (is_ancestor): Use distance_to_ancestor. (is_public_ancestor): Ditto. (sum_ranks): Handle subrank. (compare_ranks): Ditto. (rank_one_type): Subrank base conversions. 2010-11-04 Sami Wagiaalla <swagiaal@redhat.com> * gdb.cp/overload.exp: Added test for inheritance overload. * gdb.cp/overload.cc: Ditto. * gdb.cp/oranking.exp: Removed releveant kfails.
This commit is contained in:
parent
6403aeeaa1
commit
a9d5ef47f3
|
@ -1,3 +1,15 @@
|
|||
2010-11-04 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdbtypes.h (struct rank): Created subrank.
|
||||
* gdbtypes.c: Initialized subrank for all
|
||||
'BADNESS' constants.
|
||||
(distance_to_ancestor): New function.
|
||||
(is_ancestor): Use distance_to_ancestor.
|
||||
(is_public_ancestor): Ditto.
|
||||
(sum_ranks): Handle subrank.
|
||||
(compare_ranks): Ditto.
|
||||
(rank_one_type): Subrank base conversions.
|
||||
|
||||
2010-11-04 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdbtypes.h: Create struct rank.
|
||||
|
|
|
@ -43,25 +43,25 @@
|
|||
|
||||
/* Initialize BADNESS constants. */
|
||||
|
||||
const struct rank LENGTH_MISMATCH_BADNESS = {100};
|
||||
const struct rank LENGTH_MISMATCH_BADNESS = {100,0};
|
||||
|
||||
const struct rank TOO_FEW_PARAMS_BADNESS = {100};
|
||||
const struct rank INCOMPATIBLE_TYPE_BADNESS = {100};
|
||||
const struct rank TOO_FEW_PARAMS_BADNESS = {100,0};
|
||||
const struct rank INCOMPATIBLE_TYPE_BADNESS = {100,0};
|
||||
|
||||
const struct rank EXACT_MATCH_BADNESS = {0};
|
||||
const struct rank EXACT_MATCH_BADNESS = {0,0};
|
||||
|
||||
const struct rank INTEGER_PROMOTION_BADNESS = {1};
|
||||
const struct rank FLOAT_PROMOTION_BADNESS = {1};
|
||||
const struct rank BASE_PTR_CONVERSION_BADNESS = {1};
|
||||
const struct rank INTEGER_CONVERSION_BADNESS = {2};
|
||||
const struct rank FLOAT_CONVERSION_BADNESS = {2};
|
||||
const struct rank INT_FLOAT_CONVERSION_BADNESS = {2};
|
||||
const struct rank VOID_PTR_CONVERSION_BADNESS = {2};
|
||||
const struct rank BOOL_PTR_CONVERSION_BADNESS = {3};
|
||||
const struct rank BASE_CONVERSION_BADNESS = {2};
|
||||
const struct rank REFERENCE_CONVERSION_BADNESS = {2};
|
||||
const struct rank INTEGER_PROMOTION_BADNESS = {1,0};
|
||||
const struct rank FLOAT_PROMOTION_BADNESS = {1,0};
|
||||
const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0};
|
||||
const struct rank INTEGER_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank FLOAT_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank BOOL_PTR_CONVERSION_BADNESS = {3,0};
|
||||
const struct rank BASE_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
|
||||
|
||||
const struct rank NS_POINTER_CONVERSION_BADNESS = {10};
|
||||
const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
|
||||
|
||||
/* Floatformat pairs. */
|
||||
const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN] = {
|
||||
|
@ -1967,32 +1967,50 @@ class_types_same_p (const struct type *a, const struct type *b)
|
|||
&& !strcmp (TYPE_NAME (a), TYPE_NAME (b))));
|
||||
}
|
||||
|
||||
/* Check whether BASE is an ancestor or base class of DCLASS
|
||||
Return 1 if so, and 0 if not. If PUBLIC is 1 then only public
|
||||
ancestors are considered, and the function returns 1 only if
|
||||
BASE is a public ancestor of DCLASS. */
|
||||
/* If BASE is an ancestor of DCLASS return the distance between them.
|
||||
otherwise return -1;
|
||||
eg:
|
||||
|
||||
class A {};
|
||||
class B: public A {};
|
||||
class C: public B {};
|
||||
class D: C {};
|
||||
|
||||
distance_to_ancestor (A, A, 0) = 0
|
||||
distance_to_ancestor (A, B, 0) = 1
|
||||
distance_to_ancestor (A, C, 0) = 2
|
||||
distance_to_ancestor (A, D, 0) = 3
|
||||
|
||||
If PUBLIC is 1 then only public ancestors are considered,
|
||||
and the function returns the distance only if BASE is a public ancestor
|
||||
of DCLASS.
|
||||
Eg:
|
||||
|
||||
distance_to_ancestor (A, D, 1) = -1 */
|
||||
|
||||
static int
|
||||
do_is_ancestor (struct type *base, struct type *dclass, int public)
|
||||
distance_to_ancestor (struct type *base, struct type *dclass, int public)
|
||||
{
|
||||
int i;
|
||||
int d;
|
||||
|
||||
CHECK_TYPEDEF (base);
|
||||
CHECK_TYPEDEF (dclass);
|
||||
|
||||
if (class_types_same_p (base, dclass))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
|
||||
{
|
||||
if (public && ! BASETYPE_VIA_PUBLIC (dclass, i))
|
||||
continue;
|
||||
|
||||
if (do_is_ancestor (base, TYPE_BASECLASS (dclass, i), public))
|
||||
return 1;
|
||||
d = distance_to_ancestor (base, TYPE_BASECLASS (dclass, i), public);
|
||||
if (d >= 0)
|
||||
return 1 + d;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether BASE is an ancestor or base class or DCLASS
|
||||
|
@ -2004,7 +2022,7 @@ do_is_ancestor (struct type *base, struct type *dclass, int public)
|
|||
int
|
||||
is_ancestor (struct type *base, struct type *dclass)
|
||||
{
|
||||
return do_is_ancestor (base, dclass, 0);
|
||||
return distance_to_ancestor (base, dclass, 0) >= 0;
|
||||
}
|
||||
|
||||
/* Like is_ancestor, but only returns true when BASE is a public
|
||||
|
@ -2013,7 +2031,7 @@ is_ancestor (struct type *base, struct type *dclass)
|
|||
int
|
||||
is_public_ancestor (struct type *base, struct type *dclass)
|
||||
{
|
||||
return do_is_ancestor (base, dclass, 1);
|
||||
return distance_to_ancestor (base, dclass, 1) >= 0;
|
||||
}
|
||||
|
||||
/* A helper function for is_unique_ancestor. */
|
||||
|
@ -2085,6 +2103,7 @@ sum_ranks (struct rank a, struct rank b)
|
|||
{
|
||||
struct rank c;
|
||||
c.rank = a.rank + b.rank;
|
||||
c.subrank = a.subrank + b.subrank;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -2097,11 +2116,19 @@ int
|
|||
compare_ranks (struct rank a, struct rank b)
|
||||
{
|
||||
if (a.rank == b.rank)
|
||||
return 0;
|
||||
{
|
||||
if (a.subrank == b.subrank)
|
||||
return 0;
|
||||
if (a.subrank < b.subrank)
|
||||
return 1;
|
||||
if (a.subrank > b.subrank)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.rank < b.rank)
|
||||
return 1;
|
||||
|
||||
/* a.rank > b.rank */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2292,6 +2319,7 @@ types_equal (struct type *a, struct type *b)
|
|||
struct rank
|
||||
rank_one_type (struct type *parm, struct type *arg)
|
||||
{
|
||||
struct rank rank = {0,0};
|
||||
|
||||
if (types_equal (parm, arg))
|
||||
return EXACT_MATCH_BADNESS;
|
||||
|
@ -2332,9 +2360,11 @@ rank_one_type (struct type *parm, struct type *arg)
|
|||
return VOID_PTR_CONVERSION_BADNESS;
|
||||
|
||||
/* (b) pointer to ancestor-pointer conversion. */
|
||||
if (is_ancestor (TYPE_TARGET_TYPE (parm),
|
||||
TYPE_TARGET_TYPE (arg)))
|
||||
return BASE_PTR_CONVERSION_BADNESS;
|
||||
rank.subrank = distance_to_ancestor (TYPE_TARGET_TYPE (parm),
|
||||
TYPE_TARGET_TYPE (arg),
|
||||
0);
|
||||
if (rank.subrank >= 0)
|
||||
return sum_ranks (BASE_PTR_CONVERSION_BADNESS, rank);
|
||||
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
case TYPE_CODE_ARRAY:
|
||||
|
@ -2573,8 +2603,9 @@ rank_one_type (struct type *parm, struct type *arg)
|
|||
{
|
||||
case TYPE_CODE_STRUCT:
|
||||
/* Check for derivation */
|
||||
if (is_ancestor (parm, arg))
|
||||
return BASE_CONVERSION_BADNESS;
|
||||
rank.subrank = distance_to_ancestor (parm, arg, 0);
|
||||
if (rank.subrank >= 0)
|
||||
return sum_ranks (BASE_CONVERSION_BADNESS, rank);
|
||||
/* else fall through */
|
||||
default:
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
|
|
|
@ -852,7 +852,15 @@ struct vbase
|
|||
/* Struct used to store conversion rankings. */
|
||||
struct rank
|
||||
{
|
||||
int rank;
|
||||
short rank;
|
||||
|
||||
/* When two conversions are of the same type and therefore have the same
|
||||
rank, subrank is used to differentiate the two.
|
||||
Eg: Two derived-class-pointer to base-class-pointer conversions would
|
||||
both have base pointer conversion rank, but the conversion with the
|
||||
shorter distance to the ancestor is preferable. 'subrank' would be used
|
||||
to reflect that. */
|
||||
short subrank;
|
||||
};
|
||||
|
||||
/* Struct used for ranking a function for overload resolution */
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2010-11-04 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdb.cp/overload.exp: Added test for inheritance overload.
|
||||
* gdb.cp/overload.cc: Ditto.
|
||||
* gdb.cp/oranking.exp: Removed releveant kfails.
|
||||
|
||||
2010-11-04 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
|
|
|
@ -58,15 +58,12 @@ gdb_test "p test6()" "28"
|
|||
gdb_test "p foo6(bp)" "28"
|
||||
|
||||
gdb_test "p test7()" "210"
|
||||
setup_kfail "gdb/10343" *-*-*
|
||||
gdb_test "p foo7(cp)" "210"
|
||||
|
||||
gdb_test "p test8()" "212"
|
||||
setup_kfail "gdb/10343" *-*-*
|
||||
gdb_test "p foo8(co)" "212"
|
||||
|
||||
gdb_test "p test9()" "214"
|
||||
setup_kfail "gdb/12098" *-*-*
|
||||
gdb_test "p foo9(co)" "214"
|
||||
|
||||
gdb_test "p test10()" "216"
|
||||
|
|
|
@ -89,6 +89,14 @@ namespace XXX {
|
|||
void marker2() {}
|
||||
}
|
||||
|
||||
class A {};
|
||||
class B: public A {};
|
||||
class C: public B {};
|
||||
class D: C {};
|
||||
|
||||
int bar (A) { return 11; }
|
||||
int bar (B) { return 22; }
|
||||
|
||||
int main ()
|
||||
{
|
||||
char arg2 = 2;
|
||||
|
@ -105,6 +113,15 @@ int main ()
|
|||
int arg13 = 200.0;
|
||||
char arg14 = 'a';
|
||||
|
||||
A a;
|
||||
B b;
|
||||
C c;
|
||||
D d;
|
||||
|
||||
bar (a);
|
||||
bar (b);
|
||||
bar (c);
|
||||
|
||||
char *str = (char *) "A";
|
||||
foo foo_instance1(111);
|
||||
foo foo_instance2(222, str);
|
||||
|
@ -132,6 +149,7 @@ int main ()
|
|||
|
||||
marker1(); // marker1-returns-here
|
||||
XXX::marker2(); // marker1-returns-here
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,11 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
|
|||
"\\$\[0-9\]+ = 14" \
|
||||
"print call overloaded func char\\* arg"
|
||||
|
||||
gdb_test "print bar(a)" "= 11"
|
||||
gdb_test "print bar(b)" "= 22"
|
||||
gdb_test "print bar(c)" "= 22"
|
||||
gdb_test "print bar(d)" "= 22"
|
||||
|
||||
# ---
|
||||
|
||||
# List overloaded functions.
|
||||
|
|
Loading…
Reference in New Issue