Commit 8220e3f9 by Than McIntosh Committed by Ian Lance Taylor

compiler: add containing Bfunction to some backend interfaces.

    
    Change the interfaces for backend methods that create statements to
    always pass in the enclosing Bfunction for the statement.  Having the
    function available simplifies things if a temporary variable has to be
    created during the construction of a statement.
    
    This also includes a change to the Mark_lvalue_varexprs helper
    class to handle indirections on the left hand side of assignments
    (e.g. "*x.y = ...").
    
    Reviewed-on: https://go-review.googlesource.com/34471

	* go-gcc.cc (Gcc_backend::expression_statement): Add Bfunction*
	parameter.
	(Gcc_backend::init_statement): Likewise.
	(Gcc_backend::assignment_statement): Likewise.
	(Gcc_backend::if_statement): Likewise.

From-SVN: r243766
parent 5cdc4b0e
2016-12-16 Than McIntosh <thanm@google.com>
* go-gcc.cc (Gcc_backend::expression_statement): Add Bfunction*
parameter.
(Gcc_backend::init_statement): Likewise.
(Gcc_backend::assignment_statement): Likewise.
(Gcc_backend::if_statement): Likewise.
2016-12-06 Than McIntosh <thanm@google.com> 2016-12-06 Than McIntosh <thanm@google.com>
* go-gcc.cc (Gcc_backend::var_expression): Add Varexpr_context * go-gcc.cc (Gcc_backend::var_expression): Add Varexpr_context
......
...@@ -361,21 +361,22 @@ class Gcc_backend : public Backend ...@@ -361,21 +361,22 @@ class Gcc_backend : public Backend
{ return this->make_statement(error_mark_node); } { return this->make_statement(error_mark_node); }
Bstatement* Bstatement*
expression_statement(Bexpression*); expression_statement(Bfunction*, Bexpression*);
Bstatement* Bstatement*
init_statement(Bvariable* var, Bexpression* init); init_statement(Bfunction*, Bvariable* var, Bexpression* init);
Bstatement* Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, Location); assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
Location);
Bstatement* Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
Location); Location);
Bstatement* Bstatement*
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block, if_statement(Bfunction*, Bexpression* condition, Bblock* then_block,
Location); Bblock* else_block, Location);
Bstatement* Bstatement*
switch_statement(Bfunction* function, Bexpression* value, switch_statement(Bfunction* function, Bexpression* value,
...@@ -1972,7 +1973,7 @@ Gcc_backend::stack_allocation_expression(int64_t size, Location location) ...@@ -1972,7 +1973,7 @@ Gcc_backend::stack_allocation_expression(int64_t size, Location location)
// An expression as a statement. // An expression as a statement.
Bstatement* Bstatement*
Gcc_backend::expression_statement(Bexpression* expr) Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
{ {
return this->make_statement(expr->get_tree()); return this->make_statement(expr->get_tree());
} }
...@@ -1980,7 +1981,7 @@ Gcc_backend::expression_statement(Bexpression* expr) ...@@ -1980,7 +1981,7 @@ Gcc_backend::expression_statement(Bexpression* expr)
// Variable initialization. // Variable initialization.
Bstatement* Bstatement*
Gcc_backend::init_statement(Bvariable* var, Bexpression* init) Gcc_backend::init_statement(Bfunction*, Bvariable* var, Bexpression* init)
{ {
tree var_tree = var->get_decl(); tree var_tree = var->get_decl();
tree init_tree = init->get_tree(); tree init_tree = init->get_tree();
...@@ -2013,8 +2014,8 @@ Gcc_backend::init_statement(Bvariable* var, Bexpression* init) ...@@ -2013,8 +2014,8 @@ Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
// Assignment. // Assignment.
Bstatement* Bstatement*
Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs, Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
Location location) Bexpression* rhs, Location location)
{ {
tree lhs_tree = lhs->get_tree(); tree lhs_tree = lhs->get_tree();
tree rhs_tree = rhs->get_tree(); tree rhs_tree = rhs->get_tree();
...@@ -2029,8 +2030,8 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs, ...@@ -2029,8 +2030,8 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
// anything anyhow. // anything anyhow.
if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0 if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
|| int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0) || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
return this->compound_statement(this->expression_statement(lhs), return this->compound_statement(this->expression_statement(bfn, lhs),
this->expression_statement(rhs)); this->expression_statement(bfn, rhs));
// Sometimes the same unnamed Go type can be created multiple times // Sometimes the same unnamed Go type can be created multiple times
// and thus have multiple tree representations. Make sure this does // and thus have multiple tree representations. Make sure this does
...@@ -2194,8 +2195,9 @@ Gcc_backend::exception_handler_statement(Bstatement* bstat, ...@@ -2194,8 +2195,9 @@ Gcc_backend::exception_handler_statement(Bstatement* bstat,
// If. // If.
Bstatement* Bstatement*
Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block, Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
Bblock* else_block, Location location) Bblock* then_block, Bblock* else_block,
Location location)
{ {
tree cond_tree = condition->get_tree(); tree cond_tree = condition->get_tree();
tree then_tree = then_block->get_tree(); tree then_tree = then_block->get_tree();
...@@ -2700,7 +2702,8 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock, ...@@ -2700,7 +2702,8 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
// Don't initialize VAR with BINIT, but still evaluate BINIT for // Don't initialize VAR with BINIT, but still evaluate BINIT for
// its side effects. // its side effects.
if (this->type_size(btype) == 0 && init_tree != NULL_TREE) if (this->type_size(btype) == 0 && init_tree != NULL_TREE)
*pstatement = this->compound_statement(this->expression_statement(binit), *pstatement =
this->compound_statement(this->expression_statement(function, binit),
*pstatement); *pstatement);
return new Bvariable(var); return new Bvariable(var);
......
310862eb11ec0705f21a375c0dd16f46a8d901c1 e6fb629c5b246bceab5fc8e8613cf2cf82b1e98f
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -389,19 +389,19 @@ class Backend ...@@ -389,19 +389,19 @@ class Backend
virtual Bstatement* virtual Bstatement*
error_statement() = 0; error_statement() = 0;
// Create an expression statement. // Create an expression statement within the specified function.
virtual Bstatement* virtual Bstatement*
expression_statement(Bexpression*) = 0; expression_statement(Bfunction*, Bexpression*) = 0;
// Create a variable initialization statement. This initializes a // Create a variable initialization statement in the specified
// local variable at the point in the program flow where it is // function. This initializes a local variable at the point in the
// declared. // program flow where it is declared.
virtual Bstatement* virtual Bstatement*
init_statement(Bvariable* var, Bexpression* init) = 0; init_statement(Bfunction*, Bvariable* var, Bexpression* init) = 0;
// Create an assignment statement. // Create an assignment statement within the specified function.
virtual Bstatement* virtual Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
Location) = 0; Location) = 0;
// Create a return statement, passing the representation of the // Create a return statement, passing the representation of the
...@@ -410,9 +410,10 @@ class Backend ...@@ -410,9 +410,10 @@ class Backend
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
Location) = 0; Location) = 0;
// Create an if statement. ELSE_BLOCK may be NULL. // Create an if statement within a function. ELSE_BLOCK may be NULL.
virtual Bstatement* virtual Bstatement*
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block, if_statement(Bfunction*, Bexpression* condition,
Bblock* then_block, Bblock* else_block,
Location) = 0; Location) = 0;
// Create a switch statement where the case values are constants. // Create a switch statement where the case values are constants.
......
...@@ -964,8 +964,12 @@ Set_and_use_temporary_expression::do_get_backend(Translate_context* context) ...@@ -964,8 +964,12 @@ Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
Bvariable* bvar = this->statement_->get_backend_variable(context); Bvariable* bvar = this->statement_->get_backend_variable(context);
Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc); Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc);
Named_object* fn = context->function();
go_assert(fn != NULL);
Bfunction* bfn = fn->func_value()->get_or_make_decl(gogo, fn);
Bexpression* bexpr = this->expr_->get_backend(context); Bexpression* bexpr = this->expr_->get_backend(context);
Bstatement* set = gogo->backend()->assignment_statement(lvar_ref, bexpr, loc); Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref,
bexpr, loc);
Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc); Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc);
Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc); Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
return ret; return ret;
...@@ -4229,8 +4233,12 @@ Unary_expression::do_get_backend(Translate_context* context) ...@@ -4229,8 +4233,12 @@ Unary_expression::do_get_backend(Translate_context* context)
gogo->backend()->var_expression(bvar, VE_lvalue, loc); gogo->backend()->var_expression(bvar, VE_lvalue, loc);
Bexpression* bval = sut->expression()->get_backend(context); Bexpression* bval = sut->expression()->get_backend(context);
Named_object* fn = context->function();
go_assert(fn != NULL);
Bfunction* bfn =
fn->func_value()->get_or_make_decl(gogo, fn);
Bstatement* bassign = Bstatement* bassign =
gogo->backend()->assignment_statement(bvar_expr, bval, loc); gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
Bexpression* bvar_addr = Bexpression* bvar_addr =
gogo->backend()->address_expression(bvar_expr, loc); gogo->backend()->address_expression(bvar_expr, loc);
return gogo->backend()->compound_expression(bassign, bvar_addr, loc); return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
...@@ -10197,8 +10205,10 @@ Call_expression::do_get_backend(Translate_context* context) ...@@ -10197,8 +10205,10 @@ Call_expression::do_get_backend(Translate_context* context)
Expression* call_ref = Expression* call_ref =
Expression::make_temporary_reference(this->call_temp_, location); Expression::make_temporary_reference(this->call_temp_, location);
Bexpression* bcall_ref = call_ref->get_backend(context); Bexpression* bcall_ref = call_ref->get_backend(context);
Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* assn_stmt = Bstatement* assn_stmt =
gogo->backend()->assignment_statement(bcall_ref, call, location); gogo->backend()->assignment_statement(bfunction,
bcall_ref, call, location);
this->call_ = this->set_results(context, bcall_ref); this->call_ = this->set_results(context, bcall_ref);
...@@ -10235,11 +10245,13 @@ Call_expression::set_results(Translate_context* context, Bexpression* call) ...@@ -10235,11 +10245,13 @@ Call_expression::set_results(Translate_context* context, Bexpression* call)
Expression::make_temporary_reference(temp, loc); Expression::make_temporary_reference(temp, loc);
ref->set_is_lvalue(); ref->set_is_lvalue();
Bfunction* bfunction = context->function()->func_value()->get_decl();
Bexpression* result_ref = ref->get_backend(context); Bexpression* result_ref = ref->get_backend(context);
Bexpression* call_result = Bexpression* call_result =
gogo->backend()->struct_field_expression(call, i, loc); gogo->backend()->struct_field_expression(call, i, loc);
Bstatement* assn_stmt = Bstatement* assn_stmt =
gogo->backend()->assignment_statement(result_ref, call_result, loc); gogo->backend()->assignment_statement(bfunction,
result_ref, call_result, loc);
Bexpression* result = Bexpression* result =
gogo->backend()->compound_expression(assn_stmt, call_result, loc); gogo->backend()->compound_expression(assn_stmt, call_result, loc);
...@@ -10248,7 +10260,8 @@ Call_expression::set_results(Translate_context* context, Bexpression* call) ...@@ -10248,7 +10260,8 @@ Call_expression::set_results(Translate_context* context, Bexpression* call)
results = result; results = result;
else else
{ {
Bstatement* expr_stmt = gogo->backend()->expression_statement(result); Bstatement* expr_stmt =
gogo->backend()->expression_statement(bfunction, result);
results = results =
gogo->backend()->compound_expression(expr_stmt, results, loc); gogo->backend()->compound_expression(expr_stmt, results, loc);
} }
...@@ -11951,7 +11964,9 @@ Interface_field_reference_expression::do_get_backend(Translate_context* context) ...@@ -11951,7 +11964,9 @@ Interface_field_reference_expression::do_get_backend(Translate_context* context)
Bexpression* bcond = Bexpression* bcond =
gogo->backend()->conditional_expression(NULL, bnil_check, bcrash, NULL, loc); gogo->backend()->conditional_expression(NULL, bnil_check, bcrash, NULL, loc);
Bstatement* cond_statement = gogo->backend()->expression_statement(bcond); Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* cond_statement =
gogo->backend()->expression_statement(bfunction, bcond);
return gogo->backend()->compound_expression(cond_statement, bclosure, loc); return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
} }
...@@ -14151,7 +14166,8 @@ Heap_expression::do_get_backend(Translate_context* context) ...@@ -14151,7 +14166,8 @@ Heap_expression::do_get_backend(Translate_context* context)
gogo->backend()->indirect_expression(expr_btype, space, true, loc); gogo->backend()->indirect_expression(expr_btype, space, true, loc);
Bexpression* bexpr = this->expr_->get_backend(context); Bexpression* bexpr = this->expr_->get_backend(context);
Bstatement* assn = gogo->backend()->assignment_statement(ref, bexpr, loc); Bstatement* assn = gogo->backend()->assignment_statement(fndecl, ref,
bexpr, loc);
decl = gogo->backend()->compound_statement(decl, assn); decl = gogo->backend()->compound_statement(decl, assn);
space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc); space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc);
return gogo->backend()->compound_expression(decl, space, loc); return gogo->backend()->compound_expression(decl, space, loc);
...@@ -15451,7 +15467,9 @@ Compound_expression::do_get_backend(Translate_context* context) ...@@ -15451,7 +15467,9 @@ Compound_expression::do_get_backend(Translate_context* context)
{ {
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
Bexpression* binit = this->init_->get_backend(context); Bexpression* binit = this->init_->get_backend(context);
Bstatement* init_stmt = gogo->backend()->expression_statement(binit); Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* init_stmt = gogo->backend()->expression_statement(bfunction,
binit);
Bexpression* bexpr = this->expr_->get_backend(context); Bexpression* bexpr = this->expr_->get_backend(context);
return gogo->backend()->compound_expression(init_stmt, bexpr, return gogo->backend()->compound_expression(init_stmt, bexpr,
this->location()); this->location());
......
...@@ -661,7 +661,7 @@ Gogo::recompute_init_priorities() ...@@ -661,7 +661,7 @@ Gogo::recompute_init_priorities()
// package. // package.
void void
Gogo::init_imports(std::vector<Bstatement*>& init_stmts) Gogo::init_imports(std::vector<Bstatement*>& init_stmts, Bfunction *bfunction)
{ {
go_assert(this->is_main_package()); go_assert(this->is_main_package());
...@@ -703,7 +703,8 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts) ...@@ -703,7 +703,8 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts)
Bexpression* pfunc_call = Bexpression* pfunc_call =
this->backend()->call_expression(pfunc_code, empty_args, this->backend()->call_expression(pfunc_code, empty_args,
NULL, unknown_loc); NULL, unknown_loc);
init_stmts.push_back(this->backend()->expression_statement(pfunc_call)); init_stmts.push_back(this->backend()->expression_statement(bfunction,
pfunc_call));
} }
} }
...@@ -726,7 +727,8 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts) ...@@ -726,7 +727,8 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts)
void void
Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc, Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
std::vector<Bstatement*>& init_stmts) std::vector<Bstatement*>& init_stmts,
Bfunction* init_bfn)
{ {
if (var_gc.empty()) if (var_gc.empty())
return; return;
...@@ -830,7 +832,7 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc, ...@@ -830,7 +832,7 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
Translate_context context(this, NULL, NULL, NULL); Translate_context context(this, NULL, NULL, NULL);
Bexpression* bcall = register_roots->get_backend(&context); Bexpression* bcall = register_roots->get_backend(&context);
init_stmts.push_back(this->backend()->expression_statement(bcall)); init_stmts.push_back(this->backend()->expression_statement(init_bfn, bcall));
} }
// Get the name to use for the import control function. If there is a // Get the name to use for the import control function. If there is a
...@@ -1253,14 +1255,19 @@ Gogo::write_globals() ...@@ -1253,14 +1255,19 @@ Gogo::write_globals()
std::vector<Bexpression*> const_decls; std::vector<Bexpression*> const_decls;
std::vector<Bfunction*> func_decls; std::vector<Bfunction*> func_decls;
// The init function declaration, if necessary. // The init function declaration and associated Bfunction, if necessary.
Named_object* init_fndecl = NULL; Named_object* init_fndecl = NULL;
Bfunction* init_bfn = NULL;
std::vector<Bstatement*> init_stmts; std::vector<Bstatement*> init_stmts;
std::vector<Bstatement*> var_init_stmts; std::vector<Bstatement*> var_init_stmts;
if (this->is_main_package()) if (this->is_main_package())
this->init_imports(init_stmts); {
init_fndecl = this->initialization_function_decl();
init_bfn = init_fndecl->func_value()->get_or_make_decl(this, init_fndecl);
this->init_imports(init_stmts, init_bfn);
}
// A list of variable initializations. // A list of variable initializations.
Var_inits var_inits; Var_inits var_inits;
...@@ -1345,7 +1352,11 @@ Gogo::write_globals() ...@@ -1345,7 +1352,11 @@ Gogo::write_globals()
else else
{ {
if (init_fndecl == NULL) if (init_fndecl == NULL)
{
init_fndecl = this->initialization_function_decl(); init_fndecl = this->initialization_function_decl();
Function* func = init_fndecl->func_value();
init_bfn = func->get_or_make_decl(this, init_fndecl);
}
var_init_fn = init_fndecl; var_init_fn = init_fndecl;
} }
Bexpression* var_binit = var->get_init(this, var_init_fn); Bexpression* var_binit = var->get_init(this, var_init_fn);
...@@ -1364,15 +1375,15 @@ Gogo::write_globals() ...@@ -1364,15 +1375,15 @@ Gogo::write_globals()
} }
else if (is_sink) else if (is_sink)
var_init_stmt = var_init_stmt =
this->backend()->expression_statement(var_binit); this->backend()->expression_statement(init_bfn, var_binit);
else else
{ {
Location loc = var->location(); Location loc = var->location();
Bexpression* var_expr = Bexpression* var_expr =
this->backend()->var_expression(bvar, VE_lvalue, loc); this->backend()->var_expression(bvar, VE_lvalue, loc);
var_init_stmt = var_init_stmt =
this->backend()->assignment_statement(var_expr, var_binit, this->backend()->assignment_statement(init_bfn, var_expr,
loc); var_binit, loc);
} }
} }
else else
...@@ -1402,7 +1413,7 @@ Gogo::write_globals() ...@@ -1402,7 +1413,7 @@ Gogo::write_globals()
Btype* btype = no->var_value()->type()->get_backend(this); Btype* btype = no->var_value()->type()->get_backend(this);
Bexpression* zero = this->backend()->zero_expression(btype); Bexpression* zero = this->backend()->zero_expression(btype);
Bstatement* zero_stmt = Bstatement* zero_stmt =
this->backend()->expression_statement(zero); this->backend()->expression_statement(init_bfn, zero);
var_inits.push_back(Var_init(no, zero_stmt)); var_inits.push_back(Var_init(no, zero_stmt));
} }
...@@ -1412,7 +1423,7 @@ Gogo::write_globals() ...@@ -1412,7 +1423,7 @@ Gogo::write_globals()
} }
// Register global variables with the garbage collector. // Register global variables with the garbage collector.
this->register_gc_vars(var_gc, init_stmts); this->register_gc_vars(var_gc, init_stmts, init_bfn);
// Simple variable initializations, after all variables are // Simple variable initializations, after all variables are
// registered. // registered.
...@@ -1446,7 +1457,8 @@ Gogo::write_globals() ...@@ -1446,7 +1457,8 @@ Gogo::write_globals()
Bexpression* call = this->backend()->call_expression(func_code, Bexpression* call = this->backend()->call_expression(func_code,
empty_args, empty_args,
NULL, func_loc); NULL, func_loc);
init_stmts.push_back(this->backend()->expression_statement(call)); Bstatement* ist = this->backend()->expression_statement(initfn, call);
init_stmts.push_back(ist);
} }
// Set up a magic function to do all the initialization actions. // Set up a magic function to do all the initialization actions.
...@@ -5594,7 +5606,8 @@ Function::build(Gogo* gogo, Named_object* named_function) ...@@ -5594,7 +5606,8 @@ Function::build(Gogo* gogo, Named_object* named_function)
for (size_t i = 0; i < vars.size(); ++i) for (size_t i = 0; i < vars.size(); ++i)
{ {
Bstatement* init_stmt = Bstatement* init_stmt =
gogo->backend()->init_statement(vars[i], var_inits[i]); gogo->backend()->init_statement(this->fndecl_, vars[i],
var_inits[i]);
init.push_back(init_stmt); init.push_back(init_stmt);
} }
if (defer_init != NULL) if (defer_init != NULL)
...@@ -5666,7 +5679,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function, ...@@ -5666,7 +5679,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
this->defer_stack(end_loc)); this->defer_stack(end_loc));
Translate_context context(gogo, named_function, NULL, NULL); Translate_context context(gogo, named_function, NULL, NULL);
Bexpression* defer = call->get_backend(&context); Bexpression* defer = call->get_backend(&context);
stmts.push_back(gogo->backend()->expression_statement(defer)); stmts.push_back(gogo->backend()->expression_statement(this->fndecl_, defer));
Bstatement* ret_bstmt = this->return_value(gogo, named_function, end_loc); Bstatement* ret_bstmt = this->return_value(gogo, named_function, end_loc);
if (ret_bstmt != NULL) if (ret_bstmt != NULL)
...@@ -5705,7 +5718,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function, ...@@ -5705,7 +5718,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
Bexpression* bref = ref->get_backend(&context); Bexpression* bref = ref->get_backend(&context);
ret = gogo->backend()->conditional_expression(NULL, bref, ret, NULL, ret = gogo->backend()->conditional_expression(NULL, bref, ret, NULL,
end_loc); end_loc);
stmts.push_back(gogo->backend()->expression_statement(ret)); stmts.push_back(gogo->backend()->expression_statement(this->fndecl_, ret));
} }
go_assert(*fini == NULL); go_assert(*fini == NULL);
...@@ -6547,6 +6560,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, ...@@ -6547,6 +6560,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
Translate_context context(gogo, function, NULL, NULL); Translate_context context(gogo, function, NULL, NULL);
Bblock* bblock = this->preinit_->get_backend(&context); Bblock* bblock = this->preinit_->get_backend(&context);
Bfunction* bfunction =
function->func_value()->get_or_make_decl(gogo, function);
// It's possible to have pre-init statements without an initializer // It's possible to have pre-init statements without an initializer
// if the pre-init statements set the variable. // if the pre-init statements set the variable.
...@@ -6556,7 +6571,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, ...@@ -6556,7 +6571,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
if (var_decl == NULL) if (var_decl == NULL)
{ {
Bexpression* init_bexpr = this->init_->get_backend(&context); Bexpression* init_bexpr = this->init_->get_backend(&context);
decl_init = gogo->backend()->expression_statement(init_bexpr); decl_init = gogo->backend()->expression_statement(bfunction,
init_bexpr);
} }
else else
{ {
...@@ -6566,7 +6582,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, ...@@ -6566,7 +6582,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
Bexpression* val = val_expr->get_backend(&context); Bexpression* val = val_expr->get_backend(&context);
Bexpression* var_ref = Bexpression* var_ref =
gogo->backend()->var_expression(var_decl, VE_lvalue, loc); gogo->backend()->var_expression(var_decl, VE_lvalue, loc);
decl_init = gogo->backend()->assignment_statement(var_ref, val, loc); decl_init = gogo->backend()->assignment_statement(bfunction, var_ref,
val, loc);
} }
} }
Bstatement* block_stmt = gogo->backend()->block_statement(bblock); Bstatement* block_stmt = gogo->backend()->block_statement(bblock);
......
...@@ -773,14 +773,16 @@ class Gogo ...@@ -773,14 +773,16 @@ class Gogo
Named_object* Named_object*
create_initialization_function(Named_object* fndecl, Bstatement* code_stmt); create_initialization_function(Named_object* fndecl, Bstatement* code_stmt);
// Initialize imported packages. // Initialize imported packages. BFUNCTION is the function
// into which the package init calls will be placed.
void void
init_imports(std::vector<Bstatement*>&); init_imports(std::vector<Bstatement*>&, Bfunction* bfunction);
// Register variables with the garbage collector. // Register variables with the garbage collector.
void void
register_gc_vars(const std::vector<Named_object*>&, register_gc_vars(const std::vector<Named_object*>&,
std::vector<Bstatement*>&); std::vector<Bstatement*>&,
Bfunction* init_bfunction);
// Type used to map import names to packages. // Type used to map import names to packages.
typedef std::map<std::string, Package*> Imports; typedef std::map<std::string, Package*> Imports;
......
...@@ -285,6 +285,7 @@ Variable_declaration_statement::do_flatten(Gogo* gogo, Named_object* function, ...@@ -285,6 +285,7 @@ Variable_declaration_statement::do_flatten(Gogo* gogo, Named_object* function,
Bstatement* Bstatement*
Variable_declaration_statement::do_get_backend(Translate_context* context) Variable_declaration_statement::do_get_backend(Translate_context* context)
{ {
Bfunction* bfunction = context->function()->func_value()->get_decl();
Variable* var = this->var_->var_value(); Variable* var = this->var_->var_value();
Bvariable* bvar = this->var_->get_backend_variable(context->gogo(), Bvariable* bvar = this->var_->get_backend_variable(context->gogo(),
context->function()); context->function());
...@@ -293,7 +294,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context) ...@@ -293,7 +294,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
if (!var->is_in_heap()) if (!var->is_in_heap())
{ {
go_assert(binit != NULL); go_assert(binit != NULL);
return context->backend()->init_statement(bvar, binit); return context->backend()->init_statement(bfunction, bvar, binit);
} }
// Something takes the address of this variable, so the value is // Something takes the address of this variable, so the value is
...@@ -316,12 +317,12 @@ Variable_declaration_statement::do_get_backend(Translate_context* context) ...@@ -316,12 +317,12 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
Expression* e = Expression::make_temporary_reference(temp, loc); Expression* e = Expression::make_temporary_reference(temp, loc);
e = Expression::make_unary(OPERATOR_MULT, e, loc); e = Expression::make_unary(OPERATOR_MULT, e, loc);
Bexpression* be = e->get_backend(context); Bexpression* be = e->get_backend(context);
set = context->backend()->assignment_statement(be, binit, loc); set = context->backend()->assignment_statement(bfunction, be, binit, loc);
} }
Expression* ref = Expression::make_temporary_reference(temp, loc); Expression* ref = Expression::make_temporary_reference(temp, loc);
Bexpression* bref = ref->get_backend(context); Bexpression* bref = ref->get_backend(context);
Bstatement* sinit = context->backend()->init_statement(bvar, bref); Bstatement* sinit = context->backend()->init_statement(bfunction, bvar, bref);
std::vector<Bstatement*> stats; std::vector<Bstatement*> stats;
stats.reserve(3); stats.reserve(3);
...@@ -896,6 +897,10 @@ int Mark_lvalue_varexprs::expression(Expression** ppexpr) ...@@ -896,6 +897,10 @@ int Mark_lvalue_varexprs::expression(Expression** ppexpr)
return TRAVERSE_EXIT; return TRAVERSE_EXIT;
} }
Unary_expression* ue = e->unary_expression();
if (ue && ue->op() == OPERATOR_MULT)
return TRAVERSE_CONTINUE;
return TRAVERSE_EXIT; return TRAVERSE_EXIT;
} }
...@@ -907,7 +912,8 @@ Assignment_statement::do_get_backend(Translate_context* context) ...@@ -907,7 +912,8 @@ Assignment_statement::do_get_backend(Translate_context* context)
if (this->lhs_->is_sink_expression()) if (this->lhs_->is_sink_expression())
{ {
Bexpression* rhs = this->rhs_->get_backend(context); Bexpression* rhs = this->rhs_->get_backend(context);
return context->backend()->expression_statement(rhs); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, rhs);
} }
Mark_lvalue_varexprs mlve; Mark_lvalue_varexprs mlve;
...@@ -918,7 +924,9 @@ Assignment_statement::do_get_backend(Translate_context* context) ...@@ -918,7 +924,9 @@ Assignment_statement::do_get_backend(Translate_context* context)
Expression::convert_for_assignment(context->gogo(), this->lhs_->type(), Expression::convert_for_assignment(context->gogo(), this->lhs_->type(),
this->rhs_, this->location()); this->rhs_, this->location());
Bexpression* rhs = conv->get_backend(context); Bexpression* rhs = conv->get_backend(context);
return context->backend()->assignment_statement(lhs, rhs, this->location()); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->assignment_statement(bfunction, lhs, rhs,
this->location());
} }
// Dump the AST representation for an assignment statement. // Dump the AST representation for an assignment statement.
...@@ -1801,7 +1809,8 @@ Bstatement* ...@@ -1801,7 +1809,8 @@ Bstatement*
Expression_statement::do_get_backend(Translate_context* context) Expression_statement::do_get_backend(Translate_context* context)
{ {
Bexpression* bexpr = this->expr_->get_backend(context); Bexpression* bexpr = this->expr_->get_backend(context);
return context->backend()->expression_statement(bexpr); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bexpr);
} }
// Dump the AST representation for an expression statement // Dump the AST representation for an expression statement
...@@ -2582,7 +2591,8 @@ Go_statement::do_get_backend(Translate_context* context) ...@@ -2582,7 +2591,8 @@ Go_statement::do_get_backend(Translate_context* context)
Expression* call = Runtime::make_call(Runtime::GO, this->location(), 2, Expression* call = Runtime::make_call(Runtime::GO, this->location(), 2,
fn, arg); fn, arg);
Bexpression* bcall = call->get_backend(context); Bexpression* bcall = call->get_backend(context);
return context->backend()->expression_statement(bcall); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bcall);
} }
// Dump the AST representation for go statement. // Dump the AST representation for go statement.
...@@ -2620,7 +2630,8 @@ Defer_statement::do_get_backend(Translate_context* context) ...@@ -2620,7 +2630,8 @@ Defer_statement::do_get_backend(Translate_context* context)
Expression* call = Runtime::make_call(Runtime::DEFERPROC, loc, 3, Expression* call = Runtime::make_call(Runtime::DEFERPROC, loc, 3,
ds, fn, arg); ds, fn, arg);
Bexpression* bcall = call->get_backend(context); Bexpression* bcall = call->get_backend(context);
return context->backend()->expression_statement(bcall); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bcall);
} }
// Dump the AST representation for defer statement. // Dump the AST representation for defer statement.
...@@ -3032,7 +3043,8 @@ Label_statement::do_get_backend(Translate_context* context) ...@@ -3032,7 +3043,8 @@ Label_statement::do_get_backend(Translate_context* context)
if (this->label_->is_dummy_label()) if (this->label_->is_dummy_label())
{ {
Bexpression* bce = context->backend()->boolean_constant_expression(false); Bexpression* bce = context->backend()->boolean_constant_expression(false);
return context->backend()->expression_statement(bce); Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bce);
} }
Blabel* blabel = this->label_->get_backend_label(context); Blabel* blabel = this->label_->get_backend_label(context);
return context->backend()->label_definition_statement(blabel); return context->backend()->label_definition_statement(blabel);
...@@ -3157,7 +3169,9 @@ If_statement::do_get_backend(Translate_context* context) ...@@ -3157,7 +3169,9 @@ If_statement::do_get_backend(Translate_context* context)
Bblock* else_block = (this->else_block_ == NULL Bblock* else_block = (this->else_block_ == NULL
? NULL ? NULL
: this->else_block_->get_backend(context)); : this->else_block_->get_backend(context));
return context->backend()->if_statement(cond, then_block, else_block, Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->if_statement(bfunction,
cond, then_block, else_block,
this->location()); this->location());
} }
...@@ -4478,7 +4492,8 @@ Send_statement::do_get_backend(Translate_context* context) ...@@ -4478,7 +4492,8 @@ Send_statement::do_get_backend(Translate_context* context)
context->gogo()->lower_expression(context->function(), NULL, &call); context->gogo()->lower_expression(context->function(), NULL, &call);
Bexpression* bcall = call->get_backend(context); Bexpression* bcall = call->get_backend(context);
Bstatement* s = context->backend()->expression_statement(bcall); Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* s = context->backend()->expression_statement(bfunction, bcall);
if (btemp == NULL) if (btemp == NULL)
return s; return s;
...@@ -4923,7 +4938,10 @@ Select_clauses::get_backend(Translate_context* context, ...@@ -4923,7 +4938,10 @@ Select_clauses::get_backend(Translate_context* context,
Bexpression* bcall = call->get_backend(context); Bexpression* bcall = call->get_backend(context);
if (count == 0) if (count == 0)
return context->backend()->expression_statement(bcall); {
Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bcall);
}
std::vector<Bstatement*> statements; std::vector<Bstatement*> statements;
statements.reserve(2); statements.reserve(2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment