1 /*===-- include/flang/ISO_Fortran_binding.h -----------------------*- C++ -*-=== 2 * 3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 * See https://llvm.org/LICENSE.txt for license information. 5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 * 7 * ===-----------------------------------------------------------------------=== 8 */ 9 10 #ifndef CFI_ISO_FORTRAN_BINDING_H_ 11 #define CFI_ISO_FORTRAN_BINDING_H_ 12 13 #include <stddef.h> 14 15 /* Standard interface to Fortran from C and C++. 16 * These interfaces are named in subclause 18.5 of the Fortran 2018 17 * standard, with most of the actual details being left to the 18 * implementation. 19 */ 20 21 #ifdef __cplusplus 22 namespace Fortran { 23 namespace ISO { 24 inline namespace Fortran_2018 { 25 #endif 26 27 /* 18.5.4 */ 28 #define CFI_VERSION 20180515 29 30 #define CFI_MAX_RANK 15 31 typedef unsigned char CFI_rank_t; 32 33 /* This type is probably larger than a default Fortran INTEGER 34 * and should be used for all array indexing and loop bound calculations. 35 */ 36 typedef ptrdiff_t CFI_index_t; 37 38 typedef unsigned char CFI_attribute_t; 39 #define CFI_attribute_pointer 1 40 #define CFI_attribute_allocatable 2 41 #define CFI_attribute_other 0 /* neither pointer nor allocatable */ 42 43 typedef signed char CFI_type_t; 44 /* These codes are required to be macros (i.e., #ifdef will work). 45 * They are not required to be distinct, but neither are they required 46 * to have had their synonyms combined. Codes marked as extensions may be 47 * place holders for as yet unimplemented types. 48 */ 49 #define CFI_type_signed_char 1 50 #define CFI_type_short 2 51 #define CFI_type_int 3 52 #define CFI_type_long 4 53 #define CFI_type_long_long 5 54 #define CFI_type_size_t 6 55 #define CFI_type_int8_t 7 56 #define CFI_type_int16_t 8 57 #define CFI_type_int32_t 9 58 #define CFI_type_int64_t 10 59 #define CFI_type_int128_t 11 /* extension */ 60 #define CFI_type_int_least8_t 12 61 #define CFI_type_int_least16_t 13 62 #define CFI_type_int_least32_t 14 63 #define CFI_type_int_least64_t 15 64 #define CFI_type_int_least128_t 16 /* extension */ 65 #define CFI_type_int_fast8_t 17 66 #define CFI_type_int_fast16_t 18 67 #define CFI_type_int_fast32_t 19 68 #define CFI_type_int_fast64_t 20 69 #define CFI_type_int_fast128_t 21 /* extension */ 70 #define CFI_type_intmax_t 22 71 #define CFI_type_intptr_t 23 72 #define CFI_type_ptrdiff_t 24 73 #define CFI_type_half_float 25 /* extension: kind=2 */ 74 #define CFI_type_bfloat 26 /* extension: kind=3 */ 75 #define CFI_type_float 27 76 #define CFI_type_double 28 77 #define CFI_type_extended_double 29 /* extension: kind=10 */ 78 #define CFI_type_long_double 30 79 #define CFI_type_float128 31 /* extension: kind=16 */ 80 #define CFI_type_half_float_Complex 32 /* extension: kind=2 */ 81 #define CFI_type_bfloat_Complex 33 /* extension: kind=3 */ 82 #define CFI_type_float_Complex 34 83 #define CFI_type_double_Complex 35 84 #define CFI_type_extended_double_Complex 36 /* extension: kind=10 */ 85 #define CFI_type_long_double_Complex 37 86 #define CFI_type_float128_Complex 38 /* extension: kind=16 */ 87 #define CFI_type_Bool 39 88 #define CFI_type_char 40 89 #define CFI_type_cptr 41 90 #define CFI_type_struct 42 91 #define CFI_type_char16_t 43 /* extension */ 92 #define CFI_type_char32_t 44 /* extension */ 93 #define CFI_TYPE_LAST CFI_type_char32_t 94 #define CFI_type_other (-1) // must be negative 95 96 /* Error code macros - skip some of the small values to avoid conflicts with 97 * other status codes mandated by the standard, e.g. those returned by 98 * GET_ENVIRONMENT_VARIABLE (16.9.84) */ 99 #define CFI_SUCCESS 0 /* must be zero */ 100 #define CFI_ERROR_BASE_ADDR_NULL 11 101 #define CFI_ERROR_BASE_ADDR_NOT_NULL 12 102 #define CFI_INVALID_ELEM_LEN 13 103 #define CFI_INVALID_RANK 14 104 #define CFI_INVALID_TYPE 15 105 #define CFI_INVALID_ATTRIBUTE 16 106 #define CFI_INVALID_EXTENT 17 107 #define CFI_INVALID_DESCRIPTOR 18 108 #define CFI_ERROR_MEM_ALLOCATION 19 109 #define CFI_ERROR_OUT_OF_BOUNDS 20 110 111 /* 18.5.2 per-dimension information */ 112 typedef struct CFI_dim_t { 113 CFI_index_t lower_bound; 114 CFI_index_t extent; /* == -1 for assumed size */ 115 CFI_index_t sm; /* memory stride in bytes */ 116 } CFI_dim_t; 117 118 #ifdef __cplusplus 119 namespace cfi_internal { 120 // C++ does not support flexible array. 121 // The below structure emulates a flexible array. This structure does not take 122 // care of getting the memory storage. Note that it already contains one element 123 // because a struct cannot be empty. 124 template <typename T> struct FlexibleArray : T { 125 T &operator[](int index) { return *(this + index); } 126 const T &operator[](int index) const { return *(this + index); } 127 operator T *() { return this; } 128 operator const T *() const { return this; } 129 }; 130 } // namespace cfi_internal 131 #endif 132 133 /* 18.5.3 generic data descriptor */ 134 typedef struct CFI_cdesc_t { 135 /* These three members must appear first, in exactly this order. */ 136 void *base_addr; 137 size_t elem_len; /* element size in bytes */ 138 int version; /* == CFI_VERSION */ 139 CFI_rank_t rank; /* [0 .. CFI_MAX_RANK] */ 140 CFI_type_t type; 141 CFI_attribute_t attribute; 142 unsigned char f18Addendum; 143 #ifdef __cplusplus 144 cfi_internal::FlexibleArray<CFI_dim_t> dim; 145 #else 146 CFI_dim_t dim[]; /* must appear last */ 147 #endif 148 } CFI_cdesc_t; 149 150 /* 18.5.4 */ 151 #ifdef __cplusplus 152 // The struct below take care of getting the memory storage for C++ CFI_cdesc_t 153 // that contain an emulated flexible array. 154 namespace cfi_internal { 155 template <int r> struct CdescStorage : public CFI_cdesc_t { 156 static_assert((r > 1 && r <= CFI_MAX_RANK), "CFI_INVALID_RANK"); 157 CFI_dim_t dim[r - 1]; 158 }; 159 template <> struct CdescStorage<1> : public CFI_cdesc_t {}; 160 template <> struct CdescStorage<0> : public CFI_cdesc_t {}; 161 } // namespace cfi_internal 162 #define CFI_CDESC_T(rank) cfi_internal::CdescStorage<rank> 163 #else 164 #define CFI_CDESC_T(rank) \ 165 struct { \ 166 CFI_cdesc_t cdesc; /* must be first */ \ 167 CFI_dim_t dim[rank]; \ 168 } 169 #endif 170 171 /* 18.5.5 procedural interfaces*/ 172 #ifdef __cplusplus 173 extern "C" { 174 #endif 175 void *CFI_address(const CFI_cdesc_t *, const CFI_index_t subscripts[]); 176 int CFI_allocate(CFI_cdesc_t *, const CFI_index_t lower_bounds[], 177 const CFI_index_t upper_bounds[], size_t elem_len); 178 int CFI_deallocate(CFI_cdesc_t *); 179 int CFI_establish(CFI_cdesc_t *, void *base_addr, CFI_attribute_t, CFI_type_t, 180 size_t elem_len, CFI_rank_t, const CFI_index_t extents[]); 181 int CFI_is_contiguous(const CFI_cdesc_t *); 182 int CFI_section(CFI_cdesc_t *, const CFI_cdesc_t *source, 183 const CFI_index_t lower_bounds[], const CFI_index_t upper_bounds[], 184 const CFI_index_t strides[]); 185 int CFI_select_part(CFI_cdesc_t *, const CFI_cdesc_t *source, 186 size_t displacement, size_t elem_len); 187 int CFI_setpointer( 188 CFI_cdesc_t *, const CFI_cdesc_t *source, const CFI_index_t lower_bounds[]); 189 #ifdef __cplusplus 190 } // extern "C" 191 } // inline namespace Fortran_2018 192 } 193 } 194 #endif 195 196 #endif /* CFI_ISO_FORTRAN_BINDING_H_ */ 197