packaging: Add python3-base dependency
[platform/upstream/gdb.git] / gdb / opencl-lang.c
index 03699b1..0052c56 100644 (file)
@@ -1,5 +1,5 @@
 /* OpenCL language support for GDB, the GNU debugger.
-   Copyright (C) 2010-2019 Free Software Foundation, Inc.
+   Copyright (C) 2010-2023 Free Software Foundation, Inc.
 
    Contributed by Ken Werner <ken.werner@de.ibm.com>.
 
 #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);
-}
+#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
@@ -79,10 +38,7 @@ 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)
@@ -91,24 +47,20 @@ lookup_opencl_vector_type (struct gdbarch *gdbarch, enum type_code code,
   /* 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;
+  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
@@ -122,10 +74,10 @@ array_has_dups (int *arr, int n)
   for (i = 0; i < n; i++)
     {
       for (j = i + 1; j < n; j++)
-        {
-          if (arr[i] == arr[j])
-            return 1;
-        }
+       {
+         if (arr[i] == arr[j])
+           return 1;
+       }
     }
 
   return 0;
@@ -169,14 +121,14 @@ 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)));
+  struct type *eltype = check_typedef (value_type (c->val))->target_type ();
   LONGEST offset = value_offset (v);
-  LONGEST elsize = TYPE_LENGTH (eltype);
+  LONGEST elsize = eltype->length ();
   int n, i, j = 0;
   LONGEST lowb = 0;
   LONGEST highb = 0;
 
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+  if (type->code () == TYPE_CODE_ARRAY
       && !get_array_bounds (type, &lowb, &highb))
     error (_("Could not determine the vector bounds"));
 
@@ -187,25 +139,26 @@ lval_func_read (struct value *v)
   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,
+    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)
 {
-  struct value *mark = value_mark ();
+  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 = TYPE_TARGET_TYPE (check_typedef (value_type (c->val)));
+  struct type *eltype = check_typedef (value_type (c->val))->target_type ();
   LONGEST offset = value_offset (v);
-  LONGEST elsize = TYPE_LENGTH (eltype);
+  LONGEST elsize = eltype->length ();
   int n, i, j = 0;
   LONGEST lowb = 0;
   LONGEST highb = 0;
 
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+  if (type->code () == TYPE_CODE_ARRAY
       && !get_array_bounds (type, &lowb, &highb))
     error (_("Could not determine the vector bounds"));
 
@@ -227,13 +180,11 @@ lval_func_write (struct value *v, struct value *fromval)
       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,
+      memcpy (value_contents_writeable (from_elm_val).data (),
+             value_contents (fromval).data () + 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
@@ -246,7 +197,7 @@ lval_func_check_synthetic_pointer (const struct value *v,
   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;
+      check_typedef (value_type (c->val))->target_type ()->length () * 8;
   int startrest = offset % elsize;
   int start = offset / elsize;
   int endrest = (offset + length) % elsize;
@@ -302,6 +253,7 @@ 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,
@@ -318,7 +270,7 @@ 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 type *elm_type = type->target_type ();
   struct value *ret;
 
   /* Check if a single component of a vector is requested which means
@@ -326,18 +278,18 @@ create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside,
   if (n == 1)
     {
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
-        ret = value_zero (elm_type, not_lval);
+       ret = value_zero (elm_type, not_lval);
       else
-        ret = value_subscript (val, indices[0]);
+       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);
+       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);
@@ -362,11 +314,11 @@ create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside,
 
              /* 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));
+               memcpy (value_contents_writeable (ret).data ()
+                       + (i * elm_type->length ()),
+                       value_contents (val).data ()
+                       + (indices[i] * elm_type->length ()),
+                       elm_type->length ());
            }
        }
     }
@@ -376,8 +328,8 @@ create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside,
 /* OpenCL vector component access.  */
 
 static struct value *
