/* OpenCL language support for GDB, the GNU debugger.
   Copyright (C) 2010-2023 Free Software Foundation, Inc.

   Contributed by Ken Werner <ken.werner@de.ibm.com>.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbtypes.h"
#include "symtab.h"
#include "expression.h"
#include "parser-defs.h"
#include "language.h"
#include "varobj.h"
#include "c-lang.h"
#include "gdbarch.h"
#include "c-exp.h"

/* Returns the corresponding OpenCL vector type from the given type code,
   the length of the element type, the unsigned flag and the amount of
   elements (N).  */

static struct type *
lookup_opencl_vector_type (struct gdbarch *gdbarch, enum type_code code,
			   unsigned int el_length, unsigned int flag_unsigned,
			   int n)
{
  unsigned int length;

  /* Check if n describes a valid OpenCL vector size (2, 3, 4, 8, 16).  */
  if (n != 2 && n != 3 && n != 4 && n != 8 && n != 16)
    error (_ ("Invalid OpenCL vector size: %d"), n);

  /* Triple vectors have the size of a quad vector.  */
  length = (n == 3) ? el_length * 4 : el_length * n;

  auto filter = [&] (struct type *type) {
    LONGEST lowb, highb;

    return (type->code () == TYPE_CODE_ARRAY && type->is_vector ()
	    && get_array_bounds (type, &lowb, &highb)
	    && type->target_type ()->code () == code
	    && type->target_type ()->is_unsigned () == flag_unsigned
	    && type->target_type ()->length () == el_length
	    && type->length () == length && highb - lowb + 1 == n);
  };
  const struct language_defn *lang = language_def (language_opencl);
  return language_lookup_primitive_type (lang, gdbarch, filter);
}

/* Returns nonzero if the array ARR contains duplicates within
     the first N elements.  */

static int
array_has_dups (int *arr, int n)
{
  int i, j;

  for (i = 0; i < n; i++)
    {
      for (j = i + 1; j < n; j++)
	{
	  if (arr[i] == arr[j])
	    return 1;
	}
    }

  return 0;
}

/* The OpenCL component access syntax allows to create lvalues referring to
   selected elements of an original OpenCL vector in arbitrary order.  This
   structure holds the information to describe such lvalues.  */

struct lval_closure
{
  /* Reference count.  */
  int refc;
  /* The number of indices.  */
  int n;
  /* The element indices themselves.  */
  int *indices;
  /* A pointer to the original value.  */
  struct value *val;
};

/* Allocates an instance of struct lval_closure.  */

static struct lval_closure *
allocate_lval_closure (int *indices, int n, struct value *val)
{
  struct lval_closure *c = XCNEW (struct lval_closure);

  c->refc = 1;
  c->n = n;
  c->indices = XCNEWVEC (int, n);
  memcpy (c->indices, indices, n * sizeof (int));
  value_incref (val); /* Increment the reference counter of the value.  */
  c->val = val;

  return c;
}

static void
lval_func_read (struct value *v)
{
  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
  struct type *type = check_typedef (value_type (v));
  struct type *eltype = check_typedef (value_type (c->val))->target_type ();
  LONGEST offset = value_offset (v);
  LONGEST elsize = eltype->length ();
  int n, i, j = 0;
  LONGEST lowb = 0;
  LONGEST highb = 0;

  if (type->code () == TYPE_CODE_ARRAY
      && !get_array_bounds (type, &lowb, &highb))
    error (_ ("Could not determine the vector bounds"));

  /* Assume elsize aligned offset.  */
  gdb_assert (offset % elsize == 0);
  offset /= elsize;
  n = offset + highb - lowb + 1;
  gdb_assert (n <= c->n);

  for (i = offset; i < n; i++)
    memcpy (value_contents_raw (v).data () + j++ * elsize,
	    value_contents (c->val).data () + c->indices[i] * elsize, elsize);
}

