/* OpenCL language support for GDB, the GNU debugger.
- Copyright (C) 2010-2017 Free Software Foundation, Inc.
+ Copyright (C) 2010-2020 Free Software Foundation, Inc.
Contributed by Ken Werner <ken.werner@de.ibm.com>.
#include "language.h"
#include "varobj.h"
#include "c-lang.h"
+#include "gdbarch.h"
/* This macro generates enum values from a given type. */
{
LONGEST lowb, highb;
- if (TYPE_CODE (types[i]) == TYPE_CODE_ARRAY && TYPE_VECTOR (types[i])
+ if (types[i]->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (types[i])
&& get_array_bounds (types[i], &lowb, &highb)
- && TYPE_CODE (TYPE_TARGET_TYPE (types[i])) == code
+ && TYPE_TARGET_TYPE (types[i])->code () == code
&& TYPE_UNSIGNED (TYPE_TARGET_TYPE (types[i])) == flag_unsigned
&& TYPE_LENGTH (TYPE_TARGET_TYPE (types[i])) == el_length
&& TYPE_LENGTH (types[i]) == length
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"));
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"));
if (c->refc == 0)
{
- value_free (c->val); /* Decrement the reference counter of the value. */
+ value_decref (c->val); /* Decrement the reference counter of the value. */
xfree (c->indices);
xfree (c);
}
/* 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),
+ lookup_opencl_vector_type (gdbarch, elm_type->code (),
TYPE_LENGTH (elm_type),
TYPE_UNSIGNED (elm_type), n);
struct type *rettype;
struct value *ret;
- if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+ if (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
{
struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
LONGEST lowb, highb;
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 && TYPE_VECTOR (type1));
+ t2_is_vec = (type2->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type2));
if (!t1_is_vec || !t2_is_vec)
error (_("Vector operations are not supported on scalar types"));
error (_("Could not determine the vector bounds"));
/* Check whether the vector types are compatible. */
- if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
+ if (eltype1->code () != eltype2->code ()
|| TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
|| TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
|| lowb1 != lowb2 || highb1 != highb2)
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
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
+ int t1_is_vec = (type1->code () == TYPE_CODE_ARRAY
&& TYPE_VECTOR (type1));
- int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
+ int t2_is_vec = (type2->code () == TYPE_CODE_ARRAY
&& TYPE_VECTOR (type2));
if (!t1_is_vec && !t2_is_vec)
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);
else
{
/* For scalar operations we need to avoid evaluating operands
- unecessarily. However, for vector operations we always need to
+ 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. */
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)))
+ if ((type1->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
+ || (type2->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)))
{
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
(*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))
+ if (type1->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
{
struct value *arg3, *tmp, *ret;
struct type *eltype2, *type3, *eltype3;
type2 = check_typedef (value_type (arg2));
type3 = check_typedef (value_type (arg3));
t2_is_vec
- = TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2);
+ = type2->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type2);
t3_is_vec
- = TYPE_CODE (type3) == TYPE_CODE_ARRAY && TYPE_VECTOR (type3);
+ = type3->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type3);
/* Widen the scalar operand to a vector if necessary. */
if (t2_is_vec || !t3_is_vec)
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)
+ if (eltype2->code () != eltype3->code ()
|| TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3)
|| TYPE_UNSIGNED (eltype2) != TYPE_UNSIGNED (eltype3)
|| lowb2 != lowb3 || highb2 != highb3)
return value_from_longest (builtin_type (exp->gdbarch)->
builtin_int, 1);
}
- else if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
+ else if (type1->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
{
return opencl_component_ref (exp, arg1, &exp->elts[pc + 2].string,
noside);
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,
evaluate_subexp_opencl
};
-extern const struct language_defn opencl_language_defn =
+/* Constant data representing the OpenCL language. */
+extern const struct language_data opencl_language_data =
{
"opencl", /* Language name */
"OpenCL C",
NULL,
&exp_descriptor_opencl,
c_parse,
- c_yyerror,
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_inner, /* la_value_print_inner */
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 */
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
+ c_is_string_type_p,
+ "{...}" /* la_struct_too_deep_ellipsis */
+};
+
+/* Class representing the OpenCL language. */
+
+class opencl_language : public language_defn
+{
+public:
+ opencl_language ()
+ : language_defn (language_opencl, opencl_language_data)
+ { /* Nothing. */ }
+
+ /* See language.h. */
+ void language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const override
+ {
+ 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];
+ }
+
+ /* See language.h. */
+
+ void print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags) const override
+ {
+ /* We nearly always defer to C type printing, except that vector types
+ are considered primitive in OpenCL, and should always be printed
+ using their TYPE_NAME. */
+ if (show > 0)
+ {
+ type = check_typedef (type);
+ if (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+ && type->name () != NULL)
+ show = 0;
+ }
+
+ c_print_type (type, varstring, stream, show, level, flags);
+ }
};
+/* Single instance of the OpenCL language class. */
+
+static opencl_language opencl_language_defn;
+
static void *
build_opencl_types (struct gdbarch *gdbarch)
{
#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##2]->set_name (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); \
+ 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); \
- TYPE_NAME (types[opencl_primitive_type_##TYPE##4]) = OCL_STRING(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); \
- TYPE_NAME (types[opencl_primitive_type_##TYPE##8]) = OCL_STRING(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); \
- TYPE_NAME (types[opencl_primitive_type_##TYPE##16]) = OCL_STRING(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");
return types;
}
+void _initialize_opencl_language ();
void
-_initialize_opencl_language (void)
+_initialize_opencl_language ()
{
opencl_type_data = gdbarch_data_register_post_init (build_opencl_types);
}