! RUN: %python %S/test_modfile.py %s %flang_fc1
! Resolution of generic names in expressions.
! Test by using generic function in a specification expression that needs
! to be written to a .mod file.
! Resolve based on number of arguments
module m1
interface f
pure integer(8) function f1(x)
real, intent(in) :: x
end
pure integer(8) function f2(x, y)
real, intent(in) :: x, y
end
pure integer(8) function f3(x, y, z, w)
real, intent(in) :: x, y, z, w
optional :: w
end
end interface
contains
subroutine s1(x, z)
real :: z(f(x)) ! resolves to f1
end
subroutine s2(x, y, z)
real :: z(f(x, y)) ! resolves to f2
end
subroutine s3(x, y, z, w)
real :: w(f(x, y, z)) ! resolves to f3
end
subroutine s4(x, y, z, w, u)
real :: u(f(x, y, z, w)) ! resolves to f3
end
end
!Expect: m1.mod
!module m1
! interface
! pure function f1(x)
! real(4), intent(in) :: x
! integer(8) :: f1
! end
! end interface
! interface
! pure function f2(x, y)
! real(4), intent(in) :: x
! real(4), intent(in) :: y
! integer(8) :: f2
! end
! end interface
! interface
! pure function f3(x, y, z, w)
! real(4), intent(in) :: x
! real(4), intent(in) :: y
! real(4), intent(in) :: z
! real(4), intent(in), optional :: w
! integer(8) :: f3
! end
! end interface
! interface f
! procedure :: f1
! procedure :: f2
! procedure :: f3
! end interface
!contains
! subroutine s1(x, z)
! real(4) :: x
! real(4) :: z(1_8:f1(x))
! end
! subroutine s2(x, y, z)
! real(4) :: x
! real(4) :: y
! real(4) :: z(1_8:f2(x, y))
! end
! subroutine s3(x, y, z, w)
! real(4) :: x
! real(4) :: y
! real(4) :: z
! real(4) :: w(1_8:f3(x, y, z))
! end
! subroutine s4(x, y, z, w, u)
! real(4) :: x
! real(4) :: y
! real(4) :: z
! real(4) :: w
! real(4) :: u(1_8:f3(x, y, z, w))
! end
!end
! Resolve based on type or kind
module m2
interface f
pure integer(8) function f_real4(x)
real(4), intent(in) :: x
end
pure integer(8) function f_real8(x)
real(8), intent(in) :: x
end
pure integer(8) function f_integer(x)
integer, intent(in) :: x
end
end interface
contains
subroutine s1(x, y)
real(4) :: x
real :: y(f(x)) ! resolves to f_real4
end
subroutine s2(x, y)
real(8) :: x
real :: y(f(x)) ! resolves to f_real8
end
subroutine s3(x, y)
integer :: x
real :: y(f(x)) ! resolves to f_integer
end
end
!Expect: m2.mod
!module m2
! interface
! pure function f_real4(x)
! real(4), intent(in) :: x
! integer(8) :: f_real4
! end
! end interface
! interface
! pure function f_real8(x)
! real(8), intent(in) :: x
! integer(8) :: f_real8
! end
! end interface
! interface
! pure function f_integer(x)
! integer(4), intent(in) :: x
! integer(8) :: f_integer
! end
! end interface
! interface f
! procedure :: f_real4
! procedure :: f_real8
! procedure :: f_integer
! end interface
!contains
! subroutine s1(x, y)
! real(4) :: x
! real(4) :: y(1_8:f_real4(x))
! end
! subroutine s2(x, y)
! real(8) :: x
! real(4) :: y(1_8:f_real8(x))
! end
! subroutine s3(x, y)
! integer(4) :: x
! real(4) :: y(1_8:f_integer(x))
! end
!end
! Resolve based on rank
module m3a
interface f
procedure :: f_elem
procedure :: f_vector
end interface
contains
pure integer(8) elemental function f_elem(x) result(result)
real, intent(in) :: x
result = 1_8
end
pure integer(8) function f_vector(x) result(result)
real, intent(in) :: x(:)
result = 2_8
end
end
!Expect: m3a.mod
!module m3a
! interface f
! procedure :: f_elem
! procedure :: f_vector
! end interface
!contains
! elemental pure function f_elem(x) result(result)
! real(4), intent(in) :: x
! integer(8) :: result
! end
! pure function f_vector(x) result(result)
! real(4), intent(in) :: x(:)
! integer(8) :: result
! end
!end
module m3b
use m3a
contains
subroutine s1(x, y)
real :: x
real :: y(f(x)) ! resolves to f_elem
end
subroutine s2(x, y)
real :: x(10)
real :: y(f(x)) ! resolves to f_vector (preferred over elemental one)
end
subroutine s3(x, y)
real :: x(10, 10)
real :: y(ubound(f(x), 1)) ! resolves to f_elem
end
end
!Expect: m3b.mod
!module m3b
! use m3a, only: f
! use m3a, only: f_elem
! use m3a, only: f_vector
!contains
! subroutine s1(x, y)
! real(4) :: x
! real(4) :: y(1_8:f_elem(x))
! end
! subroutine s2(x, y)
! real(4) :: x(1_8:10_8)
! real(4) :: y(1_8:f_vector(x))
! end
! subroutine s3(x, y)
! real(4) :: x(1_8:10_8, 1_8:10_8)
! real(4) :: y(1_8:10_8)
! end
!end
! Resolve defined unary operator based on type
module m4
interface operator(.foo.)
pure integer(8) function f_real(x)
real, intent(in) :: x
end
pure integer(8) function f_integer(x)
integer, intent(in) :: x
end
end interface
contains
subroutine s1(x, y)
real :: x
real :: y(.foo. x) ! resolves to f_real
end
subroutine s2(x, y)
integer :: x
real :: y(.foo. x) ! resolves to f_integer
end
end
!Expect: m4.mod
!module m4
! interface
! pure function f_real(x)
! real(4), intent(in) :: x
! integer(8) :: f_real
! end
! end interface
! interface
! pure function f_integer(x)
! integer(4), intent(in) :: x
! integer(8) :: f_integer
! end
! end interface
! interface operator(.foo.)
! procedure :: f_real
! procedure :: f_integer
! end interface
!contains
! subroutine s1(x, y)
! real(4) :: x
! real(4) :: y(1_8:f_real(x))
! end
! subroutine s2(x, y)
! integer(4) :: x
! real(4) :: y(1_8:f_integer(x))
! end
!end
! Resolve defined binary operator based on type
module m5
interface operator(.foo.)
pure integer(8) function f1(x, y)
real, intent(in) :: x
real, intent(in) :: y
end
pure integer(8) function f2(x, y)
real, intent(in) :: x
complex, intent(in) :: y
end
end interface
contains
subroutine s1(x, y)
complex :: x
real :: y(1.0 .foo. x) ! resolves to f2
end
subroutine s2(x, y)
real :: x
real :: y(1.0 .foo. x) ! resolves to f1
end
end
!Expect: m5.mod
!module m5
! interface
! pure function f1(x, y)
! real(4), intent(in) :: x
! real(4), intent(in) :: y
! integer(8) :: f1
! end
! end interface
! interface
! pure function f2(x, y)
! real(4), intent(in) :: x
! complex(4), intent(in) :: y
! integer(8) :: f2
! end
! end interface
! interface operator(.foo.)
! procedure :: f1
! procedure :: f2
! end interface
!contains
! subroutine s1(x, y)
! complex(4) :: x
! real(4) :: y(1_8:f2(1._4, x))
! end
! subroutine s2(x, y)
! real(4) :: x
! real(4) :: y(1_8:f1(1._4, x))
! end
!end