static void
lval_func_write (struct value *v, struct value *fromval)
{
  scoped_value_mark mark;

  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
  struct type *type = check_typedef (value_type (v));
  struct type *eltype = check_typedef (value_type (c->val))->target_type ();
  LONGEST offset = value_offset (v);
  LONGEST elsize = eltype->length ();
  int n, i, j = 0;
  LONGEST lowb = 0;
  LONGEST highb = 0;

  if (type->code () == TYPE_CODE_ARRAY
      && !get_array_bounds (type, &lowb, &highb))
    error (_ ("Could not determine the vector bounds"));

  /* Assume elsize aligned offset.  */
  gdb_assert (offset % elsize == 0);
  offset /= elsize;
  n = offset + highb - lowb + 1;

  /* Since accesses to the fourth component of a triple vector is undefined we
     just skip writes to the fourth element.  Imagine something like this:
       int3 i3 = (int3)(0, 1, 2);
       i3.hi.hi = 5;
     In this case n would be 4 (offset=12/4 + 1) while c->n would be 3.  */
  if (n > c->n)
    n = c->n;

  for (i = offset; i < n; i++)
    {
      struct value *from_elm_val = allocate_value (eltype);
      struct value *to_elm_val = value_subscript (c->val, c->indices[i]);

      memcpy (value_contents_writeable (from_elm_val).data (),
	      value_contents (fromval).data () + j++ * elsize, elsize);
      value_assign (to_elm_val, from_elm_val);
    }
}

/* Return nonzero if bits in V from OFFSET and LENGTH represent a
   synthetic pointer.  */

static int
lval_func_check_synthetic_pointer (const struct value *v, LONGEST offset,
				   int length)
{
  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
  /* Size of the target type in bits.  */
  int elsize
    = check_typedef (value_type (c->val))->target_type ()->length () * 8;
  int startrest = offset % elsize;
  int start = offset / elsize;
  int endrest = (offset + length) % elsize;
  int end = (offset + length) / elsize;
  int i;

  if (endrest)
    end++;

  if (end > c->n)
    return 0;

  for (i = start; i < end; i++)
    {
      int comp_offset = (i == start) ? startrest : 0;
      int comp_length = (i == end) ? endrest : elsize;

      if (!value_bits_synthetic_pointer (c->val,
					 c->indices[i] * elsize + comp_offset,
					 comp_length))
	return 0;
    }

  return 1;
}

static void *
lval_func_copy_closure (const struct value *v)
{
  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);

  ++c->refc;

  return c;
}

static void
lval_func_free_closure (struct value *v)
{
  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);

  --c->refc;

  if (c->refc == 0)
    {
      value_decref (
	c->val); /* Decrement the reference counter of the value.  */
      xfree (c->indices);
      xfree (c);
    }
}

static const struct lval_funcs opencl_value_funcs
  = { lval_func_read,
      lval_func_write,
      nullptr,
      NULL, /* indirect */
      NULL, /* coerce_ref */
      lval_func_check_synthetic_pointer,
      lval_func_copy_closure,
      lval_func_free_closure };

/* Creates a sub-vector from VAL.  The elements are selected by the indices of
   an array with the length of N.  Supported values for NOSIDE are
   EVAL_NORMAL and EVAL_AVOID_SIDE_EFFECTS.  */

static struct value *
create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside,
	      int *indices, int n)
{
  struct type *type = check_typedef (value_type (val));
  struct type *elm_type = type->target_type ();
  struct value *ret;

  /* Check if a single component of a vector is requested which means
     the resulting type is a (primitive) scalar type.  */
  if (n == 1)
    {
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	ret = value_zero (elm_type, not_lval);
      else
	ret = value_subscript (val, indices[0]);
    }
  else
    {
      /* Multiple components of the vector are requested which means the
	 resulting type is a vector as well.  */
      struct type *dst_type
	= lookup_opencl_vector_type (gdbarch, elm_type->code (),
				     elm_type->length (),
				     elm_type->is_unsigned (), n);

      if (dst_type == NULL)
	dst_type = init_vector_type (elm_type, n);

      make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type), dst_type, NULL);

      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	ret = allocate_value (dst_type);
      else
	{
	  /* Check whether to create a lvalue or not.  */
	  if (VALUE_LVAL (val) != not_lval && !array_has_dups (indices, n))
	    {
	      struct lval_closure *c = allocate_lval_closure (indices, n, val);
	      ret = allocate_computed_value (dst_type, &opencl_value_funcs, c);
	    }
	  else
	    {
	      int i;

	      ret = allocate_value (dst_type);

	      /* Copy src val contents into the destination value.  */
	      for (i = 0; i < n; i++)
		memcpy (value_contents_writeable (ret).data ()
			  + (i * elm_type->length ()),
			value_contents (val).data ()
			  + (indices[i] * elm_type->length ()),
			elm_type->length ());
	    }
	}
    }
  return ret;
}

