FreeBSD/contrib/gcc/cp/cvt.c
/* Convert the given EXPR to one of a group of types suitable for use in an
   expression.  DESIRES is a combination of various WANT_* flags (q.v.)
   which indicates which types are suitable.  If COMPLAIN is true, complain
   about ambiguity; otherwise, the caller will deal with it.  */
Convert the given EXPR to one of a group of types suitable for use in an
expression.  DESIRES is a combination of various WANT_* flags (q.v.)
which indicates which types are suitable.  If COMPLAIN is true, complain
about ambiguity; otherwise, the caller will deal with it.
Convert the given EXPR to one of a group of types suitable for use in an expression . DESIRES is a combination of various WANT_ * flags ( q . v . ) which indicates which types are suitable . If COMPLAIN is true complain about ambiguity ; otherwise the caller will deal with it .
tree
build_expr_type_conversion (int desires, tree expr, bool complain)
{
  tree basetype = TREE_TYPE (expr);
  tree conv = NULL_TREE;
  tree winner = NULL_TREE;
  if (expr == null_node
      && (desires & WANT_INT)
      && !(desires & WANT_NULL))
    warning (OPT_Wconversion, "converting NULL to non-pointer type");
  basetype = TREE_TYPE (expr);
  if (basetype == error_mark_node)
    return error_mark_node;
  if (! IS_AGGR_TYPE (basetype))
    switch (TREE_CODE (basetype))
      {
      case INTEGER_TYPE:
	if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
	  return expr;
      case BOOLEAN_TYPE:
	return (desires & WANT_INT) ? expr : NULL_TREE;
      case ENUMERAL_TYPE:
	return (desires & WANT_ENUM) ? expr : NULL_TREE;
      case REAL_TYPE:
	return (desires & WANT_FLOAT) ? expr : NULL_TREE;
      case POINTER_TYPE:
	return (desires & WANT_POINTER) ? expr : NULL_TREE;
      case FUNCTION_TYPE:
      case ARRAY_TYPE:
	return (desires & WANT_POINTER) ? decay_conversion (expr)
					: NULL_TREE;
      case VECTOR_TYPE:
	if ((desires & WANT_VECTOR) == 0)
	  return NULL_TREE;
	switch (TREE_CODE (TREE_TYPE (basetype)))
	  {
	  case INTEGER_TYPE:
	  case BOOLEAN_TYPE:
	    return (desires & WANT_INT) ? expr : NULL_TREE;
	  case ENUMERAL_TYPE:
	    return (desires & WANT_ENUM) ? expr : NULL_TREE;
	  case REAL_TYPE:
	    return (desires & WANT_FLOAT) ? expr : NULL_TREE;
	  default:
	    return NULL_TREE;
	  }
      default:
	return NULL_TREE;
      }
  if (!complete_type_or_else (basetype, expr))
    return error_mark_node;
  if (!TYPE_HAS_CONVERSION (basetype))
    return NULL_TREE;
  for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
    {
      int win = 0;
      tree candidate;
      tree cand = TREE_VALUE (conv);
      if (winner && winner == cand)
	continue;
      candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
      switch (TREE_CODE (candidate))
	{
	case BOOLEAN_TYPE:
	case INTEGER_TYPE:
	  win = (desires & WANT_INT); break;
	case ENUMERAL_TYPE:
	  win = (desires & WANT_ENUM); break;
	case REAL_TYPE:
	  win = (desires & WANT_FLOAT); break;
	case POINTER_TYPE:
	  win = (desires & WANT_POINTER); break;
	case VECTOR_TYPE:
	  if ((desires & WANT_VECTOR) == 0)
	    break;
	  switch (TREE_CODE (TREE_TYPE (candidate)))
	    {
	    case BOOLEAN_TYPE:
	    case INTEGER_TYPE:
	      win = (desires & WANT_INT); break;
	    case ENUMERAL_TYPE:
	      win = (desires & WANT_ENUM); break;
	    case REAL_TYPE:
	      win = (desires & WANT_FLOAT); break;
	    default:
	      break;
	    }
	  break;
	default:
	  break;
	}
      if (win)
	{
	  if (winner)
	    {
	      if (complain)
		{
		  error ("ambiguous default type conversion from %qT",
			 basetype);
		  error ("  candidate conversions include %qD and %qD",
			 winner, cand);
		}
	      return error_mark_node;
	    }
	  else
	    winner = cand;
	}
    }
  if (winner)
    {
      tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
      return build_user_type_conversion (type, expr, LOOKUP_NORMAL);
    }
  return NULL_TREE;
}
tree build_expr_type_conversion ( int desires , tree expr , bool complain ) { tree basetype = TREE_TYPE ( expr ) ; tree conv = NULL_TREE ; tree winner = NULL_TREE ; if ( expr == null_node && ( desires & WANT_INT ) && ! ( desires & WANT_NULL ) ) warning ( OPT_Wconversion , " " ) ; basetype = TREE_TYPE ( expr ) ; if ( basetype == error_mark_node ) return error_mark_node ; if ( ! IS_AGGR_TYPE ( basetype ) ) switch ( TREE_CODE ( basetype ) ) { case INTEGER_TYPE : if ( ( desires & WANT_NULL ) && null_ptr_cst_p ( expr ) ) return expr ; case BOOLEAN_TYPE : return ( desires & WANT_INT ) ? expr : NULL_TREE ; case ENUMERAL_TYPE : return ( desires & WANT_ENUM ) ? expr : NULL_TREE ; case REAL_TYPE : return ( desires & WANT_FLOAT ) ? expr : NULL_TREE ; case POINTER_TYPE : return ( desires & WANT_POINTER ) ? expr : NULL_TREE ; case FUNCTION_TYPE : case ARRAY_TYPE : return ( desires & WANT_POINTER ) ? decay_conversion ( expr ) : NULL_TREE ; case VECTOR_TYPE : if ( ( desires & WANT_VECTOR ) == 0 ) return NULL_TREE ; switch ( TREE_CODE ( TREE_TYPE ( basetype ) ) ) { case INTEGER_TYPE : case BOOLEAN_TYPE : return ( desires & WANT_INT ) ? expr : NULL_TREE ; case ENUMERAL_TYPE : return ( desires & WANT_ENUM ) ? expr : NULL_TREE ; case REAL_TYPE : return ( desires & WANT_FLOAT ) ? expr : NULL_TREE ; default : return NULL_TREE ; } default : return NULL_TREE ; } if ( ! complete_type_or_else ( basetype , expr ) ) return error_mark_node ; if ( ! TYPE_HAS_CONVERSION ( basetype ) ) return NULL_TREE ; for ( conv = lookup_conversions ( basetype ) ; conv ; conv = TREE_CHAIN ( conv ) ) { int win = 0 ; tree candidate ; tree cand = TREE_VALUE ( conv ) ; if ( winner && winner == cand ) continue ; candidate = non_reference ( TREE_TYPE ( TREE_TYPE ( cand ) ) ) ; switch ( TREE_CODE ( candidate ) ) { case BOOLEAN_TYPE : case INTEGER_TYPE : win = ( desires & WANT_INT ) ; break ; case ENUMERAL_TYPE : win = ( desires & WANT_ENUM ) ; break ; case REAL_TYPE : win = ( desires & WANT_FLOAT ) ; break ; case POINTER_TYPE : win = ( desires & WANT_POINTER ) ; break ; case VECTOR_TYPE : if ( ( desires & WANT_VECTOR ) == 0 ) break ; switch ( TREE_CODE ( TREE_TYPE ( candidate ) ) ) { case BOOLEAN_TYPE : case INTEGER_TYPE : win = ( desires & WANT_INT ) ; break ; case ENUMERAL_TYPE : win = ( desires & WANT_ENUM ) ; break ; case REAL_TYPE : win = ( desires & WANT_FLOAT ) ; break ; default : break ; } break ; default : break ; } if ( win ) { if ( winner ) { if ( complain ) { error ( " " , basetype ) ; error ( " " , winner , cand ) ; } return error_mark_node ; } else winner = cand ; } } if ( winner ) { tree type = non_reference ( TREE_TYPE ( TREE_TYPE ( winner ) ) ) ; return build_user_type_conversion ( type , expr , LOOKUP_NORMAL ) ; } return NULL_TREE ; }
Convert the given EXPR to one of a group of types suitable for use in an
expression.
Convert the given EXPR to one of a group of types suitable for use in an expression .
/* else fall through...  */ /* The code for conversions from class type is currently only used for
     delete expressions.  Other expressions are handled by build_new_op.  */