2019-12-21 04:52:07 +08:00
|
|
|
!===-- module/iso_c_binding.f90 --------------------------------------------===!
|
2019-06-01 07:35:52 +08:00
|
|
|
!
|
2019-12-21 04:52:07 +08:00
|
|
|
! 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
|
2019-06-01 07:35:52 +08:00
|
|
|
!
|
2020-01-11 04:12:03 +08:00
|
|
|
!===------------------------------------------------------------------------===!
|
2019-06-01 07:35:52 +08:00
|
|
|
|
|
|
|
! See Fortran 2018, clause 18.2
|
|
|
|
|
|
|
|
module iso_c_binding
|
|
|
|
|
2019-12-26 04:29:50 +08:00
|
|
|
use __Fortran_builtins, only: &
|
|
|
|
c_f_pointer => __builtin_c_f_pointer, &
|
|
|
|
c_ptr => __builtin_c_ptr, &
|
2020-12-16 03:06:44 +08:00
|
|
|
c_funptr => __builtin_c_funptr, &
|
2021-01-15 04:49:27 +08:00
|
|
|
c_sizeof => sizeof, &
|
|
|
|
c_loc => __builtin_c_loc
|
2019-06-01 07:35:52 +08:00
|
|
|
|
2020-12-08 06:46:24 +08:00
|
|
|
type(c_ptr), parameter :: c_null_ptr = c_ptr(0)
|
|
|
|
type(c_funptr), parameter :: c_null_funptr = c_funptr(0)
|
2019-06-01 07:35:52 +08:00
|
|
|
|
|
|
|
! Table 18.2 (in clause 18.3.1)
|
|
|
|
! TODO: Specialize (via macros?) for alternative targets
|
|
|
|
integer, parameter :: &
|
|
|
|
c_int8_t = 1, &
|
|
|
|
c_int16_t = 2, &
|
|
|
|
c_int32_t = 4, &
|
|
|
|
c_int64_t = 8, &
|
|
|
|
c_int128_t = 16 ! anticipating future addition
|
|
|
|
integer, parameter :: &
|
|
|
|
c_int = c_int32_t, &
|
|
|
|
c_short = c_int16_t, &
|
|
|
|
c_long = c_int64_t, &
|
|
|
|
c_long_long = c_int64_t, &
|
|
|
|
c_signed_char = c_int8_t, &
|
2020-12-16 03:06:44 +08:00
|
|
|
c_size_t = kind(c_sizeof(1)), &
|
2019-06-01 07:35:52 +08:00
|
|
|
c_intmax_t = c_int128_t, &
|
|
|
|
c_intptr_t = c_size_t, &
|
|
|
|
c_ptrdiff_t = c_size_t
|
|
|
|
integer, parameter :: &
|
|
|
|
c_int_least8_t = c_int8_t, &
|
|
|
|
c_int_fast8_t = c_int8_t, &
|
|
|
|
c_int_least16_t = c_int16_t, &
|
|
|
|
c_int_fast16_t = c_int16_t, &
|
|
|
|
c_int_least32_t = c_int32_t, &
|
|
|
|
c_int_fast32_t = c_int32_t, &
|
|
|
|
c_int_least64_t = c_int64_t, &
|
|
|
|
c_int_fast64_t = c_int64_t, &
|
|
|
|
c_int_least128_t = c_int128_t, &
|
|
|
|
c_int_fast128_t = c_int128_t
|
|
|
|
|
|
|
|
integer, parameter :: &
|
|
|
|
c_float = 4, &
|
|
|
|
c_double = 8, &
|
|
|
|
#if __x86_64__
|
|
|
|
c_long_double = 10
|
|
|
|
#else
|
|
|
|
c_long_double = 16
|
|
|
|
#endif
|
|
|
|
|
|
|
|
integer, parameter :: &
|
|
|
|
c_float_complex = c_float, &
|
|
|
|
c_double_complex = c_double, &
|
|
|
|
c_long_double_complex = c_long_double
|
|
|
|
|
|
|
|
integer, parameter :: c_bool = 1 ! TODO: or default LOGICAL?
|
2019-07-02 07:54:53 +08:00
|
|
|
integer, parameter :: c_char = 1
|
2019-06-01 07:35:52 +08:00
|
|
|
|
2019-08-14 11:41:43 +08:00
|
|
|
! C characters with special semantics
|
2019-08-15 01:36:29 +08:00
|
|
|
character(kind=c_char, len=1), parameter :: c_null_char = achar(0)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_alert = achar(7)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_backspace = achar(8)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_form_feed = achar(12)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_new_line = achar(10)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_carriage_return = achar(13)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_horizontal_tab = achar(9)
|
|
|
|
character(kind=c_char, len=1), parameter :: c_vertical_tab = achar(11)
|
2019-08-14 11:41:43 +08:00
|
|
|
|
2021-01-15 04:49:27 +08:00
|
|
|
interface c_associated
|
|
|
|
module procedure c_associated_c_ptr
|
|
|
|
module procedure c_associated_c_funptr
|
|
|
|
end interface
|
|
|
|
private :: c_associated_c_ptr, c_associated_c_funptr
|
|
|
|
|
|
|
|
! gfortran extensions
|
|
|
|
integer, parameter :: &
|
|
|
|
c_float128 = 16, &
|
|
|
|
c_float128_complex = c_float128
|
|
|
|
|
2019-06-01 07:35:52 +08:00
|
|
|
contains
|
|
|
|
|
2021-01-15 04:49:27 +08:00
|
|
|
logical function c_associated_c_ptr(c_ptr_1, c_ptr_2)
|
2019-06-01 07:35:52 +08:00
|
|
|
type(c_ptr), intent(in) :: c_ptr_1
|
|
|
|
type(c_ptr), intent(in), optional :: c_ptr_2
|
2019-12-26 04:29:50 +08:00
|
|
|
if (c_ptr_1%__address == c_null_ptr%__address) then
|
2021-01-15 04:49:27 +08:00
|
|
|
c_associated_c_ptr = .false.
|
2019-06-01 07:35:52 +08:00
|
|
|
else if (present(c_ptr_2)) then
|
2021-01-15 04:49:27 +08:00
|
|
|
c_associated_c_ptr = c_ptr_1%__address == c_ptr_2%__address
|
2019-06-01 07:35:52 +08:00
|
|
|
else
|
2021-01-15 04:49:27 +08:00
|
|
|
c_associated_c_ptr = .true.
|
2019-06-01 07:35:52 +08:00
|
|
|
end if
|
2021-01-15 04:49:27 +08:00
|
|
|
end function c_associated_c_ptr
|
2019-06-01 07:35:52 +08:00
|
|
|
|
2021-01-15 04:49:27 +08:00
|
|
|
logical function c_associated_c_funptr(c_funptr_1, c_funptr_2)
|
|
|
|
type(c_funptr), intent(in) :: c_funptr_1
|
|
|
|
type(c_funptr), intent(in), optional :: c_funptr_2
|
|
|
|
if (c_funptr_1%__address == c_null_ptr%__address) then
|
|
|
|
c_associated_c_funptr = .false.
|
|
|
|
else if (present(c_funptr_2)) then
|
|
|
|
c_associated_c_funptr = c_funptr_1%__address == c_funptr_2%__address
|
|
|
|
else
|
|
|
|
c_associated_c_funptr = .true.
|
|
|
|
end if
|
|
|
|
end function c_associated_c_funptr
|
2019-07-02 07:54:53 +08:00
|
|
|
|
|
|
|
function c_funloc(x)
|
|
|
|
type(c_funptr) :: c_funloc
|
|
|
|
external :: x
|
|
|
|
c_funloc = c_funptr(loc(x))
|
|
|
|
end function c_funloc
|
|
|
|
|
2019-06-01 07:35:52 +08:00
|
|
|
! TODO c_f_procpointer
|
|
|
|
|
|
|
|
end module iso_c_binding
|