/* OpenCL vector component access.  */

static struct value *
opencl_component_ref (struct expression *exp, struct value *val,
		      const char *comps, enum noside noside)
{
  LONGEST lowb, highb;
  int src_len;
  struct value *v;
  int indices[16], i;
  int dst_len;

  if (!get_array_bounds (check_typedef (value_type (val)), &lowb, &highb))
    error (_ ("Could not determine the vector bounds"));

  src_len = highb - lowb + 1;

  /* Throw an error if the amount of array elements does not fit a
     valid OpenCL vector size (2, 3, 4, 8, 16).  */
  if (src_len != 2 && src_len != 3 && src_len != 4 && src_len != 8
      && src_len != 16)
    error (_ ("Invalid OpenCL vector size"));

  if (strcmp (comps, "lo") == 0)
    {
      dst_len = (src_len == 3) ? 2 : src_len / 2;

      for (i = 0; i < dst_len; i++)
	indices[i] = i;
    }
  else if (strcmp (comps, "hi") == 0)
    {
      dst_len = (src_len == 3) ? 2 : src_len / 2;

      for (i = 0; i < dst_len; i++)
	indices[i] = dst_len + i;
    }
  else if (strcmp (comps, "even") == 0)
    {
      dst_len = (src_len == 3) ? 2 : src_len / 2;

      for (i = 0; i < dst_len; i++)
	indices[i] = i * 2;
    }
  else if (strcmp (comps, "odd") == 0)
    {
      dst_len = (src_len == 3) ? 2 : src_len / 2;

      for (i = 0; i < dst_len; i++)
	indices[i] = i * 2 + 1;
    }
  else if (strncasecmp (comps, "s", 1) == 0)
    {
#define HEXCHAR_TO_INT(C)      \
  ((C >= '0' && C <= '9')      \
     ? C - '0'                 \
     : ((C >= 'A' && C <= 'F') \
	  ? C - 'A' + 10       \
	  : ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : -1)))

      dst_len = strlen (comps);
      /* Skip the s/S-prefix.  */
      dst_len--;

      for (i = 0; i < dst_len; i++)
	{
	  indices[i] = HEXCHAR_TO_INT (comps[i + 1]);
	  /* Check if the requested component is invalid or exceeds
	     the vector.  */
	  if (indices[i] < 0 || indices[i] >= src_len)
	    error (_ ("Invalid OpenCL vector component accessor %s"), comps);
	}
    }
  else
    {
      dst_len = strlen (comps);

      for (i = 0; i < dst_len; i++)
	{
	  /* x, y, z, w */
	  switch (comps[i])
	    {
	    case 'x':
	      indices[i] = 0;
	      break;
	    case 'y':
	      indices[i] = 1;
	      break;
	    case 'z':
	      if (src_len < 3)
		error (_ ("Invalid OpenCL vector component accessor %s"),
		       comps);
	      indices[i] = 2;
	      break;
	    case 'w':
	      if (src_len < 4)
		error (_ ("Invalid OpenCL vector component accessor %s"),
		       comps);
	      indices[i] = 3;
	      break;
	    default:
	      error (_ ("Invalid OpenCL vector component accessor %s"), comps);
	      break;
	    }
	}
    }

  /* Throw an error if the amount of requested components does not
     result in a valid length (1, 2, 3, 4, 8, 16).  */
  if (dst_len != 1 && dst_len != 2 && dst_len != 3 && dst_len != 4
      && dst_len != 8 && dst_len != 16)
    error (_ ("Invalid OpenCL vector component accessor %s"), comps);

  v = create_value (exp->gdbarch, val, noside, indices, dst_len);

  return v;
}

/* Perform the unary logical not (!) operation.  */

struct value *
opencl_logical_not (struct type *expect_type, struct expression *exp,
		    enum noside noside, enum exp_opcode op, struct value *arg)
{
  struct type *type = check_typedef (value_type (arg));
  struct type *rettype;
  struct value *ret;

