// Perform the usual arithmetic conversions on `e1` and `e2`. This // tries to find a common type for `e1` and `e2` and convert both // expressions to that type. // // NOTE: In C++ lvalue-to-rvalue conversions are required on a // per-expression basis, independently of converting to a common // type. Also, non-user-defined types are unqualified prior to // analysis. It would be easier if we found an absolute common // type and then instantiated a declaration suitable for overload // resolution. Maybe. // // TODO: Handle conversions for character types (or promote to a // corresponding integer type?). // // TODO: How does bool work with this set of conversions? Promote // bool to int? // // TODO: Can we unify this with the common type required by the // conditional expression? Note that the arithmetic version converts // to values, and the conditional expression can retain references. Expr_pair arithmetic_conversions(Context& cxt, Expr& e1, Expr& e2) { // If the types are the same, no conversions are applied. if (is_equivalent(e1.type(), e2.type())) return {e1, e2}; // If either operand has floating point type, convert to the type // with the greatest precision. // // TODO: Why isn't convert_to_common_float symmetric? This seems like // an issue. if (has_floating_point_type(e1)) return convert_to_common_float(cxt, e2, e1); if (has_floating_point_type(e2)) return convert_to_common_float(cxt, e1, e2); // If both operands have integer type, the following rules apply. if (has_integer_type(e1) && has_integer_type(e2)) return convert_to_common_int(cxt, e1, e2); // TODO: No conversion from e1 to e2. error(cxt, "no usual arithmetic conversion of '{}' and '{}'", e1, e2); throw Type_error(); }
// Perform the usual arithmetic conversions on `e1` and `e2`. This // tries to find a common type for `e1` and `e2` and convert both // expressions to that type. // // NOTE: In C++ lvalue-to-rvalue conversions are required on a // per-expression basis, independently of converting to a common // type. Also, non-user-defined types are unqualified prior to // analysis. It would be easier if we found an absolute common // type and then instantiated a declaration suitable for overload // resolution. Maybe. // // TODO: Handle conversions for character types (or promote to a // corresponding integer type?). // // TODO: How does bool work with this set of conversions? Promote // bool to int? // // TODO: Can we unify this with the common type required by the // conditional expression? Note that the arithmetic version converts // to values, and the conditional expression can retain references. Expr_pair arithmetic_conversion(Expr& e1, Expr& e2) { // If the types are the same, no conversions are applied. if (is_equivalent(e1.type(), e2.type())) return {e1, e2}; // If either operand has floating point type, convert to the type // with the greatest precision. if (has_floating_point_type(e1)) return convert_to_common_float(e2, e1); if (has_floating_point_type(e2)) return convert_to_common_float(e1, e2); // If both oerands have integer type, the following rules apply. if (has_integer_type(e1) && has_integer_type(e2)) return convert_to_common_int(e1, e2); // TODO: No conversion from e1 to e2. throw std::runtime_error("incompatible types"); }