FreeBSD/contrib/gcc/cp/typeck.c
/* Convert RHS to be of type TYPE.
   If EXP is nonzero, it is the target of the initialization.
   ERRTYPE is a string to use in error messages.

   Two major differences between the behavior of
   `convert_for_assignment' and `convert_for_initialization'
   are that references are bashed in the former, while
   copied in the latter, and aggregates are assigned in
   the former (operator=) while initialized in the
   latter (X(X&)).

   If using constructor make sure no conversion operator exists, if one does
   exist, an ambiguity exists.

   If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything.  */
Convert RHS to be of type TYPE.
If EXP is nonzero, it is the target of the initialization.
ERRTYPE is a string to use in error messages.

Two major differences between the behavior of
`convert_for_assignment' and `convert_for_initialization'
are that references are bashed in the former, while
copied in the latter, and aggregates are assigned in
the former (operator=) while initialized in the
latter (X(X&)).

If using constructor make sure no conversion operator exists, if one does
exist, an ambiguity exists.

If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything.
Convert RHS to be of type TYPE . If EXP is nonzero it is the target of the initialization . ERRTYPE is a string to use in error messages . Two major differences between the behavior of ` convert_for_assignment ' and ` convert_for_initialization ' are that references are bashed in the former while copied in the latter and aggregates are assigned in the former ( operator = ) while initialized in the latter ( X ( X& )) . If using constructor make sure no conversion operator exists if one does exist an ambiguity exists . If flags doesn ' t include LOOKUP_COMPLAIN don ' t complain about anything .
tree
convert_for_initialization (tree exp, tree type, tree rhs, int flags,
			    const char *errtype, tree fndecl, int parmnum)
{
  enum tree_code codel = TREE_CODE (type);
  tree rhstype;
  enum tree_code coder;
  if (TREE_CODE (rhs) == NOP_EXPR
      && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
      && codel != REFERENCE_TYPE)
    rhs = TREE_OPERAND (rhs, 0);
  if (type == error_mark_node
      || rhs == error_mark_node
      || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
    return error_mark_node;
  if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
       && TREE_CODE (type) != ARRAY_TYPE
       && (TREE_CODE (type) != REFERENCE_TYPE
	   || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
      || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
	  && (TREE_CODE (type) != REFERENCE_TYPE
	      || TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE))
      || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
    rhs = decay_conversion (rhs);
  rhstype = TREE_TYPE (rhs);
  coder = TREE_CODE (rhstype);
  if (coder == ERROR_MARK)
    return error_mark_node;
  if (codel == REFERENCE_TYPE)
    {
      int savew = 0, savee = 0;
      if (fndecl)
	savew = warningcount, savee = errorcount;
      rhs = initialize_reference (type, rhs, NULL_TREE,
				  NULL);
      if (fndecl)
	{
	  if (warningcount > savew)
	    warning (0, "in passing argument %P of %q+D", parmnum, fndecl);
	  else if (errorcount > savee)
	    error ("in passing argument %P of %q+D", parmnum, fndecl);
	}
      return rhs;
    }
  if (exp != 0)
    exp = require_complete_type (exp);
  if (exp == error_mark_node)
    return error_mark_node;
  rhstype = non_reference (rhstype);
  type = complete_type (type);
  if (IS_AGGR_TYPE (type))
    return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
  return convert_for_assignment (type, rhs, errtype, fndecl, parmnum);
}
tree convert_for_initialization ( tree exp , tree type , tree rhs , int flags , const char * errtype , tree fndecl , int parmnum ) { enum tree_code codel = TREE_CODE ( type ) ; tree rhstype ; enum tree_code coder ; if ( TREE_CODE ( rhs ) == NOP_EXPR && TREE_TYPE ( rhs ) == TREE_TYPE ( TREE_OPERAND ( rhs , 0 ) ) && codel != REFERENCE_TYPE ) rhs = TREE_OPERAND ( rhs , 0 ) ; if ( type == error_mark_node || rhs == error_mark_node || ( TREE_CODE ( rhs ) == TREE_LIST && TREE_VALUE ( rhs ) == error_mark_node ) ) return error_mark_node ; if ( ( TREE_CODE ( TREE_TYPE ( rhs ) ) == ARRAY_TYPE && TREE_CODE ( type ) != ARRAY_TYPE && ( TREE_CODE ( type ) != REFERENCE_TYPE || TREE_CODE ( TREE_TYPE ( type ) ) != ARRAY_TYPE ) ) || ( TREE_CODE ( TREE_TYPE ( rhs ) ) == FUNCTION_TYPE && ( TREE_CODE ( type ) != REFERENCE_TYPE || TREE_CODE ( TREE_TYPE ( type ) ) != FUNCTION_TYPE ) ) || TREE_CODE ( TREE_TYPE ( rhs ) ) == METHOD_TYPE ) rhs = decay_conversion ( rhs ) ; rhstype = TREE_TYPE ( rhs ) ; coder = TREE_CODE ( rhstype ) ; if ( coder == ERROR_MARK ) return error_mark_node ; if ( codel == REFERENCE_TYPE ) { int savew = 0 , savee = 0 ; if ( fndecl ) savew = warningcount , savee = errorcount ; rhs = initialize_reference ( type , rhs , NULL_TREE , NULL ) ; if ( fndecl ) { if ( warningcount > savew ) warning ( 0 , " " , parmnum , fndecl ) ; else if ( errorcount > savee ) error ( " " , parmnum , fndecl ) ; } return rhs ; } if ( exp != 0 ) exp = require_complete_type ( exp ) ; if ( exp == error_mark_node ) return error_mark_node ; rhstype = non_reference ( rhstype ) ; type = complete_type ( type ) ; if ( IS_AGGR_TYPE ( type ) ) return ocp_convert ( type , rhs , CONV_IMPLICIT | CONV_FORCE_TEMP , flags ) ; return convert_for_assignment ( type , rhs , errtype , fndecl , parmnum ) ; }
Convert RHS to be of type TYPE.
Convert RHS to be of type TYPE .
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */ /* We accept references to incomplete types, so we can
     return here before checking if RHS is of complete type.  */ /* This should eventually happen in convert_arguments.  */ /*decl=*/ /*cleanup=*/