  if (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
    {
      struct type *eltype = check_typedef (type->target_type ());
      LONGEST lowb, highb;
      int i;

      if (!get_array_bounds (type, &lowb, &highb))
	error (_ ("Could not determine the vector bounds"));

      /* Determine the resulting type of the operation and allocate the
	 value.  */
      rettype
	= lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT,
				     eltype->length (), 0, highb - lowb + 1);
      ret = allocate_value (rettype);

      for (i = 0; i < highb - lowb + 1; i++)
	{
	  /* For vector types, the unary operator shall return a 0 if the
	  value of its operand compares unequal to 0, and -1 (i.e. all bits
	  set) if the value of its operand compares equal to 0.  */
	  int tmp = value_logical_not (value_subscript (arg, i)) ? -1 : 0;
	  memset ((value_contents_writeable (ret).data ()
		   + i * eltype->length ()),
		  tmp, eltype->length ());
	}
    }
  else
    {
      rettype = language_bool_type (exp->language_defn, exp->gdbarch);
      ret = value_from_longest (rettype, value_logical_not (arg));
    }

  return ret;
}

/* Perform a relational operation on two scalar operands.  */

static int
scalar_relop (struct value *val1, struct value *val2, enum exp_opcode op)
{
  int ret;

  switch (op)
    {
    case BINOP_EQUAL:
      ret = value_equal (val1, val2);
      break;
    case BINOP_NOTEQUAL:
      ret = !value_equal (val1, val2);
      break;
    case BINOP_LESS:
      ret = value_less (val1, val2);
      break;
    case BINOP_GTR:
      ret = value_less (val2, val1);
      break;
    case BINOP_GEQ:
      ret = value_less (val2, val1) || value_equal (val1, val2);
      break;
    case BINOP_LEQ:
      ret = value_less (val1, val2) || value_equal (val1, val2);
      break;
    case BINOP_LOGICAL_AND:
      ret = !value_logical_not (val1) && !value_logical_not (val2);
      break;
    case BINOP_LOGICAL_OR:
      ret = !value_logical_not (val1) || !value_logical_not (val2);
      break;
    default:
      error (_ ("Attempt to perform an unsupported operation"));
      break;
    }
  return ret;
}

/* Perform a relational operation on two vector operands.  */

static struct value *
vector_relop (struct expression *exp, struct value *val1, struct value *val2,
	      enum exp_opcode op)
{
  struct value *ret;
  struct type *type1, *type2, *eltype1, *eltype2, *rettype;
  int t1_is_vec, t2_is_vec, i;
  LONGEST lowb1, lowb2, highb1, highb2;

  type1 = check_typedef (value_type (val1));
  type2 = check_typedef (value_type (val2));

  t1_is_vec = (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ());
  t2_is_vec = (type2->code () == TYPE_CODE_ARRAY && type2->is_vector ());

  if (!t1_is_vec || !t2_is_vec)
    error (_ ("Vector operations are not supported on scalar types"));

  eltype1 = check_typedef (type1->target_type ());
  eltype2 = check_typedef (type2->target_type ());

  if (!get_array_bounds (type1, &lowb1, &highb1)
      || !get_array_bounds (type2, &lowb2, &highb2))
    error (_ ("Could not determine the vector bounds"));

  /* Check whether the vector types are compatible.  */
  if (eltype1->code () != eltype2->code ()
      || eltype1->length () != eltype2->length ()
      || eltype1->is_unsigned () != eltype2->is_unsigned () || lowb1 != lowb2
      || highb1 != highb2)
    error (_ ("Cannot perform operation on vectors with different types"));

  /* Determine the resulting type of the operation and allocate the value.  */
  rettype
    = lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT,
				 eltype1->length (), 0, highb1 - lowb1 + 1);
  ret = allocate_value (rettype);

  for (i = 0; i < highb1 - lowb1 + 1; i++)
    {
      /* For vector types, the relational, equality and logical operators shall
	 return 0 if the specified relation is false and -1 (i.e. all bits set)
	 if the specified relation is true.  */
      int tmp = scalar_relop (value_subscript (val1, i),
			      value_subscript (val2, i), op)
		  ? -1
		  : 0;
      memset ((value_contents_writeable (ret).data ()
	       + i * eltype1->length ()),
	      tmp, eltype1->length ());
    }

  return ret;
}

