+2010-11-04 Sami Wagiaalla <swagiaal@redhat.com>
+
+ * gdbtypes.h: Create struct rank.
+ Convert all 'BADNESS' macros to const struct rank declarations.
+ (sum_ranks): New function.
+ (compare_ranks): New function.
+ * valops.c (find_oload_champ): Updated.
+ (classify_oload_match): Use compare_ranks.
+ Improved comments.
+ (compare_parameters): Use compare_ranks.
+ * gdbtypes.c: Initialize 'BADNESS' constants.
+ (sum_ranks): New function.
+ (compare_ranks): New function.
+ (compare_badness): Use compare_ranks.
+ (rank_function): Use global constants instead of literals.
+ (rank_one_type): Ditto.
+ Return struct rank.
+ Use sum_ranks.
+
2010-11-04 Doug Evans <dje@google.com>
* python/py-prettyprint.c (find_pretty_printer_from_gdb): Fix comment.
#include "hashtab.h"
+/* Initialize BADNESS constants. */
+
+const struct rank LENGTH_MISMATCH_BADNESS = {100};
+
+const struct rank TOO_FEW_PARAMS_BADNESS = {100};
+const struct rank INCOMPATIBLE_TYPE_BADNESS = {100};
+
+const struct rank EXACT_MATCH_BADNESS = {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 NS_POINTER_CONVERSION_BADNESS = {10};
+
/* Floatformat pairs. */
const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN] = {
&floatformat_ieee_half_big,
\f
+/* Return the sum of the rank of A with the rank of B. */
+
+struct rank
+sum_ranks (struct rank a, struct rank b)
+{
+ struct rank c;
+ c.rank = a.rank + b.rank;
+ return c;
+}
+
+/* Compare rank A and B and return:
+ 0 if a = b
+ 1 if a is better than b
+ -1 if b is better than a. */
+
+int
+compare_ranks (struct rank a, struct rank b)
+{
+ if (a.rank == b.rank)
+ return 0;
+
+ if (a.rank < b.rank)
+ return 1;
+
+ return -1;
+}
/* Functions for overload resolution begin here */
/* Subtract b from a */
for (i = 0; i < a->length; i++)
{
- tmp = a->rank[i] - b->rank[i];
+ tmp = compare_ranks (b->rank[i], a->rank[i]);
if (tmp > 0)
found_pos = 1;
else if (tmp < 0)
arguments and ellipsis parameter lists, we should consider those
and rank the length-match more finely. */
- LENGTH_MATCH (bv) = (nargs != nparms) ? LENGTH_MISMATCH_BADNESS : 0;
+ LENGTH_MATCH (bv) = (nargs != nparms)
+ ? LENGTH_MISMATCH_BADNESS
+ : EXACT_MATCH_BADNESS;
/* Now rank all the parameters of the candidate function */
for (i = 1; i <= min_len; i++)
* PARM is to ARG. The higher the return value, the worse the match.
* Generally the "bad" conversions are all uniformly assigned a 100. */
-int
+struct rank
rank_one_type (struct type *parm, struct type *arg)
{
if (types_equal (parm, arg))
- return 0;
+ return EXACT_MATCH_BADNESS;
/* Resolve typedefs */
if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
/* See through references, since we can almost make non-references
references. */
if (TYPE_CODE (arg) == TYPE_CODE_REF)
- return (rank_one_type (parm, TYPE_TARGET_TYPE (arg))
- + REFERENCE_CONVERSION_BADNESS);
+ return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg)),
+ REFERENCE_CONVERSION_BADNESS));
if (TYPE_CODE (parm) == TYPE_CODE_REF)
- return (rank_one_type (TYPE_TARGET_TYPE (parm), arg)
- + REFERENCE_CONVERSION_BADNESS);
+ return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg),
+ REFERENCE_CONVERSION_BADNESS));
if (overload_debug)
/* Debugging only. */
fprintf_filtered (gdb_stderr,
case TYPE_CODE_ARRAY:
if (types_equal (TYPE_TARGET_TYPE (parm),
TYPE_TARGET_TYPE (arg)))
- return 0;
+ return EXACT_MATCH_BADNESS;
return INCOMPATIBLE_TYPE_BADNESS;
case TYPE_CODE_FUNC:
return rank_one_type (TYPE_TARGET_TYPE (parm), arg);
{
/* This case only for character types */
if (TYPE_NOSIGN (arg))
- return 0; /* plain char -> plain char */
+ return EXACT_MATCH_BADNESS; /* plain char -> plain char */
else /* signed/unsigned char -> plain char */
return INTEGER_CONVERSION_BADNESS;
}
unsigned long -> unsigned long */
if (integer_types_same_name_p (TYPE_NAME (parm),
TYPE_NAME (arg)))
- return 0;
+ return EXACT_MATCH_BADNESS;
else if (integer_types_same_name_p (TYPE_NAME (arg),
"int")
&& integer_types_same_name_p (TYPE_NAME (parm),
{
if (integer_types_same_name_p (TYPE_NAME (parm),
TYPE_NAME (arg)))
- return 0;
+ return EXACT_MATCH_BADNESS;
else if (integer_types_same_name_p (TYPE_NAME (arg),
"int")
&& integer_types_same_name_p (TYPE_NAME (parm),
if (TYPE_NOSIGN (parm))
{
if (TYPE_NOSIGN (arg))
- return 0;
+ return EXACT_MATCH_BADNESS;
else
return INTEGER_CONVERSION_BADNESS;
}
else if (TYPE_UNSIGNED (parm))
{
if (TYPE_UNSIGNED (arg))
- return 0;
+ return EXACT_MATCH_BADNESS;
else
return INTEGER_PROMOTION_BADNESS;
}
else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
- return 0;
+ return EXACT_MATCH_BADNESS;
else
return INTEGER_CONVERSION_BADNESS;
default:
case TYPE_CODE_PTR:
return BOOL_PTR_CONVERSION_BADNESS;
case TYPE_CODE_BOOL:
- return 0;
+ return EXACT_MATCH_BADNESS;
default:
return INCOMPATIBLE_TYPE_BADNESS;
}
if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
return FLOAT_PROMOTION_BADNESS;
else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
- return 0;
+ return EXACT_MATCH_BADNESS;
else
return FLOAT_CONVERSION_BADNESS;
case TYPE_CODE_INT:
case TYPE_CODE_FLT:
return FLOAT_PROMOTION_BADNESS;
case TYPE_CODE_COMPLEX:
- return 0;
+ return EXACT_MATCH_BADNESS;
default:
return INCOMPATIBLE_TYPE_BADNESS;
}
struct vbase *next; /* next in chain */
};
+/* Struct used to store conversion rankings. */
+struct rank
+ {
+ int rank;
+ };
+
/* Struct used for ranking a function for overload resolution */
struct badness_vector
{
int length;
- int *rank;
+ struct rank *rank;
};
/* GNAT Ada-specific information for various Ada types. */
#define LENGTH_MATCH(bv) ((bv)->rank[0])
/* Badness if parameter list length doesn't match arg list length */
-#define LENGTH_MISMATCH_BADNESS 100
+extern const struct rank LENGTH_MISMATCH_BADNESS;
+
/* Dummy badness value for nonexistent parameter positions */
-#define TOO_FEW_PARAMS_BADNESS 100
+extern const struct rank TOO_FEW_PARAMS_BADNESS;
/* Badness if no conversion among types */
-#define INCOMPATIBLE_TYPE_BADNESS 100
+extern const struct rank INCOMPATIBLE_TYPE_BADNESS;
+
+/* Badness of an exact match. */
+extern const struct rank EXACT_MATCH_BADNESS;
/* Badness of integral promotion */
-#define INTEGER_PROMOTION_BADNESS 1
+extern const struct rank INTEGER_PROMOTION_BADNESS;
/* Badness of floating promotion */
-#define FLOAT_PROMOTION_BADNESS 1
+extern const struct rank FLOAT_PROMOTION_BADNESS;
/* Badness of converting a derived class pointer
to a base class pointer. */
-#define BASE_PTR_CONVERSION_BADNESS 1
+extern const struct rank BASE_PTR_CONVERSION_BADNESS;
/* Badness of integral conversion */
-#define INTEGER_CONVERSION_BADNESS 2
+extern const struct rank INTEGER_CONVERSION_BADNESS;
/* Badness of floating conversion */
-#define FLOAT_CONVERSION_BADNESS 2
+extern const struct rank FLOAT_CONVERSION_BADNESS;
/* Badness of integer<->floating conversions */
-#define INT_FLOAT_CONVERSION_BADNESS 2
+extern const struct rank INT_FLOAT_CONVERSION_BADNESS;
/* Badness of conversion of pointer to void pointer */
-#define VOID_PTR_CONVERSION_BADNESS 2
+extern const struct rank VOID_PTR_CONVERSION_BADNESS;
/* Badness of conversion of pointer to boolean. */
-#define BOOL_PTR_CONVERSION_BADNESS 3
+extern const struct rank BOOL_PTR_CONVERSION_BADNESS;
/* Badness of converting derived to base class */
-#define BASE_CONVERSION_BADNESS 2
+extern const struct rank BASE_CONVERSION_BADNESS;
/* Badness of converting from non-reference to reference */
-#define REFERENCE_CONVERSION_BADNESS 2
+extern const struct rank REFERENCE_CONVERSION_BADNESS;
/* Non-standard conversions allowed by the debugger */
/* Converting a pointer to an int is usually OK */
-#define NS_POINTER_CONVERSION_BADNESS 10
+extern const struct rank NS_POINTER_CONVERSION_BADNESS;
+
+extern struct rank sum_ranks (struct rank a, struct rank b);
+extern int compare_ranks (struct rank a, struct rank b);
extern int compare_badness (struct badness_vector *, struct badness_vector *);
extern struct badness_vector *rank_function (struct type **, int,
struct type **, int);
-extern int rank_one_type (struct type *, struct type *);
+extern struct rank rank_one_type (struct type *, struct type *);
extern void recursive_dump_type (struct type *, int);
for (jj = 0; jj < nargs - static_offset; jj++)
fprintf_filtered (gdb_stderr,
"...Badness @ %d : %d\n",
- jj, bv->rank[jj]);
+ jj, bv->rank[jj].rank);
fprintf_filtered (gdb_stderr,
"Overload resolution champion is %d, ambiguous? %d\n",
oload_champ, oload_ambiguous);
for (ix = 1; ix <= nargs - static_offset; ix++)
{
- if (oload_champ_bv->rank[ix] >= 100)
+ /* If this conversion is as bad as INCOMPATIBLE_TYPE_BADNESS
+ or worse return INCOMPATIBLE. */
+ if (compare_ranks (oload_champ_bv->rank[ix],
+ INCOMPATIBLE_TYPE_BADNESS) <= 0)
return INCOMPATIBLE; /* Truly mismatched types. */
- else if (oload_champ_bv->rank[ix] >= 10)
+ /* Otherwise If this conversion is as bad as
+ NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD. */
+ else if (compare_ranks (oload_champ_bv->rank[ix],
+ NS_POINTER_CONVERSION_BADNESS) <= 0)
return NON_STANDARD; /* Non-standard type conversions
needed. */
}
for (i = 0; i < TYPE_NFIELDS (t2); ++i)
{
- if (rank_one_type (TYPE_FIELD_TYPE (t1, start + i),
- TYPE_FIELD_TYPE (t2, i))
- != 0)
+ if (compare_ranks (rank_one_type (TYPE_FIELD_TYPE (t1, start + i),
+ TYPE_FIELD_TYPE (t2, i)),
+ EXACT_MATCH_BADNESS) != 0)
return 0;
}