+/* Perform a cast of ARG into TYPE. There's sadly a lot of duplication in
+ here from valops.c:value_cast, opencl is different only in the
+ behaviour of scalar to vector casting. As far as possibly we're going
+ to try and delegate back to the standard value_cast function. */
+
+static struct value *
+opencl_value_cast (struct type *type, struct value *arg)
+{
+ if (type != value_type (arg))
+ {
+ /* Casting scalar to vector is a special case for OpenCL, scalar
+ is cast to element type of vector then replicated into each
+ element of the vector. First though, we need to work out if
+ this is a scalar to vector cast; code lifted from
+ valops.c:value_cast. */
+ enum type_code code1, code2;
+ struct type *to_type;
+ int scalar;
+
+ to_type = check_typedef (type);
+
+ code1 = TYPE_CODE (to_type);
+ code2 = TYPE_CODE (check_typedef (value_type (arg)));
+
+ if (code2 == TYPE_CODE_REF)
+ code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
+
+ scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
+ || code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
+ || code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
+ || code2 == TYPE_CODE_RANGE);
+
+ if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
+ {
+ struct type *eltype;
+
+ /* Cast to the element type of the vector here as
+ value_vector_widen will error if the scalar value is
+ truncated by the cast. To avoid the error, cast (and
+ possibly truncate) here. */
+ eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
+ arg = value_cast (eltype, arg);
+
+ return value_vector_widen (arg, type);
+ }
+ else
+ /* Standard cast handler. */
+ arg = value_cast (type, arg);
+ }
+ return arg;
+}
+