/* 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. */

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 = to_type->code ();
      code2 = check_typedef (value_type (arg))->code ();

      if (code2 == TYPE_CODE_REF)
	code2 = check_typedef (value_type (coerce_ref (arg)))->code ();

      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 && to_type->is_vector () && 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 (to_type->target_type ());
	  arg = value_cast (eltype, arg);

	  return value_vector_widen (arg, type);
	}
      else
	/* Standard cast handler.  */
	arg = value_cast (type, arg);
    }
  return arg;
}

/* Perform a relational operation on two operands.  */

struct value *
opencl_relop (struct type *expect_type, struct expression *exp,
	      enum noside noside, enum exp_opcode op, struct value *arg1,
	      struct value *arg2)
{
  struct value *val;
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));
  int t1_is_vec = (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ());
  int t2_is_vec = (type2->code () == TYPE_CODE_ARRAY && type2->is_vector ());

  if (!t1_is_vec && !t2_is_vec)
    {
      int tmp = scalar_relop (arg1, arg2, op);
      struct type *type
	= language_bool_type (exp->language_defn, exp->gdbarch);

      val = value_from_longest (type, tmp);
    }
  else if (t1_is_vec && t2_is_vec)
    {
      val = vector_relop (exp, arg1, arg2, op);
    }
  else
    {
      /* Widen the scalar operand to a vector.  */
      struct value **v = t1_is_vec ? &arg2 : &arg1;
      struct type *t = t1_is_vec ? type2 : type1;

      if (t->code () != TYPE_CODE_FLT && !is_integral_type (t))
	error (_ ("Argument to operation not a number or boolean."));

      *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
      val = vector_relop (exp, arg1, arg2, op);
    }

  return val;
}

/* A helper function for BINOP_ASSIGN.  */

struct value *
eval_opencl_assign (struct type *expect_type, struct expression *exp,
		    enum noside noside, enum exp_opcode op, struct value *arg1,
		    struct value *arg2)
{
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return arg1;

  struct type *type1 = value_type (arg1);
  if (deprecated_value_modifiable (arg1)
      && VALUE_LVAL (arg1) != lval_internalvar)
    arg2 = opencl_value_cast (type1, arg2);

  return value_assign (arg1, arg2);
}

namespace expr
{

value *
opencl_structop_operation::evaluate (struct type *expect_type,
				     struct expression *exp,
				     enum noside noside)
{
  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  struct type *type1 = check_typedef (value_type (arg1));

  if (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
    return opencl_component_ref (exp, arg1, std::get<1> (m_storage).c_str (),
				 noside);
  else
    {
      struct value *v
	= value_struct_elt (&arg1, {}, std::get<1> (m_storage).c_str (), NULL,
			    "structure");

      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	v = value_zero (value_type (v), VALUE_LVAL (v));
      return v;
    }
}

value *
opencl_logical_binop_operation::evaluate (struct type *expect_type,
					  struct expression *exp,
					  enum noside noside)
{
  enum exp_opcode op = std::get<0> (m_storage);
  value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);

  /* For scalar operations we need to avoid evaluating operands
     unnecessarily.  However, for vector operations we always need to
     evaluate both operands.  Unfortunately we only know which of the
     two cases apply after we know the type of the second operand.
     Therefore we evaluate it once using EVAL_AVOID_SIDE_EFFECTS.  */
  value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp,
						   EVAL_AVOID_SIDE_EFFECTS);
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));

  if ((type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
      || (type2->code () == TYPE_CODE_ARRAY && type2->is_vector ()))
    {
      arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);

      return opencl_relop (nullptr, exp, noside, op, arg1, arg2);
    }
  else
    {
      /* For scalar built-in types, only evaluate the right
	 hand operand if the left hand operand compares
	 unequal(&&)/equal(||) to 0.  */
      bool tmp = value_logical_not (arg1);

      if (op == BINOP_LOGICAL_OR)
	tmp = !tmp;

      if (!tmp)
	{
	  arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
	  tmp = value_logical_not (arg2);
	  if (op == BINOP_LOGICAL_OR)
	    tmp = !tmp;
	}

      type1 = language_bool_type (exp->language_defn, exp->gdbarch);
      return value_from_longest (type1, tmp);
    }
}

