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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
! Test basic parts of derived type entities lowering
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! Note: only testing non parameterized derived type here.
module d
type r
real :: x
end type
type r2
real :: x_array(10, 20)
end type
type c
character(10) :: ch
end type
type c2
character(10) :: ch_array(20, 30)
end type
contains
! -----------------------------------------------------------------------------
! Test simple derived type symbol lowering
! -----------------------------------------------------------------------------
! CHECK-LABEL: func @_QMdPderived_dummy(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.type<_QMdTr{x:f32}>>{{.*}}, %{{.*}}: !fir.ref<!fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>>{{.*}}) {
subroutine derived_dummy(some_r, some_c2)
type(r) :: some_r
type(c2) :: some_c2
end subroutine
! CHECK-LABEL: func @_QMdPlocal_derived(
subroutine local_derived()
! CHECK-DAG: fir.alloca !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
! CHECK-DAG: fir.alloca !fir.type<_QMdTr{x:f32}>
type(r) :: some_r
type(c2) :: some_c2
end subroutine
! CHECK-LABEL: func @_QMdPsaved_derived(
subroutine saved_derived()
! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_c2) : !fir.ref<!fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>>
! CHECK-DAG: fir.address_of(@_QMdFsaved_derivedEsome_r) : !fir.ref<!fir.type<_QMdTr{x:f32}>>
type(r), save :: some_r
type(c2), save :: some_c2
call use_symbols(some_r, some_c2)
end subroutine
! -----------------------------------------------------------------------------
! Test simple derived type references
! -----------------------------------------------------------------------------
! CHECK-LABEL: func @_QMdPscalar_numeric_ref(
subroutine scalar_numeric_ref()
! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}>
type(r) :: some_r
! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}>
! CHECK: fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref<!fir.type<_QMdTr{x:f32}>>, !fir.field) -> !fir.ref<f32>
call real_bar(some_r%x)
end subroutine
! CHECK-LABEL: func @_QMdPscalar_character_ref(
subroutine scalar_character_ref()
! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTc{ch:!fir.char<1,10>}>
type(c) :: some_c
! CHECK: %[[field:.*]] = fir.field_index ch, !fir.type<_QMdTc{ch:!fir.char<1,10>}>
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref<!fir.type<_QMdTc{ch:!fir.char<1,10>}>>, !fir.field) -> !fir.ref<!fir.char<1,10>>
! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : index
! CHECK-DAG: %[[conv:.*]] = fir.convert %[[coor]] : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,?>>
! CHECK: fir.emboxchar %[[conv]], %c10 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
call char_bar(some_c%ch)
end subroutine
! FIXME: coordinate of generated for derived%array_comp(i) are not zero based as they
! should be.
! CHECK-LABEL: func @_QMdParray_comp_elt_ref(
subroutine array_comp_elt_ref()
type(r2) :: some_r2
! CHECK: %[[alloc:.*]] = fir.alloca !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}>
! CHECK: %[[field:.*]] = fir.field_index x_array, !fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}>
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[alloc]], %[[field]] : (!fir.ref<!fir.type<_QMdTr2{x_array:!fir.array<10x20xf32>}>>, !fir.field) -> !fir.ref<!fir.array<10x20xf32>>
! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64
! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64
! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref<!fir.array<10x20xf32>>, i64, i64) -> !fir.ref<f32>
call real_bar(some_r2%x_array(5, 6))
end subroutine
! CHECK-LABEL: func @_QMdPchar_array_comp_elt_ref(
subroutine char_array_comp_elt_ref()
type(c2) :: some_c2
! CHECK: %[[coor:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref<!fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>>, !fir.field) -> !fir.ref<!fir.array<20x30x!fir.char<1,10>>>
! CHECK-DAG: %[[index1:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64
! CHECK-DAG: %[[index2:.*]] = arith.subi %c6{{.*}}, %c1{{.*}} : i64
! CHECK: fir.coordinate_of %[[coor]], %[[index1]], %[[index2]] : (!fir.ref<!fir.array<20x30x!fir.char<1,10>>>, i64, i64) -> !fir.ref<!fir.char<1,10>>
! CHECK: fir.emboxchar %{{.*}}, %c10 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
call char_bar(some_c2%ch_array(5, 6))
end subroutine
! CHECK: @_QMdParray_elt_comp_ref
subroutine array_elt_comp_ref()
type(r) :: some_r_array(100)
! CHECK: %[[alloca:.*]] = fir.alloca !fir.array<100x!fir.type<_QMdTr{x:f32}>>
! CHECK: %[[index:.*]] = arith.subi %c5{{.*}}, %c1{{.*}} : i64
! CHECK: %[[elt:.*]] = fir.coordinate_of %[[alloca]], %[[index]] : (!fir.ref<!fir.array<100x!fir.type<_QMdTr{x:f32}>>>, i64) -> !fir.ref<!fir.type<_QMdTr{x:f32}>>
! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}>
! CHECK: fir.coordinate_of %[[elt]], %[[field]] : (!fir.ref<!fir.type<_QMdTr{x:f32}>>, !fir.field) -> !fir.ref<f32>
call real_bar(some_r_array(5)%x)
end subroutine
! CHECK: @_QMdPchar_array_elt_comp_ref
subroutine char_array_elt_comp_ref()
type(c) :: some_c_array(100)
! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref<!fir.array<100x!fir.type<_QMdTc{ch:!fir.char<1,10>}>>>, i64) -> !fir.ref<!fir.type<_QMdTc{ch:!fir.char<1,10>}>>
! CHECK: fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref<!fir.type<_QMdTc{ch:!fir.char<1,10>}>>, !fir.field) -> !fir.ref<!fir.char<1,10>>
! CHECK: fir.emboxchar %{{.*}}, %c10{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
call char_bar(some_c_array(5)%ch)
end subroutine
! -----------------------------------------------------------------------------
! Test loading derived type components
! -----------------------------------------------------------------------------
! Most of the other tests only require lowering code to compute the address of
! components. This one requires loading a component which tests other code paths
! in lowering.
! CHECK-LABEL: func @_QMdPscalar_numeric_load(
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.type<_QMdTr{x:f32}>>
real function scalar_numeric_load(some_r)
type(r) :: some_r
! CHECK: %[[field:.*]] = fir.field_index x, !fir.type<_QMdTr{x:f32}>
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[field]] : (!fir.ref<!fir.type<_QMdTr{x:f32}>>, !fir.field) -> !fir.ref<f32>
! CHECK: fir.load %[[coor]]
scalar_numeric_load = some_r%x
end function
! -----------------------------------------------------------------------------
! Test returned derived types (no length parameters)
! -----------------------------------------------------------------------------
! CHECK-LABEL: func @_QMdPbar_return_derived() -> !fir.type<_QMdTr{x:f32}>
function bar_return_derived()
! CHECK: %[[res:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}>
type(r) :: bar_return_derived
! CHECK: %[[resLoad:.*]] = fir.load %[[res]] : !fir.ref<!fir.type<_QMdTr{x:f32}>>
! CHECK: return %[[resLoad]] : !fir.type<_QMdTr{x:f32}>
end function
! CHECK-LABEL: func @_QMdPcall_bar_return_derived(
subroutine call_bar_return_derived()
! CHECK: %[[tmp:.*]] = fir.alloca !fir.type<_QMdTr{x:f32}>
! CHECK: %[[call:.*]] = fir.call @_QMdPbar_return_derived() {{.*}}: () -> !fir.type<_QMdTr{x:f32}>
! CHECK: fir.save_result %[[call]] to %[[tmp]] : !fir.type<_QMdTr{x:f32}>, !fir.ref<!fir.type<_QMdTr{x:f32}>>
! CHECK: fir.call @_QPr_bar(%[[tmp]]) {{.*}}: (!fir.ref<!fir.type<_QMdTr{x:f32}>>) -> ()
call r_bar(bar_return_derived())
end subroutine
end module
! -----------------------------------------------------------------------------
! Test derived type with pointer/allocatable components
! -----------------------------------------------------------------------------
module d2
type recursive_t
real :: x
type(recursive_t), pointer :: ptr
end type
contains
! CHECK-LABEL: func @_QMd2Ptest_recursive_type(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.type<_QMd2Trecursive_t{x:f32,ptr:!fir.box<!fir.ptr<!fir.type<_QMd2Trecursive_t>>>}>>{{.*}}) {
subroutine test_recursive_type(some_recursive)
type(recursive_t) :: some_recursive
end subroutine
end module
! -----------------------------------------------------------------------------
! Test global derived type symbol lowering
! -----------------------------------------------------------------------------
module data_mod
use d
type(r) :: some_r
type(c2) :: some_c2
end module
! Test globals
! CHECK-DAG: fir.global @_QMdata_modEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
! CHECK-DAG: fir.global @_QMdata_modEsome_r : !fir.type<_QMdTr{x:f32}>
! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_c2 : !fir.type<_QMdTc2{ch_array:!fir.array<20x30x!fir.char<1,10>>}>
! CHECK-DAG: fir.global internal @_QMdFsaved_derivedEsome_r : !fir.type<_QMdTr{x:f32}>
|