/* OpenCL language support for GDB, the GNU debugger.
   Copyright (C) 2010-2018 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"

/* This macro generates enum values from a given type.  */

#define OCL_P_TYPE(TYPE)\
  opencl_primitive_type_##TYPE,\
  opencl_primitive_type_##TYPE##2,\
  opencl_primitive_type_##TYPE##3,\
  opencl_primitive_type_##TYPE##4,\
  opencl_primitive_type_##TYPE##8,\
  opencl_primitive_type_##TYPE##16

enum opencl_primitive_types {
  OCL_P_TYPE (char),
  OCL_P_TYPE (uchar),
  OCL_P_TYPE (short),
  OCL_P_TYPE (ushort),
  OCL_P_TYPE (int),
  OCL_P_TYPE (uint),
  OCL_P_TYPE (long),
  OCL_P_TYPE (ulong),
  OCL_P_TYPE (half),
  OCL_P_TYPE (float),
  OCL_P_TYPE (double),
  opencl_primitive_type_bool,
  opencl_primitive_type_unsigned_char,
  opencl_primitive_type_unsigned_short,
  opencl_primitive_type_unsigned_int,
  opencl_primitive_type_unsigned_long,
  opencl_primitive_type_size_t,
  opencl_primitive_type_ptrdiff_t,
  opencl_primitive_type_intptr_t,
  opencl_primitive_type_uintptr_t,
  opencl_primitive_type_void,
  nr_opencl_primitive_types
};

static struct gdbarch_data *opencl_type_data;

static struct type **
builtin_opencl_type (struct gdbarch *gdbarch)
{
  return (struct type **) gdbarch_data (gdbarch, opencl_type_data);
}

/* 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)
{
  int i;
  unsigned int length;
  struct type *type = NULL;
  struct type **types = builtin_opencl_type (gdbarch);

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

  for (i = 0; i < nr_opencl_primitive_types; i++)
    {
      LONGEST lowb, highb;

      if (TYPE_CODE (types[i]) == TYPE_CODE_ARRAY && TYPE_VECTOR (types[i])
	  && get_array_bounds (types[i], &lowb, &highb)
	  && TYPE_CODE (TYPE_TARGET_TYPE (types[i])) == code
	  && TYPE_UNSIGNED (TYPE_TARGET_TYPE (types[i])) == flag_unsigned
	  && TYPE_LENGTH (TYPE_TARGET_TYPE (types[i])) == el_length
	  && TYPE_LENGTH (types[i]) == length
	  && highb - lowb + 1 == n)
	{
	  type = types[i];
	  break;
	}
    }

  return type;
}

/* 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 = TYPE_TARGET_TYPE (check_typedef (value_type (c->val)));
  LONGEST offset = value_offset (v);
  LONGEST elsize = TYPE_LENGTH (eltype);
  int n, i, j = 0;
  LONGEST lowb = 0;
  LONGEST highb = 0;

  if (TYPE_CODE (type) == 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) + j++ * elsize,
	    value_contents (c->val) + c->indices[i] * elsize,
	    elsize);
}

static void
lval_func_write (struct value *v, struct value *fromval)
{
  struct value *mark = value_mark ();
  struct lval_closure *c = (struct lval_closure *) value_computed_closure (v);
  struct type *type = check_typedef (value_type (v));
  struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val)));
  LONGEST offset = value_offset (v);
  LONGEST elsize = TYPE_LENGTH (eltype);
  int n, i, j = 0;
  LONGEST lowb = 0;
  LONGEST highb = 0;

  if (TYPE_CODE (type) == 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),
	      value_contents (fromval) + j++ * elsize,
	      elsize);
      value_assign (to_elm_val, from_elm_val);
    }

  value_free_to_mark (mark);
}

/* 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 =
      TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 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,
    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 (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, TYPE_CODE (elm_type),
				   TYPE_LENGTH (elm_type),
				   TYPE_UNSIGNED (elm_type), 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)
			+ (i * TYPE_LENGTH (elm_type)),
			value_contents (val)
			+ (indices[i] * TYPE_LENGTH (elm_type)),
			TYPE_LENGTH (elm_type));
	    }
	}
    }
  return ret;
}

/* OpenCL vector component access.  */

static struct value *
opencl_component_ref (struct expression *exp, struct value *val, 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.  */

static struct value *
opencl_logical_not (struct expression *exp, struct value *arg)
{
  struct type *type = check_typedef (value_type (arg));
  struct type *rettype;
  struct value *ret;

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
    {
      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (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,
					   TYPE_LENGTH (eltype), 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) + i * TYPE_LENGTH (eltype),
		  tmp, TYPE_LENGTH (eltype));
	}
    }
  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 = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1));
  t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2));

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

  eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
  eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));

  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 (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
      || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
      || 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,
				       TYPE_LENGTH (eltype1), 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) + i * TYPE_LENGTH (eltype1),
	      tmp, TYPE_LENGTH (eltype1));
     }

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

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;
}

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