value *
opencl_ternop_cond_operation::evaluate (struct type *expect_type,
					struct expression *exp,
					enum noside noside)
{
  value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  struct type *type1 = check_typedef (value_type (arg1));
  if (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
    {
      struct value *arg2, *arg3, *tmp, *ret;
      struct type *eltype2, *type2, *type3, *eltype3;
      int t2_is_vec, t3_is_vec, i;
      LONGEST lowb1, lowb2, lowb3, highb1, highb2, highb3;

      arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
      arg3 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
      type2 = check_typedef (value_type (arg2));
      type3 = check_typedef (value_type (arg3));
      t2_is_vec = type2->code () == TYPE_CODE_ARRAY && type2->is_vector ();
      t3_is_vec = type3->code () == TYPE_CODE_ARRAY && type3->is_vector ();

      /* Widen the scalar operand to a vector if necessary.  */
      if (t2_is_vec || !t3_is_vec)
	{
	  arg3 = opencl_value_cast (type2, arg3);
	  type3 = value_type (arg3);
	}
      else if (!t2_is_vec || t3_is_vec)
	{
	  arg2 = opencl_value_cast (type3, arg2);
	  type2 = value_type (arg2);
	}
      else if (!t2_is_vec || !t3_is_vec)
	{
	  /* Throw an error if arg2 or arg3 aren't vectors.  */
	  error (_ ("\
Cannot perform conditional operation on incompatible types"));
	}

      eltype2 = check_typedef (type2->target_type ());
      eltype3 = check_typedef (type3->target_type ());

      if (!get_array_bounds (type1, &lowb1, &highb1)
	  || !get_array_bounds (type2, &lowb2, &highb2)
	  || !get_array_bounds (type3, &lowb3, &highb3))
	error (_ ("Could not determine the vector bounds"));

      /* Throw an error if the types of arg2 or arg3 are incompatible.  */
      if (eltype2->code () != eltype3->code ()
	  || eltype2->length () != eltype3->length ()
	  || eltype2->is_unsigned () != eltype3->is_unsigned ()
	  || lowb2 != lowb3 || highb2 != highb3)
	error (_ ("\
Cannot perform operation on vectors with different types"));

      /* Throw an error if the sizes of arg1 and arg2/arg3 differ.  */
      if (lowb1 != lowb2 || lowb1 != lowb3 || highb1 != highb2
	  || highb1 != highb3)
	error (_ ("\
Cannot perform conditional operation on vectors with different sizes"));

      ret = allocate_value (type2);

      for (i = 0; i < highb1 - lowb1 + 1; i++)
	{
	  tmp = value_logical_not (value_subscript (arg1, i))
		  ? value_subscript (arg3, i)
		  : value_subscript (arg2, i);
	  memcpy (value_contents_writeable (ret).data ()
		    + i * eltype2->length (),
		  value_contents_all (tmp).data (), eltype2->length ());
	}

      return ret;
    }
  else
    {
      if (value_logical_not (arg1))
	return std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
      else
	return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
    }
}

} /* namespace expr */

/* Class representing the OpenCL language.  */

class opencl_language : public language_defn
{
public:

  opencl_language ()
    : language_defn (language_opencl)
  { /* Nothing.  */
  }

  /* See language.h.  */

  const char *name () const override { return "opencl"; }

  /* See language.h.  */

  const char *natural_name () const override { return "OpenCL C"; }

