Polymorphic Entities#
A polymorphic entity is a data entity that can be of different type during the execution of a program.
This document aims to give insights at the representation of polymorphic entities in FIR and how polymorphic related constructs and features are lowered to FIR.
Fortran standard#
Here is a list of the sections and constraints of the Fortran standard involved for polymorphic entities.
7.3.2.1 - 7.3.2.2: TYPE specifier (TYPE(*))
C708
C709
C710
C711
7.3.2.3: CLASS specifier
7.5.4.5: The passed-object dummy argument
C760
9.7.1: ALLOCATE statement
C933
9.7.2: NULLIFY statement
When a NULLIFY statement is applied to a polymorphic pointer (7.3.2.3), its dynamic type becomes the same as its declared type.
10.2.2.3: Data pointer assignment
11.1.3: ASSOCIATE construct
11.1.11: SELECT TYPE construct
C1157
C1158
C1159
C1160
C1161
C1162
C1163
C1164
C1165
16.9.76 EXTENDS_TYPE_OF (A, MOLD)
16.9.165 SAME_TYPE_AS (A, B)
16.9.184 STORAGE_SIZE (A [, KIND])
C.10.5 Polymorphic Argument Association (15.5.2.9)
Representation in FIR#
Polymorphic entities CLASS(type1)#
A polymorphic entity is represented as a class type in FIR. In the example below
the dummy argument p is passed to the subroutine foo as a polymorphic entity
with the extensible type point. The type information captured in the class is
the best statically available at compile time.
!fir.class is a new type introduced for polymorphic entities. It’s similar to
a box type but allows the distinction between a monomorphic and a polymorphic
descriptor.
!fir.class and !fir.box are based on a same BaseBoxType similar to the
BaseMemRefType done for MemRef.
Fortran
type point
real :: x, y
end type point
type, extends(point) :: point_3d
real :: z
end type
subroutine foo(p)
class(point) :: p
! code of the subroutine
end subroutine
FIR
func.func @foo(%p : !fir.class<!fir.type<_QTpoint{x:f32,y:f32}>>)
Unlimited polymorphic entities CLASS(*)#
The unlimited polymorphic entity is represented as a class type with none as
element type.
Fortran
subroutine bar(x)
class(*) :: x
! code of the subroutine
end subroutine
FIR
func.func @bar(%x : !fir.class<none>)
Assumed-type TYPE(*)#
Assumed type is added in Fortran 2018 and it is available only for dummy
arguments. It’s mainly used for interfaces to non-Fortran code and is similar
to C’s void.
An entity that is declared using the TYPE(*) type specifier is assumed-type
and is an unlimited polymorphic entity. It is not declared to have a type, and
is not considered to have the same declared type as any other entity,
including another unlimited polymorphic entity. Its dynamic type and type
parameters are assumed from its effective argument (7.3.2.2 - 3).
Assumed-type is represented in FIR as !fir.box<none>.
SELECT TYPE construct#
The SELECT TYPE construct select for execution at most one of its constituent
block. The selection is based on the dynamic type of the selector.
Fortran
type point
real :: x, y
end type point
type, extends(point) :: point_3d
real :: z
end type point_3d
type, extends(point) :: color_point
integer :: color
end type color_point
type(point), target :: p
type(point_3d), target :: p3
type(color_point), target :: c
class(point), pointer :: p_or_c
p_or_c => c
select type ( a => p_or_c