#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 (); }