summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gfortran.dg/submodule_7.f08
blob: 7d650bfff1d47af8c0f3f439fb21eee5db745061 (plain)
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
! { dg-do run }
!
! Example in F2008 C.8.4 to demonstrate submodules
!
module color_points
  type color_point
    private
    real :: x, y
    integer :: color
  end type color_point

  interface
! Interfaces for procedures with separate
! bodies in the submodule color_points_a
    module subroutine color_point_del ( p ) ! Destroy a color_point object
      type(color_point), allocatable :: p
    end subroutine color_point_del
! Distance between two color_point objects
    real module function color_point_dist ( a, b )
      type(color_point), intent(in) :: a, b
    end function color_point_dist
    module subroutine color_point_draw ( p ) ! Draw a color_point object
      type(color_point), intent(in) :: p
    end subroutine color_point_draw
    module subroutine color_point_new ( p ) ! Create a color_point object
      type(color_point), allocatable :: p
    end subroutine color_point_new
    module subroutine verify_cleanup ( p1, p2 ) ! Check cleanup of color_point objects
      type(color_point), allocatable :: p1, p2
    end subroutine verify_cleanup
  end interface
end module color_points

module palette_stuff
  type :: palette ;
!...
  end type palette
contains
  subroutine test_palette ( p )
! Draw a color wheel using procedures from the color_points module
    use color_points ! This does not cause a circular dependency because
! the "use palette_stuff" that is logically within
! color_points is in the color_points_a submodule.
    type(palette), intent(in) :: p
  end subroutine test_palette
end module palette_stuff


submodule ( color_points ) color_points_a ! Submodule of color_points
  integer :: instance_count = 0
  interface
! Interface for a procedure with a separate
! body in submodule color_points_b
    module subroutine inquire_palette ( pt, pal )
      use palette_stuff
! palette_stuff, especially submodules
! thereof, can reference color_points by use
! association without causing a circular
! dependence during translation because this
! use is not in the module. Furthermore,
! changes in the module palette_stuff do not
! affect the translation of color_points.
      type(color_point), intent(in) :: pt
      type(palette), intent(out) :: pal
    end subroutine inquire_palette
  end interface
contains
! Invisible bodies for public separate module procedures
! declared in the module
  module subroutine color_point_del ( p )
    type(color_point), allocatable :: p
    instance_count = instance_count - 1
    deallocate ( p )
  end subroutine color_point_del
  real module function color_point_dist ( a, b ) result ( dist )
    type(color_point), intent(in) :: a, b
    dist = sqrt( (b%x - a%x)**2 + (b%y - a%y)**2 )
  end function color_point_dist
  module subroutine color_point_new ( p )
    type(color_point), allocatable :: p
    instance_count = instance_count + 1
    allocate ( p )
! Added to example so that it does something.
    p%x = real (instance_count) * 1.0
    p%y = real (instance_count) * 2.0
    p%color = instance_count
  end subroutine color_point_new
end submodule color_points_a


submodule ( color_points:color_points_a ) color_points_b ! Subsidiary**2 submodule

contains
! Invisible body for interface declared in the ancestor module
  module subroutine color_point_draw ( p )
    use palette_stuff, only: palette
    type(color_point), intent(in) :: p
    type(palette) :: MyPalette
    call inquire_palette ( p, MyPalette )
! Added to example so that it does something.
    if (abs (p%x - real (p%color) * 1.0) .gt. 1.0e-6) STOP 1
    if (abs (p%y - real (p%color) * 2.0) .gt. 1.0e-6) STOP 2
  end subroutine color_point_draw
! Invisible body for interface declared in the parent submodule
  module procedure inquire_palette
!... implementation of inquire_palette
  end procedure inquire_palette
  module procedure verify_cleanup
    if (allocated (p1) .or. allocated (p2)) STOP 3
    if (instance_count .ne. 0) STOP 4
  end procedure
  subroutine private_stuff ! not accessible from color_points_a
!...
  end subroutine private_stuff
end submodule color_points_b


program main
  use color_points
! "instance_count" and "inquire_palette" are not accessible here
! because they are not declared in the "color_points" module.
! "color_points_a" and "color_points_b" cannot be referenced by
! use association.
  interface draw
! just to demonstrate it’s possible
    module procedure color_point_draw
  end interface
  type(color_point), allocatable :: C_1, C_2
  real :: RC
!...
  call color_point_new (c_1)
  call color_point_new (c_2)
! body in color_points_a, interface in color_points
!...
  call draw (c_1)
! body in color_points_b, specific interface
! in color_points, generic interface here.
!...
  rc = color_point_dist (c_1, c_2) ! body in color_points_a, interface in color_points
  if (abs (rc - 2.23606801) .gt. 1.0e-6) STOP 5
!...
  call color_point_del (c_1)
  call color_point_del (c_2)
! body in color_points_a, interface in color_points
  call verify_cleanup (c_1, c_2)
!...
end program main