diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-05-01 19:18:56 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-05-01 19:18:56 +0000 |
commit | e14b9135f169d290f59cad9d5fd521d2022955c7 (patch) | |
tree | c8f2e8aa8863578dafa94ae1aed58c20613f5004 /gcc/go/gofrontend | |
parent | b6799f373ac288dc5de71240a13488e9e3530f2a (diff) | |
download | gcc-e14b9135f169d290f59cad9d5fd521d2022955c7.zip gcc-e14b9135f169d290f59cad9d5fd521d2022955c7.tar.gz gcc-e14b9135f169d290f59cad9d5fd521d2022955c7.tar.bz2 |
compiler: Use backend interface for heap expressions.
From-SVN: r209983
Diffstat (limited to 'gcc/go/gofrontend')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 43 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 9 |
2 files changed, 29 insertions, 23 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 2756263..275bee5 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -13798,30 +13798,31 @@ class Heap_expression : public Expression tree Heap_expression::do_get_tree(Translate_context* context) { - tree expr_tree = this->expr_->get_tree(context); - if (expr_tree == error_mark_node || TREE_TYPE(expr_tree) == error_mark_node) + if (this->expr_->is_error_expression() || this->expr_->type()->is_error()) return error_mark_node; - Expression* alloc = - Expression::make_allocation(this->expr_->type(), this->location()); - + Location loc = this->location(); Gogo* gogo = context->gogo(); - Btype* btype = this->expr_->type()->get_backend(gogo); - size_t expr_size = gogo->backend()->type_size(btype); - tree space = alloc->get_tree(context); - if (expr_size == 0) - return space; - - space = save_expr(space); - tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(), - space); - TREE_THIS_NOTRAP(ref) = 1; - tree ret = build2(COMPOUND_EXPR, - type_to_tree(this->type()->get_backend(gogo)), - build2(MODIFY_EXPR, void_type_node, ref, expr_tree), - space); - SET_EXPR_LOCATION(ret, this->location().gcc_location()); - return ret; + Btype* btype = this->type()->get_backend(gogo); + Expression* alloc = Expression::make_allocation(this->expr_->type(), loc); + Bexpression* space = tree_to_expr(alloc->get_tree(context)); + + Bstatement* decl; + Named_object* fn = context->function(); + go_assert(fn != NULL); + Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn); + Bvariable* space_temp = + gogo->backend()->temporary_variable(fndecl, context->bblock(), btype, + space, true, loc, &decl); + space = gogo->backend()->var_expression(space_temp, loc); + Bexpression* ref = gogo->backend()->indirect_expression(space, true, loc); + + Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context)); + Bstatement* assn = gogo->backend()->assignment_statement(ref, bexpr, loc); + decl = gogo->backend()->compound_statement(decl, assn); + space = gogo->backend()->var_expression(space_temp, loc); + Bexpression* ret = gogo->backend()->compound_expression(decl, space, loc); + return expr_to_tree(ret); } // Dump ast representation for a heap expression. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 995a4f2..ab54f84 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1147,8 +1147,6 @@ Gogo::write_globals() Bstatement* var_init_stmt = NULL; if (!var->has_pre_init()) { - Bexpression* var_binit = var->get_init(this, NULL); - // If the backend representation of the variable initializer is // constant, we can just set the initial value using // global_var_set_init instead of during the init() function. @@ -1168,6 +1166,13 @@ Gogo::write_globals() init_cast->is_immutable() && !var_type->has_pointer(); } + // Non-constant variable initializations might need to create + // temporary variables, which will need the initialization + // function as context. + if (!is_constant_initializer && init_fndecl == NULL) + init_fndecl = this->initialization_function_decl(); + Bexpression* var_binit = var->get_init(this, init_fndecl); + if (var_binit == NULL) ; else if (is_constant_initializer) |