-opencl_component_ref (struct expression *exp, struct value *val, char *comps,
-                     enum noside noside)
+opencl_component_ref (struct expression *exp, struct value *val,
+                     const char *comps, enum noside noside)
 {
   LONGEST lowb, highb;
   int src_len;
@@ -422,14 +374,14 @@ opencl_component_ref (struct expression *exp, struct value *val, char *comps,
       dst_len = (src_len == 3) ? 2 : src_len / 2;
 
       for (i = 0; i < dst_len; i++)
-        indices[i] = i*2+1;
+       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)))
+                          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.  */
@@ -489,16 +441,18 @@ opencl_component_ref (struct expression *exp, struct value *val, char *comps,
 
 /* Perform the unary logical not (!) operation.  */
 
-static struct value *
-opencl_logical_not (struct expression *exp, struct value *arg)
+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) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+  if (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
     {
-      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+      struct type *eltype = check_typedef (type->target_type ());
       LONGEST lowb, highb;
       int i;
 
@@ -508,7 +462,7 @@ opencl_logical_not (struct expression *exp, struct value *arg)
       /* 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,
+                                          eltype->length (), 0,
                                           highb - lowb + 1);
       ret = allocate_value (rettype);
 
@@ -518,8 +472,9 @@ opencl_logical_not (struct expression *exp, struct value *arg)
          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));
+         memset ((value_contents_writeable (ret).data ()
+                  + i * eltype->length ()),
+                 tmp, eltype->length ());
        }
     }
   else
@@ -585,29 +540,29 @@ vector_relop (struct expression *exp, struct value *val1, struct value *val2,
   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));
+  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 (TYPE_TARGET_TYPE (type1));
-  eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
+  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 (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
-      || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
-      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
+  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,
-                                      TYPE_LENGTH (eltype1), 0,
+                                      eltype1->length (), 0,
                                       highb1 - lowb1 + 1);
   ret = allocate_value (rettype);
 
@@ -618,8 +573,9 @@ vector_relop (struct expression *exp, struct value *val1, struct value *val2,
         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));
+      memset ((value_contents_writeable (ret).data ()
+              + i * eltype1->length ()),
+             tmp, eltype1->length ());
      }
 
   return ret;
@@ -630,7 +586,7 @@ vector_relop (struct expression *exp, struct value *val1, struct value *val2,
    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 *
+struct value *
 opencl_value_cast (struct type *type, struct value *arg)
 {
   if (type != value_type (arg))
@@ -646,18 +602,18 @@ opencl_value_cast (struct type *type, struct value *arg)
 
       to_type = check_typedef (type);
 
-      code1 = TYPE_CODE (to_type);
-      code2 = TYPE_CODE (check_typedef (value_type (arg)));
+      code1 = to_type->code ();
+      code2 = check_typedef (value_type (arg))->code ();
 
       if (code2 == TYPE_CODE_REF)
-       code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
+       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 && TYPE_VECTOR (to_type) && scalar)
+      if (code1 == TYPE_CODE_ARRAY && to_type->is_vector () && scalar)
        {
          struct type *eltype;
 
@@ -665,7 +621,7 @@ opencl_value_cast (struct type *type, struct value *arg)
             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));
+         eltype = check_typedef (to_type->target_type ());
          arg = value_cast (eltype, arg);
 
          return value_vector_widen (arg, type);
@@ -679,17 +635,18 @@ opencl_value_cast (struct type *type, struct value *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 *
+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 = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
-                  && TYPE_VECTOR (type1));
-  int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
-                  && TYPE_VECTOR (type2));
+  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)
     {
@@ -709,7 +666,7 @@ opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
       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))
+      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);
@@ -719,466 +676,314 @@ opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
   return val;
 }
 
-/* Expression evaluator for the OpenCL.  Most operations are delegated to
-   evaluate_subexp_standard; see that function for a description of the
-   arguments.  */
+/* A helper function for BINOP_ASSIGN.  */
 
-static struct value *
-evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
-                  int *pos, enum noside noside)
+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)
 {
-  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_AVOID_SIDE_EFFECTS)
+    return arg1;
 
-      if (noside == EVAL_SKIP || 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);
 
-      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);
+  return value_assign (arg1, arg2);
+}
 
-    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);
+namespace expr
+{
 
-      if (noside == EVAL_SKIP)
-       return value_from_longest (builtin_type (exp->gdbarch)->
-                                  builtin_int, 1);
+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));
 
