[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / flang / docs / PolymorphicEntities.md
blob8eabc9eb3c6ab2d88f9f23bafcc9ae97ea08e5cf
1 # Polymorphic Entities
3 A polymorphic entity is a data entity that can be of different type during the
4 execution of a program.
6 This document aims to give insights at the representation of polymorphic
7 entities in FIR and how polymorphic related constructs and features are lowered
8 to FIR.
10 ## Fortran standard
12 Here is a list of the sections and constraints of the Fortran standard involved
13 for polymorphic entities.
15 - 7.3.2.1 - 7.3.2.2: TYPE specifier (TYPE(*))
16   - C708
17   - C709
18   - C710
19   - C711
20 - 7.3.2.3: CLASS specifier
21 - 7.5.4.5: The passed-object dummy argument
22   - C760
23 - 9.7.1: ALLOCATE statement
24   - C933
25 - 9.7.2: NULLIFY statement
26    - When a NULLIFY statement is applied to a polymorphic pointer (7.3.2.3),
27      its dynamic type becomes the same as its declared type.
28 - 10.2.2.3: Data pointer assignment
29 - 11.1.3: ASSOCIATE construct
30 - 11.1.11: SELECT TYPE construct
31   - C1157
32   - C1158
33   - C1159
34   - C1160
35   - C1161
36   - C1162
37   - C1163
38   - C1164
39   - C1165
40 - 16.9.76 EXTENDS_TYPE_OF (A, MOLD)
41 - 16.9.165 SAME_TYPE_AS (A, B)
42 - 16.9.184 STORAGE_SIZE (A [, KIND])
43 - C.10.5 Polymorphic Argument Association (15.5.2.9)
45 ---
47 ## Representation in FIR
49 ### Polymorphic entities `CLASS(type1)`
51 A polymorphic entity is represented as a class type in FIR. In the example below
52 the dummy argument `p` is passed to the subroutine `foo` as a polymorphic entity
53 with the extensible type `point`. The type information captured in the class is
54 the best statically available at compile time.
55 `!fir.class` is a new type introduced for polymorphic entities. It's similar to
56 a box type but allows the distinction between a monomorphic and a polymorphic
57 descriptor.
58 `!fir.class` and `!fir.box` are based on a same `BaseBoxType` similar to the
59 `BaseMemRefType` done for MemRef.
61 **Fortran**
62 ```fortran
63 type point
64   real :: x, y
65 end type point
67 type, extends(point) :: point_3d
68   real :: z
69 end type
71 subroutine foo(p)
72   class(point) :: p
73   ! code of the subroutine
74 end subroutine
75 ```
77 **FIR**
78 ```
79 func.func @foo(%p : !fir.class<!fir.type<_QTpoint{x:f32,y:f32}>>)
80 ```
82 ### Unlimited polymorphic entities `CLASS(*)`
84 The unlimited polymorphic entity is represented as a class type with `none` as
85 element type.
87 **Fortran**
88 ```fortran
89 subroutine bar(x)
90   class(*) :: x
91   ! code of the subroutine
92 end subroutine
93 ```
95 **FIR**
96 ```
97 func.func @bar(%x : !fir.class<none>)
98 ```
100 ### Assumed-type `TYPE(*)`
102 Assumed type is added in Fortran 2018 and it is available only for dummy
103 arguments. It's mainly used for interfaces to non-Fortran code and is similar
104 to C's `void`.
105 An entity that is declared using the `TYPE(*)` type specifier is assumed-type
106 and is an unlimited polymorphic entity. It is not declared to have a type, and
107 is not considered to have the same declared type as any other entity,
108 including another unlimited polymorphic entity. Its dynamic type and type
109 parameters are assumed from its effective argument (7.3.2.2 - 3).
111 Assumed-type is represented in FIR as `!fir.box<none>`.
113 ### SELECT TYPE construct
115 The `SELECT TYPE` construct select for execution at most one of its constituent
116 block. The selection is based on the dynamic type of the selector.
118 **Fortran**
119 ```fortran
120 type point
121   real :: x, y
122 end type point
123 type, extends(point) :: point_3d
124   real :: z
125 end type point_3d
126 type, extends(point) :: color_point
127   integer :: color
128 end type color_point
130 type(point), target :: p
131 type(point_3d), target :: p3
132 type(color_point), target :: c
133 class(point), pointer :: p_or_c
134 p_or_c => c
135 select type ( a => p_or_c )
136 class is (point)
137   print*, a%x, a%y
138 type is (point_3d)
139   print*, a%x, a%y, a%z
140 class default
141   print*,'default'
142 end select
145 From the Fortran standard:
146 > A `TYPE IS` type guard statement matches the selector if the dynamic type
147 and kind type parameter values of the selector are the same as those specified
148 by the statement. A `CLASS IS` type guard statement matches the selector if the
149 dynamic type of the selector is an extension of the type specified by the
150 statement and the kind type parameter values specified by the statement are the
151 same as the corresponding type parameter values of the dynamic type of the
152 selector.
154 In the example above the `CLASS IS` type guard is matched.
156 The construct is lowered to a specific FIR operation `fir.select_type`. It is
157 similar to other FIR "select" operations such as `fir.select` and
158 `fir.select_rank`. The dynamic type of the selector value is matched against a
159 list of type descriptor. The `TYPE IS` type guard statement is represented by a
160 `#fir.type_is` attribute and the `CLASS IS` type guard statement is represented
161 by a `#fir.class_is` attribute.
162 The `CLASS DEFAULT` type guard statement is represented by a `unit` attribute.
164 **FIR**
166 fir.select_type %6 : !fir.class<!fir.ptr<!fir.type<_QFTpoint{x:f32,y:f32}>>> [
167   #fir.class_is<!fir.type<_QFTpoint{x:f32,y:f32}>>, ^bb1,
168   #fir.type_is<!fir.type<_QFTpoint_3d{x:f32,y:f32,z:f32}>>, ^bb2,
169   unit, ^bb3]
172 Lowering of the `fir.select_type` operation will produce a if-then-else ladder.
173 The testing of the dynamic type of the selector is done by calling runtime
174 functions.
176 The runtime has two functions to compare dynamic types. Note that these two
177 functions _ignore_ the values of `KIND` type parameters.
179 The functions for the `EXTENDS_TYPE_OF` and `SAME_TYPE_AS`
180 intrinsics (`flang/include/flang/Runtime/derived-api.h`).
181 ```cpp
182 // Perform the test of the SAME_TYPE_AS intrinsic.
183 bool RTNAME(SameTypeAs)(const Descriptor &, const Descriptor &);
185 // Perform the test of the EXTENDS_TYPE_OF intrinsic.
186 bool RTNAME(ExtendsTypeOf)(const Descriptor &, const Descriptor &);
189 For the `SELECT TYPE` construct, the `KIND` type parameter is not ignored. The
190 `TYPE IS` type guard statement is lowered to an inlined comparison. The
191 `CLASS IS` type guard statement is lowered to a runtime function call.
193 The function `ClassIs` implements the dynamic type comparison.
194 (`flang/include/flang/Runtime/derived-api.h`).
195 ```cpp
196 // Perform the test of the CLASS IS type guard statement of the SELECT TYPE
197 // construct.
198 bool RTNAME(ClassIs)(const Descriptor &, const typeInfo::DerivedType &);
201 **FIR** (lower level FIR/MLIR after conversion to an if-then-else ladder)
203 module  {
204   func @f(%arg0: !fir.class<!fir.ptr<!fir.type<_QFTpoint{x:f32,y:f32}>>>) -> () {
205     // TYPE IS comparison done inlined.
206     %0 = fir.address_of(@_QFE.dt.point_3d) : !fir.ref<!fir type<_QM__fortran_type_infoTderivedtype{}>>
207     %1 = fir.box_tdesc %arg0 : (!fir.class<!fir.ptr<!fir.type<_QFTpoint{x:f32,y:f32}>>>) -> !fir.tdesc<none>
208     %2 = fir.convert %0 : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{}>>) -> index
209     %3 = fir.convert %1 : (!fir.tdesc<none>) -> index
210     %4 = arith.cmpi eq, %2, %3 : index
211     cf.cond_br %4, ^bb4, ^bb3
212   ^bb1:  // pred: ^bb3
213     cf.br ^bb5
214   ^bb2:  // pred: ^bb3
215     // CLASS IS block.
216     cf.br ^bb6
217   ^bb3:  // pred: ^bb0
218     // CLASS IS comparison done with a runtime function call.
219     %24 = fir.address_of(@_QFE.dt.point) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{}>>
220     %25 = fir.convert %24 : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{}>>) -> !fir.ref<none>
221     %26 = fir.convert %6 : (!fir.class<!fir.ptr<!fir.type<_QFTpoint{x:f32,y:f32}>>>) -> !fir.box<none>
222     %27 = fir.call @_FortranAClassIs(%26, %25) : (!fir.box<none>, !fir.ref<none>) -> i1
223     cf.cond_br %27, ^bb2, ^bb1
224   ^bb4:  // pred: ^bb0
225     // TYPE IS block
226     cf.br ^bb6
227   ^bb5:  // pred: ^bb1
228     // CLASS DEFAULT block.
229     cf.br ^bb6
230   ^bb6:  // 3 preds: ^bb2, ^bb4, ^bb5
231     return
232   }
233   func.func private @_FortranAClassIs(!fir.box<none>, !fir.ref<none>) -> i1
237 Dynamic type comparisons are inlined for performance whenever possible.
238 Dynamic type comparison for the `TYPE IS` type guard is inlined and
239 intrinsic types comparison when dealing with unlimited polymorphic entities are
240 also inlined.
242 ```fortran
243 type is (integer(4))
247 %i32typecode = arith.constant 9 : i8
248 %typecode = fir.box_typecode %selector : (!fir.class<none>) -> i8
249 %isi32 = arith.cmpi eq, %typecode, %i32typecode : i8
254 ## Dynamic dispatch
256 Dynamic dispatch is the process of selecting which implementation of a
257 polymorphic procedure to call at runtime. The runtime already has information
258 to be used in this process (more information can be found here:
259 [RuntimeTypeInfo.md](RuntimeTypeInfo.md)).
261 The declaration of the data structures are present in
262 `flang/runtime/type-info.h`.
264 In the example below, there is a basic type `shape` with two type extensions
265 `triangle` and `rectangle`.
266 The two type extensions override the `get_area` type-bound procedure.
268 **UML**
271                           |---------------------|
272                           |        Shape        |
273                           |---------------------|
274                           | + color:integer     |
275                           | + isFilled:logical  |
276                           |---------------------|
277                           | + init()            |
278                           | + get_area():real   |
279                           |---------------------|
280                                      /\
281                                     /__\
282                                      |
283             |---------------------------------------------------|
284             |                                                   |
285             |                                                   |
286 |---------------------|                              |---------------------|
287 |      triangle       |                              |      rectangle      |
288 |---------------------|                              |---------------------|
289 | + base:real         |                              | + length:real       |
290 | + height:real       |                              | + width:real        |
291 |---------------------|                              |---------------------|
292 | + get_area():real   |                              | + get_area():real   |
293 |---------------------|                              |---------------------|
297 **Fortran**
298 ```fortran
299 module geometry
300 type :: shape
301   integer :: color
302   logical :: isFilled
303 contains
304   procedure :: get_area => get_area_shape
305   procedure :: init => init_shape
306 end type shape
308 type, extends(shape) :: triangle
309   real :: base
310   real :: height
311 contains
312   procedure :: get_area => get_area_triangle
313 end type triangle
315 type, extends(shape) :: rectangle
316   real :: length
317   real :: width
318 contains
319   procedure :: get_area => get_area_rectangle
320 end type rectangle
322 type shape_array
323   class(shape), allocatable :: item
324 end type
326 contains
328 function get_area_shape(this)
329   real :: get_area_shape
330   class(shape) :: this
331   get_area_shape = 0.0
332 end function
334 subroutine init_shape(this, color)
335   class(shape) :: this
336   integer :: color
337   this%color = color
338   this%isFilled = .false.
339 end subroutine
341 function get_area_triangle(this)
342   real :: get_area_triangle
343   class(triangle) :: this
344   get_area_triangle = (this%base * this%height) / 2
345 end function
347 function get_area_rectangle(this)
348   real :: get_area_rectangle
349   class(rectangle) :: this
350   get_area_rectangle = this%length * this%width
351 end function
353 function get_all_area(shapes)
354   real :: get_all_area
355   type(shape_array) :: shapes(:)
356   real :: sum
357   integer :: i
359   get_all_area = 0.0
361   do i = 1, size(shapes)
362     get_all_area = get_all_area + shapes(i)%item%get_area()
363   end do
364 end function
366 subroutine set_base_values(sh, v1, v2)
367   class(shape) :: sh
368   real, intent(in) :: v1, v2
370   select type (sh)
371   type is (triangle)
372     sh%base = v1
373     sh%height = v2
374   type is (rectangle)
375     sh%length = v1
376     sh%width = v2
377   class default
378     print*,'Cannot set values'
379   end select
380 end subroutine
382 end module
384 program foo
385   use geometry
387   real :: area
389   type(shape_array), dimension(2) :: shapes
391   allocate (triangle::shapes(1)%item)
392   allocate (rectangle::shapes(2)%item)
394   do i = 1, size(shapes)
395     call shapes(i)%item%init(i)
396   end do
398   call set_base_values(shapes(1)%item, 2.0, 1.5)
399   call set_base_values(shapes(2)%item, 5.0, 4.5)
401   area = get_all_area(shapes)
403   print*, area
405   deallocate(shapes(1)%item)
406   deallocate(shapes(2)%item)
407 end program
410 The `fir.dispatch` operation is used to perform a dynamic dispatch. This
411 operation is comparable to the `fir.call` operation but for polymorphic
412 entities.
413 Call to `NON_OVERRIDABLE` type-bound procedure are resolved at compile time and
414 a `fir.call` operation is emitted instead of a `fir.dispatch`.
415 When the type of a polymorphic entity can be fully determined at compile
416 time, a `fir.dispatch` op can even be converted to a `fir.call` op. This will
417 be discussed in more detailed later in the document in the devirtualization
418 section.
420 **FIR**
421 Here is simple example of the `fir.dispatch` operation. The operation specify
422 the binding name of the type-bound procedure to be called and pass the
423 descriptor as argument. If the `NOPASS` attribute is set then the descriptor is
424 not passed as argument when lowered. If `PASS(arg-name)` is specified, the
425 `fir.pass` attribute is added to point to the PASS argument in the
426 `fir.dispatch` operation. `fir.nopass` attribute is added for the `NOPASS`. The
427 descriptor still need to be present in the `fir.dispatch` operation for the
428 dynamic dispatch. The CodeGen will then omit the descriptor in the argument
429 of the generated call.
431 The dispatch explanation focus only on the call to `get_area()` as seen in the
432 example.
434 **Fortran**
435 ```fortran
436 get_all_area = get_all_area + shapes(i)%item%get_area()
439 **FIR**
441 %1 = fir.convert %0 : !fir.ref<!fir.class<!fir.type<_QMgeometryTtriangle{color:i32,isFilled:!fir.logical<4>,base:f32,height:f32>>>
442 %2 = fir.dispatch "get_area"(%1 : !fir.class<!fir.type<_QMgeometryTtriangle{color:i32,isFilled:!fir.logical<4>,base:f32,height:f32>>) -> f32
445 The type information is stored in the `f18Addendum` of the descriptor. The
446 format is defined in `flang/runtime/type-info.h` and part of its representation
447 in LLVM IR is shown below. The binding is comparable to a vtable. Each derived
448 type has a complete type-bound procedure table in which all of the bindings of
449 its ancestor types appear first.
451 **LLVMIR**
453 Representation of the derived type information with the bindings.
455 %_QM__fortran_type_infoTderivedtype = type { { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, { ptr, i64, i32, i8, i8, i8, i8 }, i64, { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, i32, i8, i8, i8, i8, [4 x i8] }
456 %_QM__fortran_type_infoTbinding = type { %_QM__fortran_builtinsT__builtin_c_funptr, { ptr, i64, i32, i8, i8, i8, i8 } }
457 %_QM__fortran_builtinsT__builtin_c_funptr = type { i64 }
460 The `fir.dispatch` is lowered to FIR operations by the `PolymorphicOpConversion`
461 pass. It uses the runtime information to extract the
462 correct function from the vtable and to perform the actual call. Here is
463 what it can look like in pseudo LLVM IR code.
465 **FIR**
467   %2 = fir.box_tdesc %arg0 : (!fir.class<!fir.type<_QMgeometryTtriangle{color:i32,isFilled:!fir.logical<4>,base:f32,height:f32>>) -> !fir.tdesc<none>
468   %3 = fir.box_tdesc %arg0 : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> !fir.tdesc<none>
469   %4 = fir.convert %3 : (!fir.tdesc<none>) -> !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{}>>
470   %5 = fir.field_index binding, !fir.type<_QM__fortran_type_infoTderivedtype{}>
471   %6 = fir.coordinate_of %4, %5 : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{}>>>>>
472   %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{}>>>>>
473   %8 = fir.box_addr %7 : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{}>>>>) -> !fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{}>>>
474   %c0 = arith.constant 0 : index
475   %9 = fir.coordinate_of %8, %c0 : (!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{}>>
476   %10 = fir.field_index proc, !fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>
477   %11 = fir.coordinate_of %9, %10 : (!fir.ref<!fir.type<_QM__fortran_type_infoTbinding{}>>, !fir.field) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>>
478   %12 = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
479   %13 = fir.coordinate_of %11, %12 : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
480   %14 = fir.load %13 : !fir.ref<i64>
481   %15 = fir.convert %14 : (i64) -> ((!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ())
482   fir.call %15(%arg0) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()
485 **LLVMIR**
487 // Retrieve the derived type runtime information and the vtable.
488 %14 = getelementptr %_QM__fortran_type_infoTderivedtype, ptr %13, i32 0, i32 0
489 %15 = load { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %14
490 store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %15, ptr %8
491 %16 = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %8, i32 0, i32 0
492 %17 = load ptr, ptr %16
493 %18 = getelementptr %_QM__fortran_type_infoTbinding, ptr %17, i64 0
494 %19 = getelementptr %_QM__fortran_type_infoTbinding, ptr %18, i32 0, i32 0
495 %20 = getelementptr %_QM__fortran_builtinsT__builtin_c_funptr, ptr %19, i32 0, i32 0
496 // Load func address
497 %21 = load i64, ptr %20
498 // Cast to func pointer
499 %22 = inttoptr i64 %21 to ptr
500 // Perform the actual function call
501 call void %22(ptr %0)
504 ### Passing polymorphic entities as argument
506 **Fortran**
507 ```fortran
508 TYPE t1
509 END TYPE
510 TYPE, EXTENDS(t1) :: t2
511 END TYPE
514 1) Dummy argument is fixed type and actual argument is fixed type.
515     - `TYPE(t1)` to `TYPE(t1)`: Nothing special to take into consideration.
516 2) Dummy argument is polymorphic and actual argument is fixed type. In these
517    cases, the actual argument need to be boxed to be passed to the
518    subroutine/function since those are expecting a descriptor.
519    ```
520    func.func @_QMmod1Ps(%arg0: !fir.class<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>)
521    func.func @_QQmain() {
522      %0 = fir.alloca !fir.type<_QMmod1Tshape{x:i32,y:i32}> {uniq_name = "_QFEsh"}
523      %1 = fir.embox %0 : (!fir.ref<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>) -> !fir.class<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>
524      fir.call @_QMmod1Ps(%1) : (!fir.class<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>) -> ()
525      return
526    }
527    ```
528     - `TYPE(t1)` to `CLASS(t1)`
529     - `TYPE(t2)` to `CLASS(t1)`
530     - `TYPE(t1)` to `CLASS(t2)` - Invalid
531     - `TYPE(t2)` to `CLASS(t2)`
532 3) Actual argument is polymorphic and dummy argument is fixed type. These case
533    are restricted to the declared type of the polymorphic entities.
534     - The simple case is when the actual argument is a scalar
535       polymorphic entity passed to a non-PDT. The caller just extract the
536       base address from the descriptor and pass it to the function.
537     - In other cases, the caller needs to perform a copyin/copyout since it
538       cannot just extract the base address of the `CLASS(T)` because it is
539       likely not contiguous.
540     - `CLASS(t1)` to `TYPE(t1)`
541     - `CLASS(t2)` to `TYPE(t1)` - Invalid
542     - `CLASS(t1)` to `TYPE(t2)` - Invalid
543     - `CLASS(t2)` to `TYPE(t2)`
544 4) Both actual and dummy arguments are polymorphic. These particular cases are
545    straight forward. The function expect polymorphic entities already.
546    The boxed type is passed without change.
547     - `CLASS(t1)` to `CLASS(t1)`
548     - `CLASS(t2)` to `CLASS(t1)`
549     - `CLASS(t1)` to `CLASS(t2)` - Invalid
550     - `CLASS(t2)` to `CLASS(t2)`
552 ### User-Defined Derived Type Input/Output
554 User-Defined Derived Type Input/Output allows to define how a derived-type
555 is read or written from/to a file.
557 There are 4 basic subroutines that can be defined:
558 - Formatted READ
559 - Formatted WRITE
560 - Unformatted READ
561 - Unformatted WRITE
563 Here are their respective interfaces:
565 **Fortran**
566 ```fortran
567 subroutine read_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
568 subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
569 subroutine read_unformatted(dtv, unit, iotype, v_list, iostat, iomsg)
570 subroutine write_unformatted(dtv, unit, iotype, v_list, iostat, iomsg)
573 When defined on a derived-type, these specific type-bound procedures are stored
574 as special bindings in the type descriptor (see `SpecialBinding` in
575 `flang/runtime/type-info.h`).
577 With a derived-type the function call to `@_FortranAioOutputDescriptor` from IO
578 runtime will be emitted in lowering.
580 **Fortran**
581 ```fortran
582 type(t) :: x
583 write(10), x
586 **FIR**
588 %5 = fir.call @_FortranAioBeginUnformattedOutput(%c10_i32, %4, %c56_i32) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
589 %6 = fir.embox %2 : (!fir.ref<!fir.type<_QTt>>) -> !fir.class<!fir.type<_QTt>>
590 %7 = fir.convert %6 : (!fir.class<!fir.type<_QTt>>) -> !fir.box<none>
591 %8 = fir.call @_FortranAioOutputDescriptor(%5, %7) : (!fir.ref<i8>, !fir.box<none>) -> i1
592 %9 = fir.call @_FortranAioEndIoStatement(%5) : (!fir.ref<i8>) -> i32
595 When dealing with polymorphic entities the call to IO runtime can stay
596 unchanged. The runtime function `OutputDescriptor` can make the dynamic dispatch
597 to the correct binding stored in the descriptor.
599 ### Finalization
601 The `FINAL` specifies a final subroutine that might  be executed when a data
602 entity of that type is finalized. Section 7.5.6.3 defines when finalization
603 occurs.
605 Final subroutines like User-Defined Derived Type Input/Output are stored as
606 special bindings in the type descriptor. The runtime is able to handle the
607 finalization with a call the the `@_FortranADestroy` function
608 (`flang/include/flang/Runtime/derived-api.h`).
610 **FIR**
612 %5 = fir.call @_FortranADestroy(%desc) : (!fir.box<none>) -> none
615 The `@_FortranADestroy` function will take care to call the final subroutines
616 and the ones from the parent type.
618 Appropriate call to finalization have to be lowered at the right places (7.5.6.3
619 When finalization occurs).
621 ### Devirtualization
623 Sometimes there is enough information at compile-time to avoid going through
624 a dynamic dispatch for a type-bound procedure call on a polymorphic entity. To
625 be able to perform this optimization directly in FIR the dispatch table is also
626 present statically with the `fir.dispatch_table` and `fir.dt_entry` operations.
628 Here is an example of these operations representing the dispatch tables for the
629 same example than for the dynamic dispatch.
631 **FIR**
633 fir.dispatch_table @_QMgeometryE.dt.shape {
634   fir.dt_entry init, @_QMgeometryPinit_shape
635   fir.dt_entry get_area, @_QMgeometryPget_area_shape
638 fir.dispatch_table @_QMgeometryE.dt.rectangle {
639   fir.dt_entry init, @_QMgeometryPinit_shape
640   fir.dt_entry get_area, @_QMgeometryPget_area_rectangle
643 fir.dispatch_table @_QMgeometryE.dt.triangle {
644   fir.dt_entry init, @_QMgeometryPinit_shape
645   fir.dt_entry get_area, @_QMgeometryPget_area_triangle
649 With this information, an optimization pass can replace `fir.dispatch`
650 operations with `fir.call` operations to the correct functions when the type is
651 know at compile time.
653 This is the case in a `type is` type-guard block as illustrated below.
655 **Fortran**
656 ```fortran
657 subroutine get_only_triangle_area(sh)
658   class(shape) :: sh
659   real :: area
661   select type (sh)
662   type is (triangle)
663     area = sh%get_area()
664   class default
665     area = 0.0
666   end select
668 end subroutine
671 **FIR**
673 The call to `get_area` in the `type is (triangle)` guard can be replaced.
675 %3 = fir.dispatch "get_area"(%desc)
676 // Replaced by
677 %3 = fir.call @get_area_triangle(%desc)
680 Another example would be the one below. In this case as well, a dynamic dispatch
681 is not necessary and a `fir.call` can be emitted instead.
683 **Fortran**
684 ```fortran
685 real :: area
686 class(shape), pointer :: sh
687 type(triangle), target :: tr
689 sh => tr
691 area = sh%get_area()
694 Note that the frontend is already replacing some of the dynamic dispatch calls
695 with the correct static ones. The optimization pass is useful for cases not
696 handled by the frontend and especially cases showing up after some other
697 optimizations are applied.
699 ### `ALLOCATE`/`DEALLOCATE` statements
701 The allocation and deallocation of polymorphic entities are delegated to the
702 runtime.
703 The corresponding function signatures can be found in
704 `flang/include/flang/Runtime/allocatable.h` and in
705 `flang/include/flang/Runtime/pointer.h` for pointer allocation.
707 `ALLOCATE`
709 The `ALLOCATE` statement is lowered to runtime calls as shown in the example
710 below.
712 **Fortran**
713 ```fortran
714 allocate(triangle::shapes(1)%item)
715 allocate(rectangle::shapes(2)%item)
718 **FIR**
720 %0 = fir.address_of(@_QMgeometryE.dt.triangle) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype>>
721 %1 = fir.convert %item1 : (!fir.ref<!fir.class<!fir.type<_QMgeometryTtriangle{color:i32,isFilled:!fir.logical<4>,base:f32,height:f32>>>) -> !fir.ref<!fir.box<none>>
722 %2 = fir.call @_FortranAAllocatableInitDerived(%1, %0)
723 %3 = fir.call @_FortranAAllocatableAllocate(%1, ...)
725 %4 = fir.address_of(@_QMgeometryE.dt.rectangle) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype>>
726 %5 = fir.convert %item2 : (!fir.ref<!fir.class<_QMgeometryTtriangle{color:i32,isFilled:!fir.logical<4>,base:f32,height:f32}>>>) -> !fir.ref<!fir.box<none>>
727 %6 = fir.call @_FortranAAllocatableInitDerived(%5, %4)
728 %7 = fir.call @_FortranAAllocatableAllocate(%5, ...)
731 For pointer allocation, the `PointerAllocate` function is used.
733 `DEALLOCATE`
735 The `DEALLOCATE` statement is lowered to a runtime call to
736 `AllocatableDeallocate` and `PointerDeallocate` for pointers.
738 **Fortran**
739 ```fortran
740 deallocate(shapes(1)%item)
741 deallocate(shapes(2)%item)
744 **FIR**
746 %8 = fir.call @_FortranAAllocatableDeallocate(%desc1)
747 %9 = fir.call @_FortranAAllocatableDeallocate(%desc2)
750 ### `EXTENDS_TYPE_OF`/`SAME_TYPE_AS` intrinsics
752 `EXTENDS_TYPE_OF` and `SAME_TYPE_AS` intrinsics have implementation in the
753 runtime. Respectively `SameTypeAs` and `ExtendsTypeOf` in
754 `flang/include/flang/Evaluate/type.h`.
756 Both intrinsic functions are lowered to their respective runtime calls.
758 ### Assignment / Pointer assignment
760 Intrinsic assignment of an object to another is already implemented in the
761 runtime. The function `@_FortranAAsssign` performs the correct operations.
763 Available in `flang/include/flang/Runtime/assign.h`.
765 ### User defined assignment and operator
767 **Fortran**
768 ```fortran
769 module mod1
770 type t1
771 contains
772   procedure :: assign_t1
773   generic :: assignment(=) => assign_t1
774 end type t1
776 type, extends(t1) :: t2
777 end type
779 contains
781 subroutine assign_t1(to, from)
782   class(t1), intent(inout) :: to
783   class(t1), intent(in) :: from
784   ! Custom code for the assignment
785 end subroutine
787 subroutine assign_t2(to, from)
788   class(t2), intent(inout) :: to
789   class(t2), intent(in) :: from
790   ! Custom code for the assignment
791 end subroutine
793 end module
795 program main
796 use mod
798 class(t1), allocatable :: v1
799 class(t1), allocatable :: v2
801 allocate(t2::v1)
802 allocate(t2::v2)
804 v2 = v1
806 end program
809 In the example above the assignment `v2 = v1` is done by a call to `assign_t1`.
810 This is resolved at compile time since `t2` could not have a generic type-bound
811 procedure for assignment with an interface that is not distinguishable. This
812 is the same for user defined operators.
814 ### `NULLIFY`
816 When a `NULLIFY` statement is applied to a polymorphic pointer (7.3.2.3), its
817 dynamic type becomes the same as its declared type.
819 The `NULLIFY` statement is lowered to a call to the corresponding runtime
820 function `PointerNullifyDerived` in `flang/include/flang/Runtime/pointer.h`.
822 ### Impact on existing FIR operations dealing with descriptors
824 Currently, FIR has a couple of operations taking descriptors as inputs or
825 producing descriptors as outputs. These operations might need to deal with the
826 dynamic type of polymorphic entities.
828 - `fir.load`/`fir.store`
829   - Currently a `fir.load` of a `fir.box` is a special case. In the code
830     generation no copy is made. This could be problematic with polymorphic
831     entities. When a `fir.load` is performed on a `fir.class` type, the dynamic
832     can be copied.
834   **Fortran**
835   ```fortran
836   module mod1
837     class(shape), pointer :: a
838   contains
839   subroutine sub1(a, b)
840     class(shape) :: b
841     associate (b => a)
842       ! Some more code
843     end associate
844   end subroutine
845   end module
846   ```
848   In the example above, the dynamic type of `a` and `b` might be different. The
849   dynamic type of `a` must be copied when it is associated on `b`.
851   **FIR**
852   ```
853   // fir.load must copy the dynamic type from the pointer `a`
854   %0 = fir.address_of(@_QMmod1Ea) : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>>>
855   %1 = fir.load %0 : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmod1Tshape{x:i32,y:i32}>>>>
856   ```
858 - `fir.embox`
859   - The embox operation is used to create a descriptor from a reference. With
860     polymorphic entities, it is used to create a polymorphic descriptor from
861     a derived type. The declared type of the descriptor and the derived type
862     are identical. The dynamic type of the descriptor must be set when it is
863     created. This is already handled by lowering.
865 - `fir.rebox`
866   - The rebox operation is used to create a new descriptor from a another
867     descriptor with new optional dimension. If the original descriptor is a
868     polymorphic entities its dynamic type must be propagated to the new
869     descriptor.
870   ```
871   %0 = fir.slice %c10, %c33, %c2 : (index, index, index) -> !fir.slice<1>
872   %1 = fir.shift %c0 : (index) -> !fir.shift<1>
873   %2 = fir.rebox %x(%1)[%0] : (!fir.class<!fir.array<?x!fir.type<>>>, !fir.shift<1>, !fir.slice<1>) -> !fir.class<!fir.array<?x!fir.type<>>>
874   ```
877 # Testing
879 - Lowering part is tested with LIT tests in tree
880 - Polymorphic entities involved a lot of runtime information so executable
881   tests will be useful for full testing.
885 # Current TODOs
886 Current list of TODOs in lowering:
887 - `flang/lib/Lower/Bridge.cpp:448` not yet implemented: create polymorphic host associated copy
888 - `flang/lib/Lower/CallInterface.cpp:795` not yet implemented: support for polymorphic types
889 - `flang/lib/Lower/ConvertType.cpp:237` not yet implemented: support for polymorphic types
893 Resources:
894 - [1] https://www.pgroup.com/blogs/posts/f03-oop-part1.htm
895 - [2] https://www.pgroup.com/blogs/posts/f03-oop-part2.htm
896 - [3] https://www.pgroup.com/blogs/posts/f03-oop-part3.htm
897 - [4] https://www.pgroup.com/blogs/posts/f03-oop-part4.htm
898 - [5] Modern Fortran explained