summaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-16 22:11:28 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-16 22:11:28 +0000
commit0ab486564ccb6ff6f00d12dd1f7b6aa9f2776f76 (patch)
tree7be95802bcfe2fc53857c96560d39afd05204959 /gcc/go/gofrontend
parent604b7d8a08bf49187bb9d6f302a2d2d3c23c9071 (diff)
downloadgcc-0ab486564ccb6ff6f00d12dd1f7b6aa9f2776f76.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243766 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/backend.h21
-rw-r--r--gcc/go/gofrontend/expressions.cc34
-rw-r--r--gcc/go/gofrontend/gogo.cc53
-rw-r--r--gcc/go/gofrontend/gogo.h8
-rw-r--r--gcc/go/gofrontend/statements.cc44
6 files changed, 109 insertions, 53 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 8a515e61859..33c1aef34d3 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-310862eb11ec0705f21a375c0dd16f46a8d901c1
+e6fb629c5b246bceab5fc8e8613cf2cf82b1e98f
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
index e9a19128e5c..cad659aca3b 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -389,19 +389,19 @@ class Backend
virtual Bstatement*
error_statement() = 0;
- // Create an expression statement.
+ // Create an expression statement within the specified function.
virtual Bstatement*
- expression_statement(Bexpression*) = 0;
+ expression_statement(Bfunction*, Bexpression*) = 0;
- // Create a variable initialization statement. This initializes a
- // local variable at the point in the program flow where it is
- // declared.
+ // Create a variable initialization statement in the specified
+ // function. This initializes a local variable at the point in the
+ // program flow where it is declared.
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*
- assignment_statement(Bexpression* lhs, Bexpression* rhs,
+ assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
Location) = 0;
// Create a return statement, passing the representation of the
@@ -410,9 +410,10 @@ class Backend
return_statement(Bfunction*, const std::vector<Bexpression*>&,
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*
- if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
+ if_statement(Bfunction*, Bexpression* condition,
+ Bblock* then_block, Bblock* else_block,
Location) = 0;
// Create a switch statement where the case values are constants.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2022c4749b3..02c33203309 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -964,8 +964,12 @@ Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
Bvariable* bvar = this->statement_->get_backend_variable(context);
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);
- 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* ret = gogo->backend()->compound_expression(set, var_ref, loc);
return ret;
@@ -4229,8 +4233,12 @@ Unary_expression::do_get_backend(Translate_context* context)
gogo->backend()->var_expression(bvar, VE_lvalue, loc);
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 =
- gogo->backend()->assignment_statement(bvar_expr, bval, loc);
+ gogo->backend()->assignment_statement(bfn, bvar_expr, bval, loc);
Bexpression* bvar_addr =
gogo->backend()->address_expression(bvar_expr, loc);
return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
@@ -10197,8 +10205,10 @@ Call_expression::do_get_backend(Translate_context* context)
Expression* call_ref =
Expression::make_temporary_reference(this->call_temp_, location);
Bexpression* bcall_ref = call_ref->get_backend(context);
+ Bfunction* bfunction = context->function()->func_value()->get_decl();
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);
@@ -10235,11 +10245,13 @@ Call_expression::set_results(Translate_context* context, Bexpression* call)
Expression::make_temporary_reference(temp, loc);
ref->set_is_lvalue();
+ Bfunction* bfunction = context->function()->func_value()->get_decl();
Bexpression* result_ref = ref->get_backend(context);
Bexpression* call_result =
gogo->backend()->struct_field_expression(call, i, loc);
Bstatement* assn_stmt =
- gogo->backend()->assignment_statement(result_ref, call_result, loc);
+ gogo->backend()->assignment_statement(bfunction,
+ result_ref, call_result, loc);
Bexpression* result =
gogo->backend()->compound_expression(assn_stmt, call_result, loc);
@@ -10248,7 +10260,8 @@ Call_expression::set_results(Translate_context* context, Bexpression* call)
results = result;
else
{
- Bstatement* expr_stmt = gogo->backend()->expression_statement(result);
+ Bstatement* expr_stmt =
+ gogo->backend()->expression_statement(bfunction, result);
results =
gogo->backend()->compound_expression(expr_stmt, results, loc);
}
@@ -11951,7 +11964,9 @@ Interface_field_reference_expression::do_get_backend(Translate_context* context)
Bexpression* bcond =
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);
}
@@ -14151,7 +14166,8 @@ Heap_expression::do_get_backend(Translate_context* context)
gogo->backend()->indirect_expression(expr_btype, space, true, loc);
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);
space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc);
return gogo->backend()->compound_expression(decl, space, loc);
@@ -15451,7 +15467,9 @@ Compound_expression::do_get_backend(Translate_context* context)
{
Gogo* gogo = context->gogo();
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);
return gogo->backend()->compound_expression(init_stmt, bexpr,
this->location());
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index e9cc6b43f94..51de4283946 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -661,7 +661,7 @@ Gogo::recompute_init_priorities()
// package.
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());
@@ -703,7 +703,8 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts)
Bexpression* pfunc_call =
this->backend()->call_expression(pfunc_code, empty_args,
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)
void
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())
return;
@@ -830,7 +832,7 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
Translate_context context(this, NULL, NULL, NULL);
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
@@ -1253,14 +1255,19 @@ Gogo::write_globals()
std::vector<Bexpression*> const_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;
+ Bfunction* init_bfn = NULL;
std::vector<Bstatement*> init_stmts;
std::vector<Bstatement*> var_init_stmts;
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.
Var_inits var_inits;
@@ -1345,7 +1352,11 @@ Gogo::write_globals()
else
{
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;
}
Bexpression* var_binit = var->get_init(this, var_init_fn);
@@ -1364,15 +1375,15 @@ Gogo::write_globals()
}
else if (is_sink)
var_init_stmt =
- this->backend()->expression_statement(var_binit);
+ this->backend()->expression_statement(init_bfn, var_binit);
else
{
Location loc = var->location();
Bexpression* var_expr =
this->backend()->var_expression(bvar, VE_lvalue, loc);
var_init_stmt =
- this->backend()->assignment_statement(var_expr, var_binit,
- loc);
+ this->backend()->assignment_statement(init_bfn, var_expr,
+ var_binit, loc);
}
}
else
@@ -1402,7 +1413,7 @@ Gogo::write_globals()
Btype* btype = no->var_value()->type()->get_backend(this);
Bexpression* zero = this->backend()->zero_expression(btype);
Bstatement* zero_stmt =
- this->backend()->expression_statement(zero);
+ this->backend()->expression_statement(init_bfn, zero);
var_inits.push_back(Var_init(no, zero_stmt));
}
@@ -1412,7 +1423,7 @@ Gogo::write_globals()
}
// 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
// registered.
@@ -1446,7 +1457,8 @@ Gogo::write_globals()
Bexpression* call = this->backend()->call_expression(func_code,
empty_args,
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.
@@ -5594,7 +5606,8 @@ Function::build(Gogo* gogo, Named_object* named_function)
for (size_t i = 0; i < vars.size(); ++i)
{
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);
}
if (defer_init != NULL)
@@ -5666,7 +5679,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
this->defer_stack(end_loc));
Translate_context context(gogo, named_function, NULL, NULL);
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);
if (ret_bstmt != NULL)
@@ -5705,7 +5718,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
Bexpression* bref = ref->get_backend(&context);
ret = gogo->backend()->conditional_expression(NULL, bref, ret, NULL,
end_loc);
- stmts.push_back(gogo->backend()->expression_statement(ret));
+ stmts.push_back(gogo->backend()->expression_statement(this->fndecl_, ret));
}
go_assert(*fini == NULL);
@@ -6547,6 +6560,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
Translate_context context(gogo, function, NULL, NULL);
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
// if the pre-init statements set the variable.
@@ -6556,7 +6571,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
if (var_decl == NULL)
{
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
{
@@ -6566,7 +6582,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
Bexpression* val = val_expr->get_backend(&context);
Bexpression* var_ref =
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);
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 7ddb3ce3ced..23d1f08a59a 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -773,14 +773,16 @@ class Gogo
Named_object*
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
- init_imports(std::vector<Bstatement*>&);
+ init_imports(std::vector<Bstatement*>&, Bfunction* bfunction);
// Register variables with the garbage collector.
void
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.
typedef std::map<std::string, Package*> Imports;
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index c7b4fe82ceb..dc226e8b21e 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -285,6 +285,7 @@ Variable_declaration_statement::do_flatten(Gogo* gogo, Named_object* function,
Bstatement*
Variable_declaration_statement::do_get_backend(Translate_context* context)
{
+ Bfunction* bfunction = context->function()->func_value()->get_decl();
Variable* var = this->var_->var_value();
Bvariable* bvar = this->var_->get_backend_variable(context->gogo(),
context->function());
@@ -293,7 +294,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
if (!var->is_in_heap())
{
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
@@ -316,12 +317,12 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
Expression* e = Expression::make_temporary_reference(temp, loc);
e = Expression::make_unary(OPERATOR_MULT, e, loc);
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);
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;
stats.reserve(3);
@@ -896,6 +897,10 @@ int Mark_lvalue_varexprs::expression(Expression** ppexpr)
return TRAVERSE_EXIT;
}
+ Unary_expression* ue = e->unary_expression();
+ if (ue && ue->op() == OPERATOR_MULT)
+ return TRAVERSE_CONTINUE;
+
return TRAVERSE_EXIT;
}
@@ -907,7 +912,8 @@ Assignment_statement::do_get_backend(Translate_context* context)
if (this->lhs_->is_sink_expression())
{
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;
@@ -918,7 +924,9 @@ Assignment_statement::do_get_backend(Translate_context* context)
Expression::convert_for_assignment(context->gogo(), this->lhs_->type(),
this->rhs_, this->location());
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.
@@ -1801,7 +1809,8 @@ Bstatement*
Expression_statement::do_get_backend(Translate_context* 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
@@ -2582,7 +2591,8 @@ Go_statement::do_get_backend(Translate_context* context)
Expression* call = Runtime::make_call(Runtime::GO, this->location(), 2,
fn, arg);
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.
@@ -2620,7 +2630,8 @@ Defer_statement::do_get_backend(Translate_context* context)
Expression* call = Runtime::make_call(Runtime::DEFERPROC, loc, 3,
ds, fn, arg);
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.
@@ -3032,7 +3043,8 @@ Label_statement::do_get_backend(Translate_context* context)
if (this->label_->is_dummy_label())
{
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);
return context->backend()->label_definition_statement(blabel);
@@ -3157,7 +3169,9 @@ If_statement::do_get_backend(Translate_context* context)
Bblock* else_block = (this->else_block_ == NULL
? NULL
: 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());
}
@@ -4478,7 +4492,8 @@ Send_statement::do_get_backend(Translate_context* context)
context->gogo()->lower_expression(context->function(), NULL, &call);
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)
return s;
@@ -4912,7 +4927,7 @@ Select_clauses::get_backend(Translate_context* context,
if (s == NULL)
clauses[i] = g;
else
- clauses[i] = context->backend()->compound_statement(s, g);
+ clauses[i] = context->backend()->compound_statement(s, g);
}
Expression* selref = Expression::make_temporary_reference(sel, location);
@@ -4923,7 +4938,10 @@ Select_clauses::get_backend(Translate_context* context,
Bexpression* bcall = call->get_backend(context);
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;
statements.reserve(2);