Mercurial > vim
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); |