static struct value *
opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
	      enum exp_opcode op)
{
  struct value *val;
  struct type *type1 = check_typedef (value_type (arg1));
  struct type *type2 = check_typedef (value_type (arg2));
  int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
		   && TYPE_VECTOR (type1));
  int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
		   && TYPE_VECTOR (type2));

  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 (TYPE_CODE (t) != 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;
}

/* Expression evaluator for the OpenCL.  Most operations are delegated to
   evaluate_subexp_standard; see that function for a description of the
   arguments.  */

static struct value *
evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
		   int *pos, enum noside noside)
{
  enum exp_opcode op = exp->elts[*pos].opcode;
  struct value *arg1 = NULL;
  struct value *arg2 = NULL;
  struct type *type1, *type2;

  switch (op)
    {
    /* Handle assignment and cast operators to support OpenCL-style
       scalar-to-vector widening.  */
    case BINOP_ASSIGN:
      (*pos)++;
      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
      type1 = value_type (arg1);
      arg2 = evaluate_subexp (type1, exp, pos, noside);

      if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
	return arg1;

      if (deprecated_value_modifiable (arg1)
	  && VALUE_LVAL (arg1) != lval_internalvar)
	arg2 = opencl_value_cast (type1, arg2);

      return value_assign (arg1, arg2);

    case UNOP_CAST:
      type1 = exp->elts[*pos + 1].type;
      (*pos) += 2;
      arg1 = evaluate_subexp (type1, exp, pos, noside);

      if (noside == EVAL_SKIP)
	return value_from_longest (builtin_type (exp->gdbarch)->
				   builtin_int, 1);

      return opencl_value_cast (type1, arg1);

    case UNOP_CAST_TYPE:
      (*pos)++;
      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
      type1 = value_type (arg1);
      arg1 = evaluate_subexp (type1, exp, pos, noside);

      if (noside == EVAL_SKIP)
	return value_from_longest (builtin_type (exp->gdbarch)->
				   builtin_int, 1);

      return opencl_value_cast (type1, arg1);

    /* Handle binary relational and equality operators that are either not
       or differently defined for GNU vectors.  */
    case BINOP_EQUAL:
    case BINOP_NOTEQUAL:
    case BINOP_LESS:
    case BINOP_GTR:
    case BINOP_GEQ:
    case BINOP_LEQ:
      (*pos)++;
      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
      arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);

      if (noside == EVAL_SKIP)
	return value_from_longest (builtin_type (exp->gdbarch)->
				   builtin_int, 1);

      return opencl_relop (exp, arg1, arg2, op);

    /* Handle the logical unary operator not(!).  */
    case UNOP_LOGICAL_NOT:
      (*pos)++;
      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);

      if (noside == EVAL_SKIP)
	return value_from_longest (builtin_type (exp->gdbarch)->
				   builtin_int, 1);

      return opencl_logical_not (exp, arg1);

    /* Handle the logical operator and(&&) and or(||).  */
    case BINOP_LOGICAL_AND:
    case BINOP_LOGICAL_OR:
      (*pos)++;
      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);

      if (noside == EVAL_SKIP)
	{
	  evaluate_subexp (NULL_TYPE, exp, pos, noside);

	  return value_from_longest (builtin_type (exp->gdbarch)->
				     builtin_int, 1);
	}
      else
	{
	  /* For scalar operations we need to avoid evaluating operands
	     unecessarily.  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.  */
	  int oldpos = *pos;

	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
				  EVAL_AVOID_SIDE_EFFECTS);
	  *pos = oldpos;
	  type1 = check_typedef (value_type (arg1));
	  type2 = check_typedef (value_type (arg2));

	  if ((TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
	      || (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)))
	    {
	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);

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

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

	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos,
				      tmp ? EVAL_SKIP : noside);
	      type1 = language_bool_type (exp->language_defn, exp->gdbarch);

	      if (op == BINOP_LOGICAL_AND)
		res = !tmp && !value_logical_not (arg2);
	      else /* BINOP_LOGICAL_OR */
		res = tmp || !value_logical_not (arg2);

	      return value_from_longest (type1, res);
	    }
	}

    /* Handle the ternary selection operator.  */
    case TERNOP_COND:
      (*pos)++;
      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
      type1 = check_typedef (value_type (arg1));
      if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
	{
	  struct value *arg3, *tmp, *ret;
	  struct type *eltype2, *type3, *eltype3;
	  int t2_is_vec, t3_is_vec, i;
	  LONGEST lowb1, lowb2, lowb3, highb1, highb2, highb3;

	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
	  arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
	  type2 = check_typedef (value_type (arg2));
	  type3 = check_typedef (value_type (arg3));
	  t2_is_vec
	    = TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2);
	  t3_is_vec
	    = TYPE_CODE (type3) == TYPE_CODE_ARRAY && TYPE_VECTOR (type3);

	  /* 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 (TYPE_TARGET_TYPE (type2));
	  eltype3 = check_typedef (TYPE_TARGET_TYPE (type3));

	  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 (TYPE_CODE (eltype2) != TYPE_CODE (eltype3)
	      || TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3)
	      || TYPE_UNSIGNED (eltype2) != TYPE_UNSIGNED (eltype3)
	      || 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) +
		      i * TYPE_LENGTH (eltype2), value_contents_all (tmp),
		      TYPE_LENGTH (eltype2));
	    }

	  return ret;
	}
      else
	{
	  if (value_logical_not (arg1))
	    {
	      /* Skip the second operand.  */
	      evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);

	      return evaluate_subexp (NULL_TYPE, exp, pos, noside);
	    }
	  else
	    {
	      /* Skip the third operand.  */
	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
	      evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);

	      return arg2;
	    }
	}

    /* Handle STRUCTOP_STRUCT to allow component access on OpenCL vectors.  */
    case STRUCTOP_STRUCT:
      {
	int pc = (*pos)++;
	int tem = longest_to_int (exp->elts[pc + 1].longconst);

	(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
	arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
	type1 = check_typedef (value_type (arg1));

	if (noside == EVAL_SKIP)
	  {
	    return value_from_longest (builtin_type (exp->gdbarch)->
				       builtin_int, 1);
	  }
	else if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
	  {
	    return opencl_component_ref (exp, arg1, &exp->elts[pc + 2].string,
					 noside);
	  }
	else
	  {
	    struct value *v = value_struct_elt (&arg1, NULL,
						&exp->elts[pc + 2].string, NULL,
						"structure");

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

  return evaluate_subexp_c (expect_type, exp, pos, noside);
}

/* Print OpenCL types.  */

static void
opencl_print_type (struct type *type, const char *varstring,
		   struct ui_file *stream, int show, int level,
		   const struct type_print_options *flags)
{
  /* 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) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
	  && TYPE_NAME (type) != NULL)
	show = 0;
    }

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

static void
opencl_language_arch_info (struct gdbarch *gdbarch,
			   struct language_arch_info *lai)
{
  struct type **types = builtin_opencl_type (gdbarch);

  /* Copy primitive types vector from gdbarch.  */
  lai->primitive_type_vector = types;

  /* Type of elements of strings.  */
  lai->string_char_type = types [opencl_primitive_type_char];

  /* Specifies the return type of logical and relational operations.  */
  lai->bool_type_symbol = "int";
  lai->bool_type_default = types [opencl_primitive_type_int];
}

const struct exp_descriptor exp_descriptor_opencl =
{
  print_subexp_standard,
  operator_length_standard,
  operator_check_standard,
  op_name_standard,
  dump_subexp_body_standard,
  evaluate_subexp_opencl
};

extern const struct language_defn opencl_language_defn =
{
  "opencl",			/* Language name */
  "OpenCL C",
  language_opencl,
  range_check_off,
  case_sensitive_on,
  array_row_major,
  macro_expansion_c,
  NULL,
  &exp_descriptor_opencl,
  c_parse,
  null_post_parser,
  c_printchar,			/* Print a character constant */
  c_printstr,			/* Function to print string constant */
  c_emit_char,			/* Print a single char */
  opencl_print_type,		/* Print a type using appropriate syntax */
  c_print_typedef,		/* Print a typedef using appropriate syntax */
  c_val_print,			/* Print a value using appropriate syntax */
  c_value_print,		/* Print a top-level value */
  default_read_var_value,	/* la_read_var_value */
  NULL,				/* Language specific skip_trampoline */
  NULL,                         /* name_of_this */
  false,			/* la_store_sym_names_in_linkage_form_p */
  basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
  basic_lookup_transparent_type,/* lookup_transparent_type */
  NULL,				/* Language specific symbol demangler */
  NULL,
  NULL,				/* Language specific
				   class_name_from_physname */
  c_op_print_tab,		/* expression operators for printing */
  1,				/* c-style arrays */
  0,				/* String lower bound */
  default_word_break_characters,
  default_collect_symbol_completion_matches,
  opencl_language_arch_info,
  default_print_array_index,
  default_pass_by_reference,
  c_get_string,
  c_watch_location_expression,
  NULL,				/* la_get_symbol_name_matcher */
  iterate_over_symbols,
  default_search_name_hash,
  &default_varobj_ops,
  NULL,
  NULL,
  LANG_MAGIC
};

static void *
build_opencl_types (struct gdbarch *gdbarch)
{
  struct type **types
    = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_opencl_primitive_types + 1,
			      struct type *);

/* 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)\
  types[opencl_primitive_type_##TYPE##2] \
    = init_vector_type (types[opencl_primitive_type_##TYPE], 2); \
  TYPE_NAME (types[opencl_primitive_type_##TYPE##2]) = OCL_STRING(TYPE ## 2); \
  types[opencl_primitive_type_##TYPE##3] \
    = init_vector_type (types[opencl_primitive_type_##TYPE], 3); \
  TYPE_NAME (types[opencl_primitive_type_##TYPE##3]) = OCL_STRING(TYPE ## 3); \
  TYPE_LENGTH (types[opencl_primitive_type_##TYPE##3]) \
    = 4 * TYPE_LENGTH (types[opencl_primitive_type_##TYPE]); \
  types[opencl_primitive_type_##TYPE##4] \
    = init_vector_type (types[opencl_primitive_type_##TYPE], 4); \
  TYPE_NAME (types[opencl_primitive_type_##TYPE##4]) = OCL_STRING(TYPE ## 4); \
  types[opencl_primitive_type_##TYPE##8] \
    = init_vector_type (types[opencl_primitive_type_##TYPE], 8); \
  TYPE_NAME (types[opencl_primitive_type_##TYPE##8]) = OCL_STRING(TYPE ## 8); \
  types[opencl_primitive_type_##TYPE##16] \
    = init_vector_type (types[opencl_primitive_type_##TYPE], 16); \
  TYPE_NAME (types[opencl_primitive_type_##TYPE##16]) = OCL_STRING(TYPE ## 16)

  types[opencl_primitive_type_char]
    = arch_integer_type (gdbarch, 8, 0, "char");
  BUILD_OCL_VTYPES (char);
  types[opencl_primitive_type_uchar]
    = arch_integer_type (gdbarch, 8, 1, "uchar");
  BUILD_OCL_VTYPES (uchar);
  types[opencl_primitive_type_short]
    = arch_integer_type (gdbarch, 16, 0, "short");
  BUILD_OCL_VTYPES (short);
  types[opencl_primitive_type_ushort]
    = arch_integer_type (gdbarch, 16, 1, "ushort");
  BUILD_OCL_VTYPES (ushort);
  types[opencl_primitive_type_int]
    = arch_integer_type (gdbarch, 32, 0, "int");
  BUILD_OCL_VTYPES (int);
  types[opencl_primitive_type_uint]
    = arch_integer_type (gdbarch, 32, 1, "uint");
  BUILD_OCL_VTYPES (uint);
  types[opencl_primitive_type_long]
    = arch_integer_type (gdbarch, 64, 0, "long");
  BUILD_OCL_VTYPES (long);
  types[opencl_primitive_type_ulong]
    = arch_integer_type (gdbarch, 64, 1, "ulong");
  BUILD_OCL_VTYPES (ulong);
  types[opencl_primitive_type_half]
    = arch_float_type (gdbarch, 16, "half", floatformats_ieee_half);
  BUILD_OCL_VTYPES (half);
  types[opencl_primitive_type_float]
    = arch_float_type (gdbarch, 32, "float", floatformats_ieee_single);
  BUILD_OCL_VTYPES (float);
  types[opencl_primitive_type_double]
    = arch_float_type (gdbarch, 64, "double", floatformats_ieee_double);
  BUILD_OCL_VTYPES (double);
  types[opencl_primitive_type_bool]
    = arch_boolean_type (gdbarch, 8, 1, "bool");
  types[opencl_primitive_type_unsigned_char]
    = arch_integer_type (gdbarch, 8, 1, "unsigned char");
  types[opencl_primitive_type_unsigned_short]
    = arch_integer_type (gdbarch, 16, 1, "unsigned short");
  types[opencl_primitive_type_unsigned_int]
    = arch_integer_type (gdbarch, 32, 1, "unsigned int");
  types[opencl_primitive_type_unsigned_long]
    = arch_integer_type (gdbarch, 64, 1, "unsigned long");
  types[opencl_primitive_type_size_t]
    = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "size_t");
  types[opencl_primitive_type_ptrdiff_t]
    = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "ptrdiff_t");
  types[opencl_primitive_type_intptr_t]
    = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "intptr_t");
  types[opencl_primitive_type_uintptr_t]
    = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr_t");
  types[opencl_primitive_type_void]
    = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");

  return types;
}

void
_initialize_opencl_language (void)
{
  opencl_type_data = gdbarch_data_register_post_init (build_opencl_types);
}
