compiler/resolution/functionResolution.cpp
//
// returns true if dispatching from actualType to formalType results
// in a compile-time coercion; this is a subset of canCoerce below.
//
returns true if dispatching from actualType to formalType results
in a compile-time coercion; this is a subset of canCoerce below.
returns true if dispatching from actualType to formalType results in a compile - time coercion ; this is a subset of canCoerce below .
static bool canParamCoerce(Type*   actualType,
                           Symbol* actualSym,
                           Type*   formalType,
                           bool*   paramNarrows) {
  if (is_bool_type(formalType) && is_bool_type(actualType)) {
    return true;
  }
  if (is_int_type(formalType)) {
    if (is_bool_type(actualType)) {
      return true;
    }
    if (is_int_type(actualType) &&
        get_width(actualType) < get_width(formalType)) {
      return true;
    }
    if (is_uint_type(actualType) &&
        get_width(actualType) < get_width(formalType)) {
      return true;
    }
     For smaller integer types, if the argument is a param, does it
     store a value that's small enough that it could dispatch to
     this argument?
    if (get_width(formalType) < 64) {
      if (VarSymbol* var = toVarSymbol(actualSym)) {
        if (var->immediate) {
          if (fits_in_int(get_width(formalType), var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
      }
    }
  }
  if (is_uint_type(formalType)) {
    if (is_bool_type(actualType)) {
      return true;
    }
    if (is_uint_type(actualType) &&
        get_width(actualType) < get_width(formalType)) {
      return true;
    }
    if (VarSymbol* var = toVarSymbol(actualSym)) {
      if (var->immediate) {
        if (fits_in_uint(get_width(formalType), var->immediate)) {
          *paramNarrows = true;
          return true;
        }
      }
    }
     For smaller integer types, if the argument is a param, does it
     store a value that's small enough that it could dispatch to
     this argument?
    if (get_width(formalType) < 64) {
      if (VarSymbol* var = toVarSymbol(actualSym)) {
        if (var->immediate) {
          if (fits_in_uint(get_width(formalType), var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
      }
    }
  }
   param strings can coerce between string and c_string
  if ((formalType == dtString || formalType == dtStringC) &&
      (actualType == dtString || actualType == dtStringC)) {
    if (actualSym && actualSym->isImmediate()) {
      return true;
    }
  }
   coerce fully representable integers into real / real part of complex
  if (is_real_type(formalType)) {
    int mantissa_width = get_mantissa_width(formalType);
     don't coerce bools to reals (per spec: "unintended by programmer")
     coerce any integer type to maximum width real
    if ((is_int_type(actualType) || is_uint_type(actualType))
        && get_width(formalType) >= 64)
      return true;
     coerce integer types that are exactly representable
    if (is_int_type(actualType) &&
        get_width(actualType) < mantissa_width)
      return true;
    if (is_uint_type(actualType) &&
        get_width(actualType) < mantissa_width)
      return true;
     coerce real from smaller size
    if (is_real_type(actualType) &&
        get_width(actualType) < get_width(formalType))
      return true;
     coerce literal/param ints that are exactly representable
    if (VarSymbol* var = toVarSymbol(actualSym)) {
      if (var->immediate) {
        if (is_int_type(actualType) || is_uint_type(actualType)) {
          if (fits_in_mantissa(mantissa_width, var->immediate)) {
              *paramNarrows = true;
              return true;
          }
        }
        if (is_real_type(actualType)) {
          if (fits_in_mantissa_exponent(mantissa_width,
                                        get_exponent_width(formalType),
                                        var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
      }
    }
  }
  if (is_complex_type(formalType)) {
    int mantissa_width = get_mantissa_width(formalType);
     don't coerce bools to complexes (per spec: "unintended by programmer")
     coerce any integer type to maximum width complex
    if ((is_int_type(actualType) || is_uint_type(actualType)) &&
        get_width(formalType) >= 128)
      return true;
     coerce integer types that are exactly representable
    if (is_int_type(actualType) &&
        get_width(actualType) < mantissa_width)
      return true;
    if (is_uint_type(actualType) &&
        get_width(actualType) < mantissa_width)
      return true;
     coerce real/imag from smaller size
    if (is_real_type(actualType) &&
        get_width(actualType) <= get_width(formalType)/2)
      return true;
    if (is_imag_type(actualType) &&
        get_width(actualType) <= get_width(formalType)/2)
      return true;
     coerce smaller complex types
    if (is_complex_type(actualType) &&
        (get_width(actualType) < get_width(formalType)))
      return true;
     coerce literal/param complexes that are exactly representable
    if (VarSymbol* var = toVarSymbol(actualSym)) {
      if (var->immediate) {
        if (is_int_type(actualType) || is_uint_type(actualType)) {
          if (fits_in_mantissa(mantissa_width, var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
        if (is_real_type(actualType)) {
          if (fits_in_mantissa_exponent(mantissa_width,
                                        get_exponent_width(formalType),
                                        var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
        if (is_imag_type(actualType)) {
          if (fits_in_mantissa_exponent(mantissa_width,
                                        get_exponent_width(formalType),
                                        var->immediate)) {
            *paramNarrows = true;
            return true;
          }
        }
        if (is_complex_type(actualType)) {
          bool rePartFits = fits_in_mantissa_exponent(mantissa_width,
                                                      get_exponent_width(formalType),
                                                      var->immediate,
                                                      true);
          bool imPartFits = fits_in_mantissa_exponent(mantissa_width,
                                                      get_exponent_width(formalType),
                                                      var->immediate,
                                                      false);
          if (rePartFits && imPartFits) {
            *paramNarrows = true;
            return true;
          }
        }
      }
    }
  }
  return false;
}
static bool canParamCoerce ( Type * actualType , Symbol * actualSym , Type * formalType , bool * paramNarrows ) { if ( is_bool_type ( formalType ) && is_bool_type ( actualType ) ) { return true ; } if ( is_int_type ( formalType ) ) { if ( is_bool_type ( actualType ) ) { return true ; } if ( is_int_type ( actualType ) && get_width ( actualType ) < get_width ( formalType ) ) { return true ; } if ( is_uint_type ( actualType ) && get_width ( actualType ) < get_width ( formalType ) ) { return true ; } if ( get_width ( formalType ) < 64 ) { if ( VarSymbol * var = toVarSymbol ( actualSym ) ) { if ( var -> immediate ) { if ( fits_in_int ( get_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } } } } if ( is_uint_type ( formalType ) ) { if ( is_bool_type ( actualType ) ) { return true ; } if ( is_uint_type ( actualType ) && get_width ( actualType ) < get_width ( formalType ) ) { return true ; } if ( VarSymbol * var = toVarSymbol ( actualSym ) ) { if ( var -> immediate ) { if ( fits_in_uint ( get_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } } if ( get_width ( formalType ) < 64 ) { if ( VarSymbol * var = toVarSymbol ( actualSym ) ) { if ( var -> immediate ) { if ( fits_in_uint ( get_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } } } } if ( ( formalType == dtString || formalType == dtStringC ) && ( actualType == dtString || actualType == dtStringC ) ) { if ( actualSym && actualSym -> isImmediate ( ) ) { return true ; } } if ( is_real_type ( formalType ) ) { int mantissa_width = get_mantissa_width ( formalType ) ; if ( ( is_int_type ( actualType ) || is_uint_type ( actualType ) ) && get_width ( formalType ) >= 64 ) return true ; if ( is_int_type ( actualType ) && get_width ( actualType ) < mantissa_width ) return true ; if ( is_uint_type ( actualType ) && get_width ( actualType ) < mantissa_width ) return true ; if ( is_real_type ( actualType ) && get_width ( actualType ) < get_width ( formalType ) ) return true ; if ( VarSymbol * var = toVarSymbol ( actualSym ) ) { if ( var -> immediate ) { if ( is_int_type ( actualType ) || is_uint_type ( actualType ) ) { if ( fits_in_mantissa ( mantissa_width , var -> immediate ) ) { * paramNarrows = true ; return true ; } } if ( is_real_type ( actualType ) ) { if ( fits_in_mantissa_exponent ( mantissa_width , get_exponent_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } } } } if ( is_complex_type ( formalType ) ) { int mantissa_width = get_mantissa_width ( formalType ) ; if ( ( is_int_type ( actualType ) || is_uint_type ( actualType ) ) && get_width ( formalType ) >= 128 ) return true ; if ( is_int_type ( actualType ) && get_width ( actualType ) < mantissa_width ) return true ; if ( is_uint_type ( actualType ) && get_width ( actualType ) < mantissa_width ) return true ; if ( is_real_type ( actualType ) && get_width ( actualType ) <= get_width ( formalType ) / 2 ) return true ; if ( is_imag_type ( actualType ) && get_width ( actualType ) <= get_width ( formalType ) / 2 ) return true ; if ( is_complex_type ( actualType ) && ( get_width ( actualType ) < get_width ( formalType ) ) ) return true ; if ( VarSymbol * var = toVarSymbol ( actualSym ) ) { if ( var -> immediate ) { if ( is_int_type ( actualType ) || is_uint_type ( actualType ) ) { if ( fits_in_mantissa ( mantissa_width , var -> immediate ) ) { * paramNarrows = true ; return true ; } } if ( is_real_type ( actualType ) ) { if ( fits_in_mantissa_exponent ( mantissa_width , get_exponent_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } if ( is_imag_type ( actualType ) ) { if ( fits_in_mantissa_exponent ( mantissa_width , get_exponent_width ( formalType ) , var -> immediate ) ) { * paramNarrows = true ; return true ; } } if ( is_complex_type ( actualType ) ) { bool rePartFits = fits_in_mantissa_exponent ( mantissa_width , get_exponent_width ( formalType ) , var -> immediate , true ) ; bool imPartFits = fits_in_mantissa_exponent ( mantissa_width , get_exponent_width ( formalType ) , var -> immediate , false ) ; if ( rePartFits && imPartFits ) { * paramNarrows = true ; return true ; } } } } } return false ; }
returns true if dispatching from actualType to formalType results
in a compile-time coercion; this is a subset of canCoerce below.
returns true if dispatching from actualType to formalType results in a compile - time coercion ; this is a subset of canCoerce below .
// // For smaller integer types, if the argument is a param, does it // store a value that's small enough that it could dispatch to // this argument? // // // For smaller integer types, if the argument is a param, does it // store a value that's small enough that it could dispatch to // this argument? // // param strings can coerce between string and c_string // coerce fully representable integers into real / real part of complex // don't coerce bools to reals (per spec: "unintended by programmer") // coerce any integer type to maximum width real // coerce integer types that are exactly representable // coerce real from smaller size // coerce literal/param ints that are exactly representable // don't coerce bools to complexes (per spec: "unintended by programmer") // coerce any integer type to maximum width complex // coerce integer types that are exactly representable // coerce real/imag from smaller size // coerce smaller complex types // coerce literal/param complexes that are exactly representable