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