/* OpenCL language support for GDB, the GNU debugger.
- Copyright (C) 2010-2020 Free Software Foundation, Inc.
+ Copyright (C) 2010-2022 Free Software Foundation, Inc.
Contributed by Ken Werner <ken.werner@de.ibm.com>.
#include "varobj.h"
#include "c-lang.h"
#include "gdbarch.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 "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
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)
/* 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 (types[i]->code () == TYPE_CODE_ARRAY && types[i]->is_vector ()
- && get_array_bounds (types[i], &lowb, &highb)
- && TYPE_TARGET_TYPE (types[i])->code () == code
- && TYPE_TARGET_TYPE (types[i])->is_unsigned () == 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 (type)->code () == code
+ && TYPE_TARGET_TYPE (type)->is_unsigned () == flag_unsigned
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == el_length
+ && TYPE_LENGTH (type) == 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
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;
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);
}
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);
}
{
lval_func_read,
lval_func_write,
+ nullptr,
NULL, /* indirect */
NULL, /* coerce_ref */
lval_func_check_synthetic_pointer,
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
{
/* Copy src val contents into the destination value. */
for (i = 0; i < n; i++)
- memcpy (value_contents_writeable (ret)
+ memcpy (value_contents_writeable (ret).data ()
+ (i * TYPE_LENGTH (elm_type)),
- value_contents (val)
+ value_contents (val).data ()
+ (indices[i] * TYPE_LENGTH (elm_type)),
TYPE_LENGTH (elm_type));
}
/* 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;
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. */
/* 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;
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),
+ memset ((value_contents_writeable (ret).data ()
+ + i * TYPE_LENGTH (eltype)),
tmp, TYPE_LENGTH (eltype));
}
}
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),
+ memset ((value_contents_writeable (ret).data ()
+ + i * TYPE_LENGTH (eltype1)),
tmp, TYPE_LENGTH (eltype1));
}
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))
/* 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));
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 (nullptr, 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 (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return arg1;
- if (deprecated_value_modifiable (arg1)
- && VALUE_LVAL (arg1) != lval_internalvar)
- arg2 = opencl_value_cast (type1, arg2);
+ 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);
-
- 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 (nullptr, 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 (nullptr, 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 (nullptr, 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 (nullptr, 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
- 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. */
- int oldpos = *pos;
-
- arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
- *pos = oldpos;
- type1 = check_typedef (value_type (arg1));
- type2 = check_typedef (value_type (arg2));
-
- if ((type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
- || (type2->code () == TYPE_CODE_ARRAY && type2->is_vector ()))
- {
- arg2 = evaluate_subexp (nullptr, 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 (nullptr, 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 (nullptr, exp, pos, noside);
- type1 = check_typedef (value_type (arg1));
- if (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
+ 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 (nullptr, exp, pos, noside);
- arg3 = evaluate_subexp (nullptr, exp, pos, 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 (_("\
+ /* 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 (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"));
+ 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 ()
- || TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3)
- || eltype2->is_unsigned () != eltype3->is_unsigned ()
- || lowb2 != lowb3 || highb2 != highb3)
- error (_("\
+ /* Throw an error if the types of arg2 or arg3 are incompatible. */
+ if (eltype2->code () != eltype3->code ()
+ || TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3)
+ || 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;
- }
- else
+ for (i = 0; i < highb1 - lowb1 + 1; i++)
{
- if (value_logical_not (arg1))
- {
- /* Skip the second operand. */
- evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-
- return evaluate_subexp (nullptr, exp, pos, noside);
- }
- else
- {
- /* Skip the third operand. */
- arg2 = evaluate_subexp (nullptr, exp, pos, noside);
- evaluate_subexp (nullptr, exp, pos, EVAL_SKIP);
-
- return arg2;
- }
+ tmp = value_logical_not (value_subscript (arg1, i)) ?
+ value_subscript (arg3, i) : value_subscript (arg2, i);
+ memcpy (value_contents_writeable (ret).data () +
+ i * TYPE_LENGTH (eltype2), value_contents_all (tmp).data (),
+ TYPE_LENGTH (eltype2));
}
- /* 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 (nullptr, 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 (type1->code () == TYPE_CODE_ARRAY && type1->is_vector ())
- {
- 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 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);
}
-
- return evaluate_subexp_c (expect_type, exp, pos, noside);
}
-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
-};
+} /* namespace expr */
/* Class representing the OpenCL language. */
void language_arch_info (struct gdbarch *gdbarch,
struct language_arch_info *lai) const override
{
- struct type **types = builtin_opencl_type (gdbarch);
+ /* 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
- /* Copy primitive types vector from gdbarch. */
- lai->primitive_type_vector = types;
+/* 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)); \
+ TYPE_LENGTH (tmp) = 4 * TYPE_LENGTH (ELEMENT_TYPE); \
+ 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->string_char_type = types [opencl_primitive_type_char];
+ lai->set_string_char_type (char_type);
/* Specifies the return type of logical and relational operations. */
- lai->bool_type_symbol = "int";
- lai->bool_type_default = types [opencl_primitive_type_int];
+ lai->set_bool_type (int_type, "int");
}
/* See language.h. */
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
-
- /* See language.h. */
-
- const struct exp_descriptor *expression_ops () const override
- { return &exp_descriptor_opencl; }
-
- /* See language.h. */
-
- const struct op_print *opcode_print_table () const override
- { return c_op_print_tab; }
};
/* Single instance of the OpenCL language class. */
static opencl_language opencl_language_defn;
-
-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); \
- types[opencl_primitive_type_##TYPE##2]->set_name (OCL_STRING(TYPE ## 2)); \
- types[opencl_primitive_type_##TYPE##3] \
- = init_vector_type (types[opencl_primitive_type_##TYPE], 3); \
- types[opencl_primitive_type_##TYPE##3]->set_name (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); \
- types[opencl_primitive_type_##TYPE##4]->set_name (OCL_STRING(TYPE ## 4)); \
- types[opencl_primitive_type_##TYPE##8] \
- = init_vector_type (types[opencl_primitive_type_##TYPE], 8); \
- types[opencl_primitive_type_##TYPE##8]->set_name (OCL_STRING(TYPE ## 8)); \
- types[opencl_primitive_type_##TYPE##16] \
- = init_vector_type (types[opencl_primitive_type_##TYPE], 16); \
- types[opencl_primitive_type_##TYPE##16]->set_name (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
-_initialize_opencl_language ()
-{
- opencl_type_data = gdbarch_data_register_post_init (build_opencl_types);
-}