335 lines · plain
1! RUN: bbc -emit-hlfir %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s2! RUN: bbc -emit-hlfir %s -o - | FileCheck %s --check-prefix=BT3 4! Tests codegen of fir.dispatch operation. This test is intentionally run from5! Fortran through bbc and tco so we have all the binding tables lowered to FIR6! from semantics.7 8module dispatch19 10 type p111 integer :: a12 integer :: b13 contains14 procedure :: aproc15 procedure :: display1 => display1_p116 procedure :: display2 => display2_p117 procedure :: get_value => get_value_p118 procedure :: proc_with_values => proc_p119 procedure, nopass :: proc_nopass => proc_nopass_p120 procedure, pass(this) :: proc_pass => proc_pass_p121 procedure, nopass :: z_proc_nopass_bindc => proc_nopass_bindc_p122 end type23 24 type, extends(p1) :: p225 integer :: c26 contains27 procedure :: display1 => display1_p228 procedure :: display2 => display2_p229 procedure :: display330 procedure :: get_value => get_value_p231 procedure :: proc_with_values => proc_p232 procedure, nopass :: proc_nopass => proc_nopass_p233 procedure, pass(this) :: proc_pass => proc_pass_p234 procedure, nopass :: z_proc_nopass_bindc => proc_nopass_bindc_p235 end type36 37 type, abstract :: a138 integer a39 contains40 procedure :: a1_proc41 end type42 43 type, extends(a1) :: a244 integer b45 contains46 procedure :: a1_proc => a2_proc47 end type48 49 type ty_kind(i, j)50 integer, kind :: i, j51 integer :: a(i)52 end Type53 54 type, extends(ty_kind) :: ty_kind_ex55 integer :: b(j)56 end type57 type(ty_kind(10,20)) :: tk158 type(ty_kind_ex(10,20)) :: tke159contains60 61 subroutine display1_p1(this)62 class(p1) :: this63 print*,'call display1_p1'64 end subroutine65 66 subroutine display2_p1(this)67 class(p1) :: this68 print*,'call display2_p1'69 end subroutine70 71 subroutine display1_p2(this)72 class(p2) :: this73 print*,'call display1_p2'74 end subroutine75 76 subroutine display2_p2(this)77 class(p2) :: this78 print*,'call display2_p2'79 end subroutine80 81 subroutine aproc(this)82 class(p1) :: this83 print*,'call aproc'84 end subroutine85 86 subroutine display3(this)87 class(p2) :: this88 print*,'call display3'89 end subroutine90 91 function get_value_p1(this)92 class(p1) :: this93 integer :: get_value_p194 get_value_p1 = 1095 end function96 97 function get_value_p2(this)98 class(p2) :: this99 integer :: get_value_p2100 get_value_p2 = 10101 end function102 103 subroutine proc_p1(this, v)104 class(p1) :: this105 real :: v106 print*, 'call proc1 with ', v107 end subroutine108 109 subroutine proc_p2(this, v)110 class(p2) :: this111 real :: v112 print*, 'call proc1 with ', v113 end subroutine114 115 subroutine proc_nopass_p1()116 print*, 'call proc_nopass_p1'117 end subroutine118 119 subroutine proc_nopass_p2()120 print*, 'call proc_nopass_p2'121 end subroutine122 123 subroutine proc_nopass_bindc_p1() bind(c)124 print*, 'call proc_nopass_bindc_p1'125 end subroutine126 127 subroutine proc_nopass_bindc_p2() bind(c)128 print*, 'call proc_nopass_bindc_p2'129 end subroutine130 131 subroutine proc_pass_p1(i, this)132 integer :: i133 class(p1) :: this134 print*, 'call proc_pass_p1'135 end subroutine136 137 subroutine proc_pass_p2(i, this)138 integer :: i139 class(p2) :: this140 print*, 'call proc_pass_p2'141 end subroutine142 143 subroutine display_class(p)144 class(p1) :: p145 integer :: i146 call p%display2()147 call p%display1()148 call p%aproc()149 i = p%get_value()150 call p%proc_with_values(2.5)151 call p%proc_nopass()152 call p%proc_pass(1)153 call p%z_proc_nopass_bindc()154 end subroutine155 156 subroutine no_pass_array(a)157 class(p1) :: a(:)158 call a(1)%proc_nopass()159 end subroutine160 161 subroutine no_pass_array_allocatable(a)162 class(p1), allocatable :: a(:)163 call a(1)%proc_nopass()164 end subroutine165 166 subroutine no_pass_array_pointer(a)167 class(p1), allocatable :: a(:)168 call a(1)%proc_nopass()169 end subroutine170 171 subroutine a1_proc(this)172 class(a1) :: this173 end subroutine174 175 subroutine a2_proc(this)176 class(a2) :: this177 end subroutine178 179 subroutine call_a1_proc(p)180 class(a1), pointer :: p181 call p%a1_proc()182 end subroutine183 184end module185 186program test_type_to_class187 use dispatch1188 type(p1) :: t1 = p1(1,2)189 type(p2) :: t2 = p2(1,2,3)190 191 call display_class(t1)192 call display_class(t2)193end194 195 196! CHECK-LABEL: func.func @_QMdispatch1Pdisplay_class(197! CHECK-SAME: %[[ARG:.*]]: [[CLASS:!fir.class<.*>>]]198! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMdispatch1Fdisplay_classEp"} : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.dscope) -> (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>)199 200! Check dynamic dispatch equal to `call p%display2()` with binding index = 2.201! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>202! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>203! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>204! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>205! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>206! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c2{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>207! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>208! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address209! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>210! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ())211! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()212 213! Check dynamic dispatch equal to `call p%display1()` with binding index = 1.214! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>215! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>216! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>217! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>218! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>219! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c1{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>220! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>221! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address222! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>223! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ())224! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()225 226! Check dynamic dispatch equal to `call p%aproc()` with binding index = 0.227! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>228! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>229! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>230! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>231! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>232! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c0{{.*}}: (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>233! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>234! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address235! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>236! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> ())237! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> ()238 239! Check dynamic dispatch of a function with result.240! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>241! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>242! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>243! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>244! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>245! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c3 : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>246! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>247! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address248! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>249! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]]) -> i32)250! CHECK: %[[RES:.*]] = fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>) -> i32251 252! Check dynamic dispatch of call with passed-object and additional argument253! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>254! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>255! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>256! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>257! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>258! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c6{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>259! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>260! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address261! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>262! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (([[CLASS]], !fir.ref<f32>) -> ())263! CHECK: fir.call %[[FUNC_PTR]](%[[ARG_DECL]]#0, %{{.*}}) : (!fir.class<!fir.type<_QMdispatch1Tp1{a:i32,b:i32}>>, !fir.ref<f32>) -> ()264 265! Check dynamic dispatch of a call with NOPASS266! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#1 : ([[CLASS]]) -> !fir.tdesc<none>267! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>268! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>269! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<{{.*}}>>>>>270! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<{{.*}}>>>271! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c4{{.*}} : (!fir.ptr<!fir.array<?x!fir.type<{{.*}}>>>, index) -> !fir.ref<!fir.type<{{.*}}>>272! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>273! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address274! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>275! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> (() -> ())276! CHECK: fir.call %[[FUNC_PTR]]() : () -> ()277 278! CHECK: %[[BOXDESC:.*]] = fir.box_tdesc %[[ARG_DECL]]#0 : ([[CLASS]]) -> !fir.tdesc<none>279! CHECK: %[[TYPEDESCPTR:.*]] = fir.convert %[[BOXDESC]] : (!fir.tdesc<none>) -> !fir.ref<[[TYPEINFO:!fir.type<_QM__fortran_type_infoTderivedtype{.*}>]]>280! CHECK: %[[BINDING_BOX_ADDR:.*]] = fir.coordinate_of %[[TYPEDESCPTR]], binding : (!fir.ref<[[TYPEINFO]]>) -> !fir.ref<[[BINDING_BOX_TYPE:.*]]>281! CHECK: %[[BINDING_BOX:.*]] = fir.load %[[BINDING_BOX_ADDR]] : !fir.ref<[[BINDING_BOX_TYPE]]>282! CHECK: %[[BINDING_BASE_ADDR:.*]] = fir.box_addr %[[BINDING_BOX]] : ([[BINDING_BOX_TYPE]]) -> !fir.ptr<[[BINDINGSINFO:.*]]>283! CHECK: %[[BINDING_PTR:.*]] = fir.coordinate_of %[[BINDING_BASE_ADDR]], %c5{{.*}} : (!fir.ptr<[[BINDINGSINFO]]>, index) -> !fir.ref<[[BINDINGINFO:.*]]>284! CHECK: %[[BUILTIN_FUNC_PTR:.*]] = fir.coordinate_of %[[BINDING_PTR]], proc : ({{.*}}) -> !fir.ref<[[BUILTIN_FUNC_TYPE:.*]]>285! CHECK: %[[FUNC_ADDR_PTR:.*]] = fir.coordinate_of %[[BUILTIN_FUNC_PTR]], __address286! CHECK: %[[FUNC_ADDR:.*]] = fir.load %[[FUNC_ADDR_PTR]] : !fir.ref<i64>287! CHECK: %[[FUNC_PTR:.*]] = fir.convert %[[FUNC_ADDR]] : (i64) -> ((!fir.ref<i32>, [[CLASS]]) -> ())288! CHECK: fir.call %[[FUNC_PTR]](%{{.*}}, %[[ARG_DECL]]#0) : (!fir.ref<i32>, [[CLASS]]) -> ()289 290! Test attributes are propagated from fir.dispatch to fir.call291! for `call p%z_proc_nopass_bindc()`292! CHECK: fir.call %{{.*}}() proc_attrs<bind_c> : () -> ()293 294! CHECK-LABEL: _QMdispatch1Pno_pass_array295! CHECK-LABEL: _QMdispatch1Pno_pass_array_allocatable296! CHECK-LABEL: _QMdispatch1Pno_pass_array_pointer297! CHECK-LABEL: _QMdispatch1Pcall_a1_proc298 299! Check the layout of the binding table. This is easier to do in FIR than in300! LLVM IR.301 302! BT-LABEL: fir.type_info @_QMdispatch1Tty_kindK10K20303! BT-LABEL: fir.type_info @_QMdispatch1Tty_kind_exK10K20 {{.*}}extends !fir.type<_QMdispatch1Tty_kindK10K20{{.*}}>304 305! BT-LABEL: fir.type_info @_QMdispatch1Tp1306! BT: fir.dt_entry "aproc", @_QMdispatch1Paproc307! BT: fir.dt_entry "display1", @_QMdispatch1Pdisplay1_p1308! BT: fir.dt_entry "display2", @_QMdispatch1Pdisplay2_p1309! BT: fir.dt_entry "get_value", @_QMdispatch1Pget_value_p1310! BT: fir.dt_entry "proc_nopass", @_QMdispatch1Pproc_nopass_p1311! BT: fir.dt_entry "proc_pass", @_QMdispatch1Pproc_pass_p1312! BT: fir.dt_entry "proc_with_values", @_QMdispatch1Pproc_p1313! BT: fir.dt_entry "z_proc_nopass_bindc", @proc_nopass_bindc_p1314! BT: }315 316! BT-LABEL: fir.type_info @_QMdispatch1Ta1317! BT: fir.dt_entry "a1_proc", @_QMdispatch1Pa1_proc318! BT: }319 320! BT-LABEL: fir.type_info @_QMdispatch1Ta2 {{.*}}extends !fir.type<_QMdispatch1Ta1{{.*}}>321! BT: fir.dt_entry "a1_proc", @_QMdispatch1Pa2_proc322! BT: }323 324! BT-LABEL: fir.type_info @_QMdispatch1Tp2 {{.*}}extends !fir.type<_QMdispatch1Tp1{{.*}}>325! BT: fir.dt_entry "aproc", @_QMdispatch1Paproc326! BT: fir.dt_entry "display1", @_QMdispatch1Pdisplay1_p2327! BT: fir.dt_entry "display2", @_QMdispatch1Pdisplay2_p2328! BT: fir.dt_entry "get_value", @_QMdispatch1Pget_value_p2329! BT: fir.dt_entry "proc_nopass", @_QMdispatch1Pproc_nopass_p2330! BT: fir.dt_entry "proc_pass", @_QMdispatch1Pproc_pass_p2331! BT: fir.dt_entry "proc_with_values", @_QMdispatch1Pproc_p2332! BT: fir.dt_entry "z_proc_nopass_bindc", @proc_nopass_bindc_p2333! BT: fir.dt_entry "display3", @_QMdispatch1Pdisplay3334! BT: }335