diff options
author | kugwa <kugwa2000@gmail.com> | 2016-01-19 11:14:46 +0800 |
---|---|---|
committer | kugwa <kugwa2000@gmail.com> | 2016-01-19 11:14:46 +0800 |
commit | b0af78b88c674cbc552e348bc3703e792650d1d7 (patch) | |
tree | 5b7c1152565dd7454acaa446c7280ef120ba5b18 /src | |
parent | e9435761fc4aafe290fe128ac8198afcce796b7e (diff) | |
download | compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar.gz compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar.bz2 compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar.lz compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar.xz compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.tar.zst compiler2015-b0af78b88c674cbc552e348bc3703e792650d1d7.zip |
Fix the problem of initializing local variables
Diffstat (limited to 'src')
-rw-r--r-- | src/code-generation.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/code-generation.c b/src/code-generation.c index 7bc3416..a2d93da 100644 --- a/src/code-generation.c +++ b/src/code-generation.c @@ -991,10 +991,6 @@ static uint64_t generate_local_variable( CcmmcSymbol *var_sym = ccmmc_symbol_table_retrieve(state->table, var_decl->value_id.name); switch (var_decl->value_id.kind) { - case CCMMC_KIND_ID_NORMAL: - current_offset += 4; - var_sym->attr.addr = current_offset; - break; case CCMMC_KIND_ID_ARRAY: { size_t total_elements = 1; assert(var_sym->type.array_dimension > 0); @@ -1003,15 +999,11 @@ static uint64_t generate_local_variable( current_offset += total_elements * 4; var_sym->attr.addr = current_offset; } break; - case CCMMC_KIND_ID_WITH_INIT: { + case CCMMC_KIND_ID_NORMAL: + case CCMMC_KIND_ID_WITH_INIT: current_offset += 4; var_sym->attr.addr = current_offset; - // FIXME: This only works for single constant initializer. - // The value of sp is wrong, so evaluating expressions - // can overwrite other variables! - calc_and_save_expression_result(var_decl, var_decl->child, - state, ¤t_offset); - } break; + break; default: assert(false); } @@ -1019,6 +1011,17 @@ static uint64_t generate_local_variable( return current_offset; } +static void init_local_variable( + CcmmcAst *local_decl, CcmmcState *state, uint64_t current_offset) +{ + for (CcmmcAst *var_decl = local_decl->child->right_sibling; + var_decl != NULL; var_decl = var_decl->right_sibling) { + if (var_decl->value_id.kind == CCMMC_KIND_ID_WITH_INIT) + calc_and_save_expression_result(var_decl, var_decl->child, + state, ¤t_offset); + } +} + static void generate_block( CcmmcAst *block, CcmmcState *state, uint64_t current_offset) { @@ -1043,6 +1046,8 @@ static void generate_block( #undef REG_TMP } } + for (CcmmcAst *local = child->child; local != NULL; local = local->right_sibling) + init_local_variable(local, state, current_offset); child = child->right_sibling; } if (child != NULL && child->type_node == CCMMC_AST_NODE_STMT_LIST) { |