| #include <stdlib.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include <ISO_Fortran_binding.h> |
| #include "dump-descriptors.h" |
| |
| /* Declare some source arrays. */ |
| struct ss { |
| char c[4]; |
| signed char b[4]; |
| int i, j, k; |
| } s[10][5][3]; |
| |
| char c[10][16]; |
| |
| double _Complex dc[10]; |
| |
| CFI_index_t extents3[] = {3,5,10}; |
| CFI_index_t extents1[] = {10}; |
| |
| /* External entry point. */ |
| extern void ctest (void); |
| |
| void |
| ctest (void) |
| { |
| CFI_CDESC_T(3) sdesc; |
| CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc; |
| CFI_CDESC_T(3) rdesc; |
| CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc; |
| size_t offset; |
| |
| /* Extract an array of structure elements. */ |
| offset = offsetof (struct ss, j); |
| check_CFI_status ("CFI_establish", |
| CFI_establish (source, (void *)s, CFI_attribute_other, |
| CFI_type_struct, |
| sizeof (struct ss), 3, extents3)); |
| check_CFI_status ("CFI_establish", |
| CFI_establish (result, NULL, CFI_attribute_pointer, |
| CFI_type_int, 0, 3, NULL)); |
| check_CFI_status ("CFI_select_part", |
| CFI_select_part (result, source, offset, 0)); |
| dump_CFI_cdesc_t (source); |
| dump_CFI_cdesc_t (result); |
| |
| if (result->elem_len != sizeof (int)) |
| abort (); |
| if (result->base_addr != source->base_addr + offset) |
| abort (); |
| if (result->dim[0].extent != source->dim[0].extent) |
| abort (); |
| if (result->dim[0].sm != source->dim[0].sm) |
| abort (); |
| if (result->dim[1].extent != source->dim[1].extent) |
| abort (); |
| if (result->dim[1].sm != source->dim[1].sm) |
| abort (); |
| if (result->dim[2].extent != source->dim[2].extent) |
| abort (); |
| if (result->dim[2].sm != source->dim[2].sm) |
| abort (); |
| |
| /* Check that we use the given elem_size for char but not for |
| signed char, which is considered an integer type instead of a Fortran |
| character type. */ |
| check_CFI_status ("CFI_establish", |
| CFI_establish (result, NULL, CFI_attribute_pointer, |
| CFI_type_char, 4, 3, NULL)); |
| if (result->elem_len != 4) |
| abort (); |
| offset = offsetof (struct ss, c); |
| check_CFI_status ("CFI_select_part", |
| CFI_select_part (result, source, offset, 4)); |
| if (result->elem_len != 4) |
| abort (); |
| |
| check_CFI_status ("CFI_establish", |
| CFI_establish (result, NULL, CFI_attribute_pointer, |
| CFI_type_signed_char, 4, 3, NULL)); |
| if (result->elem_len != sizeof (signed char)) |
| abort (); |
| offset = offsetof (struct ss, c); |
| check_CFI_status ("CFI_select_part", |
| CFI_select_part (result, source, offset, 4)); |
| if (result->elem_len != sizeof (signed char)) |
| abort (); |
| |
| /* Extract an array of character substrings. */ |
| offset = 2; |
| check_CFI_status ("CFI_establish", |
| CFI_establish (source, (void *)c, CFI_attribute_other, |
| CFI_type_char, 16, 1, extents1)); |
| check_CFI_status ("CFI_establish", |
| CFI_establish (result, NULL, CFI_attribute_pointer, |
| CFI_type_char, 8, 1, NULL)); |
| check_CFI_status ("CFI_select_part", |
| CFI_select_part (result, source, offset, 8)); |
| dump_CFI_cdesc_t (source); |
| dump_CFI_cdesc_t (result); |
| |
| if (result->elem_len != 8) |
| abort (); |
| if (result->base_addr != source->base_addr + offset) |
| abort (); |
| if (result->dim[0].extent != source->dim[0].extent) |
| abort (); |
| if (result->dim[0].sm != source->dim[0].sm) |
| abort (); |
| |
| /* Extract an array the imaginary parts of complex numbers. |
| Note that the use of __imag__ to obtain the imaginary part as |
| an lvalue is a GCC extension. */ |
| offset = (void *)&(__imag__ dc[0]) - (void *)&(dc[0]); |
| check_CFI_status ("CFI_establish", |
| CFI_establish (source, (void *)dc, CFI_attribute_other, |
| CFI_type_double_Complex, |
| 0, 1, extents1)); |
| check_CFI_status ("CFI_establish", |
| CFI_establish (result, NULL, CFI_attribute_pointer, |
| CFI_type_double, 0, 1, NULL)); |
| check_CFI_status ("CFI_select_part", |
| CFI_select_part (result, source, offset, 0)); |
| dump_CFI_cdesc_t (source); |
| dump_CFI_cdesc_t (result); |
| |
| if (result->elem_len != sizeof (double)) |
| abort (); |
| if (result->base_addr != source->base_addr + offset) |
| abort (); |
| if (result->dim[0].extent != source->dim[0].extent) |
| abort (); |
| if (result->dim[0].sm != source->dim[0].sm) |
| abort (); |
| } |
| |