GDB (API)
|
00001 /* OpenCL language support for GDB, the GNU debugger. 00002 Copyright (C) 2010-2013 Free Software Foundation, Inc. 00003 00004 Contributed by Ken Werner <ken.werner@de.ibm.com>. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "defs.h" 00022 #include "gdb_string.h" 00023 #include "gdbtypes.h" 00024 #include "symtab.h" 00025 #include "expression.h" 00026 #include "parser-defs.h" 00027 #include "symtab.h" 00028 #include "language.h" 00029 #include "c-lang.h" 00030 #include "gdb_assert.h" 00031 00032 extern void _initialize_opencl_language (void); 00033 00034 /* This macro generates enum values from a given type. */ 00035 00036 #define OCL_P_TYPE(TYPE)\ 00037 opencl_primitive_type_##TYPE,\ 00038 opencl_primitive_type_##TYPE##2,\ 00039 opencl_primitive_type_##TYPE##3,\ 00040 opencl_primitive_type_##TYPE##4,\ 00041 opencl_primitive_type_##TYPE##8,\ 00042 opencl_primitive_type_##TYPE##16 00043 00044 enum opencl_primitive_types { 00045 OCL_P_TYPE (char), 00046 OCL_P_TYPE (uchar), 00047 OCL_P_TYPE (short), 00048 OCL_P_TYPE (ushort), 00049 OCL_P_TYPE (int), 00050 OCL_P_TYPE (uint), 00051 OCL_P_TYPE (long), 00052 OCL_P_TYPE (ulong), 00053 OCL_P_TYPE (half), 00054 OCL_P_TYPE (float), 00055 OCL_P_TYPE (double), 00056 opencl_primitive_type_bool, 00057 opencl_primitive_type_unsigned_char, 00058 opencl_primitive_type_unsigned_short, 00059 opencl_primitive_type_unsigned_int, 00060 opencl_primitive_type_unsigned_long, 00061 opencl_primitive_type_size_t, 00062 opencl_primitive_type_ptrdiff_t, 00063 opencl_primitive_type_intptr_t, 00064 opencl_primitive_type_uintptr_t, 00065 opencl_primitive_type_void, 00066 nr_opencl_primitive_types 00067 }; 00068 00069 static struct gdbarch_data *opencl_type_data; 00070 00071 static struct type ** 00072 builtin_opencl_type (struct gdbarch *gdbarch) 00073 { 00074 return gdbarch_data (gdbarch, opencl_type_data); 00075 } 00076 00077 /* Returns the corresponding OpenCL vector type from the given type code, 00078 the length of the element type, the unsigned flag and the amount of 00079 elements (N). */ 00080 00081 static struct type * 00082 lookup_opencl_vector_type (struct gdbarch *gdbarch, enum type_code code, 00083 unsigned int el_length, unsigned int flag_unsigned, 00084 int n) 00085 { 00086 int i; 00087 unsigned int length; 00088 struct type *type = NULL; 00089 struct type **types = builtin_opencl_type (gdbarch); 00090 00091 /* Check if n describes a valid OpenCL vector size (2, 3, 4, 8, 16). */ 00092 if (n != 2 && n != 3 && n != 4 && n != 8 && n != 16) 00093 error (_("Invalid OpenCL vector size: %d"), n); 00094 00095 /* Triple vectors have the size of a quad vector. */ 00096 length = (n == 3) ? el_length * 4 : el_length * n; 00097 00098 for (i = 0; i < nr_opencl_primitive_types; i++) 00099 { 00100 LONGEST lowb, highb; 00101 00102 if (TYPE_CODE (types[i]) == TYPE_CODE_ARRAY && TYPE_VECTOR (types[i]) 00103 && get_array_bounds (types[i], &lowb, &highb) 00104 && TYPE_CODE (TYPE_TARGET_TYPE (types[i])) == code 00105 && TYPE_UNSIGNED (TYPE_TARGET_TYPE (types[i])) == flag_unsigned 00106 && TYPE_LENGTH (TYPE_TARGET_TYPE (types[i])) == el_length 00107 && TYPE_LENGTH (types[i]) == length 00108 && highb - lowb + 1 == n) 00109 { 00110 type = types[i]; 00111 break; 00112 } 00113 } 00114 00115 return type; 00116 } 00117 00118 /* Returns nonzero if the array ARR contains duplicates within 00119 the first N elements. */ 00120 00121 static int 00122 array_has_dups (int *arr, int n) 00123 { 00124 int i, j; 00125 00126 for (i = 0; i < n; i++) 00127 { 00128 for (j = i + 1; j < n; j++) 00129 { 00130 if (arr[i] == arr[j]) 00131 return 1; 00132 } 00133 } 00134 00135 return 0; 00136 } 00137 00138 /* The OpenCL component access syntax allows to create lvalues referring to 00139 selected elements of an original OpenCL vector in arbitrary order. This 00140 structure holds the information to describe such lvalues. */ 00141 00142 struct lval_closure 00143 { 00144 /* Reference count. */ 00145 int refc; 00146 /* The number of indices. */ 00147 int n; 00148 /* The element indices themselves. */ 00149 int *indices; 00150 /* A pointer to the original value. */ 00151 struct value *val; 00152 }; 00153 00154 /* Allocates an instance of struct lval_closure. */ 00155 00156 static struct lval_closure * 00157 allocate_lval_closure (int *indices, int n, struct value *val) 00158 { 00159 struct lval_closure *c = XZALLOC (struct lval_closure); 00160 00161 c->refc = 1; 00162 c->n = n; 00163 c->indices = XCALLOC (n, int); 00164 memcpy (c->indices, indices, n * sizeof (int)); 00165 value_incref (val); /* Increment the reference counter of the value. */ 00166 c->val = val; 00167 00168 return c; 00169 } 00170 00171 static void 00172 lval_func_read (struct value *v) 00173 { 00174 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00175 struct type *type = check_typedef (value_type (v)); 00176 struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val))); 00177 int offset = value_offset (v); 00178 int elsize = TYPE_LENGTH (eltype); 00179 int n, i, j = 0; 00180 LONGEST lowb = 0; 00181 LONGEST highb = 0; 00182 00183 if (TYPE_CODE (type) == TYPE_CODE_ARRAY 00184 && !get_array_bounds (type, &lowb, &highb)) 00185 error (_("Could not determine the vector bounds")); 00186 00187 /* Assume elsize aligned offset. */ 00188 gdb_assert (offset % elsize == 0); 00189 offset /= elsize; 00190 n = offset + highb - lowb + 1; 00191 gdb_assert (n <= c->n); 00192 00193 for (i = offset; i < n; i++) 00194 memcpy (value_contents_raw (v) + j++ * elsize, 00195 value_contents (c->val) + c->indices[i] * elsize, 00196 elsize); 00197 } 00198 00199 static void 00200 lval_func_write (struct value *v, struct value *fromval) 00201 { 00202 struct value *mark = value_mark (); 00203 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00204 struct type *type = check_typedef (value_type (v)); 00205 struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val))); 00206 int offset = value_offset (v); 00207 int elsize = TYPE_LENGTH (eltype); 00208 int n, i, j = 0; 00209 LONGEST lowb = 0; 00210 LONGEST highb = 0; 00211 00212 if (TYPE_CODE (type) == TYPE_CODE_ARRAY 00213 && !get_array_bounds (type, &lowb, &highb)) 00214 error (_("Could not determine the vector bounds")); 00215 00216 /* Assume elsize aligned offset. */ 00217 gdb_assert (offset % elsize == 0); 00218 offset /= elsize; 00219 n = offset + highb - lowb + 1; 00220 00221 /* Since accesses to the fourth component of a triple vector is undefined we 00222 just skip writes to the fourth element. Imagine something like this: 00223 int3 i3 = (int3)(0, 1, 2); 00224 i3.hi.hi = 5; 00225 In this case n would be 4 (offset=12/4 + 1) while c->n would be 3. */ 00226 if (n > c->n) 00227 n = c->n; 00228 00229 for (i = offset; i < n; i++) 00230 { 00231 struct value *from_elm_val = allocate_value (eltype); 00232 struct value *to_elm_val = value_subscript (c->val, c->indices[i]); 00233 00234 memcpy (value_contents_writeable (from_elm_val), 00235 value_contents (fromval) + j++ * elsize, 00236 elsize); 00237 value_assign (to_elm_val, from_elm_val); 00238 } 00239 00240 value_free_to_mark (mark); 00241 } 00242 00243 /* Return nonzero if all bits in V within OFFSET and LENGTH are valid. */ 00244 00245 static int 00246 lval_func_check_validity (const struct value *v, int offset, int length) 00247 { 00248 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00249 /* Size of the target type in bits. */ 00250 int elsize = 00251 TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; 00252 int startrest = offset % elsize; 00253 int start = offset / elsize; 00254 int endrest = (offset + length) % elsize; 00255 int end = (offset + length) / elsize; 00256 int i; 00257 00258 if (endrest) 00259 end++; 00260 00261 if (end > c->n) 00262 return 0; 00263 00264 for (i = start; i < end; i++) 00265 { 00266 int comp_offset = (i == start) ? startrest : 0; 00267 int comp_length = (i == end) ? endrest : elsize; 00268 00269 if (!value_bits_valid (c->val, c->indices[i] * elsize + comp_offset, 00270 comp_length)) 00271 return 0; 00272 } 00273 00274 return 1; 00275 } 00276 00277 /* Return nonzero if any bit in V is valid. */ 00278 00279 static int 00280 lval_func_check_any_valid (const struct value *v) 00281 { 00282 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00283 /* Size of the target type in bits. */ 00284 int elsize = 00285 TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; 00286 int i; 00287 00288 for (i = 0; i < c->n; i++) 00289 if (value_bits_valid (c->val, c->indices[i] * elsize, elsize)) 00290 return 1; 00291 00292 return 0; 00293 } 00294 00295 /* Return nonzero if bits in V from OFFSET and LENGTH represent a 00296 synthetic pointer. */ 00297 00298 static int 00299 lval_func_check_synthetic_pointer (const struct value *v, 00300 int offset, int length) 00301 { 00302 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00303 /* Size of the target type in bits. */ 00304 int elsize = 00305 TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; 00306 int startrest = offset % elsize; 00307 int start = offset / elsize; 00308 int endrest = (offset + length) % elsize; 00309 int end = (offset + length) / elsize; 00310 int i; 00311 00312 if (endrest) 00313 end++; 00314 00315 if (end > c->n) 00316 return 0; 00317 00318 for (i = start; i < end; i++) 00319 { 00320 int comp_offset = (i == start) ? startrest : 0; 00321 int comp_length = (i == end) ? endrest : elsize; 00322 00323 if (!value_bits_synthetic_pointer (c->val, 00324 c->indices[i] * elsize + comp_offset, 00325 comp_length)) 00326 return 0; 00327 } 00328 00329 return 1; 00330 } 00331 00332 static void * 00333 lval_func_copy_closure (const struct value *v) 00334 { 00335 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00336 00337 ++c->refc; 00338 00339 return c; 00340 } 00341 00342 static void 00343 lval_func_free_closure (struct value *v) 00344 { 00345 struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); 00346 00347 --c->refc; 00348 00349 if (c->refc == 0) 00350 { 00351 value_free (c->val); /* Decrement the reference counter of the value. */ 00352 xfree (c->indices); 00353 xfree (c); 00354 } 00355 } 00356 00357 static const struct lval_funcs opencl_value_funcs = 00358 { 00359 lval_func_read, 00360 lval_func_write, 00361 lval_func_check_validity, 00362 lval_func_check_any_valid, 00363 NULL, /* indirect */ 00364 NULL, /* coerce_ref */ 00365 lval_func_check_synthetic_pointer, 00366 lval_func_copy_closure, 00367 lval_func_free_closure 00368 }; 00369 00370 /* Creates a sub-vector from VAL. The elements are selected by the indices of 00371 an array with the length of N. Supported values for NOSIDE are 00372 EVAL_NORMAL and EVAL_AVOID_SIDE_EFFECTS. */ 00373 00374 static struct value * 00375 create_value (struct gdbarch *gdbarch, struct value *val, enum noside noside, 00376 int *indices, int n) 00377 { 00378 struct type *type = check_typedef (value_type (val)); 00379 struct type *elm_type = TYPE_TARGET_TYPE (type); 00380 struct value *ret; 00381 00382 /* Check if a single component of a vector is requested which means 00383 the resulting type is a (primitive) scalar type. */ 00384 if (n == 1) 00385 { 00386 if (noside == EVAL_AVOID_SIDE_EFFECTS) 00387 ret = value_zero (elm_type, not_lval); 00388 else 00389 ret = value_subscript (val, indices[0]); 00390 } 00391 else 00392 { 00393 /* Multiple components of the vector are requested which means the 00394 resulting type is a vector as well. */ 00395 struct type *dst_type = 00396 lookup_opencl_vector_type (gdbarch, TYPE_CODE (elm_type), 00397 TYPE_LENGTH (elm_type), 00398 TYPE_UNSIGNED (elm_type), n); 00399 00400 if (dst_type == NULL) 00401 dst_type = init_vector_type (elm_type, n); 00402 00403 make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type), dst_type, NULL); 00404 00405 if (noside == EVAL_AVOID_SIDE_EFFECTS) 00406 ret = allocate_value (dst_type); 00407 else 00408 { 00409 /* Check whether to create a lvalue or not. */ 00410 if (VALUE_LVAL (val) != not_lval && !array_has_dups (indices, n)) 00411 { 00412 struct lval_closure *c = allocate_lval_closure (indices, n, val); 00413 ret = allocate_computed_value (dst_type, &opencl_value_funcs, c); 00414 } 00415 else 00416 { 00417 int i; 00418 00419 ret = allocate_value (dst_type); 00420 00421 /* Copy src val contents into the destination value. */ 00422 for (i = 0; i < n; i++) 00423 memcpy (value_contents_writeable (ret) 00424 + (i * TYPE_LENGTH (elm_type)), 00425 value_contents (val) 00426 + (indices[i] * TYPE_LENGTH (elm_type)), 00427 TYPE_LENGTH (elm_type)); 00428 } 00429 } 00430 } 00431 return ret; 00432 } 00433 00434 /* OpenCL vector component access. */ 00435 00436 static struct value * 00437 opencl_component_ref (struct expression *exp, struct value *val, char *comps, 00438 enum noside noside) 00439 { 00440 LONGEST lowb, highb; 00441 int src_len; 00442 struct value *v; 00443 int indices[16], i; 00444 int dst_len; 00445 00446 if (!get_array_bounds (check_typedef (value_type (val)), &lowb, &highb)) 00447 error (_("Could not determine the vector bounds")); 00448 00449 src_len = highb - lowb + 1; 00450 00451 /* Throw an error if the amount of array elements does not fit a 00452 valid OpenCL vector size (2, 3, 4, 8, 16). */ 00453 if (src_len != 2 && src_len != 3 && src_len != 4 && src_len != 8 00454 && src_len != 16) 00455 error (_("Invalid OpenCL vector size")); 00456 00457 if (strcmp (comps, "lo") == 0 ) 00458 { 00459 dst_len = (src_len == 3) ? 2 : src_len / 2; 00460 00461 for (i = 0; i < dst_len; i++) 00462 indices[i] = i; 00463 } 00464 else if (strcmp (comps, "hi") == 0) 00465 { 00466 dst_len = (src_len == 3) ? 2 : src_len / 2; 00467 00468 for (i = 0; i < dst_len; i++) 00469 indices[i] = dst_len + i; 00470 } 00471 else if (strcmp (comps, "even") == 0) 00472 { 00473 dst_len = (src_len == 3) ? 2 : src_len / 2; 00474 00475 for (i = 0; i < dst_len; i++) 00476 indices[i] = i*2; 00477 } 00478 else if (strcmp (comps, "odd") == 0) 00479 { 00480 dst_len = (src_len == 3) ? 2 : src_len / 2; 00481 00482 for (i = 0; i < dst_len; i++) 00483 indices[i] = i*2+1; 00484 } 00485 else if (strncasecmp (comps, "s", 1) == 0) 00486 { 00487 #define HEXCHAR_TO_INT(C) ((C >= '0' && C <= '9') ? \ 00488 C-'0' : ((C >= 'A' && C <= 'F') ? \ 00489 C-'A'+10 : ((C >= 'a' && C <= 'f') ? \ 00490 C-'a'+10 : -1))) 00491 00492 dst_len = strlen (comps); 00493 /* Skip the s/S-prefix. */ 00494 dst_len--; 00495 00496 for (i = 0; i < dst_len; i++) 00497 { 00498 indices[i] = HEXCHAR_TO_INT(comps[i+1]); 00499 /* Check if the requested component is invalid or exceeds 00500 the vector. */ 00501 if (indices[i] < 0 || indices[i] >= src_len) 00502 error (_("Invalid OpenCL vector component accessor %s"), comps); 00503 } 00504 } 00505 else 00506 { 00507 dst_len = strlen (comps); 00508 00509 for (i = 0; i < dst_len; i++) 00510 { 00511 /* x, y, z, w */ 00512 switch (comps[i]) 00513 { 00514 case 'x': 00515 indices[i] = 0; 00516 break; 00517 case 'y': 00518 indices[i] = 1; 00519 break; 00520 case 'z': 00521 if (src_len < 3) 00522 error (_("Invalid OpenCL vector component accessor %s"), comps); 00523 indices[i] = 2; 00524 break; 00525 case 'w': 00526 if (src_len < 4) 00527 error (_("Invalid OpenCL vector component accessor %s"), comps); 00528 indices[i] = 3; 00529 break; 00530 default: 00531 error (_("Invalid OpenCL vector component accessor %s"), comps); 00532 break; 00533 } 00534 } 00535 } 00536 00537 /* Throw an error if the amount of requested components does not 00538 result in a valid length (1, 2, 3, 4, 8, 16). */ 00539 if (dst_len != 1 && dst_len != 2 && dst_len != 3 && dst_len != 4 00540 && dst_len != 8 && dst_len != 16) 00541 error (_("Invalid OpenCL vector component accessor %s"), comps); 00542 00543 v = create_value (exp->gdbarch, val, noside, indices, dst_len); 00544 00545 return v; 00546 } 00547 00548 /* Perform the unary logical not (!) operation. */ 00549 00550 static struct value * 00551 opencl_logical_not (struct expression *exp, struct value *arg) 00552 { 00553 struct type *type = check_typedef (value_type (arg)); 00554 struct type *rettype; 00555 struct value *ret; 00556 00557 if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)) 00558 { 00559 struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type)); 00560 LONGEST lowb, highb; 00561 int i; 00562 00563 if (!get_array_bounds (type, &lowb, &highb)) 00564 error (_("Could not determine the vector bounds")); 00565 00566 /* Determine the resulting type of the operation and allocate the 00567 value. */ 00568 rettype = lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT, 00569 TYPE_LENGTH (eltype), 0, 00570 highb - lowb + 1); 00571 ret = allocate_value (rettype); 00572 00573 for (i = 0; i < highb - lowb + 1; i++) 00574 { 00575 /* For vector types, the unary operator shall return a 0 if the 00576 value of its operand compares unequal to 0, and -1 (i.e. all bits 00577 set) if the value of its operand compares equal to 0. */ 00578 int tmp = value_logical_not (value_subscript (arg, i)) ? -1 : 0; 00579 memset (value_contents_writeable (ret) + i * TYPE_LENGTH (eltype), 00580 tmp, TYPE_LENGTH (eltype)); 00581 } 00582 } 00583 else 00584 { 00585 rettype = language_bool_type (exp->language_defn, exp->gdbarch); 00586 ret = value_from_longest (rettype, value_logical_not (arg)); 00587 } 00588 00589 return ret; 00590 } 00591 00592 /* Perform a relational operation on two scalar operands. */ 00593 00594 static int 00595 scalar_relop (struct value *val1, struct value *val2, enum exp_opcode op) 00596 { 00597 int ret; 00598 00599 switch (op) 00600 { 00601 case BINOP_EQUAL: 00602 ret = value_equal (val1, val2); 00603 break; 00604 case BINOP_NOTEQUAL: 00605 ret = !value_equal (val1, val2); 00606 break; 00607 case BINOP_LESS: 00608 ret = value_less (val1, val2); 00609 break; 00610 case BINOP_GTR: 00611 ret = value_less (val2, val1); 00612 break; 00613 case BINOP_GEQ: 00614 ret = value_less (val2, val1) || value_equal (val1, val2); 00615 break; 00616 case BINOP_LEQ: 00617 ret = value_less (val1, val2) || value_equal (val1, val2); 00618 break; 00619 case BINOP_LOGICAL_AND: 00620 ret = !value_logical_not (val1) && !value_logical_not (val2); 00621 break; 00622 case BINOP_LOGICAL_OR: 00623 ret = !value_logical_not (val1) || !value_logical_not (val2); 00624 break; 00625 default: 00626 error (_("Attempt to perform an unsupported operation")); 00627 break; 00628 } 00629 return ret; 00630 } 00631 00632 /* Perform a relational operation on two vector operands. */ 00633 00634 static struct value * 00635 vector_relop (struct expression *exp, struct value *val1, struct value *val2, 00636 enum exp_opcode op) 00637 { 00638 struct value *ret; 00639 struct type *type1, *type2, *eltype1, *eltype2, *rettype; 00640 int t1_is_vec, t2_is_vec, i; 00641 LONGEST lowb1, lowb2, highb1, highb2; 00642 00643 type1 = check_typedef (value_type (val1)); 00644 type2 = check_typedef (value_type (val2)); 00645 00646 t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)); 00647 t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)); 00648 00649 if (!t1_is_vec || !t2_is_vec) 00650 error (_("Vector operations are not supported on scalar types")); 00651 00652 eltype1 = check_typedef (TYPE_TARGET_TYPE (type1)); 00653 eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)); 00654 00655 if (!get_array_bounds (type1,&lowb1, &highb1) 00656 || !get_array_bounds (type2, &lowb2, &highb2)) 00657 error (_("Could not determine the vector bounds")); 00658 00659 /* Check whether the vector types are compatible. */ 00660 if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2) 00661 || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) 00662 || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2) 00663 || lowb1 != lowb2 || highb1 != highb2) 00664 error (_("Cannot perform operation on vectors with different types")); 00665 00666 /* Determine the resulting type of the operation and allocate the value. */ 00667 rettype = lookup_opencl_vector_type (exp->gdbarch, TYPE_CODE_INT, 00668 TYPE_LENGTH (eltype1), 0, 00669 highb1 - lowb1 + 1); 00670 ret = allocate_value (rettype); 00671 00672 for (i = 0; i < highb1 - lowb1 + 1; i++) 00673 { 00674 /* For vector types, the relational, equality and logical operators shall 00675 return 0 if the specified relation is false and -1 (i.e. all bits set) 00676 if the specified relation is true. */ 00677 int tmp = scalar_relop (value_subscript (val1, i), 00678 value_subscript (val2, i), op) ? -1 : 0; 00679 memset (value_contents_writeable (ret) + i * TYPE_LENGTH (eltype1), 00680 tmp, TYPE_LENGTH (eltype1)); 00681 } 00682 00683 return ret; 00684 } 00685 00686 /* Perform a cast of ARG into TYPE. There's sadly a lot of duplication in 00687 here from valops.c:value_cast, opencl is different only in the 00688 behaviour of scalar to vector casting. As far as possibly we're going 00689 to try and delegate back to the standard value_cast function. */ 00690 00691 static struct value * 00692 opencl_value_cast (struct type *type, struct value *arg) 00693 { 00694 if (type != value_type (arg)) 00695 { 00696 /* Casting scalar to vector is a special case for OpenCL, scalar 00697 is cast to element type of vector then replicated into each 00698 element of the vector. First though, we need to work out if 00699 this is a scalar to vector cast; code lifted from 00700 valops.c:value_cast. */ 00701 enum type_code code1, code2; 00702 struct type *to_type; 00703 int scalar; 00704 00705 to_type = check_typedef (type); 00706 00707 code1 = TYPE_CODE (to_type); 00708 code2 = TYPE_CODE (check_typedef (value_type (arg))); 00709 00710 if (code2 == TYPE_CODE_REF) 00711 code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg)))); 00712 00713 scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL 00714 || code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT 00715 || code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM 00716 || code2 == TYPE_CODE_RANGE); 00717 00718 if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar) 00719 { 00720 struct type *eltype; 00721 00722 /* Cast to the element type of the vector here as 00723 value_vector_widen will error if the scalar value is 00724 truncated by the cast. To avoid the error, cast (and 00725 possibly truncate) here. */ 00726 eltype = check_typedef (TYPE_TARGET_TYPE (to_type)); 00727 arg = value_cast (eltype, arg); 00728 00729 return value_vector_widen (arg, type); 00730 } 00731 else 00732 /* Standard cast handler. */ 00733 arg = value_cast (type, arg); 00734 } 00735 return arg; 00736 } 00737 00738 /* Perform a relational operation on two operands. */ 00739 00740 static struct value * 00741 opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2, 00742 enum exp_opcode op) 00743 { 00744 struct value *val; 00745 struct type *type1 = check_typedef (value_type (arg1)); 00746 struct type *type2 = check_typedef (value_type (arg2)); 00747 int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY 00748 && TYPE_VECTOR (type1)); 00749 int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY 00750 && TYPE_VECTOR (type2)); 00751 00752 if (!t1_is_vec && !t2_is_vec) 00753 { 00754 int tmp = scalar_relop (arg1, arg2, op); 00755 struct type *type = 00756 language_bool_type (exp->language_defn, exp->gdbarch); 00757 00758 val = value_from_longest (type, tmp); 00759 } 00760 else if (t1_is_vec && t2_is_vec) 00761 { 00762 val = vector_relop (exp, arg1, arg2, op); 00763 } 00764 else 00765 { 00766 /* Widen the scalar operand to a vector. */ 00767 struct value **v = t1_is_vec ? &arg2 : &arg1; 00768 struct type *t = t1_is_vec ? type2 : type1; 00769 00770 if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t)) 00771 error (_("Argument to operation not a number or boolean.")); 00772 00773 *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v); 00774 val = vector_relop (exp, arg1, arg2, op); 00775 } 00776 00777 return val; 00778 } 00779 00780 /* Expression evaluator for the OpenCL. Most operations are delegated to 00781 evaluate_subexp_standard; see that function for a description of the 00782 arguments. */ 00783 00784 static struct value * 00785 evaluate_subexp_opencl (struct type *expect_type, struct expression *exp, 00786 int *pos, enum noside noside) 00787 { 00788 enum exp_opcode op = exp->elts[*pos].opcode; 00789 struct value *arg1 = NULL; 00790 struct value *arg2 = NULL; 00791 struct type *type1, *type2; 00792 00793 switch (op) 00794 { 00795 /* Handle assignment and cast operators to support OpenCL-style 00796 scalar-to-vector widening. */ 00797 case BINOP_ASSIGN: 00798 (*pos)++; 00799 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00800 type1 = value_type (arg1); 00801 arg2 = evaluate_subexp (type1, exp, pos, noside); 00802 00803 if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) 00804 return arg1; 00805 00806 if (deprecated_value_modifiable (arg1) 00807 && VALUE_LVAL (arg1) != lval_internalvar) 00808 arg2 = opencl_value_cast (type1, arg2); 00809 00810 return value_assign (arg1, arg2); 00811 00812 case UNOP_CAST: 00813 type1 = exp->elts[*pos + 1].type; 00814 (*pos) += 2; 00815 arg1 = evaluate_subexp (type1, exp, pos, noside); 00816 00817 if (noside == EVAL_SKIP) 00818 return value_from_longest (builtin_type (exp->gdbarch)-> 00819 builtin_int, 1); 00820 00821 return opencl_value_cast (type1, arg1); 00822 00823 case UNOP_CAST_TYPE: 00824 (*pos)++; 00825 arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); 00826 type1 = value_type (arg1); 00827 arg1 = evaluate_subexp (type1, exp, pos, noside); 00828 00829 if (noside == EVAL_SKIP) 00830 return value_from_longest (builtin_type (exp->gdbarch)-> 00831 builtin_int, 1); 00832 00833 return opencl_value_cast (type1, arg1); 00834 00835 /* Handle binary relational and equality operators that are either not 00836 or differently defined for GNU vectors. */ 00837 case BINOP_EQUAL: 00838 case BINOP_NOTEQUAL: 00839 case BINOP_LESS: 00840 case BINOP_GTR: 00841 case BINOP_GEQ: 00842 case BINOP_LEQ: 00843 (*pos)++; 00844 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00845 arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); 00846 00847 if (noside == EVAL_SKIP) 00848 return value_from_longest (builtin_type (exp->gdbarch)-> 00849 builtin_int, 1); 00850 00851 return opencl_relop (exp, arg1, arg2, op); 00852 00853 /* Handle the logical unary operator not(!). */ 00854 case UNOP_LOGICAL_NOT: 00855 (*pos)++; 00856 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00857 00858 if (noside == EVAL_SKIP) 00859 return value_from_longest (builtin_type (exp->gdbarch)-> 00860 builtin_int, 1); 00861 00862 return opencl_logical_not (exp, arg1); 00863 00864 /* Handle the logical operator and(&&) and or(||). */ 00865 case BINOP_LOGICAL_AND: 00866 case BINOP_LOGICAL_OR: 00867 (*pos)++; 00868 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00869 00870 if (noside == EVAL_SKIP) 00871 { 00872 evaluate_subexp (NULL_TYPE, exp, pos, noside); 00873 00874 return value_from_longest (builtin_type (exp->gdbarch)-> 00875 builtin_int, 1); 00876 } 00877 else 00878 { 00879 /* For scalar operations we need to avoid evaluating operands 00880 unecessarily. However, for vector operations we always need to 00881 evaluate both operands. Unfortunately we only know which of the 00882 two cases apply after we know the type of the second operand. 00883 Therefore we evaluate it once using EVAL_AVOID_SIDE_EFFECTS. */ 00884 int oldpos = *pos; 00885 00886 arg2 = evaluate_subexp (NULL_TYPE, exp, pos, 00887 EVAL_AVOID_SIDE_EFFECTS); 00888 *pos = oldpos; 00889 type1 = check_typedef (value_type (arg1)); 00890 type2 = check_typedef (value_type (arg2)); 00891 00892 if ((TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)) 00893 || (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2))) 00894 { 00895 arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00896 00897 return opencl_relop (exp, arg1, arg2, op); 00898 } 00899 else 00900 { 00901 /* For scalar built-in types, only evaluate the right 00902 hand operand if the left hand operand compares 00903 unequal(&&)/equal(||) to 0. */ 00904 int res; 00905 int tmp = value_logical_not (arg1); 00906 00907 if (op == BINOP_LOGICAL_OR) 00908 tmp = !tmp; 00909 00910 arg2 = evaluate_subexp (NULL_TYPE, exp, pos, 00911 tmp ? EVAL_SKIP : noside); 00912 type1 = language_bool_type (exp->language_defn, exp->gdbarch); 00913 00914 if (op == BINOP_LOGICAL_AND) 00915 res = !tmp && !value_logical_not (arg2); 00916 else /* BINOP_LOGICAL_OR */ 00917 res = tmp || !value_logical_not (arg2); 00918 00919 return value_from_longest (type1, res); 00920 } 00921 } 00922 00923 /* Handle the ternary selection operator. */ 00924 case TERNOP_COND: 00925 (*pos)++; 00926 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00927 type1 = check_typedef (value_type (arg1)); 00928 if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)) 00929 { 00930 struct value *arg3, *tmp, *ret; 00931 struct type *eltype2, *type3, *eltype3; 00932 int t2_is_vec, t3_is_vec, i; 00933 LONGEST lowb1, lowb2, lowb3, highb1, highb2, highb3; 00934 00935 arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00936 arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 00937 type2 = check_typedef (value_type (arg2)); 00938 type3 = check_typedef (value_type (arg3)); 00939 t2_is_vec 00940 = TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2); 00941 t3_is_vec 00942 = TYPE_CODE (type3) == TYPE_CODE_ARRAY && TYPE_VECTOR (type3); 00943 00944 /* Widen the scalar operand to a vector if necessary. */ 00945 if (t2_is_vec || !t3_is_vec) 00946 { 00947 arg3 = opencl_value_cast (type2, arg3); 00948 type3 = value_type (arg3); 00949 } 00950 else if (!t2_is_vec || t3_is_vec) 00951 { 00952 arg2 = opencl_value_cast (type3, arg2); 00953 type2 = value_type (arg2); 00954 } 00955 else if (!t2_is_vec || !t3_is_vec) 00956 { 00957 /* Throw an error if arg2 or arg3 aren't vectors. */ 00958 error (_("\ 00959 Cannot perform conditional operation on incompatible types")); 00960 } 00961 00962 eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)); 00963 eltype3 = check_typedef (TYPE_TARGET_TYPE (type3)); 00964 00965 if (!get_array_bounds (type1, &lowb1, &highb1) 00966 || !get_array_bounds (type2, &lowb2, &highb2) 00967 || !get_array_bounds (type3, &lowb3, &highb3)) 00968 error (_("Could not determine the vector bounds")); 00969 00970 /* Throw an error if the types of arg2 or arg3 are incompatible. */ 00971 if (TYPE_CODE (eltype2) != TYPE_CODE (eltype3) 00972 || TYPE_LENGTH (eltype2) != TYPE_LENGTH (eltype3) 00973 || TYPE_UNSIGNED (eltype2) != TYPE_UNSIGNED (eltype3) 00974 || lowb2 != lowb3 || highb2 != highb3) 00975 error (_("\ 00976 Cannot perform operation on vectors with different types")); 00977 00978 /* Throw an error if the sizes of arg1 and arg2/arg3 differ. */ 00979 if (lowb1 != lowb2 || lowb1 != lowb3 00980 || highb1 != highb2 || highb1 != highb3) 00981 error (_("\ 00982 Cannot perform conditional operation on vectors with different sizes")); 00983 00984 ret = allocate_value (type2); 00985 00986 for (i = 0; i < highb1 - lowb1 + 1; i++) 00987 { 00988 tmp = value_logical_not (value_subscript (arg1, i)) ? 00989 value_subscript (arg3, i) : value_subscript (arg2, i); 00990 memcpy (value_contents_writeable (ret) + 00991 i * TYPE_LENGTH (eltype2), value_contents_all (tmp), 00992 TYPE_LENGTH (eltype2)); 00993 } 00994 00995 return ret; 00996 } 00997 else 00998 { 00999 if (value_logical_not (arg1)) 01000 { 01001 /* Skip the second operand. */ 01002 evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); 01003 01004 return evaluate_subexp (NULL_TYPE, exp, pos, noside); 01005 } 01006 else 01007 { 01008 /* Skip the third operand. */ 01009 arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 01010 evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); 01011 01012 return arg2; 01013 } 01014 } 01015 01016 /* Handle STRUCTOP_STRUCT to allow component access on OpenCL vectors. */ 01017 case STRUCTOP_STRUCT: 01018 { 01019 int pc = (*pos)++; 01020 int tem = longest_to_int (exp->elts[pc + 1].longconst); 01021 01022 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); 01023 arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); 01024 type1 = check_typedef (value_type (arg1)); 01025 01026 if (noside == EVAL_SKIP) 01027 { 01028 return value_from_longest (builtin_type (exp->gdbarch)-> 01029 builtin_int, 1); 01030 } 01031 else if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)) 01032 { 01033 return opencl_component_ref (exp, arg1, &exp->elts[pc + 2].string, 01034 noside); 01035 } 01036 else 01037 { 01038 struct value *v = value_struct_elt (&arg1, NULL, 01039 &exp->elts[pc + 2].string, NULL, 01040 "structure"); 01041 01042 if (noside == EVAL_AVOID_SIDE_EFFECTS) 01043 v = value_zero (value_type (v), not_lval); 01044 return v; 01045 } 01046 } 01047 default: 01048 break; 01049 } 01050 01051 return evaluate_subexp_c (expect_type, exp, pos, noside); 01052 } 01053 01054 /* Print OpenCL types. */ 01055 01056 static void 01057 opencl_print_type (struct type *type, const char *varstring, 01058 struct ui_file *stream, int show, int level, 01059 const struct type_print_options *flags) 01060 { 01061 /* We nearly always defer to C type printing, except that vector 01062 types are considered primitive in OpenCL, and should always 01063 be printed using their TYPE_NAME. */ 01064 if (show > 0) 01065 { 01066 CHECK_TYPEDEF (type); 01067 if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) 01068 && TYPE_NAME (type) != NULL) 01069 show = 0; 01070 } 01071 01072 c_print_type (type, varstring, stream, show, level, flags); 01073 } 01074 01075 static void 01076 opencl_language_arch_info (struct gdbarch *gdbarch, 01077 struct language_arch_info *lai) 01078 { 01079 struct type **types = builtin_opencl_type (gdbarch); 01080 01081 /* Copy primitive types vector from gdbarch. */ 01082 lai->primitive_type_vector = types; 01083 01084 /* Type of elements of strings. */ 01085 lai->string_char_type = types [opencl_primitive_type_char]; 01086 01087 /* Specifies the return type of logical and relational operations. */ 01088 lai->bool_type_symbol = "int"; 01089 lai->bool_type_default = types [opencl_primitive_type_int]; 01090 } 01091 01092 const struct exp_descriptor exp_descriptor_opencl = 01093 { 01094 print_subexp_standard, 01095 operator_length_standard, 01096 operator_check_standard, 01097 op_name_standard, 01098 dump_subexp_body_standard, 01099 evaluate_subexp_opencl 01100 }; 01101 01102 const struct language_defn opencl_language_defn = 01103 { 01104 "opencl", /* Language name */ 01105 language_opencl, 01106 range_check_off, 01107 case_sensitive_on, 01108 array_row_major, 01109 macro_expansion_c, 01110 &exp_descriptor_opencl, 01111 c_parse, 01112 c_error, 01113 null_post_parser, 01114 c_printchar, /* Print a character constant */ 01115 c_printstr, /* Function to print string constant */ 01116 c_emit_char, /* Print a single char */ 01117 opencl_print_type, /* Print a type using appropriate syntax */ 01118 c_print_typedef, /* Print a typedef using appropriate syntax */ 01119 c_val_print, /* Print a value using appropriate syntax */ 01120 c_value_print, /* Print a top-level value */ 01121 default_read_var_value, /* la_read_var_value */ 01122 NULL, /* Language specific skip_trampoline */ 01123 NULL, /* name_of_this */ 01124 basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ 01125 basic_lookup_transparent_type,/* lookup_transparent_type */ 01126 NULL, /* Language specific symbol demangler */ 01127 NULL, /* Language specific 01128 class_name_from_physname */ 01129 c_op_print_tab, /* expression operators for printing */ 01130 1, /* c-style arrays */ 01131 0, /* String lower bound */ 01132 default_word_break_characters, 01133 default_make_symbol_completion_list, 01134 opencl_language_arch_info, 01135 default_print_array_index, 01136 default_pass_by_reference, 01137 c_get_string, 01138 NULL, /* la_get_symbol_name_cmp */ 01139 iterate_over_symbols, 01140 LANG_MAGIC 01141 }; 01142 01143 static void * 01144 build_opencl_types (struct gdbarch *gdbarch) 01145 { 01146 struct type **types 01147 = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_opencl_primitive_types + 1, 01148 struct type *); 01149 01150 /* Helper macro to create strings. */ 01151 #define OCL_STRING(S) #S 01152 /* This macro allocates and assigns the type struct pointers 01153 for the vector types. */ 01154 #define BUILD_OCL_VTYPES(TYPE)\ 01155 types[opencl_primitive_type_##TYPE##2] \ 01156 = init_vector_type (types[opencl_primitive_type_##TYPE], 2); \ 01157 TYPE_NAME (types[opencl_primitive_type_##TYPE##2]) = OCL_STRING(TYPE ## 2); \ 01158 types[opencl_primitive_type_##TYPE##3] \ 01159 = init_vector_type (types[opencl_primitive_type_##TYPE], 3); \ 01160 TYPE_NAME (types[opencl_primitive_type_##TYPE##3]) = OCL_STRING(TYPE ## 3); \ 01161 TYPE_LENGTH (types[opencl_primitive_type_##TYPE##3]) \ 01162 = 4 * TYPE_LENGTH (types[opencl_primitive_type_##TYPE]); \ 01163 types[opencl_primitive_type_##TYPE##4] \ 01164 = init_vector_type (types[opencl_primitive_type_##TYPE], 4); \ 01165 TYPE_NAME (types[opencl_primitive_type_##TYPE##4]) = OCL_STRING(TYPE ## 4); \ 01166 types[opencl_primitive_type_##TYPE##8] \ 01167 = init_vector_type (types[opencl_primitive_type_##TYPE], 8); \ 01168 TYPE_NAME (types[opencl_primitive_type_##TYPE##8]) = OCL_STRING(TYPE ## 8); \ 01169 types[opencl_primitive_type_##TYPE##16] \ 01170 = init_vector_type (types[opencl_primitive_type_##TYPE], 16); \ 01171 TYPE_NAME (types[opencl_primitive_type_##TYPE##16]) = OCL_STRING(TYPE ## 16) 01172 01173 types[opencl_primitive_type_char] 01174 = arch_integer_type (gdbarch, 8, 0, "char"); 01175 BUILD_OCL_VTYPES (char); 01176 types[opencl_primitive_type_uchar] 01177 = arch_integer_type (gdbarch, 8, 1, "uchar"); 01178 BUILD_OCL_VTYPES (uchar); 01179 types[opencl_primitive_type_short] 01180 = arch_integer_type (gdbarch, 16, 0, "short"); 01181 BUILD_OCL_VTYPES (short); 01182 types[opencl_primitive_type_ushort] 01183 = arch_integer_type (gdbarch, 16, 1, "ushort"); 01184 BUILD_OCL_VTYPES (ushort); 01185 types[opencl_primitive_type_int] 01186 = arch_integer_type (gdbarch, 32, 0, "int"); 01187 BUILD_OCL_VTYPES (int); 01188 types[opencl_primitive_type_uint] 01189 = arch_integer_type (gdbarch, 32, 1, "uint"); 01190 BUILD_OCL_VTYPES (uint); 01191 types[opencl_primitive_type_long] 01192 = arch_integer_type (gdbarch, 64, 0, "long"); 01193 BUILD_OCL_VTYPES (long); 01194 types[opencl_primitive_type_ulong] 01195 = arch_integer_type (gdbarch, 64, 1, "ulong"); 01196 BUILD_OCL_VTYPES (ulong); 01197 types[opencl_primitive_type_half] 01198 = arch_float_type (gdbarch, 16, "half", floatformats_ieee_half); 01199 BUILD_OCL_VTYPES (half); 01200 types[opencl_primitive_type_float] 01201 = arch_float_type (gdbarch, 32, "float", floatformats_ieee_single); 01202 BUILD_OCL_VTYPES (float); 01203 types[opencl_primitive_type_double] 01204 = arch_float_type (gdbarch, 64, "double", floatformats_ieee_double); 01205 BUILD_OCL_VTYPES (double); 01206 types[opencl_primitive_type_bool] 01207 = arch_boolean_type (gdbarch, 8, 1, "bool"); 01208 types[opencl_primitive_type_unsigned_char] 01209 = arch_integer_type (gdbarch, 8, 1, "unsigned char"); 01210 types[opencl_primitive_type_unsigned_short] 01211 = arch_integer_type (gdbarch, 16, 1, "unsigned short"); 01212 types[opencl_primitive_type_unsigned_int] 01213 = arch_integer_type (gdbarch, 32, 1, "unsigned int"); 01214 types[opencl_primitive_type_unsigned_long] 01215 = arch_integer_type (gdbarch, 64, 1, "unsigned long"); 01216 types[opencl_primitive_type_size_t] 01217 = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "size_t"); 01218 types[opencl_primitive_type_ptrdiff_t] 01219 = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "ptrdiff_t"); 01220 types[opencl_primitive_type_intptr_t] 01221 = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 0, "intptr_t"); 01222 types[opencl_primitive_type_uintptr_t] 01223 = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr_t"); 01224 types[opencl_primitive_type_void] 01225 = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void"); 01226 01227 return types; 01228 } 01229 01230 /* Provide a prototype to silence -Wmissing-prototypes. */ 01231 extern initialize_file_ftype _initialize_opencl_language; 01232 01233 void 01234 _initialize_opencl_language (void) 01235 { 01236 opencl_type_data = gdbarch_data_register_post_init (build_opencl_types); 01237 add_language (&opencl_language_defn); 01238 }