comparison src/vim9compile.c @ 19229:d776967d0f0d v8.2.0173

patch 8.2.0173: build fails with old compiler Commit: https://github.com/vim/vim/commit/0ff6aad393c4130818fb4f49137380f78d7cc882 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 29 21:27:21 2020 +0100 patch 8.2.0173: build fails with old compiler Problem: Build fails with old compiler. Solution: Do not use anonymous unions. (John Marriott)
author Bram Moolenaar <Bram@vim.org>
date Wed, 29 Jan 2020 21:30:05 +0100
parents 173b99509038
children a8d2d3c8f0b3
comparison
equal deleted inserted replaced
19228:6db2a20db2c3 19229:d776967d0f0d
86 union { 86 union {
87 ifscope_T se_if; 87 ifscope_T se_if;
88 whilescope_T se_while; 88 whilescope_T se_while;
89 forscope_T se_for; 89 forscope_T se_for;
90 tryscope_T se_try; 90 tryscope_T se_try;
91 }; 91 } se_u;
92 }; 92 };
93 93
94 /* 94 /*
95 * Entry for "ctx_locals". Used for arguments and local variables. 95 * Entry for "ctx_locals". Used for arguments and local variables.
96 */ 96 */
3504 scope = new_scope(cctx, IF_SCOPE); 3504 scope = new_scope(cctx, IF_SCOPE);
3505 if (scope == NULL) 3505 if (scope == NULL)
3506 return NULL; 3506 return NULL;
3507 3507
3508 // "where" is set when ":elseif", "else" or ":endif" is found 3508 // "where" is set when ":elseif", "else" or ":endif" is found
3509 scope->se_if.is_if_label = instr->ga_len; 3509 scope->se_u.se_if.is_if_label = instr->ga_len;
3510 generate_JUMP(cctx, JUMP_IF_FALSE, 0); 3510 generate_JUMP(cctx, JUMP_IF_FALSE, 0);
3511 3511
3512 return p; 3512 return p;
3513 } 3513 }
3514 3514
3526 return NULL; 3526 return NULL;
3527 } 3527 }
3528 cctx->ctx_locals.ga_len = scope->se_local_count; 3528 cctx->ctx_locals.ga_len = scope->se_local_count;
3529 3529
3530 // jump from previous block to the end 3530 // jump from previous block to the end
3531 if (compile_jump_to_end(&scope->se_if.is_end_label, 3531 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
3532 JUMP_ALWAYS, cctx) == FAIL) 3532 JUMP_ALWAYS, cctx) == FAIL)
3533 return NULL; 3533 return NULL;
3534 3534
3535 // previous "if" or "elseif" jumps here 3535 // previous "if" or "elseif" jumps here
3536 isn = ((isn_T *)instr->ga_data) + scope->se_if.is_if_label; 3536 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
3537 isn->isn_arg.jump.jump_where = instr->ga_len; 3537 isn->isn_arg.jump.jump_where = instr->ga_len;
3538 3538
3539 // compile "expr" 3539 // compile "expr"
3540 if (compile_expr1(&p, cctx) == FAIL) 3540 if (compile_expr1(&p, cctx) == FAIL)
3541 return NULL; 3541 return NULL;
3542 3542
3543 // "where" is set when ":elseif", "else" or ":endif" is found 3543 // "where" is set when ":elseif", "else" or ":endif" is found
3544 scope->se_if.is_if_label = instr->ga_len; 3544 scope->se_u.se_if.is_if_label = instr->ga_len;
3545 generate_JUMP(cctx, JUMP_IF_FALSE, 0); 3545 generate_JUMP(cctx, JUMP_IF_FALSE, 0);
3546 3546
3547 return p; 3547 return p;
3548 } 3548 }
3549 3549
3561 return NULL; 3561 return NULL;
3562 } 3562 }
3563 cctx->ctx_locals.ga_len = scope->se_local_count; 3563 cctx->ctx_locals.ga_len = scope->se_local_count;
3564 3564
3565 // jump from previous block to the end 3565 // jump from previous block to the end
3566 if (compile_jump_to_end(&scope->se_if.is_end_label, 3566 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
3567 JUMP_ALWAYS, cctx) == FAIL) 3567 JUMP_ALWAYS, cctx) == FAIL)
3568 return NULL; 3568 return NULL;
3569 3569
3570 // previous "if" or "elseif" jumps here 3570 // previous "if" or "elseif" jumps here
3571 isn = ((isn_T *)instr->ga_data) + scope->se_if.is_if_label; 3571 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
3572 isn->isn_arg.jump.jump_where = instr->ga_len; 3572 isn->isn_arg.jump.jump_where = instr->ga_len;
3573 3573
3574 return p; 3574 return p;
3575 } 3575 }
3576 3576
3585 if (scope == NULL || scope->se_type != IF_SCOPE) 3585 if (scope == NULL || scope->se_type != IF_SCOPE)
3586 { 3586 {
3587 emsg(_(e_endif_without_if)); 3587 emsg(_(e_endif_without_if));
3588 return NULL; 3588 return NULL;
3589 } 3589 }
3590 ifscope = &scope->se_if; 3590 ifscope = &scope->se_u.se_if;
3591 cctx->ctx_scope = scope->se_outer; 3591 cctx->ctx_scope = scope->se_outer;
3592 cctx->ctx_locals.ga_len = scope->se_local_count; 3592 cctx->ctx_locals.ga_len = scope->se_local_count;
3593 3593
3594 // previous "if" or "elseif" jumps here 3594 // previous "if" or "elseif" jumps here
3595 isn = ((isn_T *)instr->ga_data) + scope->se_if.is_if_label; 3595 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
3596 isn->isn_arg.jump.jump_where = instr->ga_len; 3596 isn->isn_arg.jump.jump_where = instr->ga_len;
3597 3597
3598 // Fill in the "end" label in jumps at the end of the blocks. 3598 // Fill in the "end" label in jumps at the end of the blocks.
3599 compile_fill_jump_to_end(&ifscope->is_end_label, cctx); 3599 compile_fill_jump_to_end(&ifscope->is_end_label, cctx);
3600 3600
3686 3686
3687 lvar->lv_type = vartype->tt_member; 3687 lvar->lv_type = vartype->tt_member;
3688 } 3688 }
3689 3689
3690 // "for_end" is set when ":endfor" is found 3690 // "for_end" is set when ":endfor" is found
3691 scope->se_for.fs_top_label = instr->ga_len; 3691 scope->se_u.se_for.fs_top_label = instr->ga_len;
3692 3692
3693 generate_FOR(cctx, loop_idx); 3693 generate_FOR(cctx, loop_idx);
3694 generate_STORE(cctx, ISN_STORE, var_idx, NULL); 3694 generate_STORE(cctx, ISN_STORE, var_idx, NULL);
3695 3695
3696 return arg; 3696 return arg;
3710 if (scope == NULL || scope->se_type != FOR_SCOPE) 3710 if (scope == NULL || scope->se_type != FOR_SCOPE)
3711 { 3711 {
3712 emsg(_(e_for)); 3712 emsg(_(e_for));
3713 return NULL; 3713 return NULL;
3714 } 3714 }
3715 forscope = &scope->se_for; 3715 forscope = &scope->se_u.se_for;
3716 cctx->ctx_scope = scope->se_outer; 3716 cctx->ctx_scope = scope->se_outer;
3717 cctx->ctx_locals.ga_len = scope->se_local_count; 3717 cctx->ctx_locals.ga_len = scope->se_local_count;
3718 3718
3719 // At end of ":for" scope jump back to the FOR instruction. 3719 // At end of ":for" scope jump back to the FOR instruction.
3720 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); 3720 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
3755 3755
3756 scope = new_scope(cctx, WHILE_SCOPE); 3756 scope = new_scope(cctx, WHILE_SCOPE);
3757 if (scope == NULL) 3757 if (scope == NULL)
3758 return NULL; 3758 return NULL;
3759 3759
3760 scope->se_while.ws_top_label = instr->ga_len; 3760 scope->se_u.se_while.ws_top_label = instr->ga_len;
3761 3761
3762 // compile "expr" 3762 // compile "expr"
3763 if (compile_expr1(&p, cctx) == FAIL) 3763 if (compile_expr1(&p, cctx) == FAIL)
3764 return NULL; 3764 return NULL;
3765 3765
3766 // "while_end" is set when ":endwhile" is found 3766 // "while_end" is set when ":endwhile" is found
3767 if (compile_jump_to_end(&scope->se_while.ws_end_label, 3767 if (compile_jump_to_end(&scope->se_u.se_while.ws_end_label,
3768 JUMP_IF_FALSE, cctx) == FAIL) 3768 JUMP_IF_FALSE, cctx) == FAIL)
3769 return FAIL; 3769 return FAIL;
3770 3770
3771 return p; 3771 return p;
3772 } 3772 }
3786 } 3786 }
3787 cctx->ctx_scope = scope->se_outer; 3787 cctx->ctx_scope = scope->se_outer;
3788 cctx->ctx_locals.ga_len = scope->se_local_count; 3788 cctx->ctx_locals.ga_len = scope->se_local_count;
3789 3789
3790 // At end of ":for" scope jump back to the FOR instruction. 3790 // At end of ":for" scope jump back to the FOR instruction.
3791 generate_JUMP(cctx, JUMP_ALWAYS, scope->se_while.ws_top_label); 3791 generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label);
3792 3792
3793 // Fill in the "end" label in the WHILE statement so it can jump here. 3793 // Fill in the "end" label in the WHILE statement so it can jump here.
3794 // And in any jumps for ":break" 3794 // And in any jumps for ":break"
3795 compile_fill_jump_to_end(&scope->se_while.ws_end_label, cctx); 3795 compile_fill_jump_to_end(&scope->se_u.se_while.ws_end_label, cctx);
3796 3796
3797 vim_free(scope); 3797 vim_free(scope);
3798 3798
3799 return arg; 3799 return arg;
3800 } 3800 }
3819 scope = scope->se_outer; 3819 scope = scope->se_outer;
3820 } 3820 }
3821 3821
3822 // Jump back to the FOR or WHILE instruction. 3822 // Jump back to the FOR or WHILE instruction.
3823 generate_JUMP(cctx, JUMP_ALWAYS, 3823 generate_JUMP(cctx, JUMP_ALWAYS,
3824 scope->se_type == FOR_SCOPE ? scope->se_for.fs_top_label 3824 scope->se_type == FOR_SCOPE ? scope->se_u.se_for.fs_top_label
3825 : scope->se_while.ws_top_label); 3825 : scope->se_u.se_while.ws_top_label);
3826 return arg; 3826 return arg;
3827 } 3827 }
3828 3828
3829 /* 3829 /*
3830 * compile "break" 3830 * compile "break"
3847 scope = scope->se_outer; 3847 scope = scope->se_outer;
3848 } 3848 }
3849 3849
3850 // Jump to the end of the FOR or WHILE loop. 3850 // Jump to the end of the FOR or WHILE loop.
3851 if (scope->se_type == FOR_SCOPE) 3851 if (scope->se_type == FOR_SCOPE)
3852 el = &scope->se_for.fs_end_label; 3852 el = &scope->se_u.se_for.fs_end_label;
3853 else 3853 else
3854 el = &scope->se_while.ws_end_label; 3854 el = &scope->se_u.se_while.ws_end_label;
3855 if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL) 3855 if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL)
3856 return FAIL; 3856 return FAIL;
3857 3857
3858 return arg; 3858 return arg;
3859 } 3859 }
3926 if (try_scope == NULL) 3926 if (try_scope == NULL)
3927 return NULL; 3927 return NULL;
3928 3928
3929 // "catch" is set when the first ":catch" is found. 3929 // "catch" is set when the first ":catch" is found.
3930 // "finally" is set when ":finally" or ":endtry" is found 3930 // "finally" is set when ":finally" or ":endtry" is found
3931 try_scope->se_try.ts_try_label = instr->ga_len; 3931 try_scope->se_u.se_try.ts_try_label = instr->ga_len;
3932 if (generate_instr(cctx, ISN_TRY) == NULL) 3932 if (generate_instr(cctx, ISN_TRY) == NULL)
3933 return NULL; 3933 return NULL;
3934 3934
3935 // scope for the try block itself 3935 // scope for the try block itself
3936 scope = new_scope(cctx, BLOCK_SCOPE); 3936 scope = new_scope(cctx, BLOCK_SCOPE);
3961 { 3961 {
3962 emsg(_(e_catch)); 3962 emsg(_(e_catch));
3963 return NULL; 3963 return NULL;
3964 } 3964 }
3965 3965
3966 if (scope->se_try.ts_caught_all) 3966 if (scope->se_u.se_try.ts_caught_all)
3967 { 3967 {
3968 emsg(_("E1033: catch unreachable after catch-all")); 3968 emsg(_("E1033: catch unreachable after catch-all"));
3969 return NULL; 3969 return NULL;
3970 } 3970 }
3971 3971
3972 // Jump from end of previous block to :finally or :endtry 3972 // Jump from end of previous block to :finally or :endtry
3973 if (compile_jump_to_end(&scope->se_try.ts_end_label, 3973 if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
3974 JUMP_ALWAYS, cctx) == FAIL) 3974 JUMP_ALWAYS, cctx) == FAIL)
3975 return NULL; 3975 return NULL;
3976 3976
3977 // End :try or :catch scope: set value in ISN_TRY instruction 3977 // End :try or :catch scope: set value in ISN_TRY instruction
3978 isn = ((isn_T *)instr->ga_data) + scope->se_try.ts_try_label; 3978 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
3979 if (isn->isn_arg.try.try_catch == 0) 3979 if (isn->isn_arg.try.try_catch == 0)
3980 isn->isn_arg.try.try_catch = instr->ga_len; 3980 isn->isn_arg.try.try_catch = instr->ga_len;
3981 if (scope->se_try.ts_catch_label != 0) 3981 if (scope->se_u.se_try.ts_catch_label != 0)
3982 { 3982 {
3983 // Previous catch without match jumps here 3983 // Previous catch without match jumps here
3984 isn = ((isn_T *)instr->ga_data) + scope->se_try.ts_catch_label; 3984 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
3985 isn->isn_arg.jump.jump_where = instr->ga_len; 3985 isn->isn_arg.jump.jump_where = instr->ga_len;
3986 } 3986 }
3987 3987
3988 p = skipwhite(arg); 3988 p = skipwhite(arg);
3989 if (ends_excmd(*p)) 3989 if (ends_excmd(*p))
3990 { 3990 {
3991 scope->se_try.ts_caught_all = TRUE; 3991 scope->se_u.se_try.ts_caught_all = TRUE;
3992 scope->se_try.ts_catch_label = 0; 3992 scope->se_u.se_try.ts_catch_label = 0;
3993 } 3993 }
3994 else 3994 else
3995 { 3995 {
3996 // Push v:exception, push {expr} and MATCH 3996 // Push v:exception, push {expr} and MATCH
3997 generate_instr_type(cctx, ISN_PUSHEXC, &t_string); 3997 generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
4001 4001
4002 // TODO: check for strings? 4002 // TODO: check for strings?
4003 if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL) 4003 if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
4004 return NULL; 4004 return NULL;
4005 4005
4006 scope->se_try.ts_catch_label = instr->ga_len; 4006 scope->se_u.se_try.ts_catch_label = instr->ga_len;
4007 if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL) 4007 if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL)
4008 return NULL; 4008 return NULL;
4009 } 4009 }
4010 4010
4011 if (generate_instr(cctx, ISN_CATCH) == NULL) 4011 if (generate_instr(cctx, ISN_CATCH) == NULL)
4034 emsg(_(e_finally)); 4034 emsg(_(e_finally));
4035 return NULL; 4035 return NULL;
4036 } 4036 }
4037 4037
4038 // End :catch or :finally scope: set value in ISN_TRY instruction 4038 // End :catch or :finally scope: set value in ISN_TRY instruction
4039 isn = ((isn_T *)instr->ga_data) + scope->se_try.ts_try_label; 4039 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
4040 if (isn->isn_arg.try.try_finally != 0) 4040 if (isn->isn_arg.try.try_finally != 0)
4041 { 4041 {
4042 emsg(_(e_finally_dup)); 4042 emsg(_(e_finally_dup));
4043 return NULL; 4043 return NULL;
4044 } 4044 }
4045 4045
4046 // Fill in the "end" label in jumps at the end of the blocks. 4046 // Fill in the "end" label in jumps at the end of the blocks.
4047 compile_fill_jump_to_end(&scope->se_try.ts_end_label, cctx); 4047 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
4048 4048
4049 if (scope->se_try.ts_catch_label != 0) 4049 if (scope->se_u.se_try.ts_catch_label != 0)
4050 { 4050 {
4051 // Previous catch without match jumps here 4051 // Previous catch without match jumps here
4052 isn = ((isn_T *)instr->ga_data) + scope->se_try.ts_catch_label; 4052 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
4053 isn->isn_arg.jump.jump_where = instr->ga_len; 4053 isn->isn_arg.jump.jump_where = instr->ga_len;
4054 } 4054 }
4055 4055
4056 isn->isn_arg.try.try_finally = instr->ga_len; 4056 isn->isn_arg.try.try_finally = instr->ga_len;
4057 // TODO: set index in ts_finally_label jumps 4057 // TODO: set index in ts_finally_label jumps
4083 else 4083 else
4084 emsg(_(e_endif)); 4084 emsg(_(e_endif));
4085 return NULL; 4085 return NULL;
4086 } 4086 }
4087 4087
4088 isn = ((isn_T *)instr->ga_data) + scope->se_try.ts_try_label; 4088 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
4089 if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0) 4089 if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0)
4090 { 4090 {
4091 emsg(_("E1032: missing :catch or :finally")); 4091 emsg(_("E1032: missing :catch or :finally"));
4092 return NULL; 4092 return NULL;
4093 } 4093 }
4094 4094
4095 // Fill in the "end" label in jumps at the end of the blocks, if not done 4095 // Fill in the "end" label in jumps at the end of the blocks, if not done
4096 // by ":finally". 4096 // by ":finally".
4097 compile_fill_jump_to_end(&scope->se_try.ts_end_label, cctx); 4097 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
4098 4098
4099 // End :catch or :finally scope: set value in ISN_TRY instruction 4099 // End :catch or :finally scope: set value in ISN_TRY instruction
4100 if (isn->isn_arg.try.try_finally == 0) 4100 if (isn->isn_arg.try.try_finally == 0)
4101 isn->isn_arg.try.try_finally = instr->ga_len; 4101 isn->isn_arg.try.try_finally = instr->ga_len;
4102 compile_endblock(cctx); 4102 compile_endblock(cctx);