-      return opencl_value_cast (type1, 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");
 
-    /* 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_AVOID_SIDE_EFFECTS)
+       v = value_zero (value_type (v), VALUE_LVAL (v));
+      return v;
+    }
+}
 
-      if (noside == EVAL_SKIP)
-       return value_from_longest (builtin_type (exp->gdbarch)->
-                                  builtin_int, 1);
+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));
 
-      return opencl_relop (exp, arg1, arg2, op);
+  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);
 
-    /* Handle the logical unary operator not(!).  */
-    case UNOP_LOGICAL_NOT:
-      (*pos)++;
-      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, 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 (noside == EVAL_SKIP)
-       return value_from_longest (builtin_type (exp->gdbarch)->
-                                  builtin_int, 1);
+      if (op == BINOP_LOGICAL_OR)
+       tmp = !tmp;
 
-      return opencl_logical_not (exp, arg1);
+      if (!tmp)
+       {
+         arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+         tmp = value_logical_not (arg2);
+         if (op == BINOP_LOGICAL_OR)
+           tmp = !tmp;
+       }
 
-    /* Handle the logical operator and(&&) and or(||).  */
-    case BINOP_LOGICAL_AND:
-    case BINOP_LOGICAL_OR:
-      (*pos)++;
-      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      type1 = language_bool_type (exp->language_defn, exp->gdbarch);
+      return value_from_longest (type1, tmp);
+    }
+}
 
-      if (noside == EVAL_SKIP)
+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)
        {
-         evaluate_subexp (NULL_TYPE, exp, pos, noside);
-
-         return value_from_longest (builtin_type (exp->gdbarch)->
-                                    builtin_int, 1);
+         arg3 = opencl_value_cast (type2, arg3);
+         type3 = value_type (arg3);
        }
-      else
+      else if (!t2_is_vec || t3_is_vec)
        {
-         /* 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);
-           }
+         arg2 = opencl_value_cast (type3, arg2);
+         type2 = value_type (arg2);
        }
-
-    /* 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))
+      else if (!t2_is_vec || !t3_is_vec)
        {
-         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 (_("\
+         /* 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));
+      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"));
+      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 (_("\
+      /* 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 (_("\
+      /* 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);
+      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;
+      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
-       {
-         if (value_logical_not (arg1))
-           {
-             /* Skip the second operand.  */
-             evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+       return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+    }
+}
 
-             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);
+} /* namespace expr */
 
-             return arg2;
-           }
-       }
+/* Class representing the OpenCL language.  */
 
-    /* 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);
+class opencl_language : public language_defn
+{
+public:
+  opencl_language ()
+    : language_defn (language_opencl)
+  { /* Nothing.  */ }
 
-       (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-       type1 = check_typedef (value_type (arg1));
+  /* See language.h.  */
 
-       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");
+  const char *name () const override
+  { return "opencl"; }
 
-           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);
-}
+  /* See language.h.  */
 
-/* Print OpenCL types.  */
+  const char *natural_name () const override
+  { return "OpenCL C"; }
 
-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)
+  /* 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 *
     {
-      type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
-         && TYPE_NAME (type) != NULL)
-       show = 0;
-    }
+      lai->add_primitive_type (t);
+      return t;
+    };
 
-  c_print_type (type, varstring, stream, show, level, flags); 
-}
+/* Helper macro to create strings.  */
+#define OCL_STRING(S) #S
 
-static void
-opencl_language_arch_info (struct gdbarch *gdbarch,
-                          struct language_arch_info *lai)
-{
-  struct type **types = builtin_opencl_type (gdbarch);
+/* 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;
+  }
 
-  /* Copy primitive types vector from gdbarch.  */
-  lai->primitive_type_vector = types;
+  /* See language.h.  */
 
-  /* Type of elements of strings.  */
-  lai->string_char_type = types [opencl_primitive_type_char];
+  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;
+      }
 
-  /* Specifies the return type of logical and relational operations.  */
-  lai->bool_type_symbol = "int";
-  lai->bool_type_default = types [opencl_primitive_type_int];
-}
+    c_print_type (type, varstring, stream, show, level, la_language, flags);
+  }
 
-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
-};
+  /* See language.h.  */
 
-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
+  enum macro_expansion macro_expansion () const override
+  { return macro_expansion_c; }
 };
 
-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;
-}
+/* Single instance of the OpenCL language class.  */
 
-void
-_initialize_opencl_language (void)
-{
-  opencl_type_data = gdbarch_data_register_post_init (build_opencl_types);
-}
+static opencl_language opencl_language_defn;