This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch 1/2] Overload resolution among children of a common ancestor


Revised patch attached.

Sami>   /* Badness if parameter list length doesn't match arg list length */
Sami>  -#define LENGTH_MISMATCH_BADNESS      100
Sami>  +static const struct rank LENGTH_MISMATCH_BADNESS = {100};

Instead of defining a static instance in the header, define a single
instance with a different (not upper-case) name in a .c file, put an
extern declaration in the header, and then make the #define refer to it.


Hmm.. is it cool if I just declare the constants 'extern const' in the header and then define them in gdbtypes.c, without #defines ? As in the attached patch.
Create and use struct rank.

2010-10-18  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.

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index d08dbfe..bfeae90 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -41,6 +41,28 @@
 #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,
@@ -2012,6 +2034,32 @@ is_unique_ancestor (struct type *base, struct value *val)
 
 
 
+/* 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 */
 
@@ -2036,7 +2084,7 @@ compare_badness (struct badness_vector *a, struct badness_vector *b)
   /* 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)
@@ -2084,7 +2132,9 @@ rank_function (struct type **parms, int nparms,
      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++)
@@ -2195,12 +2245,12 @@ types_equal (struct type *a, struct type *b)
  * 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)
@@ -2211,11 +2261,11 @@ rank_one_type (struct type *parm, struct type *arg)
   /* 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, 
@@ -2246,7 +2296,7 @@ rank_one_type (struct type *parm, struct type *arg)
 	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);
@@ -2289,7 +2339,7 @@ rank_one_type (struct type *parm, struct type *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;
 		}
@@ -2301,7 +2351,7 @@ rank_one_type (struct type *parm, struct type *arg)
 			 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),
@@ -2325,7 +2375,7 @@ rank_one_type (struct type *parm, struct type *arg)
 		{
 		  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), 
@@ -2391,19 +2441,19 @@ rank_one_type (struct type *parm, struct type *arg)
 	  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:
@@ -2437,7 +2487,7 @@ rank_one_type (struct type *parm, struct type *arg)
 	case TYPE_CODE_PTR:
 	  return BOOL_PTR_CONVERSION_BADNESS;
 	case TYPE_CODE_BOOL:
-	  return 0;
+	  return EXACT_MATCH_BADNESS;
 	default:
 	  return INCOMPATIBLE_TYPE_BADNESS;
 	}
@@ -2449,7 +2499,7 @@ rank_one_type (struct type *parm, struct type *arg)
 	  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:
@@ -2468,7 +2518,7 @@ rank_one_type (struct type *parm, struct type *arg)
 	case TYPE_CODE_FLT:
 	  return FLOAT_PROMOTION_BADNESS;
 	case TYPE_CODE_COMPLEX:
-	  return 0;
+	  return EXACT_MATCH_BADNESS;
 	default:
 	  return INCOMPATIBLE_TYPE_BADNESS;
 	}
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 5617a1d..917938a 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -849,11 +849,17 @@ struct vbase
     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.  */
@@ -1396,45 +1402,52 @@ extern int is_unique_ancestor (struct type *, struct value *);
 #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);
 
diff --git a/gdb/valops.c b/gdb/valops.c
index fe4576e..eb0bb7d 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2884,7 +2884,7 @@ find_oload_champ (struct type **arg_types, int nargs, int method,
 	  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);
@@ -2918,9 +2918,15 @@ classify_oload_match (struct badness_vector *oload_champ_bv,
 
   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.  */
     }
@@ -3056,9 +3062,9 @@ compare_parameters (struct type *t1, struct type *t2, int skip_artificial)
 
       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;
 	}
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]