@@ -24,7 +24,9 @@ use plc_ast::{
24
24
flatten_expression_list, Allocation , AstNode , AstStatement , JumpStatement , LabelStatement , Operator ,
25
25
ReferenceAccess , ReferenceExpr ,
26
26
} ,
27
- control_statements:: { AstControlStatement , ConditionalBlock , ReturnStatement } ,
27
+ control_statements:: {
28
+ AstControlStatement , CaseStatement , ForLoopStatement , IfStatement , LoopStatement , ReturnStatement ,
29
+ } ,
28
30
} ;
29
31
use plc_diagnostics:: diagnostics:: { Diagnostic , INTERNAL_LLVM_ERROR } ;
30
32
use plc_source:: source_location:: SourceLocation ;
@@ -252,31 +254,12 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
252
254
statement : & AstControlStatement ,
253
255
) -> Result < ( ) , Diagnostic > {
254
256
match statement {
255
- AstControlStatement :: If ( ifstmt) => self . generate_if_statement (
256
- llvm_index,
257
- & ifstmt. blocks ,
258
- & ifstmt. else_block ,
259
- & ifstmt. end_location ,
260
- ) ,
261
- AstControlStatement :: ForLoop ( for_stmt) => self . generate_for_statement (
262
- llvm_index,
263
- & for_stmt. counter ,
264
- & for_stmt. start ,
265
- & for_stmt. end ,
266
- & for_stmt. by_step ,
267
- & for_stmt. body ,
268
- & for_stmt. end_location ,
269
- ) ,
257
+ AstControlStatement :: If ( ifstmt) => self . generate_if_statement ( llvm_index, ifstmt) ,
258
+ AstControlStatement :: ForLoop ( for_stmt) => self . generate_for_statement ( llvm_index, for_stmt) ,
270
259
AstControlStatement :: WhileLoop ( stmt) | AstControlStatement :: RepeatLoop ( stmt) => {
271
- self . generate_loop_statement ( llvm_index, & stmt. condition , & stmt . body , & stmt . end_location )
260
+ self . generate_loop_statement ( llvm_index, stmt)
272
261
}
273
- AstControlStatement :: Case ( stmt) => self . generate_case_statement (
274
- llvm_index,
275
- & stmt. selector ,
276
- & stmt. case_blocks ,
277
- & stmt. else_block ,
278
- & stmt. end_location ,
279
- ) ,
262
+ AstControlStatement :: Case ( stmt) => self . generate_case_statement ( llvm_index, stmt) ,
280
263
}
281
264
}
282
265
@@ -406,26 +389,20 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
406
389
/// - `end` the value indicating the end of the for loop
407
390
/// - `by_step` the step of the loop
408
391
/// - `body` the statements inside the for-loop
409
- #[ allow( clippy:: too_many_arguments) ]
410
392
fn generate_for_statement (
411
393
& self ,
412
394
llvm_index : & ' a LlvmTypedIndex < ' b > ,
413
- counter : & AstNode ,
414
- start : & AstNode ,
415
- end : & AstNode ,
416
- by_step : & Option < Box < AstNode > > ,
417
- body : & [ AstNode ] ,
418
- end_location : & SourceLocation ,
395
+ stmt : & ForLoopStatement ,
419
396
) -> Result < ( ) , Diagnostic > {
420
397
let ( builder, current_function, context) = self . get_llvm_deps ( ) ;
421
398
let exp_gen = self . create_expr_generator ( llvm_index) ;
422
399
423
- let end_ty = self . annotations . get_type_or_void ( end, self . index ) ;
424
- let counter_ty = self . annotations . get_type_or_void ( counter, self . index ) ;
400
+ let end_ty = self . annotations . get_type_or_void ( & stmt . end , self . index ) ;
401
+ let counter_ty = self . annotations . get_type_or_void ( & stmt . counter , self . index ) ;
425
402
let cast_target_ty = get_bigger_type ( self . index . get_type_or_panic ( DINT_TYPE ) , counter_ty, self . index ) ;
426
403
let cast_target_llty = llvm_index. find_associated_type ( cast_target_ty. get_name ( ) ) . unwrap ( ) ;
427
404
428
- let step_ty = by_step. as_ref ( ) . map ( |it| {
405
+ let step_ty = stmt . by_step . as_ref ( ) . map ( |it| {
429
406
self . register_debug_location ( it) ;
430
407
self . annotations . get_type_or_void ( it, self . index )
431
408
} ) ;
@@ -434,7 +411,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
434
411
step_ty. map_or_else (
435
412
|| self . llvm . create_const_numeric ( & cast_target_llty, "1" , SourceLocation :: internal ( ) ) ,
436
413
|step_ty| {
437
- let step = exp_gen. generate_expression ( by_step. as_ref ( ) . unwrap ( ) ) ?;
414
+ let step = exp_gen. generate_expression ( stmt . by_step . as_ref ( ) . unwrap ( ) ) ?;
438
415
Ok ( cast_if_needed ! ( exp_gen, cast_target_ty, step_ty, step, None ) )
439
416
} ,
440
417
)
@@ -446,8 +423,8 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
446
423
let increment = context. append_basic_block ( current_function, "increment" ) ;
447
424
let afterloop = context. append_basic_block ( current_function, "continue" ) ;
448
425
449
- self . generate_assignment_statement ( llvm_index, counter, start) ?;
450
- let counter = exp_gen. generate_lvalue ( counter) ?;
426
+ self . generate_assignment_statement ( llvm_index, & stmt . counter , & stmt . start ) ?;
427
+ let counter = exp_gen. generate_lvalue ( & stmt . counter ) ?;
451
428
452
429
// generate loop predicate selector. since `STEP` can be a reference, this needs to be a runtime eval
453
430
// XXX(mhasel): IR could possibly be improved by generating phi instructions.
@@ -470,7 +447,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
470
447
_ => unreachable ! ( ) ,
471
448
} ) ;
472
449
473
- let end = exp_gen. generate_expression_value ( end) . unwrap ( ) ;
450
+ let end = exp_gen. generate_expression_value ( & stmt . end ) . unwrap ( ) ;
474
451
let end_value = match end {
475
452
ExpressionValue :: LValue ( ptr) => builder. build_load ( ptr, "" ) ,
476
453
ExpressionValue :: RValue ( val) => val,
@@ -496,13 +473,13 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
496
473
load_suffix : self . load_suffix . clone ( ) ,
497
474
..* self
498
475
} ;
499
- body_builder. generate_body ( body) ?;
476
+ body_builder. generate_body ( & stmt . body ) ?;
500
477
// Place debug location to end of loop
501
478
self . debug . set_debug_location (
502
479
self . llvm ,
503
480
self . function_context ,
504
- end_location. get_line_plus_one ( ) ,
505
- end_location. get_column ( ) ,
481
+ stmt . end_location . get_line_plus_one ( ) ,
482
+ stmt . end_location . get_column ( ) ,
506
483
) ;
507
484
508
485
// increment counter
@@ -539,24 +516,21 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
539
516
fn generate_case_statement (
540
517
& self ,
541
518
llvm_index : & ' a LlvmTypedIndex < ' b > ,
542
- selector : & AstNode ,
543
- conditional_blocks : & [ ConditionalBlock ] ,
544
- else_body : & [ AstNode ] ,
545
- end_location : & SourceLocation ,
519
+ stmt : & CaseStatement ,
546
520
) -> Result < ( ) , Diagnostic > {
547
521
let ( builder, current_function, context) = self . get_llvm_deps ( ) ;
548
522
//Continue
549
523
let continue_block = context. append_basic_block ( current_function, "continue" ) ;
550
524
551
525
let basic_block = builder. get_insert_block ( ) . expect ( INTERNAL_LLVM_ERROR ) ;
552
526
let exp_gen = self . create_expr_generator ( llvm_index) ;
553
- let selector_statement = exp_gen. generate_expression ( selector) ?;
527
+ let selector_statement = exp_gen. generate_expression ( & stmt . selector ) ?;
554
528
555
529
let mut cases = Vec :: new ( ) ;
556
530
let else_block = context. append_basic_block ( current_function, "else" ) ;
557
531
let mut current_else_block = else_block;
558
532
559
- for conditional_block in conditional_blocks {
533
+ for conditional_block in & stmt . case_blocks {
560
534
//craete a block for the case's body
561
535
let case_block = context. prepend_basic_block ( else_block, "case" ) ;
562
536
@@ -569,7 +543,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
569
543
// since the if's generate additional blocks, we use the last one as the else-section
570
544
current_else_block = self . generate_case_range_condition (
571
545
llvm_index,
572
- selector,
546
+ & stmt . selector ,
573
547
data. start . as_ref ( ) ,
574
548
data. end . as_ref ( ) ,
575
549
case_block,
@@ -589,29 +563,29 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
589
563
self . debug . set_debug_location (
590
564
self . llvm ,
591
565
self . function_context ,
592
- end_location. get_line_plus_one ( ) ,
593
- end_location. get_column ( ) ,
566
+ stmt . end_location . get_line_plus_one ( ) ,
567
+ stmt . end_location . get_column ( ) ,
594
568
) ;
595
569
// skip all other case-bodies
596
570
builder. build_unconditional_branch ( continue_block) ;
597
571
}
598
572
// current-else is the last else-block generated by the range-expressions
599
573
builder. position_at_end ( current_else_block) ;
600
- self . generate_body ( else_body ) ?;
574
+ self . generate_body ( & stmt . else_block ) ?;
601
575
//Add debug location to the end of the case
602
576
self . debug . set_debug_location (
603
577
self . llvm ,
604
578
self . function_context ,
605
- end_location. get_line_plus_one ( ) ,
606
- end_location. get_column ( ) ,
579
+ stmt . end_location . get_line_plus_one ( ) ,
580
+ stmt . end_location . get_column ( ) ,
607
581
) ;
608
582
builder. build_unconditional_branch ( continue_block) ;
609
583
continue_block. move_after ( current_else_block) . expect ( INTERNAL_LLVM_ERROR ) ;
610
584
611
585
// now that we collected all cases, go back to the initial block and generate the switch-statement
612
586
builder. position_at_end ( basic_block) ;
613
587
614
- self . register_debug_location ( selector) ;
588
+ self . register_debug_location ( & stmt . selector ) ;
615
589
builder. build_switch ( selector_statement. into_int_value ( ) , else_block, & cases) ;
616
590
617
591
builder. position_at_end ( continue_block) ;
@@ -676,14 +650,12 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
676
650
fn generate_loop_statement (
677
651
& self ,
678
652
llvm_index : & ' a LlvmTypedIndex < ' b > ,
679
- condition : & AstNode ,
680
- body : & [ AstNode ] ,
681
- end_location : & SourceLocation ,
653
+ stmt : & LoopStatement ,
682
654
) -> Result < ( ) , Diagnostic > {
683
655
let builder = & self . llvm . builder ;
684
656
let basic_block = builder. get_insert_block ( ) . expect ( INTERNAL_LLVM_ERROR ) ;
685
657
let ( condition_block, _) =
686
- self . generate_base_while_statement ( llvm_index, condition, body, end_location) ?;
658
+ self . generate_base_while_statement ( llvm_index, & stmt . condition , & stmt . body , & stmt . end_location ) ?;
687
659
688
660
let continue_block = builder. get_insert_block ( ) . expect ( INTERNAL_LLVM_ERROR ) ;
689
661
@@ -749,17 +721,15 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
749
721
fn generate_if_statement (
750
722
& self ,
751
723
llvm_index : & ' a LlvmTypedIndex < ' b > ,
752
- conditional_blocks : & [ ConditionalBlock ] ,
753
- else_body : & [ AstNode ] ,
754
- end_location : & SourceLocation ,
724
+ stmt : & IfStatement ,
755
725
) -> Result < ( ) , Diagnostic > {
756
726
let ( builder, current_function, context) = self . get_llvm_deps ( ) ;
757
727
let mut blocks = vec ! [ builder. get_insert_block( ) . expect( INTERNAL_LLVM_ERROR ) ] ;
758
- for _ in 1 ..conditional_blocks . len ( ) {
728
+ for _ in 1 ..stmt . blocks . len ( ) {
759
729
blocks. push ( context. append_basic_block ( current_function, "branch" ) ) ;
760
730
}
761
731
762
- let else_block = if !else_body . is_empty ( ) {
732
+ let else_block = if !stmt . else_block . is_empty ( ) {
763
733
let result = context. append_basic_block ( current_function, "else" ) ;
764
734
blocks. push ( result) ;
765
735
Some ( result)
@@ -770,7 +740,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
770
740
let continue_block = context. append_basic_block ( current_function, "continue" ) ;
771
741
blocks. push ( continue_block) ;
772
742
773
- for ( i, block) in conditional_blocks . iter ( ) . enumerate ( ) {
743
+ for ( i, block) in stmt . blocks . iter ( ) . enumerate ( ) {
774
744
let then_block = blocks[ i] ;
775
745
let else_block = blocks[ i + 1 ] ;
776
746
@@ -795,22 +765,22 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
795
765
self . debug . set_debug_location (
796
766
self . llvm ,
797
767
self . function_context ,
798
- end_location. get_line_plus_one ( ) ,
799
- end_location. get_column ( ) ,
768
+ stmt . end_location . get_line_plus_one ( ) ,
769
+ stmt . end_location . get_column ( ) ,
800
770
) ;
801
771
builder. build_unconditional_branch ( continue_block) ;
802
772
}
803
773
//Else
804
774
805
775
if let Some ( else_block) = else_block {
806
776
builder. position_at_end ( else_block) ;
807
- self . generate_body ( else_body ) ?;
777
+ self . generate_body ( & stmt . else_block ) ?;
808
778
// Place debug location to end of if
809
779
self . debug . set_debug_location (
810
780
self . llvm ,
811
781
self . function_context ,
812
- end_location. get_line_plus_one ( ) ,
813
- end_location. get_column ( ) ,
782
+ stmt . end_location . get_line_plus_one ( ) ,
783
+ stmt . end_location . get_column ( ) ,
814
784
) ;
815
785
builder. build_unconditional_branch ( continue_block) ;
816
786
}
0 commit comments