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