+/* rank_one_type helper for when PARM's type code is TYPE_CODE_RANGE. */
+
+static struct rank
+rank_one_type_parm_range (struct type *parm, struct type *arg, struct value *value)
+{
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ return INTEGER_CONVERSION_BADNESS;
+ case TYPE_CODE_FLT:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_BOOL. */
+
+static struct rank
+rank_one_type_parm_bool (struct type *parm, struct type *arg, struct value *value)
+{
+ switch (TYPE_CODE (arg))
+ {
+ /* n3290 draft, section 4.12.1 (conv.bool):
+
+ "A prvalue of arithmetic, unscoped enumeration, pointer, or
+ pointer to member type can be converted to a prvalue of type
+ bool. A zero value, null pointer value, or null member pointer
+ value is converted to false; any other value is converted to
+ true. A prvalue of type std::nullptr_t can be converted to a
+ prvalue of type bool; the resulting value is false." */
+ case TYPE_CODE_INT:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_MEMBERPTR:
+ case TYPE_CODE_PTR:
+ return BOOL_CONVERSION_BADNESS;
+ case TYPE_CODE_RANGE:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ case TYPE_CODE_BOOL:
+ return EXACT_MATCH_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_FLOAT. */
+
+static struct rank
+rank_one_type_parm_float (struct type *parm, struct type *arg, struct value *value)
+{
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_FLT:
+ if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
+ return FLOAT_PROMOTION_BADNESS;
+ else if (TYPE_LENGTH (arg) == TYPE_LENGTH (parm))
+ return EXACT_MATCH_BADNESS;
+ else
+ return FLOAT_CONVERSION_BADNESS;
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_CHAR:
+ return INT_FLOAT_CONVERSION_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_COMPLEX. */
+
+static struct rank
+rank_one_type_parm_complex (struct type *parm, struct type *arg, struct value *value)
+{
+ switch (TYPE_CODE (arg))
+ { /* Strictly not needed for C++, but... */
+ case TYPE_CODE_FLT:
+ return FLOAT_PROMOTION_BADNESS;
+ case TYPE_CODE_COMPLEX:
+ return EXACT_MATCH_BADNESS;
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_STRUCT. */
+
+static struct rank
+rank_one_type_parm_struct (struct type *parm, struct type *arg, struct value *value)
+{
+ struct rank rank = {0, 0};
+
+ switch (TYPE_CODE (arg))
+ {
+ case TYPE_CODE_STRUCT:
+ /* Check for derivation */
+ rank.subrank = distance_to_ancestor (parm, arg, 0);
+ if (rank.subrank >= 0)
+ return sum_ranks (BASE_CONVERSION_BADNESS, rank);
+ /* fall through */
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+
+/* rank_one_type helper for when PARM's type code is TYPE_CODE_SET. */
+
+static struct rank
+rank_one_type_parm_set (struct type *parm, struct type *arg, struct value *value)
+{
+ switch (TYPE_CODE (arg))
+ {
+ /* Not in C++ */
+ case TYPE_CODE_SET:
+ return rank_one_type (TYPE_FIELD_TYPE (parm, 0),
+ TYPE_FIELD_TYPE (arg, 0), NULL);
+ default:
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
+}
+