示例#1
0
/* target hook for resolve_overloaded_builtin(). Returns a function call
   RTX if we can resolve the overloaded builtin */
tree
spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
{
#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
			  || SCALAR_FLOAT_TYPE_P (t) \
			  || POINTER_TYPE_P (t))
  spu_function_code new_fcode, fcode =
    DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
  struct spu_builtin_description *desc;
  tree match = NULL_TREE;

  /* The vector types are not available if the backend is not initialized.  */
  gcc_assert (!flag_preprocess_only);

  desc = &spu_builtins[fcode];
  if (desc->type != B_OVERLOAD)
    return NULL_TREE;

  /* Compare the signature of each internal builtin function with the
     function arguments until a match is found. */

  for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
       new_fcode++)
    {
      tree decl = spu_builtins[new_fcode].fndecl;
      tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
      tree arg, param;
      int p;

      for (param = params, arg = fnargs, p = 0;
	   param != void_list_node;
	   param = TREE_CHAIN (param), arg = TREE_CHAIN (arg), p++)
	{
	  tree var, arg_type, param_type = TREE_VALUE (param);

	  if (!arg)
	    {
	      error ("insufficient arguments to overloaded function %s",
		     desc->name);
	      return error_mark_node;
	    }

	  var = TREE_VALUE (arg);

	  if (TREE_CODE (var) == NON_LVALUE_EXPR)
	    var = TREE_OPERAND (var, 0);

	  if (TREE_CODE (var) == ERROR_MARK)
	    return NULL_TREE;	/* Let somebody else deal with the problem. */

	  arg_type = TREE_TYPE (var);

	  /* The intrinsics spec does not specify precisely how to
	     resolve generic intrinsics.  We require an exact match
	     for vector types and let C do it's usual parameter type
	     checking/promotions for scalar arguments, except for the
	     first argument of intrinsics which don't have a vector
	     parameter. */
	  if ((!SCALAR_TYPE_P (param_type)
	       || !SCALAR_TYPE_P (arg_type)
	       || ((fcode == SPU_SPLATS || fcode == SPU_PROMOTE
		    || fcode == SPU_HCMPEQ || fcode == SPU_HCMPGT
		    || fcode == SPU_MASKB || fcode == SPU_MASKH
		    || fcode == SPU_MASKW) && p == 0))
	      && !comptypes (TYPE_MAIN_VARIANT (param_type),
			     TYPE_MAIN_VARIANT (arg_type)))
	    break;
	}
      if (param == void_list_node)
	{
	  if (arg)
	    {
	      error ("too many arguments to overloaded function %s",
		     desc->name);
	      return error_mark_node;
	    }

	  match = decl;
	  break;
	}
    }

  if (match == NULL_TREE)
    {
      error ("parameter list does not match a valid signature for %s()",
	     desc->name);
      return error_mark_node;
    }

  return build_function_call (match, fnargs);
#undef SCALAR_TYPE_P
}
示例#2
0
int
objcp_comptypes (tree type1, tree type2)
{     
  return comptypes (type1, type2, COMPARE_STRICT);
}
示例#3
0
文件: cvt.c 项目: h4ck3rm1k3/gcc
tree
convert_to_reference (tree reftype, tree expr, int convtype,
		      int flags, tree decl)
{
  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
  tree intype;
  tree rval = NULL_TREE;
  tree rval_as_conversion = NULL_TREE;
  bool can_convert_intype_to_type;

  if (TREE_CODE (type) == FUNCTION_TYPE
      && TREE_TYPE (expr) == unknown_type_node)
    expr = instantiate_type (type, expr,
			     (flags & LOOKUP_COMPLAIN)
			     ? tf_warning_or_error : tf_none);

  if (expr == error_mark_node)
    return error_mark_node;

  intype = TREE_TYPE (expr);

  gcc_assert (TREE_CODE (intype) != REFERENCE_TYPE);
  gcc_assert (TREE_CODE (reftype) == REFERENCE_TYPE);

  intype = TYPE_MAIN_VARIANT (intype);

  can_convert_intype_to_type = can_convert (type, intype);
  if (!can_convert_intype_to_type
      && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
      && ! (flags & LOOKUP_NO_CONVERSION))
    {
      /* Look for a user-defined conversion to lvalue that we can use.  */

      rval_as_conversion
	= build_type_conversion (reftype, expr);

      if (rval_as_conversion && rval_as_conversion != error_mark_node
	  && real_lvalue_p (rval_as_conversion))
	{
	  expr = rval_as_conversion;
	  rval_as_conversion = NULL_TREE;
	  intype = type;
	  can_convert_intype_to_type = 1;
	}
    }

  if (((convtype & CONV_STATIC) && can_convert (intype, type))
      || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
    {
      if (flags & LOOKUP_COMPLAIN)
	{
	  tree ttl = TREE_TYPE (reftype);
	  tree ttr = lvalue_type (expr);

	  if (! real_lvalue_p (expr))
	    warn_ref_binding (reftype, intype, decl);

	  if (! (convtype & CONV_CONST)
		   && !at_least_as_qualified_p (ttl, ttr))
	    permerror (input_location, "conversion from %qT to %qT discards qualifiers",
		       ttr, reftype);
	}

      return build_up_reference (reftype, expr, flags, decl);
    }
  else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
    {
      /* When casting an lvalue to a reference type, just convert into
	 a pointer to the new type and deference it.  This is allowed
	 by San Diego WP section 5.2.9 paragraph 12, though perhaps it
	 should be done directly (jason).  (int &)ri ---> *(int*)&ri */

      /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
	 meant.  */
      if (TREE_CODE (intype) == POINTER_TYPE
	  && (comptypes (TREE_TYPE (intype), type,
			 COMPARE_BASE | COMPARE_DERIVED)))
	warning (0, "casting %qT to %qT does not dereference pointer",
		 intype, reftype);

      rval = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
      if (rval != error_mark_node)
	rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
			      rval, 0);
      if (rval != error_mark_node)
	rval = build1 (NOP_EXPR, reftype, rval);
    }
  else
    {
      rval = convert_for_initialization (NULL_TREE, type, expr, flags,
					 "converting", 0, 0,
                                         tf_warning_or_error);
      if (rval == NULL_TREE || rval == error_mark_node)
	return rval;
      warn_ref_binding (reftype, intype, decl);
      rval = build_up_reference (reftype, rval, flags, decl);
    }

  if (rval)
    {
      /* If we found a way to convert earlier, then use it.  */
      return rval;
    }

  if (flags & LOOKUP_COMPLAIN)
    error ("cannot convert type %qT to type %qT", intype, reftype);

  return error_mark_node;
}
int
c_types_compatible_p (tree x, tree y)
{
  return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
}