@@ -286,12 +286,31 @@ fn builtin_function_call_adr() {
286286 b : DINT;
287287 END_VAR
288288 a := ADR(b);
289+ a := ADR(IN := b);
289290 END_PROGRAM
290291 " ,
291292 ) ;
292293 // WHEN compiled
293294 // We expect the same behaviour as if REF was called, due to the assignee being a pointer
294- filtered_assert_snapshot ! ( result) ;
295+ filtered_assert_snapshot ! ( result, @r#"
296+ ; ModuleID = '<internal>'
297+ source_filename = "<internal>"
298+ target datalayout = "[filtered]"
299+ target triple = "[filtered]"
300+
301+ %main = type { i32*, i32 }
302+
303+ @main_instance = global %main zeroinitializer
304+
305+ define void @main(%main* %0) {
306+ entry:
307+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
308+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
309+ store i32* %b, i32** %a, align 8
310+ store i32* %b, i32** %a, align 8
311+ ret void
312+ }
313+ "# ) ;
295314}
296315
297316#[ test]
@@ -305,12 +324,31 @@ fn builtin_function_call_ref() {
305324 b : DINT;
306325 END_VAR
307326 a := REF(b);
327+ a := REF(IN := b);
308328 END_PROGRAM
309329 " ,
310330 ) ;
311331 // WHEN compiled
312332 // We expect a direct conversion and subsequent assignment to pointer(no call)
313- filtered_assert_snapshot ! ( result) ;
333+ filtered_assert_snapshot ! ( result, @r#"
334+ ; ModuleID = '<internal>'
335+ source_filename = "<internal>"
336+ target datalayout = "[filtered]"
337+ target triple = "[filtered]"
338+
339+ %main = type { i32*, i32 }
340+
341+ @main_instance = global %main zeroinitializer
342+
343+ define void @main(%main* %0) {
344+ entry:
345+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
346+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
347+ store i32* %b, i32** %a, align 8
348+ store i32* %b, i32** %a, align 8
349+ ret void
350+ }
351+ "# ) ;
314352}
315353
316354#[ test]
@@ -349,10 +387,36 @@ fn builtin_function_call_sel() {
349387 a,b,c : DINT;
350388 END_VAR
351389 a := SEL(TRUE, b,c);
390+ a := SEL(G := TRUE, IN0 := b, IN1 := c);
352391 END_PROGRAM" ,
353392 ) ;
354393
355- filtered_assert_snapshot ! ( result) ;
394+ filtered_assert_snapshot ! ( result, @r#"
395+ ; ModuleID = '<internal>'
396+ source_filename = "<internal>"
397+ target datalayout = "[filtered]"
398+ target triple = "[filtered]"
399+
400+ %main = type { i32, i32, i32 }
401+
402+ @main_instance = global %main zeroinitializer
403+
404+ define void @main(%main* %0) {
405+ entry:
406+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
407+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
408+ %c = getelementptr inbounds %main, %main* %0, i32 0, i32 2
409+ %load_b = load i32, i32* %b, align 4
410+ %load_c = load i32, i32* %c, align 4
411+ %1 = select i1 true, i32 %load_c, i32 %load_b
412+ store i32 %1, i32* %a, align 4
413+ %load_b1 = load i32, i32* %b, align 4
414+ %load_c2 = load i32, i32* %c, align 4
415+ %2 = select i1 true, i32 %load_c2, i32 %load_b1
416+ store i32 %2, i32* %a, align 4
417+ ret void
418+ }
419+ "# ) ;
356420}
357421
358422#[ test]
@@ -377,10 +441,31 @@ fn builtin_function_call_move() {
377441 a,b : DINT;
378442 END_VAR
379443 a := MOVE(b);
444+ a := MOVE(IN := b);
380445 END_PROGRAM" ,
381446 ) ;
382447
383- filtered_assert_snapshot ! ( result) ;
448+ filtered_assert_snapshot ! ( result, @r#"
449+ ; ModuleID = '<internal>'
450+ source_filename = "<internal>"
451+ target datalayout = "[filtered]"
452+ target triple = "[filtered]"
453+
454+ %main = type { i32, i32 }
455+
456+ @main_instance = global %main zeroinitializer
457+
458+ define void @main(%main* %0) {
459+ entry:
460+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
461+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
462+ %load_b = load i32, i32* %b, align 4
463+ store i32 %load_b, i32* %a, align 4
464+ %load_b1 = load i32, i32* %b, align 4
465+ store i32 %load_b1, i32* %a, align 4
466+ ret void
467+ }
468+ "# ) ;
384469}
385470
386471#[ test]
@@ -392,10 +477,29 @@ fn builtin_function_call_sizeof() {
392477 b: LINT;
393478 END_VAR
394479 a := SIZEOF(b);
480+ a := SIZEOF(IN := b);
395481 END_PROGRAM" ,
396482 ) ;
397483
398- filtered_assert_snapshot ! ( result) ;
484+ filtered_assert_snapshot ! ( result, @r#"
485+ ; ModuleID = '<internal>'
486+ source_filename = "<internal>"
487+ target datalayout = "[filtered]"
488+ target triple = "[filtered]"
489+
490+ %main = type { i32, i64 }
491+
492+ @main_instance = global %main zeroinitializer
493+
494+ define void @main(%main* %0) {
495+ entry:
496+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
497+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
498+ store i32 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i32), i32* %a, align 4
499+ store i32 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i32), i32* %a, align 4
500+ ret void
501+ }
502+ "# ) ;
399503}
400504
401505#[ test]
@@ -414,12 +518,63 @@ fn builtin_function_call_lower_bound() {
414518 vla: ARRAY[*] OF DINT;
415519 END_VAR
416520 foo := LOWER_BOUND(vla, 1);
521+ foo := LOWER_BOUND(arr := vla, dim := 1);
417522 END_VAR
418523 END_FUNCTION
419524 " ,
420525 ) ;
421526
422- filtered_assert_snapshot ! ( result) ;
527+ filtered_assert_snapshot ! ( result, @r#"
528+ ; ModuleID = '<internal>'
529+ source_filename = "<internal>"
530+ target datalayout = "[filtered]"
531+ target triple = "[filtered]"
532+
533+ %main = type { [2 x i32], i32 }
534+ %__foo_vla = type { i32*, [2 x i32] }
535+
536+ @main_instance = global %main zeroinitializer
537+ @____foo_vla__init = unnamed_addr constant %__foo_vla zeroinitializer
538+
539+ define void @main(%main* %0) {
540+ entry:
541+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
542+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
543+ %auto_deref = load [2 x i32], [2 x i32]* %a, align 4
544+ %outer_arr_gep = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 0
545+ %vla_struct = alloca %__foo_vla, align 8
546+ %vla_array_gep = getelementptr inbounds %__foo_vla, %__foo_vla* %vla_struct, i32 0, i32 0
547+ %vla_dimensions_gep = getelementptr inbounds %__foo_vla, %__foo_vla* %vla_struct, i32 0, i32 1
548+ store [2 x i32] [i32 0, i32 1], [2 x i32]* %vla_dimensions_gep, align 4
549+ store i32* %outer_arr_gep, i32** %vla_array_gep, align 8
550+ %1 = load %__foo_vla, %__foo_vla* %vla_struct, align 8
551+ %vla_struct_ptr = alloca %__foo_vla, align 8
552+ store %__foo_vla %1, %__foo_vla* %vla_struct_ptr, align 8
553+ %call = call i32 @foo(%__foo_vla* %vla_struct_ptr)
554+ store i32 %call, i32* %b, align 4
555+ ret void
556+ }
557+
558+ define i32 @foo(%__foo_vla* %0) {
559+ entry:
560+ %foo = alloca i32, align 4
561+ %vla = alloca %__foo_vla*, align 8
562+ store %__foo_vla* %0, %__foo_vla** %vla, align 8
563+ store i32 0, i32* %foo, align 4
564+ %deref = load %__foo_vla*, %__foo_vla** %vla, align 8
565+ %dim = getelementptr inbounds %__foo_vla, %__foo_vla* %deref, i32 0, i32 1
566+ %1 = getelementptr inbounds [2 x i32], [2 x i32]* %dim, i32 0, i32 0
567+ %2 = load i32, i32* %1, align 4
568+ store i32 %2, i32* %foo, align 4
569+ %deref1 = load %__foo_vla*, %__foo_vla** %vla, align 8
570+ %dim2 = getelementptr inbounds %__foo_vla, %__foo_vla* %deref1, i32 0, i32 1
571+ %3 = getelementptr inbounds [2 x i32], [2 x i32]* %dim2, i32 0, i32 0
572+ %4 = load i32, i32* %3, align 4
573+ store i32 %4, i32* %foo, align 4
574+ %foo_ret = load i32, i32* %foo, align 4
575+ ret i32 %foo_ret
576+ }
577+ "# ) ;
423578}
424579
425580#[ test]
@@ -438,12 +593,63 @@ fn builtin_function_call_upper_bound() {
438593 vla: ARRAY[*] OF DINT;
439594 END_VAR
440595 foo := UPPER_BOUND(vla, 1);
596+ foo := UPPER_BOUND(arr := vla, dim := 1);
441597 END_VAR
442598 END_FUNCTION
443599 " ,
444600 ) ;
445601
446- filtered_assert_snapshot ! ( result) ;
602+ filtered_assert_snapshot ! ( result, @r#"
603+ ; ModuleID = '<internal>'
604+ source_filename = "<internal>"
605+ target datalayout = "[filtered]"
606+ target triple = "[filtered]"
607+
608+ %main = type { [2 x i32], i32 }
609+ %__foo_vla = type { i32*, [2 x i32] }
610+
611+ @main_instance = global %main zeroinitializer
612+ @____foo_vla__init = unnamed_addr constant %__foo_vla zeroinitializer
613+
614+ define void @main(%main* %0) {
615+ entry:
616+ %a = getelementptr inbounds %main, %main* %0, i32 0, i32 0
617+ %b = getelementptr inbounds %main, %main* %0, i32 0, i32 1
618+ %auto_deref = load [2 x i32], [2 x i32]* %a, align 4
619+ %outer_arr_gep = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 0
620+ %vla_struct = alloca %__foo_vla, align 8
621+ %vla_array_gep = getelementptr inbounds %__foo_vla, %__foo_vla* %vla_struct, i32 0, i32 0
622+ %vla_dimensions_gep = getelementptr inbounds %__foo_vla, %__foo_vla* %vla_struct, i32 0, i32 1
623+ store [2 x i32] [i32 0, i32 1], [2 x i32]* %vla_dimensions_gep, align 4
624+ store i32* %outer_arr_gep, i32** %vla_array_gep, align 8
625+ %1 = load %__foo_vla, %__foo_vla* %vla_struct, align 8
626+ %vla_struct_ptr = alloca %__foo_vla, align 8
627+ store %__foo_vla %1, %__foo_vla* %vla_struct_ptr, align 8
628+ %call = call i32 @foo(%__foo_vla* %vla_struct_ptr)
629+ store i32 %call, i32* %b, align 4
630+ ret void
631+ }
632+
633+ define i32 @foo(%__foo_vla* %0) {
634+ entry:
635+ %foo = alloca i32, align 4
636+ %vla = alloca %__foo_vla*, align 8
637+ store %__foo_vla* %0, %__foo_vla** %vla, align 8
638+ store i32 0, i32* %foo, align 4
639+ %deref = load %__foo_vla*, %__foo_vla** %vla, align 8
640+ %dim = getelementptr inbounds %__foo_vla, %__foo_vla* %deref, i32 0, i32 1
641+ %1 = getelementptr inbounds [2 x i32], [2 x i32]* %dim, i32 0, i32 1
642+ %2 = load i32, i32* %1, align 4
643+ store i32 %2, i32* %foo, align 4
644+ %deref1 = load %__foo_vla*, %__foo_vla** %vla, align 8
645+ %dim2 = getelementptr inbounds %__foo_vla, %__foo_vla* %deref1, i32 0, i32 1
646+ %3 = getelementptr inbounds [2 x i32], [2 x i32]* %dim2, i32 0, i32 1
647+ %4 = load i32, i32* %3, align 4
648+ store i32 %4, i32* %foo, align 4
649+ %foo_ret = load i32, i32* %foo, align 4
650+ ret i32 %foo_ret
651+ }
652+ "# ) ;
447653}
448654
449655#[ test]
@@ -467,6 +673,7 @@ fn builtin_function_call_upper_bound_expr() {
467673 END_VAR
468674 // upper bound of 4th dimension => 8th element in dimension array
469675 foo := UPPER_BOUND(vla, MY_CONST - (2 * 3));
676+ foo := UPPER_BOUND(arr := vla, dim := MY_CONST - (2 * 3));
470677 END_VAR
471678 END_FUNCTION
472679 " ,
@@ -748,6 +955,80 @@ fn builtin_div_mixed() {
748955 filtered_assert_snapshot ! ( res) ;
749956}
750957
958+ #[ test]
959+ fn builtin_div_with_named_arguments ( ) {
960+ let src = r#"
961+ FUNCTION main : DINT
962+ VAR
963+ x : DINT := 20;
964+ y : DINT := 4;
965+ END_VAR
966+ DIV(IN1 := x, IN2 := y);
967+ END_FUNCTION
968+ "# ;
969+
970+ let res = codegen ( src) ;
971+
972+ filtered_assert_snapshot ! ( res, @r#"
973+ ; ModuleID = '<internal>'
974+ source_filename = "<internal>"
975+ target datalayout = "[filtered]"
976+ target triple = "[filtered]"
977+
978+ define i32 @main() {
979+ entry:
980+ %main = alloca i32, align 4
981+ %x = alloca i32, align 4
982+ %y = alloca i32, align 4
983+ store i32 20, i32* %x, align 4
984+ store i32 4, i32* %y, align 4
985+ store i32 0, i32* %main, align 4
986+ %load_x = load i32, i32* %x, align 4
987+ %load_y = load i32, i32* %y, align 4
988+ %tmpVar = sdiv i32 %load_x, %load_y
989+ %main_ret = load i32, i32* %main, align 4
990+ ret i32 %main_ret
991+ }
992+ "# ) ;
993+ }
994+
995+ #[ test]
996+ fn builtin_sub_with_named_arguments ( ) {
997+ let src = r#"
998+ FUNCTION main : DINT
999+ VAR
1000+ x : DINT := 20;
1001+ y : DINT := 4;
1002+ END_VAR
1003+ SUB(IN1 := x, IN2 := y);
1004+ END_FUNCTION
1005+ "# ;
1006+
1007+ let res = codegen ( src) ;
1008+
1009+ filtered_assert_snapshot ! ( res, @r#"
1010+ ; ModuleID = '<internal>'
1011+ source_filename = "<internal>"
1012+ target datalayout = "[filtered]"
1013+ target triple = "[filtered]"
1014+
1015+ define i32 @main() {
1016+ entry:
1017+ %main = alloca i32, align 4
1018+ %x = alloca i32, align 4
1019+ %y = alloca i32, align 4
1020+ store i32 20, i32* %x, align 4
1021+ store i32 4, i32* %y, align 4
1022+ store i32 0, i32* %main, align 4
1023+ %load_x = load i32, i32* %x, align 4
1024+ %load_y = load i32, i32* %y, align 4
1025+ %tmpVar = sub i32 %load_x, %load_y
1026+ %main_ret = load i32, i32* %main, align 4
1027+ ret i32 %main_ret
1028+ }
1029+ "# ) ;
1030+ }
1031+
7511032#[ test]
7521033fn global_namespace_operator ( ) {
7531034 let src = r#"
0 commit comments