@@ -2,7 +2,7 @@ use crate::test_utils::tests::codegen;
22use plc_util:: filtered_assert_snapshot;
33
44#[ test]
5- fn function_pointer_simple ( ) {
5+ fn function_pointer ( ) {
66 let result = codegen (
77 r"
88 FUNCTION echo : DINT
@@ -15,10 +15,10 @@ fn function_pointer_simple() {
1515
1616 FUNCTION main
1717 VAR
18- echoPtr : REF_TO echo;
18+ echoPtr : POINTER TO echo;
1919 END_VAR
2020
21- echoPtr := REF (echo);
21+ echoPtr := ADR (echo);
2222 echoPtr^(12345);
2323 END_FUNCTION
2424 " ,
@@ -56,81 +56,85 @@ fn function_pointer_simple() {
5656}
5757
5858#[ test]
59- fn function_pointer_simple_method ( ) {
59+ fn function_pointer_method ( ) {
6060 let result = codegen (
6161 r"
62- TYPE VTable:
62+ VAR_GLOBAL
63+ instanceVTableFbA: VTableFbA := (foo := ADR(FbA.foo));
64+ END_VAR
65+
66+ TYPE VTableFbA:
6367 STRUCT
64- fbEcho : REF_TO fb.fbEcho := REF(fb.fbEcho) ;
68+ foo: POINTER TO FbA.foo ;
6569 END_STRUCT
6670 END_TYPE
6771
68- FUNCTION_BLOCK fb
69- METHOD fbEcho : DINT
70- VAR_INPUT
71- value : INT;
72- END_VAR
72+ FUNCTION_BLOCK FbA
73+ VAR
74+ vtable: POINTER TO VTableFbA := ADR(instanceVTableFbA);
75+ localVariableInFbA : INT;
76+ END_VAR
7377
74- fbEcho := value;
78+ METHOD foo: INT
79+ // printf('Hello from FbA::foo$N');
7580 END_METHOD
7681 END_FUNCTION_BLOCK
7782
7883 FUNCTION main
7984 VAR
80- vt: VTable;
81- instance : fb;
85+ instanceFbA: FbA;
8286 END_VAR
8387
84- vt.fbEcho^(instance, INT#5 );
88+ instanceFbA.vtable^.foo^(instanceFbA );
8589 END_FUNCTION
8690 " ,
8791 ) ;
8892
93+ // XXX: The `__init_globals` is missing here, but we're interested in the derefs here anyways
8994 filtered_assert_snapshot ! ( result, @r#"
9095 ; ModuleID = '<internal>'
9196 source_filename = "<internal>"
9297 target datalayout = "[filtered]"
9398 target triple = "[filtered]"
9499
95- %fb = type {}
96- %VTable = type { i32 (%fb *, i16)* }
100+ %VTableFbA = type { i16 (%FbA*)* }
101+ %FbA = type { %VTableFbA *, i16 }
97102
98- @__fb__init = unnamed_addr constant %fb zeroinitializer
99- @__VTable__init = unnamed_addr constant %VTable zeroinitializer
103+ @instanceVTableFbA = global %VTableFbA zeroinitializer
104+ @__VTableFbA__init = unnamed_addr constant %VTableFbA zeroinitializer
105+ @__FbA__init = unnamed_addr constant %FbA zeroinitializer
100106
101- define void @fb(%fb * %0) {
107+ define i16 @FbA__foo(%FbA * %0) {
102108 entry:
103- %this = alloca %fb*, align 8
104- store %fb* %0, %fb** %this, align 8
105- ret void
109+ %this = alloca %FbA*, align 8
110+ store %FbA* %0, %FbA** %this, align 8
111+ %vtable = getelementptr inbounds %FbA, %FbA* %0, i32 0, i32 0
112+ %localVariableInFbA = getelementptr inbounds %FbA, %FbA* %0, i32 0, i32 1
113+ %FbA.foo = alloca i16, align 2
114+ store i16 0, i16* %FbA.foo, align 2
115+ %FbA__foo_ret = load i16, i16* %FbA.foo, align 2
116+ ret i16 %FbA__foo_ret
106117 }
107118
108- define i32 @fb__fbEcho(%fb * %0, i16 %1 ) {
119+ define void @FbA(%FbA * %0) {
109120 entry:
110- %this = alloca %fb*, align 8
111- store %fb* %0, %fb** %this, align 8
112- %fb.fbEcho = alloca i32, align 4
113- %value = alloca i16, align 2
114- store i16 %1, i16* %value, align 2
115- store i32 0, i32* %fb.fbEcho, align 4
116- %load_value = load i16, i16* %value, align 2
117- %2 = sext i16 %load_value to i32
118- store i32 %2, i32* %fb.fbEcho, align 4
119- %fb__fbEcho_ret = load i32, i32* %fb.fbEcho, align 4
120- ret i32 %fb__fbEcho_ret
121+ %this = alloca %FbA*, align 8
122+ store %FbA* %0, %FbA** %this, align 8
123+ %vtable = getelementptr inbounds %FbA, %FbA* %0, i32 0, i32 0
124+ %localVariableInFbA = getelementptr inbounds %FbA, %FbA* %0, i32 0, i32 1
125+ ret void
121126 }
122127
123128 define void @main() {
124129 entry:
125- %vt = alloca %VTable, align 8
126- %instance = alloca %fb, align 8
127- %0 = bitcast %VTable* %vt to i8*
128- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 bitcast (%VTable* @__VTable__init to i8*), i64 ptrtoint (%VTable* getelementptr (%VTable, %VTable* null, i32 1) to i64), i1 false)
129- %1 = bitcast %fb* %instance to i8*
130- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %1, i8* align 1 bitcast (%fb* @__fb__init to i8*), i64 ptrtoint (%fb* getelementptr (%fb, %fb* null, i32 1) to i64), i1 false)
131- %fbEcho = getelementptr inbounds %VTable, %VTable* %vt, i32 0, i32 0
132- %2 = load i32 (%fb*, i16)*, i32 (%fb*, i16)** %fbEcho, align 8
133- %call = call i32 %2(%fb* %instance, i16 5)
130+ %instanceFbA = alloca %FbA, align 8
131+ %0 = bitcast %FbA* %instanceFbA to i8*
132+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 bitcast (%FbA* @__FbA__init to i8*), i64 ptrtoint (%FbA* getelementptr (%FbA, %FbA* null, i32 1) to i64), i1 false)
133+ %vtable = getelementptr inbounds %FbA, %FbA* %instanceFbA, i32 0, i32 0
134+ %deref = load %VTableFbA*, %VTableFbA** %vtable, align 8
135+ %foo = getelementptr inbounds %VTableFbA, %VTableFbA* %deref, i32 0, i32 0
136+ %1 = load i16 (%FbA*)*, i16 (%FbA*)** %foo, align 8
137+ %call = call i16 %1(%FbA* %instanceFbA)
134138 ret void
135139 }
136140
0 commit comments