compiler: add containing Bfunction to some backend interfaces.
authorThan McIntosh <thanm@google.com>
Fri, 16 Dec 2016 22:11:28 +0000 (22:11 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 16 Dec 2016 22:11:28 +0000 (22:11 +0000)
    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

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/statements.cc

index 0b116eb..2ecbf5f 100644 (file)
@@ -1,3 +1,11 @@
+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>
 
        * go-gcc.cc (Gcc_backend::var_expression): Add Varexpr_context
index f1ac522..cc93667 100644 (file)
@@ -361,21 +361,22 @@ class Gcc_backend : public Backend
   { return this->make_statement(error_mark_node); }
 
   Bstatement*
-  expression_statement(Bexpression*);
+  expression_statement(Bfunction*, Bexpression*);
 
   Bstatement*
-  init_statement(Bvariable* var, Bexpression* init);
+  init_statement(Bfunction*, Bvariable* var, Bexpression* init);
 
   Bstatement*
-  assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
+  assignment_statement(Bfunction*, Bexpression* lhs, Bexpression* rhs,
+                      Location);
 
   Bstatement*
   return_statement(Bfunction*, const std::vector<Bexpression*>&,
                   Location);
 
   Bstatement*
-  if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
-              Location);
+  if_statement(Bfunction*, Bexpression* condition, Bblock* then_block,
+              Bblock* else_block, Location);
 
   Bstatement*
   switch_statement(Bfunction* function, Bexpression* value,
@@ -1972,7 +1973,7 @@ Gcc_backend::stack_allocation_expression(int64_t size, Location location)
 // An expression as a statement.
 
 Bstatement*
-Gcc_backend::expression_statement(Bexpression* expr)
+Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
 {
   return this->make_statement(expr->get_tree());
 }
@@ -1980,7 +1981,7 @@ Gcc_backend::expression_statement(Bexpression* expr)
 // Variable initialization.
 
 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 init_tree = init->get_tree();
@@ -2013,8 +2014,8 @@ Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
 // Assignment.
 
 Bstatement*
-Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
-                                 Location location)
+Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs,
+                                 Bexpression* rhs, Location location)
 {
   tree lhs_tree = lhs->get_tree();
   tree rhs_tree = rhs->get_tree();
@@ -2029,8 +2030,8 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
   // anything anyhow.
   if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
       || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
-    return this->compound_statement(this->expression_statement(lhs),
-                                   this->expression_statement(rhs));
+    return this->compound_statement(this->expression_statement(bfn, lhs),
+                                   this->expression_statement(bfn, rhs));
 
   // Sometimes the same unnamed Go type can be created multiple times
   // and thus have multiple tree representations.  Make sure this does
@@ -2194,8 +2195,9 @@ Gcc_backend::exception_handler_statement(Bstatement* bstat,
 // If.
 
 Bstatement*
-Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
-                         Bblock* else_block, Location location)
+Gcc_backend::if_statement(Bfunction*, Bexpression* condition,
+                         Bblock* then_block, Bblock* else_block,
+                         Location location)
 {
   tree cond_tree = condition->get_tree();
   tree then_tree = then_block->get_tree();
@@ -2700,8 +2702,9 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
   // Don't initialize VAR with BINIT, but still evaluate BINIT for
   // its side effects.
   if (this->type_size(btype) == 0 && init_tree != NULL_TREE)
-    *pstatement = this->compound_statement(this->expression_statement(binit),
-                                          *pstatement);
+    *pstatement =
+      this->compound_statement(this->expression_statement(function, binit),
+                              *pstatement);
 
   return new Bvariable(var);
 }
index 8a515e6..33c1aef 100644 (file)
@@ -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.
index e9a1912..cad659a 100644 (file)
@@ -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.
index 2022c47..02c3320 100644 (file)
@@ -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());
index e9cc6b4..51de428 100644 (file)
@@ -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);
index 7ddb3ce..23d1f08 100644 (file)
@@ -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;
index c7b4fe8..dc226e8 100644 (file)
@@ -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);