  /* See language.h.  */
  void language_arch_info (struct gdbarch *gdbarch,
			   struct language_arch_info *lai) const override
  {
    /* Helper function to allow shorter lines below.  */
    auto add = [&](struct type * t) -> struct type *
    {
      lai->add_primitive_type (t);
      return t;
    };

/* Helper macro to create strings.  */
#define OCL_STRING(S) #S

/* This macro allocates and assigns the type struct pointers
   for the vector types.  */
#define BUILD_OCL_VTYPES(TYPE, ELEMENT_TYPE)           \
  do                                                   \
    {                                                  \
      struct type *tmp;                                \
      tmp = add (init_vector_type (ELEMENT_TYPE, 2));  \
      tmp->set_name (OCL_STRING (TYPE##2));            \
      tmp = add (init_vector_type (ELEMENT_TYPE, 3));  \
      tmp->set_name (OCL_STRING (TYPE##3));            \
      tmp->set_length (4 * (ELEMENT_TYPE)->length ()); \
      tmp = add (init_vector_type (ELEMENT_TYPE, 4));  \
      tmp->set_name (OCL_STRING (TYPE##4));            \
      tmp = add (init_vector_type (ELEMENT_TYPE, 8));  \
      tmp->set_name (OCL_STRING (TYPE##8));            \
      tmp = init_vector_type (ELEMENT_TYPE, 16);       \
      tmp->set_name (OCL_STRING (TYPE##16));           \
    }                                                  \
  while (false)

    struct type *el_type, *char_type, *int_type;

    char_type = el_type = add (arch_integer_type (gdbarch, 8, 0, "char"));
    BUILD_OCL_VTYPES (char, el_type);
    el_type = add (arch_integer_type (gdbarch, 8, 1, "uchar"));
    BUILD_OCL_VTYPES (uchar, el_type);
    el_type = add (arch_integer_type (gdbarch, 16, 0, "short"));
    BUILD_OCL_VTYPES (short, el_type);
    el_type = add (arch_integer_type (gdbarch, 16, 1, "ushort"));
    BUILD_OCL_VTYPES (ushort, el_type);
    int_type = el_type = add (arch_integer_type (gdbarch, 32, 0, "int"));
    BUILD_OCL_VTYPES (int, el_type);
    el_type = add (arch_integer_type (gdbarch, 32, 1, "uint"));
    BUILD_OCL_VTYPES (uint, el_type);
    el_type = add (arch_integer_type (gdbarch, 64, 0, "long"));
    BUILD_OCL_VTYPES (long, el_type);
    el_type = add (arch_integer_type (gdbarch, 64, 1, "ulong"));
    BUILD_OCL_VTYPES (ulong, el_type);
    el_type
      = add (arch_float_type (gdbarch, 16, "half", floatformats_ieee_half));
    BUILD_OCL_VTYPES (half, el_type);
    el_type
      = add (arch_float_type (gdbarch, 32, "float", floatformats_ieee_single));
    BUILD_OCL_VTYPES (float, el_type);
    el_type = add (arch_float_type (gdbarch, 64, "double",
				    floatformats_ieee_double));
    BUILD_OCL_VTYPES (double, el_type);

    add (arch_boolean_type (gdbarch, 8, 1, "bool"));
    add (arch_integer_type (gdbarch, 8, 1, "unsigned char"));
    add (arch_integer_type (gdbarch, 16, 1, "unsigned short"));
    add (arch_integer_type (gdbarch, 32, 1, "unsigned int"));
    add (arch_integer_type (gdbarch, 64, 1, "unsigned long"));
    add (arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "size_t"));
    add (arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0,
			    "ptrdiff_t"));
    add (arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0,
			    "intptr_t"));
    add (arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1,
			    "uintptr_t"));
    add (arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"));

    /* Type of elements of strings.  */
    lai->set_string_char_type (char_type);

    /* Specifies the return type of logical and relational operations.  */
    lai->set_bool_type (int_type, "int");
  }

  /* See language.h.  */

  bool can_print_type_offsets () const override { return true; }

  /* See language.h.  */

  void print_type (struct type *type, const char *varstring,
		   struct ui_file *stream, int show, int level,
		   const struct type_print_options *flags) const override
  {
    /* We nearly always defer to C type printing, except that vector types
       are considered primitive in OpenCL, and should always be printed
       using their TYPE_NAME.  */
    if (show > 0)
      {
	type = check_typedef (type);
	if (type->code () == TYPE_CODE_ARRAY && type->is_vector ()
	    && type->name () != NULL)
	  show = 0;
      }

    c_print_type (type, varstring, stream, show, level, la_language, flags);
  }

  /* See language.h.  */

  enum macro_expansion macro_expansion () const override
  {
    return macro_expansion_c;
  }
};

/* Single instance of the OpenCL language class.  */

static opencl_language opencl_language_defn;
